Commit 91a3c1b00d040f92f4bdca5825e5d2205d417c2f
1 parent
e936243a
Comment non-obvious calculation. Don't clobber r3 in qemu_st64.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4548 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
33 additions
and
6 deletions
tcg/arm/tcg-target.c
| ... | ... | @@ -854,12 +854,27 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond, |
| 854 | 854 | s_bits = opc & 3; |
| 855 | 855 | |
| 856 | 856 | # ifdef USE_TLB |
| 857 | + /* Should generate something like the following: | |
| 858 | + * ror r8, addr_reg, #TARGET_PAGE_BITS | |
| 859 | + * and r0, r8, #(CPU_TLB_SIZE - 1) @ Assumption: CPU_TLB_BITS <= 8 | |
| 860 | + * add r0, T0, r0 lsl #CPU_TLB_ENTRY_BITS | |
| 861 | + */ | |
| 862 | +# if CPU_TLB_BITS > 8 | |
| 863 | +# error | |
| 864 | +# endif | |
| 857 | 865 | tcg_out_dat_reg(s, COND_AL, ARITH_MOV, |
| 858 | 866 | 8, 0, addr_reg, SHIFT_IMM_ROR(TARGET_PAGE_BITS)); |
| 859 | 867 | tcg_out_dat_imm(s, COND_AL, ARITH_AND, |
| 860 | 868 | 0, 8, CPU_TLB_SIZE - 1); |
| 861 | 869 | tcg_out_dat_reg(s, COND_AL, ARITH_ADD, |
| 862 | 870 | 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); |
| 871 | + /* In the | |
| 872 | + * ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_read))] | |
| 873 | + * below, the offset is likely to exceed 12 bits if mem_index != 0 and | |
| 874 | + * not exceed otherwise, so use an | |
| 875 | + * add r0, r0, #(mem_index * sizeof *CPUState.tlb_table) | |
| 876 | + * before. | |
| 877 | + */ | |
| 863 | 878 | # define TLB_SHIFT (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS) |
| 864 | 879 | if (mem_index) |
| 865 | 880 | tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0, |
| ... | ... | @@ -1025,12 +1040,24 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, |
| 1025 | 1040 | s_bits = opc & 3; |
| 1026 | 1041 | |
| 1027 | 1042 | # ifdef USE_TLB |
| 1043 | + /* Should generate something like the following: | |
| 1044 | + * ror r8, addr_reg, #TARGET_PAGE_BITS | |
| 1045 | + * and r0, r8, #(CPU_TLB_SIZE - 1) @ Assumption: CPU_TLB_BITS <= 8 | |
| 1046 | + * add r0, T0, r0 lsl #CPU_TLB_ENTRY_BITS | |
| 1047 | + */ | |
| 1028 | 1048 | tcg_out_dat_reg(s, COND_AL, ARITH_MOV, |
| 1029 | 1049 | 8, 0, addr_reg, SHIFT_IMM_ROR(TARGET_PAGE_BITS)); |
| 1030 | 1050 | tcg_out_dat_imm(s, COND_AL, ARITH_AND, |
| 1031 | 1051 | 0, 8, CPU_TLB_SIZE - 1); |
| 1032 | 1052 | tcg_out_dat_reg(s, COND_AL, ARITH_ADD, |
| 1033 | 1053 | 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); |
| 1054 | + /* In the | |
| 1055 | + * ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_write))] | |
| 1056 | + * below, the offset is likely to exceed 12 bits if mem_index != 0 and | |
| 1057 | + * not exceed otherwise, so use an | |
| 1058 | + * add r0, r0, #(mem_index * sizeof *CPUState.tlb_table) | |
| 1059 | + * before. | |
| 1060 | + */ | |
| 1034 | 1061 | if (mem_index) |
| 1035 | 1062 | tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0, |
| 1036 | 1063 | (mem_index << (TLB_SHIFT & 1)) | |
| ... | ... | @@ -1084,10 +1111,6 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, |
| 1084 | 1111 | tcg_out_b(s, COND_EQ, 8); |
| 1085 | 1112 | # endif |
| 1086 | 1113 | |
| 1087 | -# ifdef SAVE_LR | |
| 1088 | - tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 14, SHIFT_IMM_LSL(0)); | |
| 1089 | -# endif | |
| 1090 | - | |
| 1091 | 1114 | /* TODO: move this code to where the constants pool will be */ |
| 1092 | 1115 | if (addr_reg) |
| 1093 | 1116 | tcg_out_dat_reg(s, cond, ARITH_MOV, |
| ... | ... | @@ -1144,8 +1167,8 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, |
| 1144 | 1167 | tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index); |
| 1145 | 1168 | break; |
| 1146 | 1169 | case 3: |
| 1147 | - tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index); | |
| 1148 | - tcg_out32(s, (cond << 28) | 0x052d3010); /* str r3, [sp, #-0x10]! */ | |
| 1170 | + tcg_out_dat_imm(s, cond, ARITH_MOV, 8, 0, mem_index); | |
| 1171 | + tcg_out32(s, (cond << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */ | |
| 1149 | 1172 | if (data_reg != 2) |
| 1150 | 1173 | tcg_out_dat_reg(s, cond, ARITH_MOV, |
| 1151 | 1174 | 2, 0, data_reg, SHIFT_IMM_LSL(0)); |
| ... | ... | @@ -1156,6 +1179,10 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, |
| 1156 | 1179 | } |
| 1157 | 1180 | # endif |
| 1158 | 1181 | |
| 1182 | +# ifdef SAVE_LR | |
| 1183 | + tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 14, SHIFT_IMM_LSL(0)); | |
| 1184 | +# endif | |
| 1185 | + | |
| 1159 | 1186 | tcg_out_bl(s, cond, (tcg_target_long) qemu_st_helpers[s_bits] - |
| 1160 | 1187 | (tcg_target_long) s->code_ptr); |
| 1161 | 1188 | ... | ... |