Commit a018d617f889d486b215ac342b7f49f6ec76fad6

Authored by Filip Navara
1 parent 1fb3d0da

Use tcg_global_mem_new_i32 to allocate ARM registers in TCG.

Currently each read/write of ARM register involves a LD/ST TCG operation. This
patch uses TCG memory-backed registers to represent the ARM register set. With
memory-backed registers the LD/ST operations are transparently generated by TCG
and host registers could be used to optimize the generated code.

Signed-off-by: Filip Navara <filip.navara@gmail.com>
Showing 1 changed file with 23 additions and 17 deletions
target-arm/translate.c
... ... @@ -76,6 +76,7 @@ typedef struct DisasContext {
76 76 static TCGv_ptr cpu_env;
77 77 /* We reuse the same 64-bit temporaries for efficiency. */
78 78 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
  79 +static TCGv_i32 cpu_R[16];
79 80  
80 81 /* FIXME: These should be removed. */
81 82 static TCGv cpu_T[2];
... ... @@ -85,14 +86,26 @@ static TCGv_i64 cpu_F0d, cpu_F1d;
85 86 #define ICOUNT_TEMP cpu_T[0]
86 87 #include "gen-icount.h"
87 88  
  89 +static const char *regnames[] =
  90 + { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  91 + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
  92 +
88 93 /* initialize TCG globals. */
89 94 void arm_translate_init(void)
90 95 {
  96 + int i;
  97 +
91 98 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
92 99  
93 100 cpu_T[0] = tcg_global_reg_new_i32(TCG_AREG1, "T0");
94 101 cpu_T[1] = tcg_global_reg_new_i32(TCG_AREG2, "T1");
95 102  
  103 + for (i = 0; i < 16; i++) {
  104 + cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
  105 + offsetof(CPUState, regs[i]),
  106 + regnames[i]);
  107 + }
  108 +
96 109 #define GEN_HELPER 2
97 110 #include "helpers.h"
98 111 }
... ... @@ -167,7 +180,7 @@ static void load_reg_var(DisasContext *s, TCGv var, int reg)
167 180 addr = (long)s->pc + 4;
168 181 tcg_gen_movi_i32(var, addr);
169 182 } else {
170   - tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
  183 + tcg_gen_mov_i32(var, cpu_R[reg]);
171 184 }
172 185 }
173 186  
... ... @@ -187,7 +200,7 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
187 200 tcg_gen_andi_i32(var, var, ~1);
188 201 s->is_jmp = DISAS_JUMP;
189 202 }
190   - tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
  203 + tcg_gen_mov_i32(cpu_R[reg], var);
191 204 dead_tmp(var);
192 205 }
193 206  
... ... @@ -789,27 +802,22 @@ static inline void gen_bx_im(DisasContext *s, uint32_t addr)
789 802 TCGv tmp;
790 803  
791 804 s->is_jmp = DISAS_UPDATE;
792   - tmp = new_tmp();
793 805 if (s->thumb != (addr & 1)) {
  806 + tmp = new_tmp();
794 807 tcg_gen_movi_i32(tmp, addr & 1);
795 808 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
  809 + dead_tmp(tmp);
796 810 }
797   - tcg_gen_movi_i32(tmp, addr & ~1);
798   - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
799   - dead_tmp(tmp);
  811 + tcg_gen_mov_i32(cpu_R[15], addr & ~1);
800 812 }
801 813  
802 814 /* Set PC and Thumb state from var. var is marked as dead. */
803 815 static inline void gen_bx(DisasContext *s, TCGv var)
804 816 {
805   - TCGv tmp;
806   -
807 817 s->is_jmp = DISAS_UPDATE;
808   - tmp = new_tmp();
809   - tcg_gen_andi_i32(tmp, var, 1);
810   - store_cpu_field(tmp, thumb);
811   - tcg_gen_andi_i32(var, var, ~1);
812   - store_cpu_field(var, regs[15]);
  818 + tcg_gen_andi_i32(cpu_R[15], var, ~1);
  819 + tcg_gen_andi_i32(var, var, 1);
  820 + store_cpu_field(var, thumb);
813 821 }
814 822  
815 823 /* Variant of store_reg which uses branch&exchange logic when storing
... ... @@ -888,9 +896,7 @@ static inline void gen_movl_T2_reg(DisasContext *s, int reg)
888 896  
889 897 static inline void gen_set_pc_im(uint32_t val)
890 898 {
891   - TCGv tmp = new_tmp();
892   - tcg_gen_movi_i32(tmp, val);
893   - store_cpu_field(tmp, regs[15]);
  899 + tcg_gen_movi_i32(cpu_R[15], val);
894 900 }
895 901  
896 902 static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
... ... @@ -902,7 +908,7 @@ static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
902 908 } else {
903 909 tmp = cpu_T[t];
904 910 }
905   - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
  911 + tcg_gen_mov_i32(cpu_R[reg], tmp);
906 912 if (reg == 15) {
907 913 dead_tmp(tmp);
908 914 s->is_jmp = DISAS_JUMP;
... ...