Commit b26eefb68e7942eeb689c81fd20e67e57ad95cd2
1 parent
2a39bc41
ARM TCG conversion 1/16.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4138 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
434 additions
and
673 deletions
target-arm/cpu.h
| ... | ... | @@ -89,7 +89,7 @@ typedef struct CPUARMState { |
| 89 | 89 | uint32_t NZF; /* N is bit 31. Z is computed from NZF */ |
| 90 | 90 | uint32_t QF; /* 0 or 1 */ |
| 91 | 91 | uint32_t GE; /* cpsr[19:16] */ |
| 92 | - int thumb; /* cprs[5]. 0 = arm mode, 1 = thumb mode. */ | |
| 92 | + uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */ | |
| 93 | 93 | uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */ |
| 94 | 94 | |
| 95 | 95 | /* System control coprocessor (cp15) */ |
| ... | ... | @@ -207,6 +207,7 @@ typedef struct CPUARMState { |
| 207 | 207 | } CPUARMState; |
| 208 | 208 | |
| 209 | 209 | CPUARMState *cpu_arm_init(const char *cpu_model); |
| 210 | +void arm_translate_init(void); | |
| 210 | 211 | int cpu_arm_exec(CPUARMState *s); |
| 211 | 212 | void cpu_arm_close(CPUARMState *s); |
| 212 | 213 | void do_interrupt(CPUARMState *); | ... | ... |
target-arm/helper.c
| ... | ... | @@ -5,6 +5,7 @@ |
| 5 | 5 | #include "cpu.h" |
| 6 | 6 | #include "exec-all.h" |
| 7 | 7 | #include "gdbstub.h" |
| 8 | +#include "helpers.h" | |
| 8 | 9 | |
| 9 | 10 | static uint32_t cortexa8_cp15_c0_c1[8] = |
| 10 | 11 | { 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 }; |
| ... | ... | @@ -174,6 +175,7 @@ CPUARMState *cpu_arm_init(const char *cpu_model) |
| 174 | 175 | { |
| 175 | 176 | CPUARMState *env; |
| 176 | 177 | uint32_t id; |
| 178 | + static int inited = 0; | |
| 177 | 179 | |
| 178 | 180 | id = cpu_arm_find_by_name(cpu_model); |
| 179 | 181 | if (id == 0) |
| ... | ... | @@ -182,6 +184,11 @@ CPUARMState *cpu_arm_init(const char *cpu_model) |
| 182 | 184 | if (!env) |
| 183 | 185 | return NULL; |
| 184 | 186 | cpu_exec_init(env); |
| 187 | + if (!inited) { | |
| 188 | + inited = 1; | |
| 189 | + arm_translate_init(); | |
| 190 | + } | |
| 191 | + | |
| 185 | 192 | env->cpu_model_str = cpu_model; |
| 186 | 193 | env->cp15.c0_cpuid = id; |
| 187 | 194 | cpu_reset(env); |
| ... | ... | @@ -315,6 +322,24 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) |
| 315 | 322 | env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); |
| 316 | 323 | } |
| 317 | 324 | |
| 325 | +#define HELPER(x) helper_##x | |
| 326 | +/* Sign/zero extend */ | |
| 327 | +uint32_t HELPER(sxtb16)(uint32_t x) | |
| 328 | +{ | |
| 329 | + uint32_t res; | |
| 330 | + res = (uint16_t)(int8_t)x; | |
| 331 | + res |= (uint32_t)(int8_t)(x >> 16) << 16; | |
| 332 | + return res; | |
| 333 | +} | |
| 334 | + | |
| 335 | +uint32_t HELPER(uxtb16)(uint32_t x) | |
| 336 | +{ | |
| 337 | + uint32_t res; | |
| 338 | + res = (uint16_t)(uint8_t)x; | |
| 339 | + res |= (uint32_t)(uint8_t)(x >> 16) << 16; | |
| 340 | + return res; | |
| 341 | +} | |
| 342 | + | |
| 318 | 343 | #if defined(CONFIG_USER_ONLY) |
| 319 | 344 | |
| 320 | 345 | void do_interrupt (CPUState *env) |
| ... | ... | @@ -1861,3 +1886,4 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, |
| 1861 | 1886 | } |
| 1862 | 1887 | |
| 1863 | 1888 | #endif |
| 1889 | + | ... | ... |
target-arm/helpers.h
0 → 100644
target-arm/op.c
| ... | ... | @@ -20,122 +20,6 @@ |
| 20 | 20 | */ |
| 21 | 21 | #include "exec.h" |
| 22 | 22 | |
| 23 | -#define REGNAME r0 | |
| 24 | -#define REG (env->regs[0]) | |
| 25 | -#include "op_template.h" | |
| 26 | - | |
| 27 | -#define REGNAME r1 | |
| 28 | -#define REG (env->regs[1]) | |
| 29 | -#include "op_template.h" | |
| 30 | - | |
| 31 | -#define REGNAME r2 | |
| 32 | -#define REG (env->regs[2]) | |
| 33 | -#include "op_template.h" | |
| 34 | - | |
| 35 | -#define REGNAME r3 | |
| 36 | -#define REG (env->regs[3]) | |
| 37 | -#include "op_template.h" | |
| 38 | - | |
| 39 | -#define REGNAME r4 | |
| 40 | -#define REG (env->regs[4]) | |
| 41 | -#include "op_template.h" | |
| 42 | - | |
| 43 | -#define REGNAME r5 | |
| 44 | -#define REG (env->regs[5]) | |
| 45 | -#include "op_template.h" | |
| 46 | - | |
| 47 | -#define REGNAME r6 | |
| 48 | -#define REG (env->regs[6]) | |
| 49 | -#include "op_template.h" | |
| 50 | - | |
| 51 | -#define REGNAME r7 | |
| 52 | -#define REG (env->regs[7]) | |
| 53 | -#include "op_template.h" | |
| 54 | - | |
| 55 | -#define REGNAME r8 | |
| 56 | -#define REG (env->regs[8]) | |
| 57 | -#include "op_template.h" | |
| 58 | - | |
| 59 | -#define REGNAME r9 | |
| 60 | -#define REG (env->regs[9]) | |
| 61 | -#include "op_template.h" | |
| 62 | - | |
| 63 | -#define REGNAME r10 | |
| 64 | -#define REG (env->regs[10]) | |
| 65 | -#include "op_template.h" | |
| 66 | - | |
| 67 | -#define REGNAME r11 | |
| 68 | -#define REG (env->regs[11]) | |
| 69 | -#include "op_template.h" | |
| 70 | - | |
| 71 | -#define REGNAME r12 | |
| 72 | -#define REG (env->regs[12]) | |
| 73 | -#include "op_template.h" | |
| 74 | - | |
| 75 | -#define REGNAME r13 | |
| 76 | -#define REG (env->regs[13]) | |
| 77 | -#include "op_template.h" | |
| 78 | - | |
| 79 | -#define REGNAME r14 | |
| 80 | -#define REG (env->regs[14]) | |
| 81 | -#include "op_template.h" | |
| 82 | - | |
| 83 | -#define REGNAME r15 | |
| 84 | -#define REG (env->regs[15]) | |
| 85 | -#define SET_REG(x) REG = x & ~(uint32_t)1 | |
| 86 | -#include "op_template.h" | |
| 87 | - | |
| 88 | -void OPPROTO op_bx_T0(void) | |
| 89 | -{ | |
| 90 | - env->regs[15] = T0 & ~(uint32_t)1; | |
| 91 | - env->thumb = (T0 & 1) != 0; | |
| 92 | -} | |
| 93 | - | |
| 94 | -void OPPROTO op_movl_T0_0(void) | |
| 95 | -{ | |
| 96 | - T0 = 0; | |
| 97 | -} | |
| 98 | - | |
| 99 | -void OPPROTO op_movl_T0_im(void) | |
| 100 | -{ | |
| 101 | - T0 = PARAM1; | |
| 102 | -} | |
| 103 | - | |
| 104 | -void OPPROTO op_movl_T1_im(void) | |
| 105 | -{ | |
| 106 | - T1 = PARAM1; | |
| 107 | -} | |
| 108 | - | |
| 109 | -void OPPROTO op_mov_CF_T1(void) | |
| 110 | -{ | |
| 111 | - env->CF = ((uint32_t)T1) >> 31; | |
| 112 | -} | |
| 113 | - | |
| 114 | -void OPPROTO op_movl_T2_im(void) | |
| 115 | -{ | |
| 116 | - T2 = PARAM1; | |
| 117 | -} | |
| 118 | - | |
| 119 | -void OPPROTO op_addl_T1_im(void) | |
| 120 | -{ | |
| 121 | - T1 += PARAM1; | |
| 122 | -} | |
| 123 | - | |
| 124 | -void OPPROTO op_addl_T1_T2(void) | |
| 125 | -{ | |
| 126 | - T1 += T2; | |
| 127 | -} | |
| 128 | - | |
| 129 | -void OPPROTO op_subl_T1_T2(void) | |
| 130 | -{ | |
| 131 | - T1 -= T2; | |
| 132 | -} | |
| 133 | - | |
| 134 | -void OPPROTO op_addl_T0_T1(void) | |
| 135 | -{ | |
| 136 | - T0 += T1; | |
| 137 | -} | |
| 138 | - | |
| 139 | 23 | void OPPROTO op_addl_T0_T1_cc(void) |
| 140 | 24 | { |
| 141 | 25 | unsigned int src1; |
| ... | ... | @@ -146,11 +30,6 @@ void OPPROTO op_addl_T0_T1_cc(void) |
| 146 | 30 | env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0); |
| 147 | 31 | } |
| 148 | 32 | |
| 149 | -void OPPROTO op_adcl_T0_T1(void) | |
| 150 | -{ | |
| 151 | - T0 += T1 + env->CF; | |
| 152 | -} | |
| 153 | - | |
| 154 | 33 | void OPPROTO op_adcl_T0_T1_cc(void) |
| 155 | 34 | { |
| 156 | 35 | unsigned int src1; |
| ... | ... | @@ -169,11 +48,6 @@ void OPPROTO op_adcl_T0_T1_cc(void) |
| 169 | 48 | |
| 170 | 49 | #define OPSUB(sub, sbc, res, T0, T1) \ |
| 171 | 50 | \ |
| 172 | -void OPPROTO op_ ## sub ## l_T0_T1(void) \ | |
| 173 | -{ \ | |
| 174 | - res = T0 - T1; \ | |
| 175 | -} \ | |
| 176 | - \ | |
| 177 | 51 | void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \ |
| 178 | 52 | { \ |
| 179 | 53 | unsigned int src1; \ |
| ... | ... | @@ -211,46 +85,6 @@ OPSUB(sub, sbc, T0, T0, T1) |
| 211 | 85 | |
| 212 | 86 | OPSUB(rsb, rsc, T0, T1, T0) |
| 213 | 87 | |
| 214 | -void OPPROTO op_andl_T0_T1(void) | |
| 215 | -{ | |
| 216 | - T0 &= T1; | |
| 217 | -} | |
| 218 | - | |
| 219 | -void OPPROTO op_xorl_T0_T1(void) | |
| 220 | -{ | |
| 221 | - T0 ^= T1; | |
| 222 | -} | |
| 223 | - | |
| 224 | -void OPPROTO op_orl_T0_T1(void) | |
| 225 | -{ | |
| 226 | - T0 |= T1; | |
| 227 | -} | |
| 228 | - | |
| 229 | -void OPPROTO op_bicl_T0_T1(void) | |
| 230 | -{ | |
| 231 | - T0 &= ~T1; | |
| 232 | -} | |
| 233 | - | |
| 234 | -void OPPROTO op_notl_T0(void) | |
| 235 | -{ | |
| 236 | - T0 = ~T0; | |
| 237 | -} | |
| 238 | - | |
| 239 | -void OPPROTO op_notl_T1(void) | |
| 240 | -{ | |
| 241 | - T1 = ~T1; | |
| 242 | -} | |
| 243 | - | |
| 244 | -void OPPROTO op_logic_T0_cc(void) | |
| 245 | -{ | |
| 246 | - env->NZF = T0; | |
| 247 | -} | |
| 248 | - | |
| 249 | -void OPPROTO op_logic_T1_cc(void) | |
| 250 | -{ | |
| 251 | - env->NZF = T1; | |
| 252 | -} | |
| 253 | - | |
| 254 | 88 | #define EIP (env->regs[15]) |
| 255 | 89 | |
| 256 | 90 | void OPPROTO op_test_eq(void) |
| ... | ... | @@ -485,51 +319,6 @@ void OPPROTO op_clrex(void) |
| 485 | 319 | |
| 486 | 320 | /* shifts */ |
| 487 | 321 | |
| 488 | -/* Used by NEON. */ | |
| 489 | -void OPPROTO op_shll_T0_im(void) | |
| 490 | -{ | |
| 491 | - T1 = T1 << PARAM1; | |
| 492 | -} | |
| 493 | - | |
| 494 | -/* T1 based */ | |
| 495 | - | |
| 496 | -void OPPROTO op_shll_T1_im(void) | |
| 497 | -{ | |
| 498 | - T1 = T1 << PARAM1; | |
| 499 | -} | |
| 500 | - | |
| 501 | -void OPPROTO op_shrl_T1_im(void) | |
| 502 | -{ | |
| 503 | - T1 = (uint32_t)T1 >> PARAM1; | |
| 504 | -} | |
| 505 | - | |
| 506 | -void OPPROTO op_shrl_T1_0(void) | |
| 507 | -{ | |
| 508 | - T1 = 0; | |
| 509 | -} | |
| 510 | - | |
| 511 | -void OPPROTO op_sarl_T1_im(void) | |
| 512 | -{ | |
| 513 | - T1 = (int32_t)T1 >> PARAM1; | |
| 514 | -} | |
| 515 | - | |
| 516 | -void OPPROTO op_sarl_T1_0(void) | |
| 517 | -{ | |
| 518 | - T1 = (int32_t)T1 >> 31; | |
| 519 | -} | |
| 520 | - | |
| 521 | -void OPPROTO op_rorl_T1_im(void) | |
| 522 | -{ | |
| 523 | - int shift; | |
| 524 | - shift = PARAM1; | |
| 525 | - T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift)); | |
| 526 | -} | |
| 527 | - | |
| 528 | -void OPPROTO op_rrxl_T1(void) | |
| 529 | -{ | |
| 530 | - T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31); | |
| 531 | -} | |
| 532 | - | |
| 533 | 322 | /* T1 based, set C flag */ |
| 534 | 323 | void OPPROTO op_shll_T1_im_cc(void) |
| 535 | 324 | { |
| ... | ... | @@ -577,44 +366,6 @@ void OPPROTO op_rrxl_T1_cc(void) |
| 577 | 366 | env->CF = c; |
| 578 | 367 | } |
| 579 | 368 | |
| 580 | -/* T2 based */ | |
| 581 | -void OPPROTO op_shll_T2_im(void) | |
| 582 | -{ | |
| 583 | - T2 = T2 << PARAM1; | |
| 584 | -} | |
| 585 | - | |
| 586 | -void OPPROTO op_shrl_T2_im(void) | |
| 587 | -{ | |
| 588 | - T2 = (uint32_t)T2 >> PARAM1; | |
| 589 | -} | |
| 590 | - | |
| 591 | -void OPPROTO op_shrl_T2_0(void) | |
| 592 | -{ | |
| 593 | - T2 = 0; | |
| 594 | -} | |
| 595 | - | |
| 596 | -void OPPROTO op_sarl_T2_im(void) | |
| 597 | -{ | |
| 598 | - T2 = (int32_t)T2 >> PARAM1; | |
| 599 | -} | |
| 600 | - | |
| 601 | -void OPPROTO op_sarl_T2_0(void) | |
| 602 | -{ | |
| 603 | - T2 = (int32_t)T2 >> 31; | |
| 604 | -} | |
| 605 | - | |
| 606 | -void OPPROTO op_rorl_T2_im(void) | |
| 607 | -{ | |
| 608 | - int shift; | |
| 609 | - shift = PARAM1; | |
| 610 | - T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift)); | |
| 611 | -} | |
| 612 | - | |
| 613 | -void OPPROTO op_rrxl_T2(void) | |
| 614 | -{ | |
| 615 | - T2 = ((uint32_t)T2 >> 1) | ((uint32_t)env->CF << 31); | |
| 616 | -} | |
| 617 | - | |
| 618 | 369 | /* T1 based, use T0 as shift count */ |
| 619 | 370 | |
| 620 | 371 | void OPPROTO op_shll_T1_T0(void) |
| ... | ... | @@ -733,53 +484,6 @@ void OPPROTO op_clz_T0(void) |
| 733 | 484 | FORCE_RET(); |
| 734 | 485 | } |
| 735 | 486 | |
| 736 | -void OPPROTO op_sarl_T0_im(void) | |
| 737 | -{ | |
| 738 | - T0 = (int32_t)T0 >> PARAM1; | |
| 739 | -} | |
| 740 | - | |
| 741 | -/* Sign/zero extend */ | |
| 742 | -void OPPROTO op_sxth_T0(void) | |
| 743 | -{ | |
| 744 | - T0 = (int16_t)T0; | |
| 745 | -} | |
| 746 | - | |
| 747 | -void OPPROTO op_sxth_T1(void) | |
| 748 | -{ | |
| 749 | - T1 = (int16_t)T1; | |
| 750 | -} | |
| 751 | - | |
| 752 | -void OPPROTO op_sxtb_T1(void) | |
| 753 | -{ | |
| 754 | - T1 = (int8_t)T1; | |
| 755 | -} | |
| 756 | - | |
| 757 | -void OPPROTO op_uxtb_T1(void) | |
| 758 | -{ | |
| 759 | - T1 = (uint8_t)T1; | |
| 760 | -} | |
| 761 | - | |
| 762 | -void OPPROTO op_uxth_T1(void) | |
| 763 | -{ | |
| 764 | - T1 = (uint16_t)T1; | |
| 765 | -} | |
| 766 | - | |
| 767 | -void OPPROTO op_sxtb16_T1(void) | |
| 768 | -{ | |
| 769 | - uint32_t res; | |
| 770 | - res = (uint16_t)(int8_t)T1; | |
| 771 | - res |= (uint32_t)(int8_t)(T1 >> 16) << 16; | |
| 772 | - T1 = res; | |
| 773 | -} | |
| 774 | - | |
| 775 | -void OPPROTO op_uxtb16_T1(void) | |
| 776 | -{ | |
| 777 | - uint32_t res; | |
| 778 | - res = (uint16_t)(uint8_t)T1; | |
| 779 | - res |= (uint32_t)(uint8_t)(T1 >> 16) << 16; | |
| 780 | - T1 = res; | |
| 781 | -} | |
| 782 | - | |
| 783 | 487 | #define SIGNBIT (uint32_t)0x80000000 |
| 784 | 488 | /* saturating arithmetic */ |
| 785 | 489 | void OPPROTO op_addl_T0_T1_setq(void) |
| ... | ... | @@ -1369,31 +1073,6 @@ void OPPROTO op_movl_user_T0(void) |
| 1369 | 1073 | FORCE_RET(); |
| 1370 | 1074 | } |
| 1371 | 1075 | |
| 1372 | -void OPPROTO op_movl_T0_T1(void) | |
| 1373 | -{ | |
| 1374 | - T0 = T1; | |
| 1375 | -} | |
| 1376 | - | |
| 1377 | -void OPPROTO op_movl_T0_T2(void) | |
| 1378 | -{ | |
| 1379 | - T0 = T2; | |
| 1380 | -} | |
| 1381 | - | |
| 1382 | -void OPPROTO op_movl_T1_T0(void) | |
| 1383 | -{ | |
| 1384 | - T1 = T0; | |
| 1385 | -} | |
| 1386 | - | |
| 1387 | -void OPPROTO op_movl_T1_T2(void) | |
| 1388 | -{ | |
| 1389 | - T1 = T2; | |
| 1390 | -} | |
| 1391 | - | |
| 1392 | -void OPPROTO op_movl_T2_T0(void) | |
| 1393 | -{ | |
| 1394 | - T2 = T0; | |
| 1395 | -} | |
| 1396 | - | |
| 1397 | 1076 | /* ARMv6 Media instructions. */ |
| 1398 | 1077 | |
| 1399 | 1078 | /* Note that signed overflow is undefined in C. The following routines are |
| ... | ... | @@ -1769,15 +1448,6 @@ void OPPROTO op_usat16_T1(void) |
| 1769 | 1448 | } |
| 1770 | 1449 | |
| 1771 | 1450 | /* Dual 16-bit add. */ |
| 1772 | -void OPPROTO op_add16_T1_T2(void) | |
| 1773 | -{ | |
| 1774 | - uint32_t mask; | |
| 1775 | - mask = (T0 & T1) & 0x8000; | |
| 1776 | - T0 ^= ~0x8000; | |
| 1777 | - T1 ^= ~0x8000; | |
| 1778 | - T0 = (T0 + T1) ^ mask; | |
| 1779 | -} | |
| 1780 | - | |
| 1781 | 1451 | static inline uint8_t do_usad(uint8_t a, uint8_t b) |
| 1782 | 1452 | { |
| 1783 | 1453 | if (a > b) | ... | ... |
target-arm/op_template.h deleted
100644 → 0
| 1 | -/* | |
| 2 | - * ARM micro operations (templates for various register related | |
| 3 | - * operations) | |
| 4 | - * | |
| 5 | - * Copyright (c) 2003 Fabrice Bellard | |
| 6 | - * | |
| 7 | - * This library is free software; you can redistribute it and/or | |
| 8 | - * modify it under the terms of the GNU Lesser General Public | |
| 9 | - * License as published by the Free Software Foundation; either | |
| 10 | - * version 2 of the License, or (at your option) any later version. | |
| 11 | - * | |
| 12 | - * This library is distributed in the hope that it will be useful, | |
| 13 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | - * Lesser General Public License for more details. | |
| 16 | - * | |
| 17 | - * You should have received a copy of the GNU Lesser General Public | |
| 18 | - * License along with this library; if not, write to the Free Software | |
| 19 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 20 | - */ | |
| 21 | - | |
| 22 | -#ifndef SET_REG | |
| 23 | -#define SET_REG(x) REG = x | |
| 24 | -#endif | |
| 25 | - | |
| 26 | -void OPPROTO glue(op_movl_T0_, REGNAME)(void) | |
| 27 | -{ | |
| 28 | - T0 = REG; | |
| 29 | -} | |
| 30 | - | |
| 31 | -void OPPROTO glue(op_movl_T1_, REGNAME)(void) | |
| 32 | -{ | |
| 33 | - T1 = REG; | |
| 34 | -} | |
| 35 | - | |
| 36 | -void OPPROTO glue(op_movl_T2_, REGNAME)(void) | |
| 37 | -{ | |
| 38 | - T2 = REG; | |
| 39 | -} | |
| 40 | - | |
| 41 | -void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void) | |
| 42 | -{ | |
| 43 | - SET_REG (T0); | |
| 44 | -} | |
| 45 | - | |
| 46 | -void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void) | |
| 47 | -{ | |
| 48 | - SET_REG (T1); | |
| 49 | -} | |
| 50 | - | |
| 51 | -#undef REG | |
| 52 | -#undef REGNAME | |
| 53 | -#undef SET_REG |
target-arm/translate.c
| ... | ... | @@ -29,6 +29,7 @@ |
| 29 | 29 | #include "exec-all.h" |
| 30 | 30 | #include "disas.h" |
| 31 | 31 | #include "tcg-op.h" |
| 32 | +#include "helpers.h" | |
| 32 | 33 | |
| 33 | 34 | #define ENABLE_ARCH_5J 0 |
| 34 | 35 | #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6) |
| ... | ... | @@ -73,6 +74,240 @@ typedef struct DisasContext { |
| 73 | 74 | extern FILE *logfile; |
| 74 | 75 | extern int loglevel; |
| 75 | 76 | |
| 77 | +static TCGv cpu_env; | |
| 78 | +/* FIXME: These should be removed. */ | |
| 79 | +static TCGv cpu_T[3]; | |
| 80 | + | |
| 81 | +/* initialize TCG globals. */ | |
| 82 | +void arm_translate_init(void) | |
| 83 | +{ | |
| 84 | + cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env"); | |
| 85 | + | |
| 86 | + cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0"); | |
| 87 | + cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1"); | |
| 88 | + cpu_T[2] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG3, "T2"); | |
| 89 | +} | |
| 90 | + | |
| 91 | +/* The code generator doesn't like lots of temporaries, so maintain our own | |
| 92 | + cache for reuse within a function. */ | |
| 93 | +#define MAX_TEMPS 8 | |
| 94 | +static int num_temps; | |
| 95 | +static TCGv temps[MAX_TEMPS]; | |
| 96 | + | |
| 97 | +/* Allocate a temporary variable. */ | |
| 98 | +static TCGv new_tmp(void) | |
| 99 | +{ | |
| 100 | + TCGv tmp; | |
| 101 | + if (num_temps == MAX_TEMPS) | |
| 102 | + abort(); | |
| 103 | + | |
| 104 | + if (GET_TCGV(temps[num_temps])) | |
| 105 | + return temps[num_temps++]; | |
| 106 | + | |
| 107 | + tmp = tcg_temp_new(TCG_TYPE_I32); | |
| 108 | + temps[num_temps++] = tmp; | |
| 109 | + return tmp; | |
| 110 | +} | |
| 111 | + | |
| 112 | +/* Release a temporary variable. */ | |
| 113 | +static void dead_tmp(TCGv tmp) | |
| 114 | +{ | |
| 115 | + int i; | |
| 116 | + num_temps--; | |
| 117 | + i = num_temps; | |
| 118 | + if (GET_TCGV(temps[i]) == GET_TCGV(tmp)) | |
| 119 | + return; | |
| 120 | + | |
| 121 | + /* Shuffle this temp to the last slot. */ | |
| 122 | + while (GET_TCGV(temps[i]) != GET_TCGV(tmp)) | |
| 123 | + i--; | |
| 124 | + while (i < num_temps) { | |
| 125 | + temps[i] = temps[i + 1]; | |
| 126 | + i++; | |
| 127 | + } | |
| 128 | + temps[i] = tmp; | |
| 129 | +} | |
| 130 | + | |
| 131 | +/* Set a variable to the value of a CPU register. */ | |
| 132 | +static void load_reg_var(DisasContext *s, TCGv var, int reg) | |
| 133 | +{ | |
| 134 | + if (reg == 15) { | |
| 135 | + uint32_t addr; | |
| 136 | + /* normaly, since we updated PC, we need only to add one insn */ | |
| 137 | + if (s->thumb) | |
| 138 | + addr = (long)s->pc + 2; | |
| 139 | + else | |
| 140 | + addr = (long)s->pc + 4; | |
| 141 | + tcg_gen_movi_i32(var, addr); | |
| 142 | + } else { | |
| 143 | + tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg])); | |
| 144 | + } | |
| 145 | +} | |
| 146 | + | |
| 147 | +/* Create a new temporary and set it to the value of a CPU register. */ | |
| 148 | +static inline TCGv load_reg(DisasContext *s, int reg) | |
| 149 | +{ | |
| 150 | + TCGv tmp = new_tmp(); | |
| 151 | + load_reg_var(s, tmp, reg); | |
| 152 | + return tmp; | |
| 153 | +} | |
| 154 | + | |
| 155 | +/* Set a CPU register. The source must be a temporary and will be | |
| 156 | + marked as dead. */ | |
| 157 | +static void store_reg(DisasContext *s, int reg, TCGv var) | |
| 158 | +{ | |
| 159 | + if (reg == 15) { | |
| 160 | + tcg_gen_andi_i32(var, var, ~1); | |
| 161 | + s->is_jmp = DISAS_JUMP; | |
| 162 | + } | |
| 163 | + tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg])); | |
| 164 | + dead_tmp(var); | |
| 165 | +} | |
| 166 | + | |
| 167 | + | |
| 168 | +/* Basic operations. */ | |
| 169 | +#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1]) | |
| 170 | +#define gen_op_movl_T0_T2() tcg_gen_mov_i32(cpu_T[0], cpu_T[2]) | |
| 171 | +#define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0]) | |
| 172 | +#define gen_op_movl_T1_T2() tcg_gen_mov_i32(cpu_T[1], cpu_T[2]) | |
| 173 | +#define gen_op_movl_T2_T0() tcg_gen_mov_i32(cpu_T[2], cpu_T[0]) | |
| 174 | +#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im) | |
| 175 | +#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im) | |
| 176 | +#define gen_op_movl_T2_im(im) tcg_gen_movi_i32(cpu_T[2], im) | |
| 177 | + | |
| 178 | +#define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im) | |
| 179 | +#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1]) | |
| 180 | +#define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1]) | |
| 181 | +#define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0]) | |
| 182 | + | |
| 183 | +#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]) | |
| 184 | +#define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1]) | |
| 185 | +#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1]) | |
| 186 | +#define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0]) | |
| 187 | +#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1]) | |
| 188 | +#define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]); | |
| 189 | +#define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]); | |
| 190 | + | |
| 191 | +#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im) | |
| 192 | +#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im) | |
| 193 | +#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im) | |
| 194 | +#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im) | |
| 195 | +#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im) | |
| 196 | + | |
| 197 | +/* Value extensions. */ | |
| 198 | +#define gen_uxtb(var) tcg_gen_andi_i32(var, var, 0xff) | |
| 199 | +#define gen_uxth(var) tcg_gen_andi_i32(var, var, 0xffff) | |
| 200 | +#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var) | |
| 201 | +#define gen_sxth(var) tcg_gen_ext16s_i32(var, var) | |
| 202 | + | |
| 203 | +#define HELPER_ADDR(x) helper_##x | |
| 204 | + | |
| 205 | +#define gen_sxtb16(var) tcg_gen_helper_1_1(HELPER_ADDR(sxtb16), var, var) | |
| 206 | +#define gen_uxtb16(var) tcg_gen_helper_1_1(HELPER_ADDR(uxtb16), var, var) | |
| 207 | + | |
| 208 | +/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead. | |
| 209 | + tmp = (t0 ^ t1) & 0x8000; | |
| 210 | + t0 &= ~0x8000; | |
| 211 | + t1 &= ~0x8000; | |
| 212 | + t0 = (t0 + t1) ^ tmp; | |
| 213 | + */ | |
| 214 | + | |
| 215 | +static void gen_add16(TCGv t0, TCGv t1) | |
| 216 | +{ | |
| 217 | + TCGv tmp = new_tmp(); | |
| 218 | + tcg_gen_xor_i32(tmp, t0, t1); | |
| 219 | + tcg_gen_andi_i32(tmp, tmp, 0x8000); | |
| 220 | + tcg_gen_andi_i32(t0, t0, ~0x8000); | |
| 221 | + tcg_gen_andi_i32(t1, t1, ~0x8000); | |
| 222 | + tcg_gen_add_i32(t0, t0, t1); | |
| 223 | + tcg_gen_xor_i32(t0, t0, tmp); | |
| 224 | + dead_tmp(tmp); | |
| 225 | + dead_tmp(t1); | |
| 226 | +} | |
| 227 | + | |
| 228 | +/* Set CF to the top bit of var. */ | |
| 229 | +static void gen_set_CF_bit31(TCGv var) | |
| 230 | +{ | |
| 231 | + TCGv tmp = new_tmp(); | |
| 232 | + tcg_gen_shri_i32(tmp, var, 31); | |
| 233 | + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, CF)); | |
| 234 | + dead_tmp(tmp); | |
| 235 | +} | |
| 236 | + | |
| 237 | +/* Set N and Z flags from var. */ | |
| 238 | +static inline void gen_logic_CC(TCGv var) | |
| 239 | +{ | |
| 240 | + tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NZF)); | |
| 241 | +} | |
| 242 | + | |
| 243 | +/* T0 += T1 + CF. */ | |
| 244 | +static void gen_adc_T0_T1(void) | |
| 245 | +{ | |
| 246 | + TCGv tmp = new_tmp(); | |
| 247 | + gen_op_addl_T0_T1(); | |
| 248 | + tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF)); | |
| 249 | + tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp); | |
| 250 | + dead_tmp(tmp); | |
| 251 | +} | |
| 252 | + | |
| 253 | +/* FIXME: Implement this natively. */ | |
| 254 | +static inline void tcg_gen_not_i32(TCGv t0, TCGv t1) | |
| 255 | +{ | |
| 256 | + tcg_gen_xori_i32(t0, t1, ~0); | |
| 257 | +} | |
| 258 | + | |
| 259 | +/* T0 &= ~T1. Clobbers T1. */ | |
| 260 | +/* FIXME: Implement bic natively. */ | |
| 261 | +static inline void gen_op_bicl_T0_T1(void) | |
| 262 | +{ | |
| 263 | + gen_op_notl_T1(); | |
| 264 | + gen_op_andl_T0_T1(); | |
| 265 | +} | |
| 266 | + | |
| 267 | +/* FIXME: Implement this natively. */ | |
| 268 | +static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i) | |
| 269 | +{ | |
| 270 | + TCGv tmp; | |
| 271 | + | |
| 272 | + if (i == 0) | |
| 273 | + return; | |
| 274 | + | |
| 275 | + tmp = new_tmp(); | |
| 276 | + tcg_gen_shri_i32(tmp, t1, i); | |
| 277 | + tcg_gen_shli_i32(t1, t1, 32 - i); | |
| 278 | + tcg_gen_or_i32(t0, t1, tmp); | |
| 279 | + dead_tmp(tmp); | |
| 280 | +} | |
| 281 | + | |
| 282 | +/* Shift by immediate. Includes special handling for shift == 0. */ | |
| 283 | +static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift) | |
| 284 | +{ | |
| 285 | + if (shift != 0) { | |
| 286 | + switch (shiftop) { | |
| 287 | + case 0: tcg_gen_shli_i32(var, var, shift); break; | |
| 288 | + case 1: tcg_gen_shri_i32(var, var, shift); break; | |
| 289 | + case 2: tcg_gen_sari_i32(var, var, shift); break; | |
| 290 | + case 3: tcg_gen_rori_i32(var, var, shift); break; | |
| 291 | + } | |
| 292 | + } else { | |
| 293 | + TCGv tmp; | |
| 294 | + | |
| 295 | + switch (shiftop) { | |
| 296 | + case 0: break; | |
| 297 | + case 1: tcg_gen_movi_i32(var, 0); break; | |
| 298 | + case 2: tcg_gen_sari_i32(var, var, 31); break; | |
| 299 | + case 3: /* rrx */ | |
| 300 | + tcg_gen_shri_i32(var, var, 1); | |
| 301 | + tmp = new_tmp(); | |
| 302 | + tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF)); | |
| 303 | + tcg_gen_shli_i32(tmp, tmp, 31); | |
| 304 | + tcg_gen_or_i32(var, var, tmp); | |
| 305 | + dead_tmp(tmp); | |
| 306 | + break; | |
| 307 | + } | |
| 308 | + } | |
| 309 | +}; | |
| 310 | + | |
| 76 | 311 | #define PAS_OP(pfx) { \ |
| 77 | 312 | gen_op_ ## pfx ## add16_T0_T1, \ |
| 78 | 313 | gen_op_ ## pfx ## addsubx_T0_T1, \ |
| ... | ... | @@ -154,34 +389,6 @@ const uint8_t table_logic_cc[16] = { |
| 154 | 389 | 1, /* mvn */ |
| 155 | 390 | }; |
| 156 | 391 | |
| 157 | -static GenOpFunc1 *gen_shift_T1_im[4] = { | |
| 158 | - gen_op_shll_T1_im, | |
| 159 | - gen_op_shrl_T1_im, | |
| 160 | - gen_op_sarl_T1_im, | |
| 161 | - gen_op_rorl_T1_im, | |
| 162 | -}; | |
| 163 | - | |
| 164 | -static GenOpFunc *gen_shift_T1_0[4] = { | |
| 165 | - NULL, | |
| 166 | - gen_op_shrl_T1_0, | |
| 167 | - gen_op_sarl_T1_0, | |
| 168 | - gen_op_rrxl_T1, | |
| 169 | -}; | |
| 170 | - | |
| 171 | -static GenOpFunc1 *gen_shift_T2_im[4] = { | |
| 172 | - gen_op_shll_T2_im, | |
| 173 | - gen_op_shrl_T2_im, | |
| 174 | - gen_op_sarl_T2_im, | |
| 175 | - gen_op_rorl_T2_im, | |
| 176 | -}; | |
| 177 | - | |
| 178 | -static GenOpFunc *gen_shift_T2_0[4] = { | |
| 179 | - NULL, | |
| 180 | - gen_op_shrl_T2_0, | |
| 181 | - gen_op_sarl_T2_0, | |
| 182 | - gen_op_rrxl_T2, | |
| 183 | -}; | |
| 184 | - | |
| 185 | 392 | static GenOpFunc1 *gen_shift_T1_im_cc[4] = { |
| 186 | 393 | gen_op_shll_T1_im_cc, |
| 187 | 394 | gen_op_shrl_T1_im_cc, |
| ... | ... | @@ -210,108 +417,6 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = { |
| 210 | 417 | gen_op_rorl_T1_T0_cc, |
| 211 | 418 | }; |
| 212 | 419 | |
| 213 | -static GenOpFunc *gen_op_movl_TN_reg[3][16] = { | |
| 214 | - { | |
| 215 | - gen_op_movl_T0_r0, | |
| 216 | - gen_op_movl_T0_r1, | |
| 217 | - gen_op_movl_T0_r2, | |
| 218 | - gen_op_movl_T0_r3, | |
| 219 | - gen_op_movl_T0_r4, | |
| 220 | - gen_op_movl_T0_r5, | |
| 221 | - gen_op_movl_T0_r6, | |
| 222 | - gen_op_movl_T0_r7, | |
| 223 | - gen_op_movl_T0_r8, | |
| 224 | - gen_op_movl_T0_r9, | |
| 225 | - gen_op_movl_T0_r10, | |
| 226 | - gen_op_movl_T0_r11, | |
| 227 | - gen_op_movl_T0_r12, | |
| 228 | - gen_op_movl_T0_r13, | |
| 229 | - gen_op_movl_T0_r14, | |
| 230 | - gen_op_movl_T0_r15, | |
| 231 | - }, | |
| 232 | - { | |
| 233 | - gen_op_movl_T1_r0, | |
| 234 | - gen_op_movl_T1_r1, | |
| 235 | - gen_op_movl_T1_r2, | |
| 236 | - gen_op_movl_T1_r3, | |
| 237 | - gen_op_movl_T1_r4, | |
| 238 | - gen_op_movl_T1_r5, | |
| 239 | - gen_op_movl_T1_r6, | |
| 240 | - gen_op_movl_T1_r7, | |
| 241 | - gen_op_movl_T1_r8, | |
| 242 | - gen_op_movl_T1_r9, | |
| 243 | - gen_op_movl_T1_r10, | |
| 244 | - gen_op_movl_T1_r11, | |
| 245 | - gen_op_movl_T1_r12, | |
| 246 | - gen_op_movl_T1_r13, | |
| 247 | - gen_op_movl_T1_r14, | |
| 248 | - gen_op_movl_T1_r15, | |
| 249 | - }, | |
| 250 | - { | |
| 251 | - gen_op_movl_T2_r0, | |
| 252 | - gen_op_movl_T2_r1, | |
| 253 | - gen_op_movl_T2_r2, | |
| 254 | - gen_op_movl_T2_r3, | |
| 255 | - gen_op_movl_T2_r4, | |
| 256 | - gen_op_movl_T2_r5, | |
| 257 | - gen_op_movl_T2_r6, | |
| 258 | - gen_op_movl_T2_r7, | |
| 259 | - gen_op_movl_T2_r8, | |
| 260 | - gen_op_movl_T2_r9, | |
| 261 | - gen_op_movl_T2_r10, | |
| 262 | - gen_op_movl_T2_r11, | |
| 263 | - gen_op_movl_T2_r12, | |
| 264 | - gen_op_movl_T2_r13, | |
| 265 | - gen_op_movl_T2_r14, | |
| 266 | - gen_op_movl_T2_r15, | |
| 267 | - }, | |
| 268 | -}; | |
| 269 | - | |
| 270 | -static GenOpFunc *gen_op_movl_reg_TN[2][16] = { | |
| 271 | - { | |
| 272 | - gen_op_movl_r0_T0, | |
| 273 | - gen_op_movl_r1_T0, | |
| 274 | - gen_op_movl_r2_T0, | |
| 275 | - gen_op_movl_r3_T0, | |
| 276 | - gen_op_movl_r4_T0, | |
| 277 | - gen_op_movl_r5_T0, | |
| 278 | - gen_op_movl_r6_T0, | |
| 279 | - gen_op_movl_r7_T0, | |
| 280 | - gen_op_movl_r8_T0, | |
| 281 | - gen_op_movl_r9_T0, | |
| 282 | - gen_op_movl_r10_T0, | |
| 283 | - gen_op_movl_r11_T0, | |
| 284 | - gen_op_movl_r12_T0, | |
| 285 | - gen_op_movl_r13_T0, | |
| 286 | - gen_op_movl_r14_T0, | |
| 287 | - gen_op_movl_r15_T0, | |
| 288 | - }, | |
| 289 | - { | |
| 290 | - gen_op_movl_r0_T1, | |
| 291 | - gen_op_movl_r1_T1, | |
| 292 | - gen_op_movl_r2_T1, | |
| 293 | - gen_op_movl_r3_T1, | |
| 294 | - gen_op_movl_r4_T1, | |
| 295 | - gen_op_movl_r5_T1, | |
| 296 | - gen_op_movl_r6_T1, | |
| 297 | - gen_op_movl_r7_T1, | |
| 298 | - gen_op_movl_r8_T1, | |
| 299 | - gen_op_movl_r9_T1, | |
| 300 | - gen_op_movl_r10_T1, | |
| 301 | - gen_op_movl_r11_T1, | |
| 302 | - gen_op_movl_r12_T1, | |
| 303 | - gen_op_movl_r13_T1, | |
| 304 | - gen_op_movl_r14_T1, | |
| 305 | - gen_op_movl_r15_T1, | |
| 306 | - }, | |
| 307 | -}; | |
| 308 | - | |
| 309 | -static GenOpFunc1 *gen_op_movl_TN_im[3] = { | |
| 310 | - gen_op_movl_T0_im, | |
| 311 | - gen_op_movl_T1_im, | |
| 312 | - gen_op_movl_T2_im, | |
| 313 | -}; | |
| 314 | - | |
| 315 | 420 | static GenOpFunc1 *gen_shift_T0_im_thumb_cc[3] = { |
| 316 | 421 | gen_op_shll_T0_im_thumb_cc, |
| 317 | 422 | gen_op_shrl_T0_im_thumb_cc, |
| ... | ... | @@ -324,12 +429,19 @@ static GenOpFunc1 *gen_shift_T0_im_thumb[3] = { |
| 324 | 429 | gen_op_sarl_T0_im_thumb, |
| 325 | 430 | }; |
| 326 | 431 | |
| 432 | +/* Set PC and thumb state from T0. Clobbers T0. */ | |
| 327 | 433 | static inline void gen_bx(DisasContext *s) |
| 328 | 434 | { |
| 329 | - s->is_jmp = DISAS_UPDATE; | |
| 330 | - gen_op_bx_T0(); | |
| 331 | -} | |
| 435 | + TCGv tmp; | |
| 332 | 436 | |
| 437 | + s->is_jmp = DISAS_UPDATE; | |
| 438 | + tmp = new_tmp(); | |
| 439 | + tcg_gen_andi_i32(tmp, cpu_T[0], 1); | |
| 440 | + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb)); | |
| 441 | + dead_tmp(tmp); | |
| 442 | + tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ~1); | |
| 443 | + tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, regs[15])); | |
| 444 | +} | |
| 333 | 445 | |
| 334 | 446 | #if defined(CONFIG_USER_ONLY) |
| 335 | 447 | #define gen_ldst(name, s) gen_op_##name##_raw() |
| ... | ... | @@ -343,41 +455,38 @@ static inline void gen_bx(DisasContext *s) |
| 343 | 455 | } while (0) |
| 344 | 456 | #endif |
| 345 | 457 | |
| 346 | -static inline void gen_movl_TN_reg(DisasContext *s, int reg, int t) | |
| 347 | -{ | |
| 348 | - int val; | |
| 349 | - | |
| 350 | - if (reg == 15) { | |
| 351 | - /* normaly, since we updated PC, we need only to add one insn */ | |
| 352 | - if (s->thumb) | |
| 353 | - val = (long)s->pc + 2; | |
| 354 | - else | |
| 355 | - val = (long)s->pc + 4; | |
| 356 | - gen_op_movl_TN_im[t](val); | |
| 357 | - } else { | |
| 358 | - gen_op_movl_TN_reg[t][reg](); | |
| 359 | - } | |
| 360 | -} | |
| 361 | - | |
| 362 | 458 | static inline void gen_movl_T0_reg(DisasContext *s, int reg) |
| 363 | 459 | { |
| 364 | - gen_movl_TN_reg(s, reg, 0); | |
| 460 | + load_reg_var(s, cpu_T[0], reg); | |
| 365 | 461 | } |
| 366 | 462 | |
| 367 | 463 | static inline void gen_movl_T1_reg(DisasContext *s, int reg) |
| 368 | 464 | { |
| 369 | - gen_movl_TN_reg(s, reg, 1); | |
| 465 | + load_reg_var(s, cpu_T[1], reg); | |
| 370 | 466 | } |
| 371 | 467 | |
| 372 | 468 | static inline void gen_movl_T2_reg(DisasContext *s, int reg) |
| 373 | 469 | { |
| 374 | - gen_movl_TN_reg(s, reg, 2); | |
| 470 | + load_reg_var(s, cpu_T[2], reg); | |
| 471 | +} | |
| 472 | + | |
| 473 | +static inline void gen_set_pc_T0(void) | |
| 474 | +{ | |
| 475 | + tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, regs[15])); | |
| 375 | 476 | } |
| 376 | 477 | |
| 377 | 478 | static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t) |
| 378 | 479 | { |
| 379 | - gen_op_movl_reg_TN[t][reg](); | |
| 480 | + TCGv tmp; | |
| 481 | + if (reg == 15) { | |
| 482 | + tmp = new_tmp(); | |
| 483 | + tcg_gen_andi_i32(tmp, cpu_T[t], ~1); | |
| 484 | + } else { | |
| 485 | + tmp = cpu_T[t]; | |
| 486 | + } | |
| 487 | + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg])); | |
| 380 | 488 | if (reg == 15) { |
| 489 | + dead_tmp(tmp); | |
| 381 | 490 | s->is_jmp = DISAS_JUMP; |
| 382 | 491 | } |
| 383 | 492 | } |
| ... | ... | @@ -403,6 +512,7 @@ static inline void gen_lookup_tb(DisasContext *s) |
| 403 | 512 | static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) |
| 404 | 513 | { |
| 405 | 514 | int val, rm, shift, shiftop; |
| 515 | + TCGv offset; | |
| 406 | 516 | |
| 407 | 517 | if (!(insn & (1 << 25))) { |
| 408 | 518 | /* immediate */ |
| ... | ... | @@ -415,17 +525,14 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) |
| 415 | 525 | /* shift/register */ |
| 416 | 526 | rm = (insn) & 0xf; |
| 417 | 527 | shift = (insn >> 7) & 0x1f; |
| 418 | - gen_movl_T2_reg(s, rm); | |
| 419 | 528 | shiftop = (insn >> 5) & 3; |
| 420 | - if (shift != 0) { | |
| 421 | - gen_shift_T2_im[shiftop](shift); | |
| 422 | - } else if (shiftop != 0) { | |
| 423 | - gen_shift_T2_0[shiftop](); | |
| 424 | - } | |
| 529 | + offset = load_reg(s, rm); | |
| 530 | + gen_arm_shift_im(offset, shiftop, shift); | |
| 425 | 531 | if (!(insn & (1 << 23))) |
| 426 | - gen_op_subl_T1_T2(); | |
| 532 | + tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset); | |
| 427 | 533 | else |
| 428 | - gen_op_addl_T1_T2(); | |
| 534 | + tcg_gen_add_i32(cpu_T[1], cpu_T[1], offset); | |
| 535 | + dead_tmp(offset); | |
| 429 | 536 | } |
| 430 | 537 | } |
| 431 | 538 | |
| ... | ... | @@ -433,6 +540,7 @@ static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, |
| 433 | 540 | int extra) |
| 434 | 541 | { |
| 435 | 542 | int val, rm; |
| 543 | + TCGv offset; | |
| 436 | 544 | |
| 437 | 545 | if (insn & (1 << 22)) { |
| 438 | 546 | /* immediate */ |
| ... | ... | @@ -447,11 +555,12 @@ static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, |
| 447 | 555 | if (extra) |
| 448 | 556 | gen_op_addl_T1_im(extra); |
| 449 | 557 | rm = (insn) & 0xf; |
| 450 | - gen_movl_T2_reg(s, rm); | |
| 558 | + offset = load_reg(s, rm); | |
| 451 | 559 | if (!(insn & (1 << 23))) |
| 452 | - gen_op_subl_T1_T2(); | |
| 560 | + tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset); | |
| 453 | 561 | else |
| 454 | - gen_op_addl_T1_T2(); | |
| 562 | + tcg_gen_add_i32(cpu_T[1], cpu_T[1], offset); | |
| 563 | + dead_tmp(offset); | |
| 455 | 564 | } |
| 456 | 565 | } |
| 457 | 566 | |
| ... | ... | @@ -979,7 +1088,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) |
| 979 | 1088 | case 3: |
| 980 | 1089 | return 1; |
| 981 | 1090 | } |
| 982 | - gen_op_movl_reg_TN[0][rd](); | |
| 1091 | + gen_movl_reg_T0(s, rd); | |
| 983 | 1092 | break; |
| 984 | 1093 | case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */ |
| 985 | 1094 | if ((insn & 0x000ff008) != 0x0003f000) |
| ... | ... | @@ -1531,21 +1640,21 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) |
| 1531 | 1640 | gen_op_iwmmxt_movq_M0_wRn(wrd); |
| 1532 | 1641 | switch ((insn >> 16) & 0xf) { |
| 1533 | 1642 | case 0x0: /* TMIA */ |
| 1534 | - gen_op_movl_TN_reg[0][rd0](); | |
| 1535 | - gen_op_movl_TN_reg[1][rd1](); | |
| 1643 | + gen_movl_T0_reg(s, rd0); | |
| 1644 | + gen_movl_T1_reg(s, rd1); | |
| 1536 | 1645 | gen_op_iwmmxt_muladdsl_M0_T0_T1(); |
| 1537 | 1646 | break; |
| 1538 | 1647 | case 0x8: /* TMIAPH */ |
| 1539 | - gen_op_movl_TN_reg[0][rd0](); | |
| 1540 | - gen_op_movl_TN_reg[1][rd1](); | |
| 1648 | + gen_movl_T0_reg(s, rd0); | |
| 1649 | + gen_movl_T1_reg(s, rd1); | |
| 1541 | 1650 | gen_op_iwmmxt_muladdsw_M0_T0_T1(); |
| 1542 | 1651 | break; |
| 1543 | 1652 | case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */ |
| 1544 | - gen_op_movl_TN_reg[1][rd0](); | |
| 1653 | + gen_movl_T1_reg(s, rd0); | |
| 1545 | 1654 | if (insn & (1 << 16)) |
| 1546 | 1655 | gen_op_shrl_T1_im(16); |
| 1547 | 1656 | gen_op_movl_T0_T1(); |
| 1548 | - gen_op_movl_TN_reg[1][rd1](); | |
| 1657 | + gen_movl_T1_reg(s, rd1); | |
| 1549 | 1658 | if (insn & (1 << 17)) |
| 1550 | 1659 | gen_op_shrl_T1_im(16); |
| 1551 | 1660 | gen_op_iwmmxt_muladdswl_M0_T0_T1(); |
| ... | ... | @@ -1580,24 +1689,24 @@ static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn) |
| 1580 | 1689 | |
| 1581 | 1690 | switch ((insn >> 16) & 0xf) { |
| 1582 | 1691 | case 0x0: /* MIA */ |
| 1583 | - gen_op_movl_TN_reg[0][rd0](); | |
| 1584 | - gen_op_movl_TN_reg[1][rd1](); | |
| 1692 | + gen_movl_T0_reg(s, rd0); | |
| 1693 | + gen_movl_T1_reg(s, rd1); | |
| 1585 | 1694 | gen_op_iwmmxt_muladdsl_M0_T0_T1(); |
| 1586 | 1695 | break; |
| 1587 | 1696 | case 0x8: /* MIAPH */ |
| 1588 | - gen_op_movl_TN_reg[0][rd0](); | |
| 1589 | - gen_op_movl_TN_reg[1][rd1](); | |
| 1697 | + gen_movl_T0_reg(s, rd0); | |
| 1698 | + gen_movl_T1_reg(s, rd1); | |
| 1590 | 1699 | gen_op_iwmmxt_muladdsw_M0_T0_T1(); |
| 1591 | 1700 | break; |
| 1592 | 1701 | case 0xc: /* MIABB */ |
| 1593 | 1702 | case 0xd: /* MIABT */ |
| 1594 | 1703 | case 0xe: /* MIATB */ |
| 1595 | 1704 | case 0xf: /* MIATT */ |
| 1596 | - gen_op_movl_TN_reg[1][rd0](); | |
| 1705 | + gen_movl_T1_reg(s, rd0); | |
| 1597 | 1706 | if (insn & (1 << 16)) |
| 1598 | 1707 | gen_op_shrl_T1_im(16); |
| 1599 | 1708 | gen_op_movl_T0_T1(); |
| 1600 | - gen_op_movl_TN_reg[1][rd1](); | |
| 1709 | + gen_movl_T1_reg(s, rd1); | |
| 1601 | 1710 | if (insn & (1 << 17)) |
| 1602 | 1711 | gen_op_shrl_T1_im(16); |
| 1603 | 1712 | gen_op_iwmmxt_muladdswl_M0_T0_T1(); |
| ... | ... | @@ -1621,13 +1730,13 @@ static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn) |
| 1621 | 1730 | |
| 1622 | 1731 | if (insn & ARM_CP_RW_BIT) { /* MRA */ |
| 1623 | 1732 | gen_op_iwmmxt_movl_T0_T1_wRn(acc); |
| 1624 | - gen_op_movl_reg_TN[0][rdlo](); | |
| 1733 | + gen_movl_reg_T0(s, rdlo); | |
| 1625 | 1734 | gen_op_movl_T0_im((1 << (40 - 32)) - 1); |
| 1626 | 1735 | gen_op_andl_T0_T1(); |
| 1627 | - gen_op_movl_reg_TN[0][rdhi](); | |
| 1736 | + gen_movl_reg_T0(s, rdhi); | |
| 1628 | 1737 | } else { /* MAR */ |
| 1629 | - gen_op_movl_TN_reg[0][rdlo](); | |
| 1630 | - gen_op_movl_TN_reg[1][rdhi](); | |
| 1738 | + gen_movl_T0_reg(s, rdlo); | |
| 1739 | + gen_movl_T1_reg(s, rdhi); | |
| 1631 | 1740 | gen_op_iwmmxt_movl_wRn_T0_T1(acc); |
| 1632 | 1741 | } |
| 1633 | 1742 | return 0; |
| ... | ... | @@ -1650,14 +1759,14 @@ static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn) |
| 1650 | 1759 | if (!env->cp[cp].cp_read) |
| 1651 | 1760 | return 1; |
| 1652 | 1761 | gen_op_movl_T0_im((uint32_t) s->pc); |
| 1653 | - gen_op_movl_reg_TN[0][15](); | |
| 1762 | + gen_set_pc_T0(); | |
| 1654 | 1763 | gen_op_movl_T0_cp(insn); |
| 1655 | 1764 | gen_movl_reg_T0(s, rd); |
| 1656 | 1765 | } else { |
| 1657 | 1766 | if (!env->cp[cp].cp_write) |
| 1658 | 1767 | return 1; |
| 1659 | 1768 | gen_op_movl_T0_im((uint32_t) s->pc); |
| 1660 | - gen_op_movl_reg_TN[0][15](); | |
| 1769 | + gen_set_pc_T0(); | |
| 1661 | 1770 | gen_movl_T0_reg(s, rd); |
| 1662 | 1771 | gen_op_movl_cp_T0(insn); |
| 1663 | 1772 | } |
| ... | ... | @@ -1713,7 +1822,7 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn) |
| 1713 | 1822 | || (insn & 0x0fff0fff) == 0x0e070f58) { |
| 1714 | 1823 | /* Wait for interrupt. */ |
| 1715 | 1824 | gen_op_movl_T0_im((long)s->pc); |
| 1716 | - gen_op_movl_reg_TN[0][15](); | |
| 1825 | + gen_set_pc_T0(); | |
| 1717 | 1826 | s->is_jmp = DISAS_WFI; |
| 1718 | 1827 | return 0; |
| 1719 | 1828 | } |
| ... | ... | @@ -1817,9 +1926,9 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 1817 | 1926 | if (offset) |
| 1818 | 1927 | gen_op_shrl_T1_im(offset); |
| 1819 | 1928 | if (insn & (1 << 23)) |
| 1820 | - gen_op_uxtb_T1(); | |
| 1929 | + gen_uxtb(cpu_T[1]); | |
| 1821 | 1930 | else |
| 1822 | - gen_op_sxtb_T1(); | |
| 1931 | + gen_sxtb(cpu_T[1]); | |
| 1823 | 1932 | break; |
| 1824 | 1933 | case 1: |
| 1825 | 1934 | NEON_GET_REG(T1, rn, pass); |
| ... | ... | @@ -1827,13 +1936,13 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 1827 | 1936 | if (offset) { |
| 1828 | 1937 | gen_op_shrl_T1_im(16); |
| 1829 | 1938 | } else { |
| 1830 | - gen_op_uxth_T1(); | |
| 1939 | + gen_uxth(cpu_T[1]); | |
| 1831 | 1940 | } |
| 1832 | 1941 | } else { |
| 1833 | 1942 | if (offset) { |
| 1834 | 1943 | gen_op_sarl_T1_im(16); |
| 1835 | 1944 | } else { |
| 1836 | - gen_op_sxth_T1(); | |
| 1945 | + gen_sxth(cpu_T[1]); | |
| 1837 | 1946 | } |
| 1838 | 1947 | } |
| 1839 | 1948 | break; |
| ... | ... | @@ -2418,11 +2527,11 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest) |
| 2418 | 2527 | if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { |
| 2419 | 2528 | tcg_gen_goto_tb(n); |
| 2420 | 2529 | gen_op_movl_T0_im(dest); |
| 2421 | - gen_op_movl_r15_T0(); | |
| 2530 | + gen_set_pc_T0(); | |
| 2422 | 2531 | tcg_gen_exit_tb((long)tb + n); |
| 2423 | 2532 | } else { |
| 2424 | 2533 | gen_op_movl_T0_im(dest); |
| 2425 | - gen_op_movl_r15_T0(); | |
| 2534 | + gen_set_pc_T0(); | |
| 2426 | 2535 | tcg_gen_exit_tb(0); |
| 2427 | 2536 | } |
| 2428 | 2537 | } |
| ... | ... | @@ -2444,13 +2553,13 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest) |
| 2444 | 2553 | static inline void gen_mulxy(int x, int y) |
| 2445 | 2554 | { |
| 2446 | 2555 | if (x) |
| 2447 | - gen_op_sarl_T0_im(16); | |
| 2556 | + tcg_gen_sari_i32(cpu_T[0], cpu_T[0], 16); | |
| 2448 | 2557 | else |
| 2449 | - gen_op_sxth_T0(); | |
| 2558 | + gen_sxth(cpu_T[0]); | |
| 2450 | 2559 | if (y) |
| 2451 | 2560 | gen_op_sarl_T1_im(16); |
| 2452 | 2561 | else |
| 2453 | - gen_op_sxth_T1(); | |
| 2562 | + gen_sxth(cpu_T[1]); | |
| 2454 | 2563 | gen_op_mul_T0_T1(); |
| 2455 | 2564 | } |
| 2456 | 2565 | |
| ... | ... | @@ -2501,7 +2610,7 @@ static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr) |
| 2501 | 2610 | /* Generate an old-style exception return. */ |
| 2502 | 2611 | static void gen_exception_return(DisasContext *s) |
| 2503 | 2612 | { |
| 2504 | - gen_op_movl_reg_TN[0][15](); | |
| 2613 | + gen_set_pc_T0(); | |
| 2505 | 2614 | gen_op_movl_T0_spsr(); |
| 2506 | 2615 | gen_op_movl_cpsr_T0(0xffffffff); |
| 2507 | 2616 | s->is_jmp = DISAS_UPDATE; |
| ... | ... | @@ -2512,7 +2621,7 @@ static void gen_rfe(DisasContext *s) |
| 2512 | 2621 | { |
| 2513 | 2622 | gen_op_movl_cpsr_T0(0xffffffff); |
| 2514 | 2623 | gen_op_movl_T0_T2(); |
| 2515 | - gen_op_movl_reg_TN[0][15](); | |
| 2624 | + gen_set_pc_T0(); | |
| 2516 | 2625 | s->is_jmp = DISAS_UPDATE; |
| 2517 | 2626 | } |
| 2518 | 2627 | |
| ... | ... | @@ -2529,7 +2638,7 @@ static void gen_nop_hint(DisasContext *s, int val) |
| 2529 | 2638 | switch (val) { |
| 2530 | 2639 | case 3: /* wfi */ |
| 2531 | 2640 | gen_op_movl_T0_im((long)s->pc); |
| 2532 | - gen_op_movl_reg_TN[0][15](); | |
| 2641 | + gen_set_pc_T0(); | |
| 2533 | 2642 | s->is_jmp = DISAS_WFI; |
| 2534 | 2643 | break; |
| 2535 | 2644 | case 2: /* wfe */ |
| ... | ... | @@ -3011,14 +3120,18 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 3011 | 3120 | } |
| 3012 | 3121 | } |
| 3013 | 3122 | if (rm != 15) { |
| 3014 | - gen_movl_T1_reg(s, rn); | |
| 3123 | + TCGv base; | |
| 3124 | + | |
| 3125 | + base = load_reg(s, rn); | |
| 3015 | 3126 | if (rm == 13) { |
| 3016 | - gen_op_addl_T1_im(stride); | |
| 3127 | + tcg_gen_addi_i32(base, base, stride); | |
| 3017 | 3128 | } else { |
| 3018 | - gen_movl_T2_reg(s, rm); | |
| 3019 | - gen_op_addl_T1_T2(); | |
| 3129 | + TCGv index; | |
| 3130 | + index = load_reg(s, rm); | |
| 3131 | + tcg_gen_add_i32(base, base, index); | |
| 3132 | + dead_tmp(index); | |
| 3020 | 3133 | } |
| 3021 | - gen_movl_reg_T1(s, rn); | |
| 3134 | + store_reg(s, rn, base); | |
| 3022 | 3135 | } |
| 3023 | 3136 | return 0; |
| 3024 | 3137 | } |
| ... | ... | @@ -4626,6 +4739,7 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 4626 | 4739 | static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 4627 | 4740 | { |
| 4628 | 4741 | unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; |
| 4742 | + TCGv tmp; | |
| 4629 | 4743 | |
| 4630 | 4744 | insn = ldl_code(s->pc); |
| 4631 | 4745 | s->pc += 4; |
| ... | ... | @@ -4936,7 +5050,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 4936 | 5050 | case 7: /* bkpt */ |
| 4937 | 5051 | gen_set_condexec(s); |
| 4938 | 5052 | gen_op_movl_T0_im((long)s->pc - 4); |
| 4939 | - gen_op_movl_reg_TN[0][15](); | |
| 5053 | + gen_set_pc_T0(); | |
| 4940 | 5054 | gen_op_bkpt(); |
| 4941 | 5055 | s->is_jmp = DISAS_JUMP; |
| 4942 | 5056 | break; |
| ... | ... | @@ -4954,7 +5068,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 4954 | 5068 | if (sh & 4) |
| 4955 | 5069 | gen_op_sarl_T1_im(16); |
| 4956 | 5070 | else |
| 4957 | - gen_op_sxth_T1(); | |
| 5071 | + gen_sxth(cpu_T[1]); | |
| 4958 | 5072 | gen_op_imulw_T0_T1(); |
| 4959 | 5073 | if ((sh & 2) == 0) { |
| 4960 | 5074 | gen_movl_T1_reg(s, rn); |
| ... | ... | @@ -5001,7 +5115,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 5001 | 5115 | val = (val >> shift) | (val << (32 - shift)); |
| 5002 | 5116 | gen_op_movl_T1_im(val); |
| 5003 | 5117 | if (logic_cc && shift) |
| 5004 | - gen_op_mov_CF_T1(); | |
| 5118 | + gen_set_CF_bit31(cpu_T[1]); | |
| 5005 | 5119 | } else { |
| 5006 | 5120 | /* register */ |
| 5007 | 5121 | rm = (insn) & 0xf; |
| ... | ... | @@ -5009,18 +5123,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 5009 | 5123 | shiftop = (insn >> 5) & 3; |
| 5010 | 5124 | if (!(insn & (1 << 4))) { |
| 5011 | 5125 | shift = (insn >> 7) & 0x1f; |
| 5012 | - if (shift != 0) { | |
| 5013 | - if (logic_cc) { | |
| 5126 | + if (logic_cc) { | |
| 5127 | + if (shift != 0) { | |
| 5014 | 5128 | gen_shift_T1_im_cc[shiftop](shift); |
| 5015 | - } else { | |
| 5016 | - gen_shift_T1_im[shiftop](shift); | |
| 5017 | - } | |
| 5018 | - } else if (shiftop != 0) { | |
| 5019 | - if (logic_cc) { | |
| 5129 | + } else if (shiftop != 0) { | |
| 5020 | 5130 | gen_shift_T1_0_cc[shiftop](); |
| 5021 | - } else { | |
| 5022 | - gen_shift_T1_0[shiftop](); | |
| 5023 | 5131 | } |
| 5132 | + } else { | |
| 5133 | + gen_arm_shift_im(cpu_T[1], shiftop, shift); | |
| 5024 | 5134 | } |
| 5025 | 5135 | } else { |
| 5026 | 5136 | rs = (insn >> 8) & 0xf; |
| ... | ... | @@ -5083,7 +5193,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 5083 | 5193 | if (set_cc) |
| 5084 | 5194 | gen_op_adcl_T0_T1_cc(); |
| 5085 | 5195 | else |
| 5086 | - gen_op_adcl_T0_T1(); | |
| 5196 | + gen_adc_T0_T1(); | |
| 5087 | 5197 | gen_movl_reg_T0(s, rd); |
| 5088 | 5198 | break; |
| 5089 | 5199 | case 0x06: |
| ... | ... | @@ -5389,20 +5499,21 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 5389 | 5499 | gen_op_rorl_T1_im(shift * 8); |
| 5390 | 5500 | op1 = (insn >> 20) & 7; |
| 5391 | 5501 | switch (op1) { |
| 5392 | - case 0: gen_op_sxtb16_T1(); break; | |
| 5393 | - case 2: gen_op_sxtb_T1(); break; | |
| 5394 | - case 3: gen_op_sxth_T1(); break; | |
| 5395 | - case 4: gen_op_uxtb16_T1(); break; | |
| 5396 | - case 6: gen_op_uxtb_T1(); break; | |
| 5397 | - case 7: gen_op_uxth_T1(); break; | |
| 5502 | + case 0: gen_sxtb16(cpu_T[1]); break; | |
| 5503 | + case 2: gen_sxtb(cpu_T[1]); break; | |
| 5504 | + case 3: gen_sxth(cpu_T[1]); break; | |
| 5505 | + case 4: gen_uxtb16(cpu_T[1]); break; | |
| 5506 | + case 6: gen_uxtb(cpu_T[1]); break; | |
| 5507 | + case 7: gen_uxth(cpu_T[1]); break; | |
| 5398 | 5508 | default: goto illegal_op; |
| 5399 | 5509 | } |
| 5400 | 5510 | if (rn != 15) { |
| 5401 | - gen_movl_T2_reg(s, rn); | |
| 5511 | + tmp = load_reg(s, rn); | |
| 5402 | 5512 | if ((op1 & 3) == 0) { |
| 5403 | - gen_op_add16_T1_T2(); | |
| 5513 | + gen_add16(cpu_T[1], tmp); | |
| 5404 | 5514 | } else { |
| 5405 | - gen_op_addl_T1_T2(); | |
| 5515 | + tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); | |
| 5516 | + dead_tmp(tmp); | |
| 5406 | 5517 | } |
| 5407 | 5518 | } |
| 5408 | 5519 | gen_movl_reg_T1(s, rd); |
| ... | ... | @@ -5667,7 +5778,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 5667 | 5778 | if (i == 15) { |
| 5668 | 5779 | /* special case: r15 = PC + 8 */ |
| 5669 | 5780 | val = (long)s->pc + 4; |
| 5670 | - gen_op_movl_TN_im[0](val); | |
| 5781 | + gen_op_movl_T0_im(val); | |
| 5671 | 5782 | } else if (user) { |
| 5672 | 5783 | gen_op_movl_T0_user(i); |
| 5673 | 5784 | } else { |
| ... | ... | @@ -5723,7 +5834,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 5723 | 5834 | val = (int32_t)s->pc; |
| 5724 | 5835 | if (insn & (1 << 24)) { |
| 5725 | 5836 | gen_op_movl_T0_im(val); |
| 5726 | - gen_op_movl_reg_TN[0][14](); | |
| 5837 | + gen_movl_reg_T0(s, 14); | |
| 5727 | 5838 | } |
| 5728 | 5839 | offset = (((int32_t)insn << 8) >> 8); |
| 5729 | 5840 | val += (offset << 2) + 4; |
| ... | ... | @@ -5740,14 +5851,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 5740 | 5851 | case 0xf: |
| 5741 | 5852 | /* swi */ |
| 5742 | 5853 | gen_op_movl_T0_im((long)s->pc); |
| 5743 | - gen_op_movl_reg_TN[0][15](); | |
| 5854 | + gen_set_pc_T0(); | |
| 5744 | 5855 | s->is_jmp = DISAS_SWI; |
| 5745 | 5856 | break; |
| 5746 | 5857 | default: |
| 5747 | 5858 | illegal_op: |
| 5748 | 5859 | gen_set_condexec(s); |
| 5749 | 5860 | gen_op_movl_T0_im((long)s->pc - 4); |
| 5750 | - gen_op_movl_reg_TN[0][15](); | |
| 5861 | + gen_set_pc_T0(); | |
| 5751 | 5862 | gen_op_undef_insn(); |
| 5752 | 5863 | s->is_jmp = DISAS_JUMP; |
| 5753 | 5864 | break; |
| ... | ... | @@ -5806,7 +5917,7 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out) |
| 5806 | 5917 | if (conds) |
| 5807 | 5918 | gen_op_adcl_T0_T1_cc(); |
| 5808 | 5919 | else |
| 5809 | - gen_op_adcl_T0_T1(); | |
| 5920 | + gen_adc_T0_T1(); | |
| 5810 | 5921 | break; |
| 5811 | 5922 | case 11: /* sbc */ |
| 5812 | 5923 | if (conds) |
| ... | ... | @@ -5832,7 +5943,7 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out) |
| 5832 | 5943 | if (logic_cc) { |
| 5833 | 5944 | gen_op_logic_T0_cc(); |
| 5834 | 5945 | if (shifter_out) |
| 5835 | - gen_op_mov_CF_T1(); | |
| 5946 | + gen_set_CF_bit31(cpu_T[1]); | |
| 5836 | 5947 | } |
| 5837 | 5948 | return 0; |
| 5838 | 5949 | } |
| ... | ... | @@ -5843,6 +5954,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
| 5843 | 5954 | { |
| 5844 | 5955 | uint32_t insn, imm, shift, offset, addr; |
| 5845 | 5956 | uint32_t rd, rn, rm, rs; |
| 5957 | + TCGv tmp; | |
| 5846 | 5958 | int op; |
| 5847 | 5959 | int shiftop; |
| 5848 | 5960 | int conds; |
| ... | ... | @@ -5966,13 +6078,15 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
| 5966 | 6078 | } else { |
| 5967 | 6079 | gen_movl_T1_reg(s, rn); |
| 5968 | 6080 | } |
| 5969 | - gen_movl_T2_reg(s, rm); | |
| 5970 | - gen_op_addl_T1_T2(); | |
| 6081 | + tmp = load_reg(s, rm); | |
| 6082 | + tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); | |
| 5971 | 6083 | if (insn & (1 << 4)) { |
| 5972 | 6084 | /* tbh */ |
| 5973 | - gen_op_addl_T1_T2(); | |
| 6085 | + tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); | |
| 6086 | + dead_tmp(tmp); | |
| 5974 | 6087 | gen_ldst(lduw, s); |
| 5975 | 6088 | } else { /* tbb */ |
| 6089 | + dead_tmp(tmp); | |
| 5976 | 6090 | gen_ldst(ldub, s); |
| 5977 | 6091 | } |
| 5978 | 6092 | gen_op_jmp_T0_im(s->pc); |
| ... | ... | @@ -6126,18 +6240,14 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
| 6126 | 6240 | shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); |
| 6127 | 6241 | conds = (insn & (1 << 20)) != 0; |
| 6128 | 6242 | logic_cc = (conds && thumb2_logic_op(op)); |
| 6129 | - if (shift != 0) { | |
| 6130 | - if (logic_cc) { | |
| 6243 | + if (logic_cc) { | |
| 6244 | + if (shift != 0) { | |
| 6131 | 6245 | gen_shift_T1_im_cc[shiftop](shift); |
| 6132 | - } else { | |
| 6133 | - gen_shift_T1_im[shiftop](shift); | |
| 6134 | - } | |
| 6135 | - } else if (shiftop != 0) { | |
| 6136 | - if (logic_cc) { | |
| 6246 | + } else if (shiftop != 0) { | |
| 6137 | 6247 | gen_shift_T1_0_cc[shiftop](); |
| 6138 | - } else { | |
| 6139 | - gen_shift_T1_0[shiftop](); | |
| 6140 | 6248 | } |
| 6249 | + } else { | |
| 6250 | + gen_arm_shift_im(cpu_T[1], shiftop, shift); | |
| 6141 | 6251 | } |
| 6142 | 6252 | if (gen_thumb2_data_op(s, op, conds, 0)) |
| 6143 | 6253 | goto illegal_op; |
| ... | ... | @@ -6172,20 +6282,21 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
| 6172 | 6282 | gen_op_rorl_T1_im(shift * 8); |
| 6173 | 6283 | op = (insn >> 20) & 7; |
| 6174 | 6284 | switch (op) { |
| 6175 | - case 0: gen_op_sxth_T1(); break; | |
| 6176 | - case 1: gen_op_uxth_T1(); break; | |
| 6177 | - case 2: gen_op_sxtb16_T1(); break; | |
| 6178 | - case 3: gen_op_uxtb16_T1(); break; | |
| 6179 | - case 4: gen_op_sxtb_T1(); break; | |
| 6180 | - case 5: gen_op_uxtb_T1(); break; | |
| 6285 | + case 0: gen_sxth(cpu_T[1]); break; | |
| 6286 | + case 1: gen_uxth(cpu_T[1]); break; | |
| 6287 | + case 2: gen_sxtb16(cpu_T[1]); break; | |
| 6288 | + case 3: gen_uxtb16(cpu_T[1]); break; | |
| 6289 | + case 4: gen_sxtb(cpu_T[1]); break; | |
| 6290 | + case 5: gen_uxtb(cpu_T[1]); break; | |
| 6181 | 6291 | default: goto illegal_op; |
| 6182 | 6292 | } |
| 6183 | 6293 | if (rn != 15) { |
| 6184 | - gen_movl_T2_reg(s, rn); | |
| 6294 | + tmp = load_reg(s, rn); | |
| 6185 | 6295 | if ((op >> 1) == 1) { |
| 6186 | - gen_op_add16_T1_T2(); | |
| 6296 | + gen_add16(cpu_T[1], tmp); | |
| 6187 | 6297 | } else { |
| 6188 | - gen_op_addl_T1_T2(); | |
| 6298 | + tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); | |
| 6299 | + dead_tmp(tmp); | |
| 6189 | 6300 | } |
| 6190 | 6301 | } |
| 6191 | 6302 | gen_movl_reg_T1(s, rd); |
| ... | ... | @@ -6286,7 +6397,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
| 6286 | 6397 | if (op) |
| 6287 | 6398 | gen_op_sarl_T1_im(16); |
| 6288 | 6399 | else |
| 6289 | - gen_op_sxth_T1(); | |
| 6400 | + gen_sxth(cpu_T[1]); | |
| 6290 | 6401 | gen_op_imulw_T0_T1(); |
| 6291 | 6402 | if (rs != 15) |
| 6292 | 6403 | { |
| ... | ... | @@ -6718,10 +6829,11 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
| 6718 | 6829 | shift = (insn >> 4) & 0xf; |
| 6719 | 6830 | if (shift > 3) |
| 6720 | 6831 | goto illegal_op; |
| 6721 | - gen_movl_T2_reg(s, rm); | |
| 6832 | + tmp = load_reg(s, rm); | |
| 6722 | 6833 | if (shift) |
| 6723 | - gen_op_shll_T2_im(shift); | |
| 6724 | - gen_op_addl_T1_T2(); | |
| 6834 | + tcg_gen_shli_i32(tmp, tmp, shift); | |
| 6835 | + tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); | |
| 6836 | + dead_tmp(tmp); | |
| 6725 | 6837 | break; |
| 6726 | 6838 | case 4: /* Negative offset. */ |
| 6727 | 6839 | gen_op_addl_T1_im(-imm); |
| ... | ... | @@ -6733,7 +6845,6 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
| 6733 | 6845 | imm = -imm; |
| 6734 | 6846 | /* Fall through. */ |
| 6735 | 6847 | case 3: /* Post-increment. */ |
| 6736 | - gen_op_movl_T2_im(imm); | |
| 6737 | 6848 | postinc = 1; |
| 6738 | 6849 | writeback = 1; |
| 6739 | 6850 | break; |
| ... | ... | @@ -6802,6 +6913,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 6802 | 6913 | uint32_t val, insn, op, rm, rn, rd, shift, cond; |
| 6803 | 6914 | int32_t offset; |
| 6804 | 6915 | int i; |
| 6916 | + TCGv tmp; | |
| 6805 | 6917 | |
| 6806 | 6918 | if (s->condexec_mask) { |
| 6807 | 6919 | cond = s->condexec_cond; |
| ... | ... | @@ -6989,7 +7101,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 6989 | 7101 | break; |
| 6990 | 7102 | case 0x5: /* adc */ |
| 6991 | 7103 | if (s->condexec_mask) |
| 6992 | - gen_op_adcl_T0_T1(); | |
| 7104 | + gen_adc_T0_T1(); | |
| 6993 | 7105 | else |
| 6994 | 7106 | gen_op_adcl_T0_T1_cc(); |
| 6995 | 7107 | break; |
| ... | ... | @@ -7064,8 +7176,9 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7064 | 7176 | rm = (insn >> 6) & 7; |
| 7065 | 7177 | op = (insn >> 9) & 7; |
| 7066 | 7178 | gen_movl_T1_reg(s, rn); |
| 7067 | - gen_movl_T2_reg(s, rm); | |
| 7068 | - gen_op_addl_T1_T2(); | |
| 7179 | + tmp = load_reg(s, rm); | |
| 7180 | + tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); | |
| 7181 | + dead_tmp(tmp); | |
| 7069 | 7182 | |
| 7070 | 7183 | if (op < 3) /* store */ |
| 7071 | 7184 | gen_movl_T0_reg(s, rd); |
| ... | ... | @@ -7106,8 +7219,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7106 | 7219 | rn = (insn >> 3) & 7; |
| 7107 | 7220 | gen_movl_T1_reg(s, rn); |
| 7108 | 7221 | val = (insn >> 4) & 0x7c; |
| 7109 | - gen_op_movl_T2_im(val); | |
| 7110 | - gen_op_addl_T1_T2(); | |
| 7222 | + tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val); | |
| 7111 | 7223 | |
| 7112 | 7224 | if (insn & (1 << 11)) { |
| 7113 | 7225 | /* load */ |
| ... | ... | @@ -7126,8 +7238,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7126 | 7238 | rn = (insn >> 3) & 7; |
| 7127 | 7239 | gen_movl_T1_reg(s, rn); |
| 7128 | 7240 | val = (insn >> 6) & 0x1f; |
| 7129 | - gen_op_movl_T2_im(val); | |
| 7130 | - gen_op_addl_T1_T2(); | |
| 7241 | + tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val); | |
| 7131 | 7242 | |
| 7132 | 7243 | if (insn & (1 << 11)) { |
| 7133 | 7244 | /* load */ |
| ... | ... | @@ -7146,8 +7257,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7146 | 7257 | rn = (insn >> 3) & 7; |
| 7147 | 7258 | gen_movl_T1_reg(s, rn); |
| 7148 | 7259 | val = (insn >> 5) & 0x3e; |
| 7149 | - gen_op_movl_T2_im(val); | |
| 7150 | - gen_op_addl_T1_T2(); | |
| 7260 | + tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val); | |
| 7151 | 7261 | |
| 7152 | 7262 | if (insn & (1 << 11)) { |
| 7153 | 7263 | /* load */ |
| ... | ... | @@ -7165,8 +7275,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7165 | 7275 | rd = (insn >> 8) & 7; |
| 7166 | 7276 | gen_movl_T1_reg(s, 13); |
| 7167 | 7277 | val = (insn & 0xff) * 4; |
| 7168 | - gen_op_movl_T2_im(val); | |
| 7169 | - gen_op_addl_T1_T2(); | |
| 7278 | + tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val); | |
| 7170 | 7279 | |
| 7171 | 7280 | if (insn & (1 << 11)) { |
| 7172 | 7281 | /* load */ |
| ... | ... | @@ -7201,13 +7310,12 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7201 | 7310 | switch (op) { |
| 7202 | 7311 | case 0: |
| 7203 | 7312 | /* adjust stack pointer */ |
| 7204 | - gen_movl_T1_reg(s, 13); | |
| 7313 | + tmp = load_reg(s, 13); | |
| 7205 | 7314 | val = (insn & 0x7f) * 4; |
| 7206 | 7315 | if (insn & (1 << 7)) |
| 7207 | 7316 | val = -(int32_t)val; |
| 7208 | - gen_op_movl_T2_im(val); | |
| 7209 | - gen_op_addl_T1_T2(); | |
| 7210 | - gen_movl_reg_T1(s, 13); | |
| 7317 | + tcg_gen_addi_i32(tmp, tmp, val); | |
| 7318 | + store_reg(s, 13, tmp); | |
| 7211 | 7319 | break; |
| 7212 | 7320 | |
| 7213 | 7321 | case 2: /* sign/zero extend. */ |
| ... | ... | @@ -7216,10 +7324,10 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7216 | 7324 | rm = (insn >> 3) & 7; |
| 7217 | 7325 | gen_movl_T1_reg(s, rm); |
| 7218 | 7326 | switch ((insn >> 6) & 3) { |
| 7219 | - case 0: gen_op_sxth_T1(); break; | |
| 7220 | - case 1: gen_op_sxtb_T1(); break; | |
| 7221 | - case 2: gen_op_uxth_T1(); break; | |
| 7222 | - case 3: gen_op_uxtb_T1(); break; | |
| 7327 | + case 0: gen_sxth(cpu_T[1]); break; | |
| 7328 | + case 1: gen_sxtb(cpu_T[1]); break; | |
| 7329 | + case 2: gen_uxth(cpu_T[1]); break; | |
| 7330 | + case 3: gen_uxtb(cpu_T[1]); break; | |
| 7223 | 7331 | } |
| 7224 | 7332 | gen_movl_reg_T1(s, rd); |
| 7225 | 7333 | break; |
| ... | ... | @@ -7235,10 +7343,8 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7235 | 7343 | offset += 4; |
| 7236 | 7344 | } |
| 7237 | 7345 | if ((insn & (1 << 11)) == 0) { |
| 7238 | - gen_op_movl_T2_im(-offset); | |
| 7239 | - gen_op_addl_T1_T2(); | |
| 7346 | + gen_op_addl_T1_im(-offset); | |
| 7240 | 7347 | } |
| 7241 | - gen_op_movl_T2_im(4); | |
| 7242 | 7348 | for (i = 0; i < 8; i++) { |
| 7243 | 7349 | if (insn & (1 << i)) { |
| 7244 | 7350 | if (insn & (1 << 11)) { |
| ... | ... | @@ -7251,7 +7357,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7251 | 7357 | gen_ldst(stl, s); |
| 7252 | 7358 | } |
| 7253 | 7359 | /* advance to the next address. */ |
| 7254 | - gen_op_addl_T1_T2(); | |
| 7360 | + gen_op_addl_T1_im(4); | |
| 7255 | 7361 | } |
| 7256 | 7362 | } |
| 7257 | 7363 | if (insn & (1 << 8)) { |
| ... | ... | @@ -7265,11 +7371,10 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7265 | 7371 | gen_movl_T0_reg(s, 14); |
| 7266 | 7372 | gen_ldst(stl, s); |
| 7267 | 7373 | } |
| 7268 | - gen_op_addl_T1_T2(); | |
| 7374 | + gen_op_addl_T1_im(4); | |
| 7269 | 7375 | } |
| 7270 | 7376 | if ((insn & (1 << 11)) == 0) { |
| 7271 | - gen_op_movl_T2_im(-offset); | |
| 7272 | - gen_op_addl_T1_T2(); | |
| 7377 | + gen_op_addl_T1_im(-offset); | |
| 7273 | 7378 | } |
| 7274 | 7379 | /* write back the new stack pointer */ |
| 7275 | 7380 | gen_movl_reg_T1(s, 13); |
| ... | ... | @@ -7308,7 +7413,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7308 | 7413 | case 0xe: /* bkpt */ |
| 7309 | 7414 | gen_set_condexec(s); |
| 7310 | 7415 | gen_op_movl_T0_im((long)s->pc - 2); |
| 7311 | - gen_op_movl_reg_TN[0][15](); | |
| 7416 | + gen_set_pc_T0(); | |
| 7312 | 7417 | gen_op_bkpt(); |
| 7313 | 7418 | s->is_jmp = DISAS_JUMP; |
| 7314 | 7419 | break; |
| ... | ... | @@ -7363,7 +7468,6 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7363 | 7468 | /* load/store multiple */ |
| 7364 | 7469 | rn = (insn >> 8) & 0x7; |
| 7365 | 7470 | gen_movl_T1_reg(s, rn); |
| 7366 | - gen_op_movl_T2_im(4); | |
| 7367 | 7471 | for (i = 0; i < 8; i++) { |
| 7368 | 7472 | if (insn & (1 << i)) { |
| 7369 | 7473 | if (insn & (1 << 11)) { |
| ... | ... | @@ -7376,7 +7480,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7376 | 7480 | gen_ldst(stl, s); |
| 7377 | 7481 | } |
| 7378 | 7482 | /* advance to the next address */ |
| 7379 | - gen_op_addl_T1_T2(); | |
| 7483 | + gen_op_addl_T1_im(4); | |
| 7380 | 7484 | } |
| 7381 | 7485 | } |
| 7382 | 7486 | /* Base register writeback. */ |
| ... | ... | @@ -7395,7 +7499,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7395 | 7499 | gen_set_condexec(s); |
| 7396 | 7500 | gen_op_movl_T0_im((long)s->pc | 1); |
| 7397 | 7501 | /* Don't set r15. */ |
| 7398 | - gen_op_movl_reg_TN[0][15](); | |
| 7502 | + gen_set_pc_T0(); | |
| 7399 | 7503 | s->is_jmp = DISAS_SWI; |
| 7400 | 7504 | break; |
| 7401 | 7505 | } |
| ... | ... | @@ -7434,7 +7538,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 7434 | 7538 | undef32: |
| 7435 | 7539 | gen_set_condexec(s); |
| 7436 | 7540 | gen_op_movl_T0_im((long)s->pc - 4); |
| 7437 | - gen_op_movl_reg_TN[0][15](); | |
| 7541 | + gen_set_pc_T0(); | |
| 7438 | 7542 | gen_op_undef_insn(); |
| 7439 | 7543 | s->is_jmp = DISAS_JUMP; |
| 7440 | 7544 | return; |
| ... | ... | @@ -7442,7 +7546,7 @@ illegal_op: |
| 7442 | 7546 | undef: |
| 7443 | 7547 | gen_set_condexec(s); |
| 7444 | 7548 | gen_op_movl_T0_im((long)s->pc - 2); |
| 7445 | - gen_op_movl_reg_TN[0][15](); | |
| 7549 | + gen_set_pc_T0(); | |
| 7446 | 7550 | gen_op_undef_insn(); |
| 7447 | 7551 | s->is_jmp = DISAS_JUMP; |
| 7448 | 7552 | } |
| ... | ... | @@ -7461,6 +7565,9 @@ static inline int gen_intermediate_code_internal(CPUState *env, |
| 7461 | 7565 | uint32_t next_page_start; |
| 7462 | 7566 | |
| 7463 | 7567 | /* generate intermediate code */ |
| 7568 | + num_temps = 0; | |
| 7569 | + memset(temps, 0, sizeof(temps)); | |
| 7570 | + | |
| 7464 | 7571 | pc_start = tb->pc; |
| 7465 | 7572 | |
| 7466 | 7573 | dc->tb = tb; |
| ... | ... | @@ -7502,7 +7609,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, |
| 7502 | 7609 | if (env->breakpoints[j] == dc->pc) { |
| 7503 | 7610 | gen_set_condexec(dc); |
| 7504 | 7611 | gen_op_movl_T0_im((long)dc->pc); |
| 7505 | - gen_op_movl_reg_TN[0][15](); | |
| 7612 | + gen_set_pc_T0(); | |
| 7506 | 7613 | gen_op_debug(); |
| 7507 | 7614 | dc->is_jmp = DISAS_JUMP; |
| 7508 | 7615 | /* Advance PC so that clearing the breakpoint will |
| ... | ... | @@ -7537,6 +7644,10 @@ static inline int gen_intermediate_code_internal(CPUState *env, |
| 7537 | 7644 | } else { |
| 7538 | 7645 | disas_arm_insn(env, dc); |
| 7539 | 7646 | } |
| 7647 | + if (num_temps) { | |
| 7648 | + fprintf(stderr, "Internal resource leak before %08x\n", dc->pc); | |
| 7649 | + num_temps = 0; | |
| 7650 | + } | |
| 7540 | 7651 | |
| 7541 | 7652 | if (dc->condjmp && !dc->is_jmp) { |
| 7542 | 7653 | gen_set_label(dc->condlabel); |
| ... | ... | @@ -7572,7 +7683,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, |
| 7572 | 7683 | } |
| 7573 | 7684 | if (dc->condjmp || !dc->is_jmp) { |
| 7574 | 7685 | gen_op_movl_T0_im((long)dc->pc); |
| 7575 | - gen_op_movl_reg_TN[0][15](); | |
| 7686 | + gen_set_pc_T0(); | |
| 7576 | 7687 | dc->condjmp = 0; |
| 7577 | 7688 | } |
| 7578 | 7689 | gen_set_condexec(dc); | ... | ... |