Commit b26eefb68e7942eeb689c81fd20e67e57ad95cd2

Authored by pbrook
1 parent 2a39bc41

ARM TCG conversion 1/16.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4138 c046a42c-6fe2-441c-8c8c-71466251a162
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
  1 +#ifndef DEF_HELPER
  2 +#define DEF_HELPER(name, ret, args) ret helper_##name args;
  3 +#endif
  4 +
  5 +DEF_HELPER(sxtb16, uint32_t, (uint32_t))
  6 +DEF_HELPER(uxtb16, uint32_t, (uint32_t))
... ...
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);
... ...