Commit b010980544b543d421b3f514bba3cafc59b3a3db

Authored by pbrook
1 parent d9ba4830

ARM TCG conversion 9/16.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4146 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/exec.h
@@ -72,8 +72,6 @@ void helper_set_cp(CPUState *, uint32_t, uint32_t); @@ -72,8 +72,6 @@ void helper_set_cp(CPUState *, uint32_t, uint32_t);
72 uint32_t helper_get_cp(CPUState *, uint32_t); 72 uint32_t helper_get_cp(CPUState *, uint32_t);
73 void helper_set_cp15(CPUState *, uint32_t, uint32_t); 73 void helper_set_cp15(CPUState *, uint32_t, uint32_t);
74 uint32_t helper_get_cp15(CPUState *, uint32_t); 74 uint32_t helper_get_cp15(CPUState *, uint32_t);
75 -void helper_set_r13_banked(CPUState *env, int mode, uint32_t val);  
76 -uint32_t helper_get_r13_banked(CPUState *env, int mode);  
77 uint32_t helper_v7m_mrs(CPUState *env, int reg); 75 uint32_t helper_v7m_mrs(CPUState *env, int reg);
78 void helper_v7m_msr(CPUState *env, int reg, uint32_t val); 76 void helper_v7m_msr(CPUState *env, int reg, uint32_t val);
79 77
target-arm/helper.c
@@ -513,12 +513,12 @@ void switch_mode(CPUState *env, int mode) @@ -513,12 +513,12 @@ void switch_mode(CPUState *env, int mode)
513 cpu_abort(env, "Tried to switch out of user mode\n"); 513 cpu_abort(env, "Tried to switch out of user mode\n");
514 } 514 }
515 515
516 -void helper_set_r13_banked(CPUState *env, int mode, uint32_t val) 516 +void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
517 { 517 {
518 cpu_abort(env, "banked r13 write\n"); 518 cpu_abort(env, "banked r13 write\n");
519 } 519 }
520 520
521 -uint32_t helper_get_r13_banked(CPUState *env, int mode) 521 +uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
522 { 522 {
523 cpu_abort(env, "banked r13 read\n"); 523 cpu_abort(env, "banked r13 read\n");
524 return 0; 524 return 0;
@@ -1793,12 +1793,12 @@ bad_reg: @@ -1793,12 +1793,12 @@ bad_reg:
1793 return 0; 1793 return 0;
1794 } 1794 }
1795 1795
1796 -void helper_set_r13_banked(CPUState *env, int mode, uint32_t val) 1796 +void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
1797 { 1797 {
1798 env->banked_r13[bank_number(mode)] = val; 1798 env->banked_r13[bank_number(mode)] = val;
1799 } 1799 }
1800 1800
1801 -uint32_t helper_get_r13_banked(CPUState *env, int mode) 1801 +uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
1802 { 1802 {
1803 return env->banked_r13[bank_number(mode)]; 1803 return env->banked_r13[bank_number(mode)];
1804 } 1804 }
target-arm/helpers.h
@@ -19,6 +19,13 @@ static inline void gen_helper_##name(TCGv arg1, TCGv arg2) \ @@ -19,6 +19,13 @@ static inline void gen_helper_##name(TCGv arg1, TCGv arg2) \
19 { \ 19 { \
20 tcg_gen_helper_0_2(helper_##name, arg1, arg2); \ 20 tcg_gen_helper_0_2(helper_##name, arg1, arg2); \
21 } 21 }
  22 +#define DEF_HELPER_0_3(name, ret, args) \
  23 +DEF_HELPER(name, ret, args) \
  24 +static inline void gen_helper_##name( \
  25 + TCGv arg1, TCGv arg2, TCGv arg3) \
  26 +{ \
  27 + tcg_gen_helper_0_3(helper_##name, arg1, arg2, arg3); \
  28 +}
22 #define DEF_HELPER_1_0(name, ret, args) \ 29 #define DEF_HELPER_1_0(name, ret, args) \
23 DEF_HELPER(name, ret, args) \ 30 DEF_HELPER(name, ret, args) \
24 static inline void gen_helper_##name(TCGv ret) \ 31 static inline void gen_helper_##name(TCGv ret) \
@@ -48,6 +55,7 @@ static inline void gen_helper_##name(TCGv ret, \ @@ -48,6 +55,7 @@ static inline void gen_helper_##name(TCGv ret, \
48 #define DEF_HELPER_0_0 DEF_HELPER 55 #define DEF_HELPER_0_0 DEF_HELPER
49 #define DEF_HELPER_0_1 DEF_HELPER 56 #define DEF_HELPER_0_1 DEF_HELPER
50 #define DEF_HELPER_0_2 DEF_HELPER 57 #define DEF_HELPER_0_2 DEF_HELPER
  58 +#define DEF_HELPER_0_3 DEF_HELPER
51 #define DEF_HELPER_1_0 DEF_HELPER 59 #define DEF_HELPER_1_0 DEF_HELPER
52 #define DEF_HELPER_1_1 DEF_HELPER 60 #define DEF_HELPER_1_1 DEF_HELPER
53 #define DEF_HELPER_1_2 DEF_HELPER 61 #define DEF_HELPER_1_2 DEF_HELPER
@@ -108,6 +116,12 @@ DEF_HELPER_0_0(wfi, void, (void)) @@ -108,6 +116,12 @@ DEF_HELPER_0_0(wfi, void, (void))
108 DEF_HELPER_0_2(cpsr_write, void, (uint32_t, uint32_t)) 116 DEF_HELPER_0_2(cpsr_write, void, (uint32_t, uint32_t))
109 DEF_HELPER_1_0(cpsr_read, uint32_t, (void)) 117 DEF_HELPER_1_0(cpsr_read, uint32_t, (void))
110 118
  119 +DEF_HELPER_1_2(get_r13_banked, uint32_t, (CPUState *, uint32_t))
  120 +DEF_HELPER_0_3(set_r13_banked, void, (CPUState *, uint32_t, uint32_t))
  121 +
  122 +DEF_HELPER_1_1(get_user_reg, uint32_t, (uint32_t))
  123 +DEF_HELPER_0_2(set_user_reg, void, (uint32_t, uint32_t))
  124 +
111 #undef DEF_HELPER 125 #undef DEF_HELPER
112 #undef DEF_HELPER_0_0 126 #undef DEF_HELPER_0_0
113 #undef DEF_HELPER_0_1 127 #undef DEF_HELPER_0_1
target-arm/op.c
@@ -589,48 +589,6 @@ void OPPROTO op_movl_T0_cp15(void) @@ -589,48 +589,6 @@ void OPPROTO op_movl_T0_cp15(void)
589 FORCE_RET(); 589 FORCE_RET();
590 } 590 }
591 591
592 -/* Access to user mode registers from privileged modes. */  
593 -void OPPROTO op_movl_T0_user(void)  
594 -{  
595 - int regno = PARAM1;  
596 - if (regno == 13) {  
597 - T0 = env->banked_r13[0];  
598 - } else if (regno == 14) {  
599 - T0 = env->banked_r14[0];  
600 - } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {  
601 - T0 = env->usr_regs[regno - 8];  
602 - } else {  
603 - T0 = env->regs[regno];  
604 - }  
605 - FORCE_RET();  
606 -}  
607 -  
608 -  
609 -void OPPROTO op_movl_user_T0(void)  
610 -{  
611 - int regno = PARAM1;  
612 - if (regno == 13) {  
613 - env->banked_r13[0] = T0;  
614 - } else if (regno == 14) {  
615 - env->banked_r14[0] = T0;  
616 - } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {  
617 - env->usr_regs[regno - 8] = T0;  
618 - } else {  
619 - env->regs[regno] = T0;  
620 - }  
621 - FORCE_RET();  
622 -}  
623 -  
624 -void OPPROTO op_movl_T1_r13_banked(void)  
625 -{  
626 - T1 = helper_get_r13_banked(env, PARAM1);  
627 -}  
628 -  
629 -void OPPROTO op_movl_r13_T1_banked(void)  
630 -{  
631 - helper_set_r13_banked(env, PARAM1, T1);  
632 -}  
633 -  
634 void OPPROTO op_v7m_mrs_T0(void) 592 void OPPROTO op_v7m_mrs_T0(void)
635 { 593 {
636 T0 = helper_v7m_mrs(env, PARAM1); 594 T0 = helper_v7m_mrs(env, PARAM1);
target-arm/op_helper.c
@@ -459,3 +459,36 @@ void HELPER(cpsr_write)(uint32_t val, uint32_t mask) @@ -459,3 +459,36 @@ void HELPER(cpsr_write)(uint32_t val, uint32_t mask)
459 { 459 {
460 cpsr_write(env, val, mask); 460 cpsr_write(env, val, mask);
461 } 461 }
  462 +
  463 +/* Access to user mode registers from privileged modes. */
  464 +uint32_t HELPER(get_user_reg)(uint32_t regno)
  465 +{
  466 + uint32_t val;
  467 +
  468 + if (regno == 13) {
  469 + val = env->banked_r13[0];
  470 + } else if (regno == 14) {
  471 + val = env->banked_r14[0];
  472 + } else if (regno >= 8
  473 + && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
  474 + val = env->usr_regs[regno - 8];
  475 + } else {
  476 + val = env->regs[regno];
  477 + }
  478 + return val;
  479 +}
  480 +
  481 +void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
  482 +{
  483 + if (regno == 13) {
  484 + env->banked_r13[0] = val;
  485 + } else if (regno == 14) {
  486 + env->banked_r14[0] = val;
  487 + } else if (regno >= 8
  488 + && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
  489 + env->usr_regs[regno - 8] = val;
  490 + } else {
  491 + env->regs[regno] = val;
  492 + }
  493 +}
  494 +
target-arm/op_mem.h
1 /* ARM memory operations. */ 1 /* ARM memory operations. */
2 2
3 -void helper_ld(uint32_t);  
4 -/* Load from address T1 into T0. */  
5 -#define MEM_LD_OP(name) \  
6 -void OPPROTO glue(op_ld##name,MEMSUFFIX)(void) \  
7 -{ \  
8 - T0 = glue(ld##name,MEMSUFFIX)(T1); \  
9 - FORCE_RET(); \  
10 -}  
11 -  
12 -MEM_LD_OP(ub)  
13 -MEM_LD_OP(sb)  
14 -MEM_LD_OP(uw)  
15 -MEM_LD_OP(sw)  
16 -MEM_LD_OP(l)  
17 -  
18 -#undef MEM_LD_OP  
19 -  
20 -/* Store T0 to address T1. */  
21 -#define MEM_ST_OP(name) \  
22 -void OPPROTO glue(op_st##name,MEMSUFFIX)(void) \  
23 -{ \  
24 - glue(st##name,MEMSUFFIX)(T1, T0); \  
25 - FORCE_RET(); \  
26 -}  
27 -  
28 -MEM_ST_OP(b)  
29 -MEM_ST_OP(w)  
30 -MEM_ST_OP(l)  
31 -  
32 -#undef MEM_ST_OP  
33 -  
34 /* Swap T0 with memory at address T1. */ 3 /* Swap T0 with memory at address T1. */
35 /* ??? Is this exception safe? */ 4 /* ??? Is this exception safe? */
36 #define MEM_SWP_OP(name, lname) \ 5 #define MEM_SWP_OP(name, lname) \
target-arm/translate.c
@@ -222,7 +222,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var) @@ -222,7 +222,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
222 222
223 #define gen_sxtb16(var) gen_helper_sxtb16(var, var) 223 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
224 #define gen_uxtb16(var) gen_helper_uxtb16(var, var) 224 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
225 -#define gen_op_rev_T0() tcg_gen_bswap_i32(cpu_T[0], cpu_T[0])  
226 225
227 #define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1]) 226 #define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
228 227
@@ -804,6 +803,51 @@ static inline void gen_bx_T0(DisasContext *s) @@ -804,6 +803,51 @@ static inline void gen_bx_T0(DisasContext *s)
804 gen_op_##name##_kernel(); \ 803 gen_op_##name##_kernel(); \
805 } while (0) 804 } while (0)
806 #endif 805 #endif
  806 +static inline TCGv gen_ld8s(TCGv addr, int index)
  807 +{
  808 + TCGv tmp = new_tmp();
  809 + tcg_gen_qemu_ld8s(tmp, addr, index);
  810 + return tmp;
  811 +}
  812 +static inline TCGv gen_ld8u(TCGv addr, int index)
  813 +{
  814 + TCGv tmp = new_tmp();
  815 + tcg_gen_qemu_ld8u(tmp, addr, index);
  816 + return tmp;
  817 +}
  818 +static inline TCGv gen_ld16s(TCGv addr, int index)
  819 +{
  820 + TCGv tmp = new_tmp();
  821 + tcg_gen_qemu_ld16s(tmp, addr, index);
  822 + return tmp;
  823 +}
  824 +static inline TCGv gen_ld16u(TCGv addr, int index)
  825 +{
  826 + TCGv tmp = new_tmp();
  827 + tcg_gen_qemu_ld16u(tmp, addr, index);
  828 + return tmp;
  829 +}
  830 +static inline TCGv gen_ld32(TCGv addr, int index)
  831 +{
  832 + TCGv tmp = new_tmp();
  833 + tcg_gen_qemu_ld32u(tmp, addr, index);
  834 + return tmp;
  835 +}
  836 +static inline void gen_st8(TCGv val, TCGv addr, int index)
  837 +{
  838 + tcg_gen_qemu_st8(val, addr, index);
  839 + dead_tmp(val);
  840 +}
  841 +static inline void gen_st16(TCGv val, TCGv addr, int index)
  842 +{
  843 + tcg_gen_qemu_st16(val, addr, index);
  844 + dead_tmp(val);
  845 +}
  846 +static inline void gen_st32(TCGv val, TCGv addr, int index)
  847 +{
  848 + tcg_gen_qemu_st32(val, addr, index);
  849 + dead_tmp(val);
  850 +}
807 851
808 static inline void gen_movl_T0_reg(DisasContext *s, int reg) 852 static inline void gen_movl_T0_reg(DisasContext *s, int reg)
809 { 853 {
@@ -859,7 +903,8 @@ static inline void gen_lookup_tb(DisasContext *s) @@ -859,7 +903,8 @@ static inline void gen_lookup_tb(DisasContext *s)
859 s->is_jmp = DISAS_UPDATE; 903 s->is_jmp = DISAS_UPDATE;
860 } 904 }
861 905
862 -static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) 906 +static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
  907 + TCGv var)
863 { 908 {
864 int val, rm, shift, shiftop; 909 int val, rm, shift, shiftop;
865 TCGv offset; 910 TCGv offset;
@@ -870,7 +915,7 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) @@ -870,7 +915,7 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
870 if (!(insn & (1 << 23))) 915 if (!(insn & (1 << 23)))
871 val = -val; 916 val = -val;
872 if (val != 0) 917 if (val != 0)
873 - gen_op_addl_T1_im(val); 918 + tcg_gen_addi_i32(var, var, val);
874 } else { 919 } else {
875 /* shift/register */ 920 /* shift/register */
876 rm = (insn) & 0xf; 921 rm = (insn) & 0xf;
@@ -879,15 +924,15 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) @@ -879,15 +924,15 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
879 offset = load_reg(s, rm); 924 offset = load_reg(s, rm);
880 gen_arm_shift_im(offset, shiftop, shift, 0); 925 gen_arm_shift_im(offset, shiftop, shift, 0);
881 if (!(insn & (1 << 23))) 926 if (!(insn & (1 << 23)))
882 - tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset); 927 + tcg_gen_sub_i32(var, var, offset);
883 else 928 else
884 - tcg_gen_add_i32(cpu_T[1], cpu_T[1], offset); 929 + tcg_gen_add_i32(var, var, offset);
885 dead_tmp(offset); 930 dead_tmp(offset);
886 } 931 }
887 } 932 }
888 933
889 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, 934 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
890 - int extra) 935 + int extra, TCGv var)
891 { 936 {
892 int val, rm; 937 int val, rm;
893 TCGv offset; 938 TCGv offset;
@@ -899,17 +944,17 @@ static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, @@ -899,17 +944,17 @@ static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
899 val = -val; 944 val = -val;
900 val += extra; 945 val += extra;
901 if (val != 0) 946 if (val != 0)
902 - gen_op_addl_T1_im(val); 947 + tcg_gen_addi_i32(var, var, val);
903 } else { 948 } else {
904 /* register */ 949 /* register */
905 if (extra) 950 if (extra)
906 - gen_op_addl_T1_im(extra); 951 + tcg_gen_addi_i32(var, var, extra);
907 rm = (insn) & 0xf; 952 rm = (insn) & 0xf;
908 offset = load_reg(s, rm); 953 offset = load_reg(s, rm);
909 if (!(insn & (1 << 23))) 954 if (!(insn & (1 << 23)))
910 - tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset); 955 + tcg_gen_sub_i32(var, var, offset);
911 else 956 else
912 - tcg_gen_add_i32(cpu_T[1], cpu_T[1], offset); 957 + tcg_gen_add_i32(var, var, offset);
913 dead_tmp(offset); 958 dead_tmp(offset);
914 } 959 }
915 } 960 }
@@ -1090,6 +1135,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) @@ -1090,6 +1135,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1090 { 1135 {
1091 int rd, wrd; 1136 int rd, wrd;
1092 int rdhi, rdlo, rd0, rd1, i; 1137 int rdhi, rdlo, rd0, rd1, i;
  1138 + TCGv tmp;
1093 1139
1094 if ((insn & 0x0e000e00) == 0x0c000000) { 1140 if ((insn & 0x0e000e00) == 0x0c000000) {
1095 if ((insn & 0x0fe00ff0) == 0x0c400000) { 1141 if ((insn & 0x0fe00ff0) == 0x0c400000) {
@@ -1114,7 +1160,9 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) @@ -1114,7 +1160,9 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1114 return 1; 1160 return 1;
1115 if (insn & ARM_CP_RW_BIT) { 1161 if (insn & ARM_CP_RW_BIT) {
1116 if ((insn >> 28) == 0xf) { /* WLDRW wCx */ 1162 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1117 - gen_ldst(ldl, s); 1163 + tmp = gen_ld32(cpu_T[1], IS_USER(s));
  1164 + tcg_gen_mov_i32(cpu_T[0], tmp);
  1165 + dead_tmp(tmp);
1118 gen_op_iwmmxt_movl_wCx_T0(wrd); 1166 gen_op_iwmmxt_movl_wCx_T0(wrd);
1119 } else { 1167 } else {
1120 if (insn & (1 << 8)) 1168 if (insn & (1 << 8))
@@ -1132,7 +1180,9 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) @@ -1132,7 +1180,9 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1132 } else { 1180 } else {
1133 if ((insn >> 28) == 0xf) { /* WSTRW wCx */ 1181 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1134 gen_op_iwmmxt_movl_T0_wCx(wrd); 1182 gen_op_iwmmxt_movl_T0_wCx(wrd);
1135 - gen_ldst(stl, s); 1183 + tmp = new_tmp();
  1184 + tcg_gen_mov_i32(tmp, cpu_T[0]);
  1185 + gen_st32(tmp, cpu_T[1], IS_USER(s));
1136 } else { 1186 } else {
1137 gen_op_iwmmxt_movq_M0_wRn(wrd); 1187 gen_op_iwmmxt_movq_M0_wRn(wrd);
1138 if (insn & (1 << 8)) 1188 if (insn & (1 << 8))
@@ -2970,12 +3020,12 @@ static void gen_exception_return(DisasContext *s) @@ -2970,12 +3020,12 @@ static void gen_exception_return(DisasContext *s)
2970 s->is_jmp = DISAS_UPDATE; 3020 s->is_jmp = DISAS_UPDATE;
2971 } 3021 }
2972 3022
2973 -/* Generate a v6 exception return. */  
2974 -static void gen_rfe(DisasContext *s) 3023 +/* Generate a v6 exception return. Marks both values as dead. */
  3024 +static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
2975 { 3025 {
2976 - gen_set_cpsr(cpu_T[0], 0xffffffff);  
2977 - gen_op_movl_T0_T2();  
2978 - gen_set_pc_T0(); 3026 + gen_set_cpsr(cpsr, 0xffffffff);
  3027 + dead_tmp(cpsr);
  3028 + store_reg(s, 15, pc);
2979 s->is_jmp = DISAS_UPDATE; 3029 s->is_jmp = DISAS_UPDATE;
2980 } 3030 }
2981 3031
@@ -3288,6 +3338,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -3288,6 +3338,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3288 int shift; 3338 int shift;
3289 uint32_t mask; 3339 uint32_t mask;
3290 int n; 3340 int n;
  3341 + TCGv tmp;
3291 3342
3292 if (!vfp_enabled(env)) 3343 if (!vfp_enabled(env))
3293 return 1; 3344 return 1;
@@ -3316,36 +3367,50 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -3316,36 +3367,50 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3316 for (pass = 0; pass < 2; pass++) { 3367 for (pass = 0; pass < 2; pass++) {
3317 if (size == 2) { 3368 if (size == 2) {
3318 if (load) { 3369 if (load) {
3319 - gen_ldst(ldl, s); 3370 + tmp = gen_ld32(cpu_T[1], IS_USER(s));
  3371 + tcg_gen_mov_i32(cpu_T[0], tmp);
  3372 + dead_tmp(tmp);
3320 NEON_SET_REG(T0, rd, pass); 3373 NEON_SET_REG(T0, rd, pass);
3321 } else { 3374 } else {
3322 NEON_GET_REG(T0, rd, pass); 3375 NEON_GET_REG(T0, rd, pass);
3323 - gen_ldst(stl, s); 3376 + tmp = new_tmp();
  3377 + tcg_gen_mov_i32(tmp, cpu_T[0]);
  3378 + gen_st32(tmp, cpu_T[1], IS_USER(s));
3324 } 3379 }
3325 gen_op_addl_T1_im(stride); 3380 gen_op_addl_T1_im(stride);
3326 } else if (size == 1) { 3381 } else if (size == 1) {
3327 if (load) { 3382 if (load) {
3328 - gen_ldst(lduw, s); 3383 + tmp = gen_ld16u(cpu_T[1], IS_USER(s));
  3384 + tcg_gen_mov_i32(cpu_T[0], tmp);
  3385 + dead_tmp(tmp);
3329 gen_op_addl_T1_im(stride); 3386 gen_op_addl_T1_im(stride);
3330 gen_op_movl_T2_T0(); 3387 gen_op_movl_T2_T0();
3331 - gen_ldst(lduw, s); 3388 + tmp = gen_ld16u(cpu_T[1], IS_USER(s));
  3389 + tcg_gen_mov_i32(cpu_T[0], tmp);
  3390 + dead_tmp(tmp);
3332 gen_op_addl_T1_im(stride); 3391 gen_op_addl_T1_im(stride);
3333 gen_op_neon_insert_elt(16, 0xffff); 3392 gen_op_neon_insert_elt(16, 0xffff);
3334 NEON_SET_REG(T2, rd, pass); 3393 NEON_SET_REG(T2, rd, pass);
3335 } else { 3394 } else {
3336 NEON_GET_REG(T2, rd, pass); 3395 NEON_GET_REG(T2, rd, pass);
3337 gen_op_movl_T0_T2(); 3396 gen_op_movl_T0_T2();
3338 - gen_ldst(stw, s); 3397 + tmp = new_tmp();
  3398 + tcg_gen_mov_i32(tmp, cpu_T[0]);
  3399 + gen_st16(tmp, cpu_T[1], IS_USER(s));
3339 gen_op_addl_T1_im(stride); 3400 gen_op_addl_T1_im(stride);
3340 gen_op_neon_extract_elt(16, 0xffff0000); 3401 gen_op_neon_extract_elt(16, 0xffff0000);
3341 - gen_ldst(stw, s); 3402 + tmp = new_tmp();
  3403 + tcg_gen_mov_i32(tmp, cpu_T[0]);
  3404 + gen_st16(tmp, cpu_T[1], IS_USER(s));
3342 gen_op_addl_T1_im(stride); 3405 gen_op_addl_T1_im(stride);
3343 } 3406 }
3344 } else /* size == 0 */ { 3407 } else /* size == 0 */ {
3345 if (load) { 3408 if (load) {
3346 mask = 0xff; 3409 mask = 0xff;
3347 for (n = 0; n < 4; n++) { 3410 for (n = 0; n < 4; n++) {
3348 - gen_ldst(ldub, s); 3411 + tmp = gen_ld8u(cpu_T[1], IS_USER(s));
  3412 + tcg_gen_mov_i32(cpu_T[0], tmp);
  3413 + dead_tmp(tmp);
3349 gen_op_addl_T1_im(stride); 3414 gen_op_addl_T1_im(stride);
3350 if (n == 0) { 3415 if (n == 0) {
3351 gen_op_movl_T2_T0(); 3416 gen_op_movl_T2_T0();
@@ -3364,7 +3429,9 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -3364,7 +3429,9 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3364 } else { 3429 } else {
3365 gen_op_neon_extract_elt(n * 8, mask); 3430 gen_op_neon_extract_elt(n * 8, mask);
3366 } 3431 }
3367 - gen_ldst(stb, s); 3432 + tmp = new_tmp();
  3433 + tcg_gen_mov_i32(tmp, cpu_T[0]);
  3434 + gen_st8(tmp, cpu_T[1], IS_USER(s));
3368 gen_op_addl_T1_im(stride); 3435 gen_op_addl_T1_im(stride);
3369 mask <<= 8; 3436 mask <<= 8;
3370 } 3437 }
@@ -3387,15 +3454,21 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -3387,15 +3454,21 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3387 for (reg = 0; reg < nregs; reg++) { 3454 for (reg = 0; reg < nregs; reg++) {
3388 switch (size) { 3455 switch (size) {
3389 case 0: 3456 case 0:
3390 - gen_ldst(ldub, s); 3457 + tmp = gen_ld8u(cpu_T[1], IS_USER(s));
  3458 + tcg_gen_mov_i32(cpu_T[0], tmp);
  3459 + dead_tmp(tmp);
3391 gen_op_neon_dup_u8(0); 3460 gen_op_neon_dup_u8(0);
3392 break; 3461 break;
3393 case 1: 3462 case 1:
3394 - gen_ldst(lduw, s); 3463 + tmp = gen_ld16u(cpu_T[1], IS_USER(s));
  3464 + tcg_gen_mov_i32(cpu_T[0], tmp);
  3465 + dead_tmp(tmp);
3395 gen_op_neon_dup_low16(); 3466 gen_op_neon_dup_low16();
3396 break; 3467 break;
3397 case 2: 3468 case 2:
3398 - gen_ldst(ldl, s); 3469 + tmp = gen_ld32(cpu_T[0], IS_USER(s));
  3470 + tcg_gen_mov_i32(cpu_T[0], tmp);
  3471 + dead_tmp(tmp);
3399 break; 3472 break;
3400 case 3: 3473 case 3:
3401 return 1; 3474 return 1;
@@ -3437,19 +3510,22 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -3437,19 +3510,22 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3437 } 3510 }
3438 switch (size) { 3511 switch (size) {
3439 case 0: 3512 case 0:
3440 - gen_ldst(ldub, s); 3513 + tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3441 break; 3514 break;
3442 case 1: 3515 case 1:
3443 - gen_ldst(lduw, s); 3516 + tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3444 break; 3517 break;
3445 case 2: 3518 case 2:
3446 - gen_ldst(ldl, s);  
3447 - NEON_SET_REG(T0, rd, pass); 3519 + tmp = gen_ld32(cpu_T[1], IS_USER(s));
3448 break; 3520 break;
3449 } 3521 }
  3522 + tcg_gen_mov_i32(cpu_T[0], tmp);
  3523 + dead_tmp(tmp);
3450 if (size != 2) { 3524 if (size != 2) {
3451 gen_op_neon_insert_elt(shift, ~mask); 3525 gen_op_neon_insert_elt(shift, ~mask);
3452 NEON_SET_REG(T0, rd, pass); 3526 NEON_SET_REG(T0, rd, pass);
  3527 + } else {
  3528 + NEON_SET_REG(T0, rd, pass);
3453 } 3529 }
3454 } else { /* Store */ 3530 } else { /* Store */
3455 if (size == 2) { 3531 if (size == 2) {
@@ -3458,15 +3534,17 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -3458,15 +3534,17 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3458 NEON_GET_REG(T2, rd, pass); 3534 NEON_GET_REG(T2, rd, pass);
3459 gen_op_neon_extract_elt(shift, mask); 3535 gen_op_neon_extract_elt(shift, mask);
3460 } 3536 }
  3537 + tmp = new_tmp();
  3538 + tcg_gen_mov_i32(tmp, cpu_T[0]);
3461 switch (size) { 3539 switch (size) {
3462 case 0: 3540 case 0:
3463 - gen_ldst(stb, s); 3541 + gen_st8(tmp, cpu_T[1], IS_USER(s));
3464 break; 3542 break;
3465 case 1: 3543 case 1:
3466 - gen_ldst(stw, s); 3544 + gen_st16(tmp, cpu_T[1], IS_USER(s));
3467 break; 3545 break;
3468 case 2: 3546 case 2:
3469 - gen_ldst(stl, s); 3547 + gen_st32(tmp, cpu_T[1], IS_USER(s));
3470 break; 3548 break;
3471 } 3549 }
3472 } 3550 }
@@ -4647,7 +4725,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -4647,7 +4725,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4647 NEON_GET_REG(T0, rm, pass * 2); 4725 NEON_GET_REG(T0, rm, pass * 2);
4648 NEON_GET_REG(T1, rm, pass * 2 + 1); 4726 NEON_GET_REG(T1, rm, pass * 2 + 1);
4649 switch (size) { 4727 switch (size) {
4650 - case 0: gen_op_rev_T0(); break; 4728 + case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4651 case 1: gen_swap_half(cpu_T[0]); break; 4729 case 1: gen_swap_half(cpu_T[0]); break;
4652 case 2: /* no-op */ break; 4730 case 2: /* no-op */ break;
4653 default: abort(); 4731 default: abort();
@@ -4658,7 +4736,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -4658,7 +4736,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4658 } else { 4736 } else {
4659 gen_op_movl_T0_T1(); 4737 gen_op_movl_T0_T1();
4660 switch (size) { 4738 switch (size) {
4661 - case 0: gen_op_rev_T0(); break; 4739 + case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4662 case 1: gen_swap_half(cpu_T[0]); break; 4740 case 1: gen_swap_half(cpu_T[0]); break;
4663 default: abort(); 4741 default: abort();
4664 } 4742 }
@@ -4827,7 +4905,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -4827,7 +4905,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4827 switch (op) { 4905 switch (op) {
4828 case 1: /* VREV32 */ 4906 case 1: /* VREV32 */
4829 switch (size) { 4907 switch (size) {
4830 - case 0: gen_op_rev_T0(); break; 4908 + case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4831 case 1: gen_swap_half(cpu_T[0]); break; 4909 case 1: gen_swap_half(cpu_T[0]); break;
4832 default: return 1; 4910 default: return 1;
4833 } 4911 }
@@ -5099,6 +5177,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5099,6 +5177,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5099 TCGv tmp; 5177 TCGv tmp;
5100 TCGv tmp2; 5178 TCGv tmp2;
5101 TCGv tmp3; 5179 TCGv tmp3;
  5180 + TCGv addr;
5102 5181
5103 insn = ldl_code(s->pc); 5182 insn = ldl_code(s->pc);
5104 s->pc += 4; 5183 s->pc += 4;
@@ -5160,9 +5239,10 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5160,9 +5239,10 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5160 ARCH(6); 5239 ARCH(6);
5161 op1 = (insn & 0x1f); 5240 op1 = (insn & 0x1f);
5162 if (op1 == (env->uncached_cpsr & CPSR_M)) { 5241 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5163 - gen_movl_T1_reg(s, 13); 5242 + addr = load_reg(s, 13);
5164 } else { 5243 } else {
5165 - gen_op_movl_T1_r13_banked(op1); 5244 + addr = new_tmp();
  5245 + gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5166 } 5246 }
5167 i = (insn >> 23) & 3; 5247 i = (insn >> 23) & 3;
5168 switch (i) { 5248 switch (i) {
@@ -5173,12 +5253,13 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5173,12 +5253,13 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5173 default: abort(); 5253 default: abort();
5174 } 5254 }
5175 if (offset) 5255 if (offset)
5176 - gen_op_addl_T1_im(offset);  
5177 - gen_movl_T0_reg(s, 14);  
5178 - gen_ldst(stl, s);  
5179 - gen_helper_cpsr_read(cpu_T[0]);  
5180 - gen_op_addl_T1_im(4);  
5181 - gen_ldst(stl, s); 5256 + tcg_gen_addi_i32(addr, addr, offset);
  5257 + tmp = load_reg(s, 14);
  5258 + gen_st32(tmp, addr, 0);
  5259 + tmp = new_tmp();
  5260 + gen_helper_cpsr_read(tmp);
  5261 + tcg_gen_addi_i32(addr, addr, 4);
  5262 + gen_st32(tmp, addr, 0);
5182 if (insn & (1 << 21)) { 5263 if (insn & (1 << 21)) {
5183 /* Base writeback. */ 5264 /* Base writeback. */
5184 switch (i) { 5265 switch (i) {
@@ -5189,12 +5270,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5189,12 +5270,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5189 default: abort(); 5270 default: abort();
5190 } 5271 }
5191 if (offset) 5272 if (offset)
5192 - gen_op_addl_T1_im(offset); 5273 + tcg_gen_addi_i32(addr, tmp, offset);
5193 if (op1 == (env->uncached_cpsr & CPSR_M)) { 5274 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5194 gen_movl_reg_T1(s, 13); 5275 gen_movl_reg_T1(s, 13);
5195 } else { 5276 } else {
5196 - gen_op_movl_r13_T1_banked(op1); 5277 + gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5197 } 5278 }
  5279 + } else {
  5280 + dead_tmp(addr);
5198 } 5281 }
5199 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) { 5282 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5200 /* rfe */ 5283 /* rfe */
@@ -5203,36 +5286,37 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5203,36 +5286,37 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5203 goto illegal_op; 5286 goto illegal_op;
5204 ARCH(6); 5287 ARCH(6);
5205 rn = (insn >> 16) & 0xf; 5288 rn = (insn >> 16) & 0xf;
5206 - gen_movl_T1_reg(s, rn); 5289 + addr = load_reg(s, rn);
5207 i = (insn >> 23) & 3; 5290 i = (insn >> 23) & 3;
5208 switch (i) { 5291 switch (i) {
5209 - case 0: offset = 0; break; /* DA */  
5210 - case 1: offset = -4; break; /* DB */  
5211 - case 2: offset = 4; break; /* IA */  
5212 - case 3: offset = 8; break; /* IB */ 5292 + case 0: offset = -4; break; /* DA */
  5293 + case 1: offset = -8; break; /* DB */
  5294 + case 2: offset = 0; break; /* IA */
  5295 + case 3: offset = 4; break; /* IB */
5213 default: abort(); 5296 default: abort();
5214 } 5297 }
5215 if (offset) 5298 if (offset)
5216 - gen_op_addl_T1_im(offset);  
5217 - /* Load CPSR into T2 and PC into T0. */  
5218 - gen_ldst(ldl, s);  
5219 - gen_op_movl_T2_T0();  
5220 - gen_op_addl_T1_im(-4);  
5221 - gen_ldst(ldl, s); 5299 + tcg_gen_addi_i32(addr, addr, offset);
  5300 + /* Load PC into tmp and CPSR into tmp2. */
  5301 + tmp = gen_ld32(addr, 0);
  5302 + tcg_gen_addi_i32(addr, addr, 4);
  5303 + tmp2 = gen_ld32(addr, 0);
5222 if (insn & (1 << 21)) { 5304 if (insn & (1 << 21)) {
5223 /* Base writeback. */ 5305 /* Base writeback. */
5224 switch (i) { 5306 switch (i) {
5225 - case 0: offset = -4; break;  
5226 - case 1: offset = 0; break;  
5227 - case 2: offset = 8; break;  
5228 - case 3: offset = 4; break; 5307 + case 0: offset = -8; break;
  5308 + case 1: offset = -4; break;
  5309 + case 2: offset = 4; break;
  5310 + case 3: offset = 0; break;
5229 default: abort(); 5311 default: abort();
5230 } 5312 }
5231 if (offset) 5313 if (offset)
5232 - gen_op_addl_T1_im(offset);  
5233 - gen_movl_reg_T1(s, rn); 5314 + tcg_gen_addi_i32(addr, addr, offset);
  5315 + store_reg(s, rn, addr);
  5316 + } else {
  5317 + dead_tmp(addr);
5234 } 5318 }
5235 - gen_rfe(s); 5319 + gen_rfe(s, tmp, tmp2);
5236 } else if ((insn & 0x0e000000) == 0x0a000000) { 5320 } else if ((insn & 0x0e000000) == 0x0a000000) {
5237 /* branch link and change to thumb (blx <offset>) */ 5321 /* branch link and change to thumb (blx <offset>) */
5238 int32_t offset; 5322 int32_t offset;
@@ -5707,22 +5791,22 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5707,22 +5791,22 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5707 /* Misc load/store */ 5791 /* Misc load/store */
5708 rn = (insn >> 16) & 0xf; 5792 rn = (insn >> 16) & 0xf;
5709 rd = (insn >> 12) & 0xf; 5793 rd = (insn >> 12) & 0xf;
5710 - gen_movl_T1_reg(s, rn); 5794 + addr = load_reg(s, rn);
5711 if (insn & (1 << 24)) 5795 if (insn & (1 << 24))
5712 - gen_add_datah_offset(s, insn, 0); 5796 + gen_add_datah_offset(s, insn, 0, addr);
5713 address_offset = 0; 5797 address_offset = 0;
5714 if (insn & (1 << 20)) { 5798 if (insn & (1 << 20)) {
5715 /* load */ 5799 /* load */
5716 switch(sh) { 5800 switch(sh) {
5717 case 1: 5801 case 1:
5718 - gen_ldst(lduw, s); 5802 + tmp = gen_ld16u(addr, IS_USER(s));
5719 break; 5803 break;
5720 case 2: 5804 case 2:
5721 - gen_ldst(ldsb, s); 5805 + tmp = gen_ld8s(addr, IS_USER(s));
5722 break; 5806 break;
5723 default: 5807 default:
5724 case 3: 5808 case 3:
5725 - gen_ldst(ldsw, s); 5809 + tmp = gen_ld16s(addr, IS_USER(s));
5726 break; 5810 break;
5727 } 5811 }
5728 load = 1; 5812 load = 1;
@@ -5730,26 +5814,26 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5730,26 +5814,26 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5730 /* doubleword */ 5814 /* doubleword */
5731 if (sh & 1) { 5815 if (sh & 1) {
5732 /* store */ 5816 /* store */
5733 - gen_movl_T0_reg(s, rd);  
5734 - gen_ldst(stl, s);  
5735 - gen_op_addl_T1_im(4);  
5736 - gen_movl_T0_reg(s, rd + 1);  
5737 - gen_ldst(stl, s); 5817 + tmp = load_reg(s, rd);
  5818 + gen_st32(tmp, addr, IS_USER(s));
  5819 + tcg_gen_addi_i32(addr, addr, 4);
  5820 + tmp = load_reg(s, rd + 1);
  5821 + gen_st32(tmp, addr, IS_USER(s));
5738 load = 0; 5822 load = 0;
5739 } else { 5823 } else {
5740 /* load */ 5824 /* load */
5741 - gen_ldst(ldl, s);  
5742 - gen_movl_reg_T0(s, rd);  
5743 - gen_op_addl_T1_im(4);  
5744 - gen_ldst(ldl, s); 5825 + tmp = gen_ld32(addr, IS_USER(s));
  5826 + store_reg(s, rd, tmp);
  5827 + tcg_gen_addi_i32(addr, addr, 4);
  5828 + tmp = gen_ld32(addr, IS_USER(s));
5745 rd++; 5829 rd++;
5746 load = 1; 5830 load = 1;
5747 } 5831 }
5748 address_offset = -4; 5832 address_offset = -4;
5749 } else { 5833 } else {
5750 /* store */ 5834 /* store */
5751 - gen_movl_T0_reg(s, rd);  
5752 - gen_ldst(stw, s); 5835 + tmp = load_reg(s, rd);
  5836 + gen_st16(tmp, addr, IS_USER(s));
5753 load = 0; 5837 load = 0;
5754 } 5838 }
5755 /* Perform base writeback before the loaded value to 5839 /* Perform base writeback before the loaded value to
@@ -5757,16 +5841,18 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5757,16 +5841,18 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5757 ldrd with base writeback is is undefined if the 5841 ldrd with base writeback is is undefined if the
5758 destination and index registers overlap. */ 5842 destination and index registers overlap. */
5759 if (!(insn & (1 << 24))) { 5843 if (!(insn & (1 << 24))) {
5760 - gen_add_datah_offset(s, insn, address_offset);  
5761 - gen_movl_reg_T1(s, rn); 5844 + gen_add_datah_offset(s, insn, address_offset, addr);
  5845 + store_reg(s, rn, addr);
5762 } else if (insn & (1 << 21)) { 5846 } else if (insn & (1 << 21)) {
5763 if (address_offset) 5847 if (address_offset)
5764 - gen_op_addl_T1_im(address_offset);  
5765 - gen_movl_reg_T1(s, rn); 5848 + tcg_gen_addi_i32(addr, addr, address_offset);
  5849 + store_reg(s, rn, addr);
  5850 + } else {
  5851 + dead_tmp(addr);
5766 } 5852 }
5767 if (load) { 5853 if (load) {
5768 /* Complete the load. */ 5854 /* Complete the load. */
5769 - gen_movl_reg_T0(s, rd); 5855 + store_reg(s, rd, tmp);
5770 } 5856 }
5771 } 5857 }
5772 break; 5858 break;
@@ -5882,21 +5968,21 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5882,21 +5968,21 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5882 gen_movl_reg_T1(s, rd); 5968 gen_movl_reg_T1(s, rd);
5883 } else if ((insn & 0x003f0f60) == 0x003f0f20) { 5969 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
5884 /* rev */ 5970 /* rev */
5885 - gen_movl_T0_reg(s, rm); 5971 + tmp = load_reg(s, rm);
5886 if (insn & (1 << 22)) { 5972 if (insn & (1 << 22)) {
5887 if (insn & (1 << 7)) { 5973 if (insn & (1 << 7)) {
5888 - gen_revsh(cpu_T[0]); 5974 + gen_revsh(tmp);
5889 } else { 5975 } else {
5890 ARCH(6T2); 5976 ARCH(6T2);
5891 - gen_helper_rbit(cpu_T[0], cpu_T[0]); 5977 + gen_helper_rbit(tmp, tmp);
5892 } 5978 }
5893 } else { 5979 } else {
5894 if (insn & (1 << 7)) 5980 if (insn & (1 << 7))
5895 - gen_rev16(cpu_T[0]); 5981 + gen_rev16(tmp);
5896 else 5982 else
5897 - gen_op_rev_T0(); 5983 + tcg_gen_bswap_i32(tmp, tmp);
5898 } 5984 }
5899 - gen_movl_reg_T0(s, rd); 5985 + store_reg(s, rd, tmp);
5900 } else { 5986 } else {
5901 goto illegal_op; 5987 goto illegal_op;
5902 } 5988 }
@@ -6020,71 +6106,47 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -6020,71 +6106,47 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6020 /* load/store byte/word */ 6106 /* load/store byte/word */
6021 rn = (insn >> 16) & 0xf; 6107 rn = (insn >> 16) & 0xf;
6022 rd = (insn >> 12) & 0xf; 6108 rd = (insn >> 12) & 0xf;
6023 - gen_movl_T1_reg(s, rn); 6109 + tmp2 = load_reg(s, rn);
6024 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000); 6110 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6025 if (insn & (1 << 24)) 6111 if (insn & (1 << 24))
6026 - gen_add_data_offset(s, insn); 6112 + gen_add_data_offset(s, insn, tmp2);
6027 if (insn & (1 << 20)) { 6113 if (insn & (1 << 20)) {
6028 /* load */ 6114 /* load */
6029 s->is_mem = 1; 6115 s->is_mem = 1;
6030 -#if defined(CONFIG_USER_ONLY)  
6031 - if (insn & (1 << 22))  
6032 - gen_op_ldub_raw();  
6033 - else  
6034 - gen_op_ldl_raw();  
6035 -#else  
6036 if (insn & (1 << 22)) { 6116 if (insn & (1 << 22)) {
6037 - if (i)  
6038 - gen_op_ldub_user();  
6039 - else  
6040 - gen_op_ldub_kernel(); 6117 + tmp = gen_ld8u(tmp2, i);
6041 } else { 6118 } else {
6042 - if (i)  
6043 - gen_op_ldl_user();  
6044 - else  
6045 - gen_op_ldl_kernel(); 6119 + tmp = gen_ld32(tmp2, i);
6046 } 6120 }
6047 -#endif  
6048 } else { 6121 } else {
6049 /* store */ 6122 /* store */
6050 - gen_movl_T0_reg(s, rd);  
6051 -#if defined(CONFIG_USER_ONLY) 6123 + tmp = load_reg(s, rd);
6052 if (insn & (1 << 22)) 6124 if (insn & (1 << 22))
6053 - gen_op_stb_raw(); 6125 + gen_st8(tmp, tmp2, i);
6054 else 6126 else
6055 - gen_op_stl_raw();  
6056 -#else  
6057 - if (insn & (1 << 22)) {  
6058 - if (i)  
6059 - gen_op_stb_user();  
6060 - else  
6061 - gen_op_stb_kernel();  
6062 - } else {  
6063 - if (i)  
6064 - gen_op_stl_user();  
6065 - else  
6066 - gen_op_stl_kernel();  
6067 - }  
6068 -#endif 6127 + gen_st32(tmp, tmp2, i);
6069 } 6128 }
6070 if (!(insn & (1 << 24))) { 6129 if (!(insn & (1 << 24))) {
6071 - gen_add_data_offset(s, insn);  
6072 - gen_movl_reg_T1(s, rn);  
6073 - } else if (insn & (1 << 21))  
6074 - gen_movl_reg_T1(s, rn); { 6130 + gen_add_data_offset(s, insn, tmp2);
  6131 + store_reg(s, rn, tmp2);
  6132 + } else if (insn & (1 << 21)) {
  6133 + store_reg(s, rn, tmp2);
  6134 + } else {
  6135 + dead_tmp(tmp2);
6075 } 6136 }
6076 if (insn & (1 << 20)) { 6137 if (insn & (1 << 20)) {
6077 /* Complete the load. */ 6138 /* Complete the load. */
6078 if (rd == 15) 6139 if (rd == 15)
6079 - gen_bx_T0(s); 6140 + gen_bx(s, tmp);
6080 else 6141 else
6081 - gen_movl_reg_T0(s, rd); 6142 + store_reg(s, rd, tmp);
6082 } 6143 }
6083 break; 6144 break;
6084 case 0x08: 6145 case 0x08:
6085 case 0x09: 6146 case 0x09:
6086 { 6147 {
6087 int j, n, user, loaded_base; 6148 int j, n, user, loaded_base;
  6149 + TCGv loaded_var;
6088 /* load/store multiple words */ 6150 /* load/store multiple words */
6089 /* XXX: store correct base if write back */ 6151 /* XXX: store correct base if write back */
6090 user = 0; 6152 user = 0;
@@ -6096,7 +6158,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -6096,7 +6158,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6096 user = 1; 6158 user = 1;
6097 } 6159 }
6098 rn = (insn >> 16) & 0xf; 6160 rn = (insn >> 16) & 0xf;
6099 - gen_movl_T1_reg(s, rn); 6161 + addr = load_reg(s, rn);
6100 6162
6101 /* compute total size */ 6163 /* compute total size */
6102 loaded_base = 0; 6164 loaded_base = 0;
@@ -6109,18 +6171,18 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -6109,18 +6171,18 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6109 if (insn & (1 << 23)) { 6171 if (insn & (1 << 23)) {
6110 if (insn & (1 << 24)) { 6172 if (insn & (1 << 24)) {
6111 /* pre increment */ 6173 /* pre increment */
6112 - gen_op_addl_T1_im(4); 6174 + tcg_gen_addi_i32(addr, addr, 4);
6113 } else { 6175 } else {
6114 /* post increment */ 6176 /* post increment */
6115 } 6177 }
6116 } else { 6178 } else {
6117 if (insn & (1 << 24)) { 6179 if (insn & (1 << 24)) {
6118 /* pre decrement */ 6180 /* pre decrement */
6119 - gen_op_addl_T1_im(-(n * 4)); 6181 + tcg_gen_addi_i32(addr, addr, -(n * 4));
6120 } else { 6182 } else {
6121 /* post decrement */ 6183 /* post decrement */
6122 if (n != 1) 6184 if (n != 1)
6123 - gen_op_addl_T1_im(-((n - 1) * 4)); 6185 + tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6124 } 6186 }
6125 } 6187 }
6126 j = 0; 6188 j = 0;
@@ -6128,34 +6190,37 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -6128,34 +6190,37 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6128 if (insn & (1 << i)) { 6190 if (insn & (1 << i)) {
6129 if (insn & (1 << 20)) { 6191 if (insn & (1 << 20)) {
6130 /* load */ 6192 /* load */
6131 - gen_ldst(ldl, s); 6193 + tmp = gen_ld32(addr, IS_USER(s));
6132 if (i == 15) { 6194 if (i == 15) {
6133 - gen_bx_T0(s); 6195 + gen_bx(s, tmp);
6134 } else if (user) { 6196 } else if (user) {
6135 - gen_op_movl_user_T0(i); 6197 + gen_helper_set_user_reg(tcg_const_i32(i), tmp);
  6198 + dead_tmp(tmp);
6136 } else if (i == rn) { 6199 } else if (i == rn) {
6137 - gen_op_movl_T2_T0(); 6200 + loaded_var = tmp;
6138 loaded_base = 1; 6201 loaded_base = 1;
6139 } else { 6202 } else {
6140 - gen_movl_reg_T0(s, i); 6203 + store_reg(s, i, tmp);
6141 } 6204 }
6142 } else { 6205 } else {
6143 /* store */ 6206 /* store */
6144 if (i == 15) { 6207 if (i == 15) {
6145 /* special case: r15 = PC + 8 */ 6208 /* special case: r15 = PC + 8 */
6146 val = (long)s->pc + 4; 6209 val = (long)s->pc + 4;
6147 - gen_op_movl_T0_im(val); 6210 + tmp = new_tmp();
  6211 + tcg_gen_movi_i32(tmp, val);
6148 } else if (user) { 6212 } else if (user) {
6149 - gen_op_movl_T0_user(i); 6213 + tmp = new_tmp();
  6214 + gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6150 } else { 6215 } else {
6151 - gen_movl_T0_reg(s, i); 6216 + tmp = load_reg(s, i);
6152 } 6217 }
6153 - gen_ldst(stl, s); 6218 + gen_st32(tmp, addr, IS_USER(s));
6154 } 6219 }
6155 j++; 6220 j++;
6156 /* no need to add after the last transfer */ 6221 /* no need to add after the last transfer */
6157 if (j != n) 6222 if (j != n)
6158 - gen_op_addl_T1_im(4); 6223 + tcg_gen_addi_i32(addr, addr, 4);
6159 } 6224 }
6160 } 6225 }
6161 if (insn & (1 << 21)) { 6226 if (insn & (1 << 21)) {
@@ -6165,23 +6230,24 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -6165,23 +6230,24 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6165 /* pre increment */ 6230 /* pre increment */
6166 } else { 6231 } else {
6167 /* post increment */ 6232 /* post increment */
6168 - gen_op_addl_T1_im(4); 6233 + tcg_gen_addi_i32(addr, addr, 4);
6169 } 6234 }
6170 } else { 6235 } else {
6171 if (insn & (1 << 24)) { 6236 if (insn & (1 << 24)) {
6172 /* pre decrement */ 6237 /* pre decrement */
6173 if (n != 1) 6238 if (n != 1)
6174 - gen_op_addl_T1_im(-((n - 1) * 4)); 6239 + tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6175 } else { 6240 } else {
6176 /* post decrement */ 6241 /* post decrement */
6177 - gen_op_addl_T1_im(-(n * 4)); 6242 + tcg_gen_addi_i32(addr, addr, -(n * 4));
6178 } 6243 }
6179 } 6244 }
6180 - gen_movl_reg_T1(s, rn); 6245 + store_reg(s, rn, addr);
  6246 + } else {
  6247 + dead_tmp(addr);
6181 } 6248 }
6182 if (loaded_base) { 6249 if (loaded_base) {
6183 - gen_op_movl_T0_T2();  
6184 - gen_movl_reg_T0(s, rn); 6250 + store_reg(s, rn, loaded_var);
6185 } 6251 }
6186 if ((insn & (1 << 22)) && !user) { 6252 if ((insn & (1 << 22)) && !user) {
6187 /* Restore CPSR from SPSR. */ 6253 /* Restore CPSR from SPSR. */
@@ -6319,11 +6385,12 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out) @@ -6319,11 +6385,12 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6319 is not legal. */ 6385 is not legal. */
6320 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) 6386 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6321 { 6387 {
6322 - uint32_t insn, imm, shift, offset, addr; 6388 + uint32_t insn, imm, shift, offset;
6323 uint32_t rd, rn, rm, rs; 6389 uint32_t rd, rn, rm, rs;
6324 TCGv tmp; 6390 TCGv tmp;
6325 TCGv tmp2; 6391 TCGv tmp2;
6326 TCGv tmp3; 6392 TCGv tmp3;
  6393 + TCGv addr;
6327 int op; 6394 int op;
6328 int shiftop; 6395 int shiftop;
6329 int conds; 6396 int conds;
@@ -6341,9 +6408,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6341,9 +6408,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6341 tcg_gen_addi_i32(tmp, tmp, offset); 6408 tcg_gen_addi_i32(tmp, tmp, offset);
6342 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); 6409 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6343 6410
6344 - addr = (uint32_t)s->pc;  
6345 tmp2 = new_tmp(); 6411 tmp2 = new_tmp();
6346 - tcg_gen_movi_i32(tmp2, addr | 1); 6412 + tcg_gen_movi_i32(tmp2, s->pc | 1);
6347 store_reg(s, 14, tmp2); 6413 store_reg(s, 14, tmp2);
6348 gen_bx(s, tmp); 6414 gen_bx(s, tmp);
6349 return 0; 6415 return 0;
@@ -6354,9 +6420,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6354,9 +6420,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6354 tmp = load_reg(s, 14); 6420 tmp = load_reg(s, 14);
6355 tcg_gen_addi_i32(tmp, tmp, 14); 6421 tcg_gen_addi_i32(tmp, tmp, 14);
6356 6422
6357 - addr = (uint32_t)s->pc;  
6358 tmp2 = new_tmp(); 6423 tmp2 = new_tmp();
6359 - tcg_gen_movi_i32(tmp2, addr | 1); 6424 + tcg_gen_movi_i32(tmp2, s->pc | 1);
6360 store_reg(s, 14, tmp2); 6425 store_reg(s, 14, tmp2);
6361 gen_bx(s, tmp); 6426 gen_bx(s, tmp);
6362 return 0; 6427 return 0;
@@ -6366,8 +6431,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6366,8 +6431,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6366 16-bit instructions in case the second half causes an 6431 16-bit instructions in case the second half causes an
6367 prefetch abort. */ 6432 prefetch abort. */
6368 offset = ((int32_t)insn << 21) >> 9; 6433 offset = ((int32_t)insn << 21) >> 9;
6369 - addr = s->pc + 2 + offset;  
6370 - gen_op_movl_T0_im(addr); 6434 + gen_op_movl_T0_im(s->pc + 2 + offset);
6371 gen_movl_reg_T0(s, 14); 6435 gen_movl_reg_T0(s, 14);
6372 return 0; 6436 return 0;
6373 } 6437 }
@@ -6396,38 +6460,41 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6396,38 +6460,41 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6396 if (insn & 0x01200000) { 6460 if (insn & 0x01200000) {
6397 /* Load/store doubleword. */ 6461 /* Load/store doubleword. */
6398 if (rn == 15) { 6462 if (rn == 15) {
6399 - gen_op_movl_T1_im(s->pc & ~3); 6463 + addr = new_tmp();
  6464 + tcg_gen_movi_i32(addr, s->pc & ~3);
6400 } else { 6465 } else {
6401 - gen_movl_T1_reg(s, rn); 6466 + addr = load_reg(s, rn);
6402 } 6467 }
6403 offset = (insn & 0xff) * 4; 6468 offset = (insn & 0xff) * 4;
6404 if ((insn & (1 << 23)) == 0) 6469 if ((insn & (1 << 23)) == 0)
6405 offset = -offset; 6470 offset = -offset;
6406 if (insn & (1 << 24)) { 6471 if (insn & (1 << 24)) {
6407 - gen_op_addl_T1_im(offset); 6472 + tcg_gen_addi_i32(addr, addr, offset);
6408 offset = 0; 6473 offset = 0;
6409 } 6474 }
6410 if (insn & (1 << 20)) { 6475 if (insn & (1 << 20)) {
6411 /* ldrd */ 6476 /* ldrd */
6412 - gen_ldst(ldl, s);  
6413 - gen_movl_reg_T0(s, rs);  
6414 - gen_op_addl_T1_im(4);  
6415 - gen_ldst(ldl, s);  
6416 - gen_movl_reg_T0(s, rd); 6477 + tmp = gen_ld32(addr, IS_USER(s));
  6478 + store_reg(s, rs, tmp);
  6479 + tcg_gen_addi_i32(addr, addr, 4);
  6480 + tmp = gen_ld32(addr, IS_USER(s));
  6481 + store_reg(s, rd, tmp);
6417 } else { 6482 } else {
6418 /* strd */ 6483 /* strd */
6419 - gen_movl_T0_reg(s, rs);  
6420 - gen_ldst(stl, s);  
6421 - gen_op_addl_T1_im(4);  
6422 - gen_movl_T0_reg(s, rd);  
6423 - gen_ldst(stl, s); 6484 + tmp = load_reg(s, rs);
  6485 + gen_st32(tmp, addr, IS_USER(s));
  6486 + tcg_gen_addi_i32(addr, addr, 4);
  6487 + tmp = load_reg(s, rd);
  6488 + gen_st32(tmp, addr, IS_USER(s));
6424 } 6489 }
6425 if (insn & (1 << 21)) { 6490 if (insn & (1 << 21)) {
6426 /* Base writeback. */ 6491 /* Base writeback. */
6427 if (rn == 15) 6492 if (rn == 15)
6428 goto illegal_op; 6493 goto illegal_op;
6429 - gen_op_addl_T1_im(offset - 4);  
6430 - gen_movl_reg_T1(s, rn); 6494 + tcg_gen_addi_i32(addr, addr, offset - 4);
  6495 + store_reg(s, rn, addr);
  6496 + } else {
  6497 + dead_tmp(addr);
6431 } 6498 }
6432 } else if ((insn & (1 << 23)) == 0) { 6499 } else if ((insn & (1 << 23)) == 0) {
6433 /* Load/store exclusive word. */ 6500 /* Load/store exclusive word. */
@@ -6442,24 +6509,26 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6442,24 +6509,26 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6442 } else if ((insn & (1 << 6)) == 0) { 6509 } else if ((insn & (1 << 6)) == 0) {
6443 /* Table Branch. */ 6510 /* Table Branch. */
6444 if (rn == 15) { 6511 if (rn == 15) {
6445 - gen_op_movl_T1_im(s->pc); 6512 + addr = new_tmp();
  6513 + tcg_gen_movi_i32(addr, s->pc);
6446 } else { 6514 } else {
6447 - gen_movl_T1_reg(s, rn); 6515 + addr = load_reg(s, rn);
6448 } 6516 }
6449 tmp = load_reg(s, rm); 6517 tmp = load_reg(s, rm);
6450 - tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); 6518 + tcg_gen_add_i32(addr, addr, tmp);
6451 if (insn & (1 << 4)) { 6519 if (insn & (1 << 4)) {
6452 /* tbh */ 6520 /* tbh */
6453 - tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); 6521 + tcg_gen_add_i32(addr, addr, tmp);
6454 dead_tmp(tmp); 6522 dead_tmp(tmp);
6455 - gen_ldst(lduw, s); 6523 + tmp = gen_ld16u(addr, IS_USER(s));
6456 } else { /* tbb */ 6524 } else { /* tbb */
6457 dead_tmp(tmp); 6525 dead_tmp(tmp);
6458 - gen_ldst(ldub, s); 6526 + tmp = gen_ld8u(addr, IS_USER(s));
6459 } 6527 }
6460 - tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 1);  
6461 - tcg_gen_addi_i32(cpu_T[0], cpu_T[0], s->pc);  
6462 - gen_movl_reg_T0(s, 15); 6528 + dead_tmp(addr);
  6529 + tcg_gen_shli_i32(tmp, tmp, 1);
  6530 + tcg_gen_addi_i32(tmp, tmp, s->pc);
  6531 + store_reg(s, 15, tmp);
6463 } else { 6532 } else {
6464 /* Load/store exclusive byte/halfword/doubleword. */ 6533 /* Load/store exclusive byte/halfword/doubleword. */
6465 op = (insn >> 4) & 0x3; 6534 op = (insn >> 4) & 0x3;
@@ -6503,68 +6572,74 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6503,68 +6572,74 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6503 /* Load/store multiple, RFE, SRS. */ 6572 /* Load/store multiple, RFE, SRS. */
6504 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) { 6573 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
6505 /* Not available in user mode. */ 6574 /* Not available in user mode. */
6506 - if (!IS_USER(s)) 6575 + if (IS_USER(s))
6507 goto illegal_op; 6576 goto illegal_op;
6508 if (insn & (1 << 20)) { 6577 if (insn & (1 << 20)) {
6509 /* rfe */ 6578 /* rfe */
6510 - gen_movl_T1_reg(s, rn);  
6511 - if (insn & (1 << 24)) {  
6512 - gen_op_addl_T1_im(4);  
6513 - } else {  
6514 - gen_op_addl_T1_im(-4);  
6515 - }  
6516 - /* Load CPSR into T2 and PC into T0. */  
6517 - gen_ldst(ldl, s);  
6518 - gen_op_movl_T2_T0();  
6519 - gen_op_addl_T1_im(-4);  
6520 - gen_ldst(ldl, s); 6579 + addr = load_reg(s, rn);
  6580 + if ((insn & (1 << 24)) == 0)
  6581 + tcg_gen_addi_i32(addr, addr, -8);
  6582 + /* Load PC into tmp and CPSR into tmp2. */
  6583 + tmp = gen_ld32(addr, 0);
  6584 + tcg_gen_addi_i32(addr, addr, 4);
  6585 + tmp2 = gen_ld32(addr, 0);
6521 if (insn & (1 << 21)) { 6586 if (insn & (1 << 21)) {
6522 /* Base writeback. */ 6587 /* Base writeback. */
6523 - if (insn & (1 << 24))  
6524 - gen_op_addl_T1_im(8);  
6525 - gen_movl_reg_T1(s, rn); 6588 + if (insn & (1 << 24)) {
  6589 + tcg_gen_addi_i32(addr, addr, 4);
  6590 + } else {
  6591 + tcg_gen_addi_i32(addr, addr, -4);
  6592 + }
  6593 + store_reg(s, rn, addr);
  6594 + } else {
  6595 + dead_tmp(addr);
6526 } 6596 }
6527 - gen_rfe(s); 6597 + gen_rfe(s, tmp, tmp2);
6528 } else { 6598 } else {
6529 /* srs */ 6599 /* srs */
6530 op = (insn & 0x1f); 6600 op = (insn & 0x1f);
6531 if (op == (env->uncached_cpsr & CPSR_M)) { 6601 if (op == (env->uncached_cpsr & CPSR_M)) {
6532 - gen_movl_T1_reg(s, 13); 6602 + addr = load_reg(s, 13);
6533 } else { 6603 } else {
6534 - gen_op_movl_T1_r13_banked(op); 6604 + addr = new_tmp();
  6605 + gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
6535 } 6606 }
6536 if ((insn & (1 << 24)) == 0) { 6607 if ((insn & (1 << 24)) == 0) {
6537 - gen_op_addl_T1_im(-8); 6608 + tcg_gen_addi_i32(addr, addr, -8);
6538 } 6609 }
6539 - gen_movl_T0_reg(s, 14);  
6540 - gen_ldst(stl, s);  
6541 - gen_helper_cpsr_read(cpu_T[0]);  
6542 - gen_op_addl_T1_im(4);  
6543 - gen_ldst(stl, s); 6610 + tmp = load_reg(s, 14);
  6611 + gen_st32(tmp, addr, 0);
  6612 + tcg_gen_addi_i32(addr, addr, 4);
  6613 + tmp = new_tmp();
  6614 + gen_helper_cpsr_read(tmp);
  6615 + gen_st32(tmp, addr, 0);
6544 if (insn & (1 << 21)) { 6616 if (insn & (1 << 21)) {
6545 if ((insn & (1 << 24)) == 0) { 6617 if ((insn & (1 << 24)) == 0) {
6546 - gen_op_addl_T1_im(-4); 6618 + tcg_gen_addi_i32(addr, addr, -4);
6547 } else { 6619 } else {
6548 - gen_op_addl_T1_im(4); 6620 + tcg_gen_addi_i32(addr, addr, 4);
6549 } 6621 }
6550 if (op == (env->uncached_cpsr & CPSR_M)) { 6622 if (op == (env->uncached_cpsr & CPSR_M)) {
6551 - gen_movl_reg_T1(s, 13); 6623 + store_reg(s, 13, addr);
6552 } else { 6624 } else {
6553 - gen_op_movl_r13_T1_banked(op); 6625 + gen_helper_set_r13_banked(cpu_env,
  6626 + tcg_const_i32(op), addr);
6554 } 6627 }
  6628 + } else {
  6629 + dead_tmp(addr);
6555 } 6630 }
6556 } 6631 }
6557 } else { 6632 } else {
6558 int i; 6633 int i;
6559 /* Load/store multiple. */ 6634 /* Load/store multiple. */
6560 - gen_movl_T1_reg(s, rn); 6635 + addr = load_reg(s, rn);
6561 offset = 0; 6636 offset = 0;
6562 for (i = 0; i < 16; i++) { 6637 for (i = 0; i < 16; i++) {
6563 if (insn & (1 << i)) 6638 if (insn & (1 << i))
6564 offset += 4; 6639 offset += 4;
6565 } 6640 }
6566 if (insn & (1 << 24)) { 6641 if (insn & (1 << 24)) {
6567 - gen_op_addl_T1_im(-offset); 6642 + tcg_gen_addi_i32(addr, addr, -offset);
6568 } 6643 }
6569 6644
6570 for (i = 0; i < 16; i++) { 6645 for (i = 0; i < 16; i++) {
@@ -6572,28 +6647,30 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6572,28 +6647,30 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6572 continue; 6647 continue;
6573 if (insn & (1 << 20)) { 6648 if (insn & (1 << 20)) {
6574 /* Load. */ 6649 /* Load. */
6575 - gen_ldst(ldl, s); 6650 + tmp = gen_ld32(addr, IS_USER(s));
6576 if (i == 15) { 6651 if (i == 15) {
6577 - gen_bx_T0(s); 6652 + gen_bx(s, tmp);
6578 } else { 6653 } else {
6579 - gen_movl_reg_T0(s, i); 6654 + store_reg(s, i, tmp);
6580 } 6655 }
6581 } else { 6656 } else {
6582 /* Store. */ 6657 /* Store. */
6583 - gen_movl_T0_reg(s, i);  
6584 - gen_ldst(stl, s); 6658 + tmp = load_reg(s, i);
  6659 + gen_st32(tmp, addr, IS_USER(s));
6585 } 6660 }
6586 - gen_op_addl_T1_im(4); 6661 + tcg_gen_addi_i32(addr, addr, 4);
6587 } 6662 }
6588 if (insn & (1 << 21)) { 6663 if (insn & (1 << 21)) {
6589 /* Base register writeback. */ 6664 /* Base register writeback. */
6590 if (insn & (1 << 24)) { 6665 if (insn & (1 << 24)) {
6591 - gen_op_addl_T1_im(-offset); 6666 + tcg_gen_addi_i32(addr, addr, -offset);
6592 } 6667 }
6593 /* Fault if writeback register is in register list. */ 6668 /* Fault if writeback register is in register list. */
6594 if (insn & (1 << rn)) 6669 if (insn & (1 << rn))
6595 goto illegal_op; 6670 goto illegal_op;
6596 - gen_movl_reg_T1(s, rn); 6671 + store_reg(s, rn, addr);
  6672 + } else {
  6673 + dead_tmp(addr);
6597 } 6674 }
6598 } 6675 }
6599 } 6676 }
@@ -6892,21 +6969,20 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6892,21 +6969,20 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6892 offset ^= ((~insn) & (1 << 13)) << 10; 6969 offset ^= ((~insn) & (1 << 13)) << 10;
6893 offset ^= ((~insn) & (1 << 11)) << 11; 6970 offset ^= ((~insn) & (1 << 11)) << 11;
6894 6971
6895 - addr = s->pc;  
6896 if (insn & (1 << 14)) { 6972 if (insn & (1 << 14)) {
6897 /* Branch and link. */ 6973 /* Branch and link. */
6898 - gen_op_movl_T1_im(addr | 1); 6974 + gen_op_movl_T1_im(s->pc | 1);
6899 gen_movl_reg_T1(s, 14); 6975 gen_movl_reg_T1(s, 14);
6900 } 6976 }
6901 6977
6902 - addr += offset; 6978 + offset += s->pc;
6903 if (insn & (1 << 12)) { 6979 if (insn & (1 << 12)) {
6904 /* b/bl */ 6980 /* b/bl */
6905 - gen_jmp(s, addr); 6981 + gen_jmp(s, offset);
6906 } else { 6982 } else {
6907 /* blx */ 6983 /* blx */
6908 - addr &= ~(uint32_t)2;  
6909 - gen_bx_im(s, addr); 6984 + offset &= ~(uint32_t)2;
  6985 + gen_bx_im(s, offset);
6910 } 6986 }
6911 } else if (((insn >> 23) & 7) == 7) { 6987 } else if (((insn >> 23) & 7) == 7) {
6912 /* Misc control */ 6988 /* Misc control */
@@ -7025,8 +7101,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -7025,8 +7101,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7025 offset |= (insn & (1 << 11)) << 8; 7101 offset |= (insn & (1 << 11)) << 8;
7026 7102
7027 /* jump to the offset */ 7103 /* jump to the offset */
7028 - addr = s->pc + offset;  
7029 - gen_jmp(s, addr); 7104 + gen_jmp(s, s->pc + offset);
7030 } 7105 }
7031 } else { 7106 } else {
7032 /* Data processing immediate. */ 7107 /* Data processing immediate. */
@@ -7114,12 +7189,12 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -7114,12 +7189,12 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7114 } else { 7189 } else {
7115 /* Add/sub 12-bit immediate. */ 7190 /* Add/sub 12-bit immediate. */
7116 if (rn == 15) { 7191 if (rn == 15) {
7117 - addr = s->pc & ~(uint32_t)3; 7192 + offset = s->pc & ~(uint32_t)3;
7118 if (insn & (1 << 23)) 7193 if (insn & (1 << 23))
7119 - addr -= imm; 7194 + offset -= imm;
7120 else 7195 else
7121 - addr += imm;  
7122 - gen_op_movl_T0_im(addr); 7196 + offset += imm;
  7197 + gen_op_movl_T0_im(offset);
7123 } else { 7198 } else {
7124 gen_movl_T0_reg(s, rn); 7199 gen_movl_T0_reg(s, rn);
7125 gen_op_movl_T1_im(imm); 7200 gen_op_movl_T1_im(imm);
@@ -7179,12 +7254,15 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -7179,12 +7254,15 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7179 { 7254 {
7180 int postinc = 0; 7255 int postinc = 0;
7181 int writeback = 0; 7256 int writeback = 0;
  7257 + int user;
7182 if ((insn & 0x01100000) == 0x01000000) { 7258 if ((insn & 0x01100000) == 0x01000000) {
7183 if (disas_neon_ls_insn(env, s, insn)) 7259 if (disas_neon_ls_insn(env, s, insn))
7184 goto illegal_op; 7260 goto illegal_op;
7185 break; 7261 break;
7186 } 7262 }
  7263 + user = IS_USER(s);
7187 if (rn == 15) { 7264 if (rn == 15) {
  7265 + addr = new_tmp();
7188 /* PC relative. */ 7266 /* PC relative. */
7189 /* s->pc has already been incremented by 4. */ 7267 /* s->pc has already been incremented by 4. */
7190 imm = s->pc & 0xfffffffc; 7268 imm = s->pc & 0xfffffffc;
@@ -7192,13 +7270,13 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -7192,13 +7270,13 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7192 imm += insn & 0xfff; 7270 imm += insn & 0xfff;
7193 else 7271 else
7194 imm -= insn & 0xfff; 7272 imm -= insn & 0xfff;
7195 - gen_op_movl_T1_im(imm); 7273 + tcg_gen_movi_i32(addr, imm);
7196 } else { 7274 } else {
7197 - gen_movl_T1_reg(s, rn); 7275 + addr = load_reg(s, rn);
7198 if (insn & (1 << 23)) { 7276 if (insn & (1 << 23)) {
7199 /* Positive offset. */ 7277 /* Positive offset. */
7200 imm = insn & 0xfff; 7278 imm = insn & 0xfff;
7201 - gen_op_addl_T1_im(imm); 7279 + tcg_gen_addi_i32(addr, addr, imm);
7202 } else { 7280 } else {
7203 op = (insn >> 8) & 7; 7281 op = (insn >> 8) & 7;
7204 imm = insn & 0xff; 7282 imm = insn & 0xff;
@@ -7210,14 +7288,15 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -7210,14 +7288,15 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7210 tmp = load_reg(s, rm); 7288 tmp = load_reg(s, rm);
7211 if (shift) 7289 if (shift)
7212 tcg_gen_shli_i32(tmp, tmp, shift); 7290 tcg_gen_shli_i32(tmp, tmp, shift);
7213 - tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); 7291 + tcg_gen_add_i32(addr, addr, tmp);
7214 dead_tmp(tmp); 7292 dead_tmp(tmp);
7215 break; 7293 break;
7216 case 4: /* Negative offset. */ 7294 case 4: /* Negative offset. */
7217 - gen_op_addl_T1_im(-imm); 7295 + tcg_gen_addi_i32(addr, addr, -imm);
7218 break; 7296 break;
7219 case 6: /* User privilege. */ 7297 case 6: /* User privilege. */
7220 - gen_op_addl_T1_im(imm); 7298 + tcg_gen_addi_i32(addr, addr, imm);
  7299 + user = 1;
7221 break; 7300 break;
7222 case 1: /* Post-decrement. */ 7301 case 1: /* Post-decrement. */
7223 imm = -imm; 7302 imm = -imm;
@@ -7230,7 +7309,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -7230,7 +7309,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7230 imm = -imm; 7309 imm = -imm;
7231 /* Fall through. */ 7310 /* Fall through. */
7232 case 7: /* Pre-increment. */ 7311 case 7: /* Pre-increment. */
7233 - gen_op_addl_T1_im(imm); 7312 + tcg_gen_addi_i32(addr, addr, imm);
7234 writeback = 1; 7313 writeback = 1;
7235 break; 7314 break;
7236 default: 7315 default:
@@ -7247,35 +7326,38 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -7247,35 +7326,38 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7247 /* Memory hint. Implemented as NOP. */ 7326 /* Memory hint. Implemented as NOP. */
7248 } else { 7327 } else {
7249 switch (op) { 7328 switch (op) {
7250 - case 0: gen_ldst(ldub, s); break;  
7251 - case 4: gen_ldst(ldsb, s); break;  
7252 - case 1: gen_ldst(lduw, s); break;  
7253 - case 5: gen_ldst(ldsw, s); break;  
7254 - case 2: gen_ldst(ldl, s); break; 7329 + case 0: tmp = gen_ld8u(addr, user); break;
  7330 + case 4: tmp = gen_ld8s(addr, user); break;
  7331 + case 1: tmp = gen_ld16u(addr, user); break;
  7332 + case 5: tmp = gen_ld16s(addr, user); break;
  7333 + case 2: tmp = gen_ld32(addr, user); break;
7255 default: goto illegal_op; 7334 default: goto illegal_op;
7256 } 7335 }
7257 if (rs == 15) { 7336 if (rs == 15) {
7258 - gen_bx_T0(s); 7337 + gen_bx(s, tmp);
7259 } else { 7338 } else {
7260 - gen_movl_reg_T0(s, rs); 7339 + store_reg(s, rs, tmp);
7261 } 7340 }
7262 } 7341 }
7263 } else { 7342 } else {
7264 /* Store. */ 7343 /* Store. */
7265 if (rs == 15) 7344 if (rs == 15)
7266 goto illegal_op; 7345 goto illegal_op;
7267 - gen_movl_T0_reg(s, rs); 7346 + tmp = load_reg(s, rs);
7268 switch (op) { 7347 switch (op) {
7269 - case 0: gen_ldst(stb, s); break;  
7270 - case 1: gen_ldst(stw, s); break;  
7271 - case 2: gen_ldst(stl, s); break; 7348 + case 0: gen_st8(tmp, addr, user); break;
  7349 + case 1: gen_st16(tmp, addr, user); break;
  7350 + case 2: gen_st32(tmp, addr, user); break;
7272 default: goto illegal_op; 7351 default: goto illegal_op;
7273 } 7352 }
7274 } 7353 }
7275 if (postinc) 7354 if (postinc)
7276 - gen_op_addl_T1_im(imm);  
7277 - if (writeback)  
7278 - gen_movl_reg_T1(s, rn); 7355 + tcg_gen_addi_i32(addr, addr, imm);
  7356 + if (writeback) {
  7357 + store_reg(s, rn, addr);
  7358 + } else {
  7359 + dead_tmp(addr);
  7360 + }
7279 } 7361 }
7280 break; 7362 break;
7281 default: 7363 default:
@@ -7293,6 +7375,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7293,6 +7375,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7293 int i; 7375 int i;
7294 TCGv tmp; 7376 TCGv tmp;
7295 TCGv tmp2; 7377 TCGv tmp2;
  7378 + TCGv addr;
7296 7379
7297 if (s->condexec_mask) { 7380 if (s->condexec_mask) {
7298 cond = s->condexec_cond; 7381 cond = s->condexec_cond;
@@ -7383,9 +7466,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7383,9 +7466,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7383 /* load pc-relative. Bit 1 of PC is ignored. */ 7466 /* load pc-relative. Bit 1 of PC is ignored. */
7384 val = s->pc + 2 + ((insn & 0xff) * 4); 7467 val = s->pc + 2 + ((insn & 0xff) * 4);
7385 val &= ~(uint32_t)2; 7468 val &= ~(uint32_t)2;
7386 - gen_op_movl_T1_im(val);  
7387 - gen_ldst(ldl, s);  
7388 - gen_movl_reg_T0(s, rd); 7469 + addr = new_tmp();
  7470 + tcg_gen_movi_i32(addr, val);
  7471 + tmp = gen_ld32(addr, IS_USER(s));
  7472 + dead_tmp(addr);
  7473 + store_reg(s, rd, tmp);
7389 break; 7474 break;
7390 } 7475 }
7391 if (insn & (1 << 10)) { 7476 if (insn & (1 << 10)) {
@@ -7410,12 +7495,13 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7410,12 +7495,13 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7410 gen_movl_reg_T0(s, rd); 7495 gen_movl_reg_T0(s, rd);
7411 break; 7496 break;
7412 case 3:/* branch [and link] exchange thumb register */ 7497 case 3:/* branch [and link] exchange thumb register */
  7498 + tmp = load_reg(s, rm);
7413 if (insn & (1 << 7)) { 7499 if (insn & (1 << 7)) {
7414 val = (uint32_t)s->pc | 1; 7500 val = (uint32_t)s->pc | 1;
7415 - gen_op_movl_T1_im(val);  
7416 - gen_movl_reg_T1(s, 14); 7501 + tmp2 = new_tmp();
  7502 + tcg_gen_movi_i32(tmp2, val);
  7503 + store_reg(s, 14, tmp2);
7417 } 7504 }
7418 - tmp = load_reg(s, rm);  
7419 gen_bx(s, tmp); 7505 gen_bx(s, tmp);
7420 break; 7506 break;
7421 } 7507 }
@@ -7553,117 +7639,122 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7553,117 +7639,122 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7553 rn = (insn >> 3) & 7; 7639 rn = (insn >> 3) & 7;
7554 rm = (insn >> 6) & 7; 7640 rm = (insn >> 6) & 7;
7555 op = (insn >> 9) & 7; 7641 op = (insn >> 9) & 7;
7556 - gen_movl_T1_reg(s, rn); 7642 + addr = load_reg(s, rn);
7557 tmp = load_reg(s, rm); 7643 tmp = load_reg(s, rm);
7558 - tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp); 7644 + tcg_gen_add_i32(addr, addr, tmp);
7559 dead_tmp(tmp); 7645 dead_tmp(tmp);
7560 7646
7561 if (op < 3) /* store */ 7647 if (op < 3) /* store */
7562 - gen_movl_T0_reg(s, rd); 7648 + tmp = load_reg(s, rd);
7563 7649
7564 switch (op) { 7650 switch (op) {
7565 case 0: /* str */ 7651 case 0: /* str */
7566 - gen_ldst(stl, s); 7652 + gen_st32(tmp, addr, IS_USER(s));
7567 break; 7653 break;
7568 case 1: /* strh */ 7654 case 1: /* strh */
7569 - gen_ldst(stw, s); 7655 + gen_st16(tmp, addr, IS_USER(s));
7570 break; 7656 break;
7571 case 2: /* strb */ 7657 case 2: /* strb */
7572 - gen_ldst(stb, s); 7658 + gen_st8(tmp, addr, IS_USER(s));
7573 break; 7659 break;
7574 case 3: /* ldrsb */ 7660 case 3: /* ldrsb */
7575 - gen_ldst(ldsb, s); 7661 + tmp = gen_ld8s(addr, IS_USER(s));
7576 break; 7662 break;
7577 case 4: /* ldr */ 7663 case 4: /* ldr */
7578 - gen_ldst(ldl, s); 7664 + tmp = gen_ld32(addr, IS_USER(s));
7579 break; 7665 break;
7580 case 5: /* ldrh */ 7666 case 5: /* ldrh */
7581 - gen_ldst(lduw, s); 7667 + tmp = gen_ld16u(addr, IS_USER(s));
7582 break; 7668 break;
7583 case 6: /* ldrb */ 7669 case 6: /* ldrb */
7584 - gen_ldst(ldub, s); 7670 + tmp = gen_ld8u(addr, IS_USER(s));
7585 break; 7671 break;
7586 case 7: /* ldrsh */ 7672 case 7: /* ldrsh */
7587 - gen_ldst(ldsw, s); 7673 + tmp = gen_ld16s(addr, IS_USER(s));
7588 break; 7674 break;
7589 } 7675 }
7590 if (op >= 3) /* load */ 7676 if (op >= 3) /* load */
7591 - gen_movl_reg_T0(s, rd); 7677 + store_reg(s, rd, tmp);
  7678 + dead_tmp(addr);
7592 break; 7679 break;
7593 7680
7594 case 6: 7681 case 6:
7595 /* load/store word immediate offset */ 7682 /* load/store word immediate offset */
7596 rd = insn & 7; 7683 rd = insn & 7;
7597 rn = (insn >> 3) & 7; 7684 rn = (insn >> 3) & 7;
7598 - gen_movl_T1_reg(s, rn); 7685 + addr = load_reg(s, rn);
7599 val = (insn >> 4) & 0x7c; 7686 val = (insn >> 4) & 0x7c;
7600 - tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val); 7687 + tcg_gen_addi_i32(addr, addr, val);
7601 7688
7602 if (insn & (1 << 11)) { 7689 if (insn & (1 << 11)) {
7603 /* load */ 7690 /* load */
7604 - gen_ldst(ldl, s);  
7605 - gen_movl_reg_T0(s, rd); 7691 + tmp = gen_ld32(addr, IS_USER(s));
  7692 + store_reg(s, rd, tmp);
7606 } else { 7693 } else {
7607 /* store */ 7694 /* store */
7608 - gen_movl_T0_reg(s, rd);  
7609 - gen_ldst(stl, s); 7695 + tmp = load_reg(s, rd);
  7696 + gen_st32(tmp, addr, IS_USER(s));
7610 } 7697 }
  7698 + dead_tmp(addr);
7611 break; 7699 break;
7612 7700
7613 case 7: 7701 case 7:
7614 /* load/store byte immediate offset */ 7702 /* load/store byte immediate offset */
7615 rd = insn & 7; 7703 rd = insn & 7;
7616 rn = (insn >> 3) & 7; 7704 rn = (insn >> 3) & 7;
7617 - gen_movl_T1_reg(s, rn); 7705 + addr = load_reg(s, rn);
7618 val = (insn >> 6) & 0x1f; 7706 val = (insn >> 6) & 0x1f;
7619 - tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val); 7707 + tcg_gen_addi_i32(addr, addr, val);
7620 7708
7621 if (insn & (1 << 11)) { 7709 if (insn & (1 << 11)) {
7622 /* load */ 7710 /* load */
7623 - gen_ldst(ldub, s);  
7624 - gen_movl_reg_T0(s, rd); 7711 + tmp = gen_ld8u(addr, IS_USER(s));
  7712 + store_reg(s, rd, tmp);
7625 } else { 7713 } else {
7626 /* store */ 7714 /* store */
7627 - gen_movl_T0_reg(s, rd);  
7628 - gen_ldst(stb, s); 7715 + tmp = load_reg(s, rd);
  7716 + gen_st8(tmp, addr, IS_USER(s));
7629 } 7717 }
  7718 + dead_tmp(addr);
7630 break; 7719 break;
7631 7720
7632 case 8: 7721 case 8:
7633 /* load/store halfword immediate offset */ 7722 /* load/store halfword immediate offset */
7634 rd = insn & 7; 7723 rd = insn & 7;
7635 rn = (insn >> 3) & 7; 7724 rn = (insn >> 3) & 7;
7636 - gen_movl_T1_reg(s, rn); 7725 + addr = load_reg(s, rn);
7637 val = (insn >> 5) & 0x3e; 7726 val = (insn >> 5) & 0x3e;
7638 - tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val); 7727 + tcg_gen_addi_i32(addr, addr, val);
7639 7728
7640 if (insn & (1 << 11)) { 7729 if (insn & (1 << 11)) {
7641 /* load */ 7730 /* load */
7642 - gen_ldst(lduw, s);  
7643 - gen_movl_reg_T0(s, rd); 7731 + tmp = gen_ld16u(addr, IS_USER(s));
  7732 + store_reg(s, rd, tmp);
7644 } else { 7733 } else {
7645 /* store */ 7734 /* store */
7646 - gen_movl_T0_reg(s, rd);  
7647 - gen_ldst(stw, s); 7735 + tmp = load_reg(s, rd);
  7736 + gen_st16(tmp, addr, IS_USER(s));
7648 } 7737 }
  7738 + dead_tmp(addr);
7649 break; 7739 break;
7650 7740
7651 case 9: 7741 case 9:
7652 /* load/store from stack */ 7742 /* load/store from stack */
7653 rd = (insn >> 8) & 7; 7743 rd = (insn >> 8) & 7;
7654 - gen_movl_T1_reg(s, 13); 7744 + addr = load_reg(s, 13);
7655 val = (insn & 0xff) * 4; 7745 val = (insn & 0xff) * 4;
7656 - tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val); 7746 + tcg_gen_addi_i32(addr, addr, val);
7657 7747
7658 if (insn & (1 << 11)) { 7748 if (insn & (1 << 11)) {
7659 /* load */ 7749 /* load */
7660 - gen_ldst(ldl, s);  
7661 - gen_movl_reg_T0(s, rd); 7750 + tmp = gen_ld32(addr, IS_USER(s));
  7751 + store_reg(s, rd, tmp);
7662 } else { 7752 } else {
7663 /* store */ 7753 /* store */
7664 - gen_movl_T0_reg(s, rd);  
7665 - gen_ldst(stl, s); 7754 + tmp = load_reg(s, rd);
  7755 + gen_st32(tmp, addr, IS_USER(s));
7666 } 7756 }
  7757 + dead_tmp(addr);
7667 break; 7758 break;
7668 7759
7669 case 10: 7760 case 10:
@@ -7700,18 +7791,18 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7700,18 +7791,18 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7700 ARCH(6); 7791 ARCH(6);
7701 rd = insn & 7; 7792 rd = insn & 7;
7702 rm = (insn >> 3) & 7; 7793 rm = (insn >> 3) & 7;
7703 - gen_movl_T1_reg(s, rm); 7794 + tmp = load_reg(s, rm);
7704 switch ((insn >> 6) & 3) { 7795 switch ((insn >> 6) & 3) {
7705 - case 0: gen_sxth(cpu_T[1]); break;  
7706 - case 1: gen_sxtb(cpu_T[1]); break;  
7707 - case 2: gen_uxth(cpu_T[1]); break;  
7708 - case 3: gen_uxtb(cpu_T[1]); break; 7796 + case 0: gen_sxth(tmp); break;
  7797 + case 1: gen_sxtb(tmp); break;
  7798 + case 2: gen_uxth(tmp); break;
  7799 + case 3: gen_uxtb(tmp); break;
7709 } 7800 }
7710 - gen_movl_reg_T1(s, rd); 7801 + store_reg(s, rd, tmp);
7711 break; 7802 break;
7712 case 4: case 5: case 0xc: case 0xd: 7803 case 4: case 5: case 0xc: case 0xd:
7713 /* push/pop */ 7804 /* push/pop */
7714 - gen_movl_T1_reg(s, 13); 7805 + addr = load_reg(s, 13);
7715 if (insn & (1 << 8)) 7806 if (insn & (1 << 8))
7716 offset = 4; 7807 offset = 4;
7717 else 7808 else
@@ -7721,44 +7812,44 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7721,44 +7812,44 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7721 offset += 4; 7812 offset += 4;
7722 } 7813 }
7723 if ((insn & (1 << 11)) == 0) { 7814 if ((insn & (1 << 11)) == 0) {
7724 - gen_op_addl_T1_im(-offset); 7815 + tcg_gen_addi_i32(addr, addr, -offset);
7725 } 7816 }
7726 for (i = 0; i < 8; i++) { 7817 for (i = 0; i < 8; i++) {
7727 if (insn & (1 << i)) { 7818 if (insn & (1 << i)) {
7728 if (insn & (1 << 11)) { 7819 if (insn & (1 << 11)) {
7729 /* pop */ 7820 /* pop */
7730 - gen_ldst(ldl, s);  
7731 - gen_movl_reg_T0(s, i); 7821 + tmp = gen_ld32(addr, IS_USER(s));
  7822 + store_reg(s, i, tmp);
7732 } else { 7823 } else {
7733 /* push */ 7824 /* push */
7734 - gen_movl_T0_reg(s, i);  
7735 - gen_ldst(stl, s); 7825 + tmp = load_reg(s, i);
  7826 + gen_st32(tmp, addr, IS_USER(s));
7736 } 7827 }
7737 /* advance to the next address. */ 7828 /* advance to the next address. */
7738 - gen_op_addl_T1_im(4); 7829 + tcg_gen_addi_i32(addr, addr, 4);
7739 } 7830 }
7740 } 7831 }
7741 if (insn & (1 << 8)) { 7832 if (insn & (1 << 8)) {
7742 if (insn & (1 << 11)) { 7833 if (insn & (1 << 11)) {
7743 /* pop pc */ 7834 /* pop pc */
7744 - gen_ldst(ldl, s); 7835 + tmp = gen_ld32(addr, IS_USER(s));
7745 /* don't set the pc until the rest of the instruction 7836 /* don't set the pc until the rest of the instruction
7746 has completed */ 7837 has completed */
7747 } else { 7838 } else {
7748 /* push lr */ 7839 /* push lr */
7749 - gen_movl_T0_reg(s, 14);  
7750 - gen_ldst(stl, s); 7840 + tmp = load_reg(s, 14);
  7841 + gen_st32(tmp, addr, IS_USER(s));
7751 } 7842 }
7752 - gen_op_addl_T1_im(4); 7843 + tcg_gen_addi_i32(addr, addr, 4);
7753 } 7844 }
7754 if ((insn & (1 << 11)) == 0) { 7845 if ((insn & (1 << 11)) == 0) {
7755 - gen_op_addl_T1_im(-offset); 7846 + tcg_gen_addi_i32(addr, addr, -offset);
7756 } 7847 }
7757 /* write back the new stack pointer */ 7848 /* write back the new stack pointer */
7758 - gen_movl_reg_T1(s, 13); 7849 + store_reg(s, 13, addr);
7759 /* set the new PC value */ 7850 /* set the new PC value */
7760 if ((insn & 0x0900) == 0x0900) 7851 if ((insn & 0x0900) == 0x0900)
7761 - gen_bx_T0(s); 7852 + gen_bx(s, tmp);
7762 break; 7853 break;
7763 7854
7764 case 1: case 3: case 9: case 11: /* czb */ 7855 case 1: case 3: case 9: case 11: /* czb */
@@ -7801,14 +7892,14 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7801,14 +7892,14 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7801 ARCH(6); 7892 ARCH(6);
7802 rn = (insn >> 3) & 0x7; 7893 rn = (insn >> 3) & 0x7;
7803 rd = insn & 0x7; 7894 rd = insn & 0x7;
7804 - gen_movl_T0_reg(s, rn); 7895 + tmp = load_reg(s, rn);
7805 switch ((insn >> 6) & 3) { 7896 switch ((insn >> 6) & 3) {
7806 - case 0: gen_op_rev_T0(); break;  
7807 - case 1: gen_rev16(cpu_T[0]); break;  
7808 - case 3: gen_revsh(cpu_T[0]); break; 7897 + case 0: tcg_gen_bswap_i32(tmp, tmp); break;
  7898 + case 1: gen_rev16(tmp); break;
  7899 + case 3: gen_revsh(tmp); break;
7809 default: goto illegal_op; 7900 default: goto illegal_op;
7810 } 7901 }
7811 - gen_movl_reg_T0(s, rd); 7902 + store_reg(s, rd, tmp);
7812 break; 7903 break;
7813 7904
7814 case 6: /* cps */ 7905 case 6: /* cps */
@@ -7846,25 +7937,28 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7846,25 +7937,28 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7846 case 12: 7937 case 12:
7847 /* load/store multiple */ 7938 /* load/store multiple */
7848 rn = (insn >> 8) & 0x7; 7939 rn = (insn >> 8) & 0x7;
7849 - gen_movl_T1_reg(s, rn); 7940 + addr = load_reg(s, rn);
7850 for (i = 0; i < 8; i++) { 7941 for (i = 0; i < 8; i++) {
7851 if (insn & (1 << i)) { 7942 if (insn & (1 << i)) {
7852 if (insn & (1 << 11)) { 7943 if (insn & (1 << 11)) {
7853 /* load */ 7944 /* load */
7854 - gen_ldst(ldl, s);  
7855 - gen_movl_reg_T0(s, i); 7945 + tmp = gen_ld32(addr, IS_USER(s));
  7946 + store_reg(s, i, tmp);
7856 } else { 7947 } else {
7857 /* store */ 7948 /* store */
7858 - gen_movl_T0_reg(s, i);  
7859 - gen_ldst(stl, s); 7949 + tmp = load_reg(s, i);
  7950 + gen_st32(tmp, addr, IS_USER(s));
7860 } 7951 }
7861 /* advance to the next address */ 7952 /* advance to the next address */
7862 - gen_op_addl_T1_im(4); 7953 + tcg_gen_addi_i32(addr, addr, 4);
7863 } 7954 }
7864 } 7955 }
7865 /* Base register writeback. */ 7956 /* Base register writeback. */
7866 - if ((insn & (1 << rn)) == 0)  
7867 - gen_movl_reg_T1(s, rn); 7957 + if ((insn & (1 << rn)) == 0) {
  7958 + store_reg(s, rn, addr);
  7959 + } else {
  7960 + dead_tmp(addr);
  7961 + }
7868 break; 7962 break;
7869 7963
7870 case 13: 7964 case 13:
tcg/tcg-op.h
@@ -199,6 +199,18 @@ static inline void tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2) @@ -199,6 +199,18 @@ static inline void tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2)
199 0, NULL, 2, args); 199 0, NULL, 2, args);
200 } 200 }
201 201
  202 +static inline void tcg_gen_helper_0_3(void *func,
  203 + TCGv arg1, TCGv arg2, TCGv arg3)
  204 +{
  205 + TCGv args[3];
  206 + args[0] = arg1;
  207 + args[1] = arg2;
  208 + args[2] = arg3;
  209 + tcg_gen_call(&tcg_ctx,
  210 + tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  211 + 0, NULL, 3, args);
  212 +}
  213 +
202 static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2, 214 static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2,
203 TCGv arg3, TCGv arg4) 215 TCGv arg3, TCGv arg4)
204 { 216 {