Commit 4cbb86e1c45acbad785490679e922344d5f144bf
1 parent
f513a41a
added JUMP_TB2 for a third basic block exit jump point
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@380 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
32 additions
and
8 deletions
exec.h
... | ... | @@ -108,7 +108,7 @@ typedef struct TranslationBlock { |
108 | 108 | the code of this one. */ |
109 | 109 | uint16_t tb_next_offset[2]; /* offset of original jump target */ |
110 | 110 | #ifdef USE_DIRECT_JUMP |
111 | - uint16_t tb_jmp_offset[2]; /* offset of jump instruction */ | |
111 | + uint16_t tb_jmp_offset[4]; /* offset of jump instruction */ | |
112 | 112 | #else |
113 | 113 | uint32_t tb_next[2]; /* address of jump generated code */ |
114 | 114 | #endif |
... | ... | @@ -160,18 +160,14 @@ static inline TranslationBlock *tb_find(TranslationBlock ***pptb, |
160 | 160 | |
161 | 161 | #if defined(__powerpc__) |
162 | 162 | |
163 | -static inline void tb_set_jmp_target(TranslationBlock *tb, | |
164 | - int n, unsigned long addr) | |
163 | +static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr) | |
165 | 164 | { |
166 | 165 | uint32_t val, *ptr; |
167 | - unsigned long offset; | |
168 | - | |
169 | - offset = (unsigned long)(tb->tc_ptr + tb->tb_jmp_offset[n]); | |
170 | 166 | |
171 | 167 | /* patch the branch destination */ |
172 | - ptr = (uint32_t *)offset; | |
168 | + ptr = (uint32_t *)jmp_addr; | |
173 | 169 | val = *ptr; |
174 | - val = (val & ~0x03fffffc) | ((addr - offset) & 0x03fffffc); | |
170 | + val = (val & ~0x03fffffc) | ((addr - jmp_addr) & 0x03fffffc); | |
175 | 171 | *ptr = val; |
176 | 172 | /* flush icache */ |
177 | 173 | asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory"); |
... | ... | @@ -181,6 +177,18 @@ static inline void tb_set_jmp_target(TranslationBlock *tb, |
181 | 177 | asm volatile ("isync" : : : "memory"); |
182 | 178 | } |
183 | 179 | |
180 | +static inline void tb_set_jmp_target(TranslationBlock *tb, | |
181 | + int n, unsigned long addr) | |
182 | +{ | |
183 | + unsigned long offset; | |
184 | + | |
185 | + offset = tb->tb_jmp_offset[n]; | |
186 | + tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr); | |
187 | + offset = tb->tb_jmp_offset[n + 2]; | |
188 | + if (offset != 0xffff) | |
189 | + tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr); | |
190 | +} | |
191 | + | |
184 | 192 | #else |
185 | 193 | |
186 | 194 | /* set the jump target */ |
... | ... | @@ -228,6 +236,11 @@ do {\ |
228 | 236 | EXIT_TB();\ |
229 | 237 | } while (0) |
230 | 238 | |
239 | +#define JUMP_TB2(opname, tbparam, n)\ | |
240 | +do {\ | |
241 | + asm volatile ("b __op_jmp%0\n" : : "i" (n + 2));\ | |
242 | +} while (0) | |
243 | + | |
231 | 244 | #else |
232 | 245 | |
233 | 246 | /* jump to next block operations (more portable code, does not need |
... | ... | @@ -244,6 +257,12 @@ dummy_label ## n:\ |
244 | 257 | EXIT_TB();\ |
245 | 258 | } while (0) |
246 | 259 | |
260 | +/* second jump to same destination 'n' */ | |
261 | +#define JUMP_TB2(opname, tbparam, n)\ | |
262 | +do {\ | |
263 | + goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\ | |
264 | +} while (0) | |
265 | + | |
247 | 266 | #endif |
248 | 267 | |
249 | 268 | /* physical memory access */ | ... | ... |
translate.c
... | ... | @@ -120,6 +120,11 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, |
120 | 120 | tb->tb_next_offset[0] = 0xffff; |
121 | 121 | tb->tb_next_offset[1] = 0xffff; |
122 | 122 | gen_code_buf = tb->tc_ptr; |
123 | +#ifdef USE_DIRECT_JUMP | |
124 | + /* the following two entries are optional (only used for string ops) */ | |
125 | + tb->tb_jmp_offset[2] = 0xffff; | |
126 | + tb->tb_jmp_offset[3] = 0xffff; | |
127 | +#endif | |
123 | 128 | gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset, |
124 | 129 | #ifdef USE_DIRECT_JUMP |
125 | 130 | tb->tb_jmp_offset, | ... | ... |