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,7 +207,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var) | ||
| 207 | #define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1]) | 207 | #define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1]) |
| 208 | #define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1]) | 208 | #define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1]) |
| 209 | #define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0]) | 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 | #define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]) | 211 | #define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]) |
| 213 | #define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1]) | 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,6 +435,16 @@ static void gen_adc_T0_T1(void) | ||
| 436 | dead_tmp(tmp); | 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 | /* dest = T0 - T1 + CF - 1. */ | 448 | /* dest = T0 - T1 + CF - 1. */ |
| 440 | static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) | 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,11 +3455,11 @@ static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr) | ||
| 3446 | return 0; | 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 | TCGv tmp; | 3461 | TCGv tmp; |
| 3453 | - gen_movl_reg_T0(s, 15); | 3462 | + store_reg(s, 15, pc); |
| 3454 | tmp = load_cpu_field(spsr); | 3463 | tmp = load_cpu_field(spsr); |
| 3455 | gen_set_cpsr(tmp, 0xffffffff); | 3464 | gen_set_cpsr(tmp, 0xffffffff); |
| 3456 | dead_tmp(tmp); | 3465 | dead_tmp(tmp); |
| @@ -6087,148 +6096,173 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -6087,148 +6096,173 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
| 6087 | /* immediate operand */ | 6096 | /* immediate operand */ |
| 6088 | val = insn & 0xff; | 6097 | val = insn & 0xff; |
| 6089 | shift = ((insn >> 8) & 0xf) * 2; | 6098 | shift = ((insn >> 8) & 0xf) * 2; |
| 6090 | - if (shift) | 6099 | + if (shift) { |
| 6091 | val = (val >> shift) | (val << (32 - shift)); | 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 | } else { | 6107 | } else { |
| 6096 | /* register */ | 6108 | /* register */ |
| 6097 | rm = (insn) & 0xf; | 6109 | rm = (insn) & 0xf; |
| 6098 | - gen_movl_T1_reg(s, rm); | 6110 | + tmp2 = load_reg(s, rm); |
| 6099 | shiftop = (insn >> 5) & 3; | 6111 | shiftop = (insn >> 5) & 3; |
| 6100 | if (!(insn & (1 << 4))) { | 6112 | if (!(insn & (1 << 4))) { |
| 6101 | shift = (insn >> 7) & 0x1f; | 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 | } else { | 6115 | } else { |
| 6104 | rs = (insn >> 8) & 0xf; | 6116 | rs = (insn >> 8) & 0xf; |
| 6105 | tmp = load_reg(s, rs); | 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 | if (op1 != 0x0f && op1 != 0x0d) { | 6121 | if (op1 != 0x0f && op1 != 0x0d) { |
| 6110 | rn = (insn >> 16) & 0xf; | 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 | rd = (insn >> 12) & 0xf; | 6127 | rd = (insn >> 12) & 0xf; |
| 6114 | switch(op1) { | 6128 | switch(op1) { |
| 6115 | case 0x00: | 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 | break; | 6135 | break; |
| 6121 | case 0x01: | 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 | break; | 6142 | break; |
| 6127 | case 0x02: | 6143 | case 0x02: |
| 6128 | if (set_cc && rd == 15) { | 6144 | if (set_cc && rd == 15) { |
| 6129 | /* SUBS r15, ... is used for exception return. */ | 6145 | /* SUBS r15, ... is used for exception return. */ |
| 6130 | - if (IS_USER(s)) | 6146 | + if (IS_USER(s)) { |
| 6131 | goto illegal_op; | 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 | } else { | 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 | break; | 6159 | break; |
| 6142 | case 0x03: | 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 | break; | 6167 | break; |
| 6149 | case 0x04: | 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 | break; | 6175 | break; |
| 6156 | case 0x05: | 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 | break; | 6183 | break; |
| 6163 | case 0x06: | 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 | break; | 6191 | break; |
| 6170 | case 0x07: | 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 | break; | 6199 | break; |
| 6177 | case 0x08: | 6200 | case 0x08: |
| 6178 | if (set_cc) { | 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 | break; | 6206 | break; |
| 6183 | case 0x09: | 6207 | case 0x09: |
| 6184 | if (set_cc) { | 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 | break; | 6213 | break; |
| 6189 | case 0x0a: | 6214 | case 0x0a: |
| 6190 | if (set_cc) { | 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 | break; | 6219 | break; |
| 6194 | case 0x0b: | 6220 | case 0x0b: |
| 6195 | if (set_cc) { | 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 | break; | 6225 | break; |
| 6199 | case 0x0c: | 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 | break; | 6232 | break; |
| 6205 | case 0x0d: | 6233 | case 0x0d: |
| 6206 | if (logic_cc && rd == 15) { | 6234 | if (logic_cc && rd == 15) { |
| 6207 | /* MOVS r15, ... is used for exception return. */ | 6235 | /* MOVS r15, ... is used for exception return. */ |
| 6208 | - if (IS_USER(s)) | 6236 | + if (IS_USER(s)) { |
| 6209 | goto illegal_op; | 6237 | goto illegal_op; |
| 6210 | - gen_op_movl_T0_T1(); | ||
| 6211 | - gen_exception_return(s); | 6238 | + } |
| 6239 | + gen_exception_return(s, tmp2); | ||
| 6212 | } else { | 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 | break; | 6246 | break; |
| 6218 | case 0x0e: | 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 | break; | 6253 | break; |
| 6224 | default: | 6254 | default: |
| 6225 | case 0x0f: | 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 | break; | 6261 | break; |
| 6231 | } | 6262 | } |
| 6263 | + if (op1 != 0x0f && op1 != 0x0d) { | ||
| 6264 | + dead_tmp(tmp2); | ||
| 6265 | + } | ||
| 6232 | } else { | 6266 | } else { |
| 6233 | /* other instructions */ | 6267 | /* other instructions */ |
| 6234 | op1 = (insn >> 24) & 0xf; | 6268 | op1 = (insn >> 24) & 0xf; |