Revision 0a878c47 exec-all.h
b/exec-all.h | ||
---|---|---|
184 | 184 |
#if defined(USE_DIRECT_JUMP) |
185 | 185 |
|
186 | 186 |
#if defined(__powerpc__) |
187 |
static inline void flush_icache_range(unsigned long start, unsigned long stop); |
|
187 | 188 |
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr) |
188 | 189 |
{ |
189 |
uint32_t val, *ptr; |
|
190 |
/* This must be in concord with INDEX_op_goto_tb inside tcg_out_op */ |
|
191 |
uint32_t *ptr; |
|
190 | 192 |
long disp = addr - jmp_addr; |
193 |
unsigned long patch_size; |
|
191 | 194 |
|
192 | 195 |
ptr = (uint32_t *)jmp_addr; |
193 |
val = *ptr; |
|
194 | 196 |
|
195 | 197 |
if ((disp << 6) >> 6 != disp) { |
196 |
uint16_t *p1; |
|
197 |
|
|
198 |
p1 = (uint16_t *) ptr; |
|
199 |
*ptr = (val & ~0x03fffffc) | 4; |
|
200 |
p1[3] = addr >> 16; |
|
201 |
p1[5] = addr & 0xffff; |
|
198 |
ptr[0] = 0x3c000000 | (addr >> 16); /* lis 0,addr@ha */ |
|
199 |
ptr[1] = 0x60000000 | (addr & 0xffff); /* la 0,addr@l(0) */ |
|
200 |
ptr[2] = 0x7c0903a6; /* mtctr 0 */ |
|
201 |
ptr[3] = 0x4e800420; /* brctr */ |
|
202 |
patch_size = 16; |
|
202 | 203 |
} else { |
203 | 204 |
/* patch the branch destination */ |
204 |
val = (val & ~0x03fffffc) | (disp & 0x03fffffc); |
|
205 |
*ptr = val; |
|
205 |
if (disp != 16) { |
|
206 |
*ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */ |
|
207 |
patch_size = 4; |
|
208 |
} else { |
|
209 |
ptr[0] = 0x60000000; /* nop */ |
|
210 |
ptr[1] = 0x60000000; |
|
211 |
ptr[2] = 0x60000000; |
|
212 |
ptr[3] = 0x60000000; |
|
213 |
patch_size = 16; |
|
214 |
} |
|
206 | 215 |
} |
207 | 216 |
/* flush icache */ |
208 |
asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory"); |
|
209 |
asm volatile ("sync" : : : "memory"); |
|
210 |
asm volatile ("icbi 0,%0" : : "r"(ptr) : "memory"); |
|
211 |
asm volatile ("sync" : : : "memory"); |
|
212 |
asm volatile ("isync" : : : "memory"); |
|
217 |
flush_icache_range(jmp_addr, jmp_addr + patch_size); |
|
213 | 218 |
} |
214 | 219 |
#elif defined(__i386__) || defined(__x86_64__) |
215 | 220 |
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr) |
Also available in: Unified diff