Commit 4cbb86e1c45acbad785490679e922344d5f144bf

Authored by bellard
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
@@ -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,