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,7 +108,7 @@ typedef struct TranslationBlock { | ||
108 | the code of this one. */ | 108 | the code of this one. */ |
109 | uint16_t tb_next_offset[2]; /* offset of original jump target */ | 109 | uint16_t tb_next_offset[2]; /* offset of original jump target */ |
110 | #ifdef USE_DIRECT_JUMP | 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 | #else | 112 | #else |
113 | uint32_t tb_next[2]; /* address of jump generated code */ | 113 | uint32_t tb_next[2]; /* address of jump generated code */ |
114 | #endif | 114 | #endif |
@@ -160,18 +160,14 @@ static inline TranslationBlock *tb_find(TranslationBlock ***pptb, | @@ -160,18 +160,14 @@ static inline TranslationBlock *tb_find(TranslationBlock ***pptb, | ||
160 | 160 | ||
161 | #if defined(__powerpc__) | 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 | uint32_t val, *ptr; | 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 | /* patch the branch destination */ | 167 | /* patch the branch destination */ |
172 | - ptr = (uint32_t *)offset; | 168 | + ptr = (uint32_t *)jmp_addr; |
173 | val = *ptr; | 169 | val = *ptr; |
174 | - val = (val & ~0x03fffffc) | ((addr - offset) & 0x03fffffc); | 170 | + val = (val & ~0x03fffffc) | ((addr - jmp_addr) & 0x03fffffc); |
175 | *ptr = val; | 171 | *ptr = val; |
176 | /* flush icache */ | 172 | /* flush icache */ |
177 | asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory"); | 173 | asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory"); |
@@ -181,6 +177,18 @@ static inline void tb_set_jmp_target(TranslationBlock *tb, | @@ -181,6 +177,18 @@ static inline void tb_set_jmp_target(TranslationBlock *tb, | ||
181 | asm volatile ("isync" : : : "memory"); | 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 | #else | 192 | #else |
185 | 193 | ||
186 | /* set the jump target */ | 194 | /* set the jump target */ |
@@ -228,6 +236,11 @@ do {\ | @@ -228,6 +236,11 @@ do {\ | ||
228 | EXIT_TB();\ | 236 | EXIT_TB();\ |
229 | } while (0) | 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 | #else | 244 | #else |
232 | 245 | ||
233 | /* jump to next block operations (more portable code, does not need | 246 | /* jump to next block operations (more portable code, does not need |
@@ -244,6 +257,12 @@ dummy_label ## n:\ | @@ -244,6 +257,12 @@ dummy_label ## n:\ | ||
244 | EXIT_TB();\ | 257 | EXIT_TB();\ |
245 | } while (0) | 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 | #endif | 266 | #endif |
248 | 267 | ||
249 | /* physical memory access */ | 268 | /* physical memory access */ |
translate.c
@@ -120,6 +120,11 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, | @@ -120,6 +120,11 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, | ||
120 | tb->tb_next_offset[0] = 0xffff; | 120 | tb->tb_next_offset[0] = 0xffff; |
121 | tb->tb_next_offset[1] = 0xffff; | 121 | tb->tb_next_offset[1] = 0xffff; |
122 | gen_code_buf = tb->tc_ptr; | 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 | gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset, | 128 | gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset, |
124 | #ifdef USE_DIRECT_JUMP | 129 | #ifdef USE_DIRECT_JUMP |
125 | tb->tb_jmp_offset, | 130 | tb->tb_jmp_offset, |