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; |