Commit e9bb4aa977391e2c62b7dc496b1e14d29b7cbd4e
Committed by
Paul Brook
1 parent
f7897430
fix ARMv7 data processing instructions
Modernize parts of target-arm/translate.c in preparation for the modifications in the subsequent patch in this patch set. This is done in order to avoid writing new code to target-arm/translate.c that would use deprecated methods and/or variables. Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com> Signed-off-by: Paul Brook <paul@codesourcery.com>
Showing
1 changed file
with
111 additions
and
77 deletions
target-arm/translate.c
... | ... | @@ -207,7 +207,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var) |
207 | 207 | #define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1]) |
208 | 208 | #define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1]) |
209 | 209 | #define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0]) |
210 | -#define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0]) | |
211 | 210 | |
212 | 211 | #define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]) |
213 | 212 | #define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1]) |
... | ... | @@ -436,6 +435,16 @@ static void gen_adc_T0_T1(void) |
436 | 435 | dead_tmp(tmp); |
437 | 436 | } |
438 | 437 | |
438 | +/* dest = T0 + T1 + CF. */ | |
439 | +static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1) | |
440 | +{ | |
441 | + TCGv tmp; | |
442 | + tcg_gen_add_i32(dest, t0, t1); | |
443 | + tmp = load_cpu_field(CF); | |
444 | + tcg_gen_add_i32(dest, dest, tmp); | |
445 | + dead_tmp(tmp); | |
446 | +} | |
447 | + | |
439 | 448 | /* dest = T0 - T1 + CF - 1. */ |
440 | 449 | static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) |
441 | 450 | { |
... | ... | @@ -3446,11 +3455,11 @@ static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr) |
3446 | 3455 | return 0; |
3447 | 3456 | } |
3448 | 3457 | |
3449 | -/* Generate an old-style exception return. */ | |
3450 | -static void gen_exception_return(DisasContext *s) | |
3458 | +/* Generate an old-style exception return. Marks pc as dead. */ | |
3459 | +static void gen_exception_return(DisasContext *s, TCGv pc) | |
3451 | 3460 | { |
3452 | 3461 | TCGv tmp; |
3453 | - gen_movl_reg_T0(s, 15); | |
3462 | + store_reg(s, 15, pc); | |
3454 | 3463 | tmp = load_cpu_field(spsr); |
3455 | 3464 | gen_set_cpsr(tmp, 0xffffffff); |
3456 | 3465 | dead_tmp(tmp); |
... | ... | @@ -6087,148 +6096,173 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
6087 | 6096 | /* immediate operand */ |
6088 | 6097 | val = insn & 0xff; |
6089 | 6098 | shift = ((insn >> 8) & 0xf) * 2; |
6090 | - if (shift) | |
6099 | + if (shift) { | |
6091 | 6100 | val = (val >> shift) | (val << (32 - shift)); |
6092 | - gen_op_movl_T1_im(val); | |
6093 | - if (logic_cc && shift) | |
6094 | - gen_set_CF_bit31(cpu_T[1]); | |
6101 | + } | |
6102 | + tmp2 = new_tmp(); | |
6103 | + tcg_gen_movi_i32(tmp2, val); | |
6104 | + if (logic_cc && shift) { | |
6105 | + gen_set_CF_bit31(tmp2); | |
6106 | + } | |
6095 | 6107 | } else { |
6096 | 6108 | /* register */ |
6097 | 6109 | rm = (insn) & 0xf; |
6098 | - gen_movl_T1_reg(s, rm); | |
6110 | + tmp2 = load_reg(s, rm); | |
6099 | 6111 | shiftop = (insn >> 5) & 3; |
6100 | 6112 | if (!(insn & (1 << 4))) { |
6101 | 6113 | shift = (insn >> 7) & 0x1f; |
6102 | - gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc); | |
6114 | + gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); | |
6103 | 6115 | } else { |
6104 | 6116 | rs = (insn >> 8) & 0xf; |
6105 | 6117 | tmp = load_reg(s, rs); |
6106 | - gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc); | |
6118 | + gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc); | |
6107 | 6119 | } |
6108 | 6120 | } |
6109 | 6121 | if (op1 != 0x0f && op1 != 0x0d) { |
6110 | 6122 | rn = (insn >> 16) & 0xf; |
6111 | - gen_movl_T0_reg(s, rn); | |
6123 | + tmp = load_reg(s, rn); | |
6124 | + } else { | |
6125 | + TCGV_UNUSED(tmp); | |
6112 | 6126 | } |
6113 | 6127 | rd = (insn >> 12) & 0xf; |
6114 | 6128 | switch(op1) { |
6115 | 6129 | case 0x00: |
6116 | - gen_op_andl_T0_T1(); | |
6117 | - gen_movl_reg_T0(s, rd); | |
6118 | - if (logic_cc) | |
6119 | - gen_op_logic_T0_cc(); | |
6130 | + tcg_gen_and_i32(tmp, tmp, tmp2); | |
6131 | + if (logic_cc) { | |
6132 | + gen_logic_CC(tmp); | |
6133 | + } | |
6134 | + store_reg(s, rd, tmp); | |
6120 | 6135 | break; |
6121 | 6136 | case 0x01: |
6122 | - gen_op_xorl_T0_T1(); | |
6123 | - gen_movl_reg_T0(s, rd); | |
6124 | - if (logic_cc) | |
6125 | - gen_op_logic_T0_cc(); | |
6137 | + tcg_gen_xor_i32(tmp, tmp, tmp2); | |
6138 | + if (logic_cc) { | |
6139 | + gen_logic_CC(tmp); | |
6140 | + } | |
6141 | + store_reg(s, rd, tmp); | |
6126 | 6142 | break; |
6127 | 6143 | case 0x02: |
6128 | 6144 | if (set_cc && rd == 15) { |
6129 | 6145 | /* SUBS r15, ... is used for exception return. */ |
6130 | - if (IS_USER(s)) | |
6146 | + if (IS_USER(s)) { | |
6131 | 6147 | goto illegal_op; |
6132 | - gen_op_subl_T0_T1_cc(); | |
6133 | - gen_exception_return(s); | |
6148 | + } | |
6149 | + gen_helper_sub_cc(tmp, tmp, tmp2); | |
6150 | + gen_exception_return(s, tmp); | |
6134 | 6151 | } else { |
6135 | - if (set_cc) | |
6136 | - gen_op_subl_T0_T1_cc(); | |
6137 | - else | |
6138 | - gen_op_subl_T0_T1(); | |
6139 | - gen_movl_reg_T0(s, rd); | |
6152 | + if (set_cc) { | |
6153 | + gen_helper_sub_cc(tmp, tmp, tmp2); | |
6154 | + } else { | |
6155 | + tcg_gen_sub_i32(tmp, tmp, tmp2); | |
6156 | + } | |
6157 | + store_reg(s, rd, tmp); | |
6140 | 6158 | } |
6141 | 6159 | break; |
6142 | 6160 | case 0x03: |
6143 | - if (set_cc) | |
6144 | - gen_op_rsbl_T0_T1_cc(); | |
6145 | - else | |
6146 | - gen_op_rsbl_T0_T1(); | |
6147 | - gen_movl_reg_T0(s, rd); | |
6161 | + if (set_cc) { | |
6162 | + gen_helper_sub_cc(tmp, tmp2, tmp); | |
6163 | + } else { | |
6164 | + tcg_gen_sub_i32(tmp, tmp2, tmp); | |
6165 | + } | |
6166 | + store_reg(s, rd, tmp); | |
6148 | 6167 | break; |
6149 | 6168 | case 0x04: |
6150 | - if (set_cc) | |
6151 | - gen_op_addl_T0_T1_cc(); | |
6152 | - else | |
6153 | - gen_op_addl_T0_T1(); | |
6154 | - gen_movl_reg_T0(s, rd); | |
6169 | + if (set_cc) { | |
6170 | + gen_helper_add_cc(tmp, tmp, tmp2); | |
6171 | + } else { | |
6172 | + tcg_gen_add_i32(tmp, tmp, tmp2); | |
6173 | + } | |
6174 | + store_reg(s, rd, tmp); | |
6155 | 6175 | break; |
6156 | 6176 | case 0x05: |
6157 | - if (set_cc) | |
6158 | - gen_op_adcl_T0_T1_cc(); | |
6159 | - else | |
6160 | - gen_adc_T0_T1(); | |
6161 | - gen_movl_reg_T0(s, rd); | |
6177 | + if (set_cc) { | |
6178 | + gen_helper_adc_cc(tmp, tmp, tmp2); | |
6179 | + } else { | |
6180 | + gen_add_carry(tmp, tmp, tmp2); | |
6181 | + } | |
6182 | + store_reg(s, rd, tmp); | |
6162 | 6183 | break; |
6163 | 6184 | case 0x06: |
6164 | - if (set_cc) | |
6165 | - gen_op_sbcl_T0_T1_cc(); | |
6166 | - else | |
6167 | - gen_sbc_T0_T1(); | |
6168 | - gen_movl_reg_T0(s, rd); | |
6185 | + if (set_cc) { | |
6186 | + gen_helper_sbc_cc(tmp, tmp, tmp2); | |
6187 | + } else { | |
6188 | + gen_sub_carry(tmp, tmp, tmp2); | |
6189 | + } | |
6190 | + store_reg(s, rd, tmp); | |
6169 | 6191 | break; |
6170 | 6192 | case 0x07: |
6171 | - if (set_cc) | |
6172 | - gen_op_rscl_T0_T1_cc(); | |
6173 | - else | |
6174 | - gen_rsc_T0_T1(); | |
6175 | - gen_movl_reg_T0(s, rd); | |
6193 | + if (set_cc) { | |
6194 | + gen_helper_sbc_cc(tmp, tmp2, tmp); | |
6195 | + } else { | |
6196 | + gen_sub_carry(tmp, tmp2, tmp); | |
6197 | + } | |
6198 | + store_reg(s, rd, tmp); | |
6176 | 6199 | break; |
6177 | 6200 | case 0x08: |
6178 | 6201 | if (set_cc) { |
6179 | - gen_op_andl_T0_T1(); | |
6180 | - gen_op_logic_T0_cc(); | |
6202 | + tcg_gen_and_i32(tmp, tmp, tmp2); | |
6203 | + gen_logic_CC(tmp); | |
6181 | 6204 | } |
6205 | + dead_tmp(tmp); | |
6182 | 6206 | break; |
6183 | 6207 | case 0x09: |
6184 | 6208 | if (set_cc) { |
6185 | - gen_op_xorl_T0_T1(); | |
6186 | - gen_op_logic_T0_cc(); | |
6209 | + tcg_gen_xor_i32(tmp, tmp, tmp2); | |
6210 | + gen_logic_CC(tmp); | |
6187 | 6211 | } |
6212 | + dead_tmp(tmp); | |
6188 | 6213 | break; |
6189 | 6214 | case 0x0a: |
6190 | 6215 | if (set_cc) { |
6191 | - gen_op_subl_T0_T1_cc(); | |
6216 | + gen_helper_sub_cc(tmp, tmp, tmp2); | |
6192 | 6217 | } |
6218 | + dead_tmp(tmp); | |
6193 | 6219 | break; |
6194 | 6220 | case 0x0b: |
6195 | 6221 | if (set_cc) { |
6196 | - gen_op_addl_T0_T1_cc(); | |
6222 | + gen_helper_add_cc(tmp, tmp, tmp2); | |
6197 | 6223 | } |
6224 | + dead_tmp(tmp); | |
6198 | 6225 | break; |
6199 | 6226 | case 0x0c: |
6200 | - gen_op_orl_T0_T1(); | |
6201 | - gen_movl_reg_T0(s, rd); | |
6202 | - if (logic_cc) | |
6203 | - gen_op_logic_T0_cc(); | |
6227 | + tcg_gen_or_i32(tmp, tmp, tmp2); | |
6228 | + if (logic_cc) { | |
6229 | + gen_logic_CC(tmp); | |
6230 | + } | |
6231 | + store_reg(s, rd, tmp); | |
6204 | 6232 | break; |
6205 | 6233 | case 0x0d: |
6206 | 6234 | if (logic_cc && rd == 15) { |
6207 | 6235 | /* MOVS r15, ... is used for exception return. */ |
6208 | - if (IS_USER(s)) | |
6236 | + if (IS_USER(s)) { | |
6209 | 6237 | goto illegal_op; |
6210 | - gen_op_movl_T0_T1(); | |
6211 | - gen_exception_return(s); | |
6238 | + } | |
6239 | + gen_exception_return(s, tmp2); | |
6212 | 6240 | } else { |
6213 | - gen_movl_reg_T1(s, rd); | |
6214 | - if (logic_cc) | |
6215 | - gen_op_logic_T1_cc(); | |
6241 | + if (logic_cc) { | |
6242 | + gen_logic_CC(tmp2); | |
6243 | + } | |
6244 | + store_reg(s, rd, tmp2); | |
6216 | 6245 | } |
6217 | 6246 | break; |
6218 | 6247 | case 0x0e: |
6219 | - gen_op_bicl_T0_T1(); | |
6220 | - gen_movl_reg_T0(s, rd); | |
6221 | - if (logic_cc) | |
6222 | - gen_op_logic_T0_cc(); | |
6248 | + tcg_gen_bic_i32(tmp, tmp, tmp2); | |
6249 | + if (logic_cc) { | |
6250 | + gen_logic_CC(tmp); | |
6251 | + } | |
6252 | + store_reg(s, rd, tmp); | |
6223 | 6253 | break; |
6224 | 6254 | default: |
6225 | 6255 | case 0x0f: |
6226 | - gen_op_notl_T1(); | |
6227 | - gen_movl_reg_T1(s, rd); | |
6228 | - if (logic_cc) | |
6229 | - gen_op_logic_T1_cc(); | |
6256 | + tcg_gen_not_i32(tmp2, tmp2); | |
6257 | + if (logic_cc) { | |
6258 | + gen_logic_CC(tmp2); | |
6259 | + } | |
6260 | + store_reg(s, rd, tmp2); | |
6230 | 6261 | break; |
6231 | 6262 | } |
6263 | + if (op1 != 0x0f && op1 != 0x0d) { | |
6264 | + dead_tmp(tmp2); | |
6265 | + } | |
6232 | 6266 | } else { |
6233 | 6267 | /* other instructions */ |
6234 | 6268 | op1 = (insn >> 24) & 0xf; | ... | ... |