Commit 9a119ff6c1cba1fde88bf6275d6ba40c95d35dce
1 parent
f51bbbfe
ARM TCG conversion 3/16.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4140 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
65 additions
and
196 deletions
target-arm/op.c
| ... | ... | @@ -317,55 +317,6 @@ void OPPROTO op_clrex(void) |
| 317 | 317 | cpu_unlock(); |
| 318 | 318 | } |
| 319 | 319 | |
| 320 | -/* shifts */ | |
| 321 | - | |
| 322 | -/* T1 based, set C flag */ | |
| 323 | -void OPPROTO op_shll_T1_im_cc(void) | |
| 324 | -{ | |
| 325 | - env->CF = (T1 >> (32 - PARAM1)) & 1; | |
| 326 | - T1 = T1 << PARAM1; | |
| 327 | -} | |
| 328 | - | |
| 329 | -void OPPROTO op_shrl_T1_im_cc(void) | |
| 330 | -{ | |
| 331 | - env->CF = (T1 >> (PARAM1 - 1)) & 1; | |
| 332 | - T1 = (uint32_t)T1 >> PARAM1; | |
| 333 | -} | |
| 334 | - | |
| 335 | -void OPPROTO op_shrl_T1_0_cc(void) | |
| 336 | -{ | |
| 337 | - env->CF = (T1 >> 31) & 1; | |
| 338 | - T1 = 0; | |
| 339 | -} | |
| 340 | - | |
| 341 | -void OPPROTO op_sarl_T1_im_cc(void) | |
| 342 | -{ | |
| 343 | - env->CF = (T1 >> (PARAM1 - 1)) & 1; | |
| 344 | - T1 = (int32_t)T1 >> PARAM1; | |
| 345 | -} | |
| 346 | - | |
| 347 | -void OPPROTO op_sarl_T1_0_cc(void) | |
| 348 | -{ | |
| 349 | - env->CF = (T1 >> 31) & 1; | |
| 350 | - T1 = (int32_t)T1 >> 31; | |
| 351 | -} | |
| 352 | - | |
| 353 | -void OPPROTO op_rorl_T1_im_cc(void) | |
| 354 | -{ | |
| 355 | - int shift; | |
| 356 | - shift = PARAM1; | |
| 357 | - env->CF = (T1 >> (shift - 1)) & 1; | |
| 358 | - T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift)); | |
| 359 | -} | |
| 360 | - | |
| 361 | -void OPPROTO op_rrxl_T1_cc(void) | |
| 362 | -{ | |
| 363 | - uint32_t c; | |
| 364 | - c = T1 & 1; | |
| 365 | - T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31); | |
| 366 | - env->CF = c; | |
| 367 | -} | |
| 368 | - | |
| 369 | 320 | /* T1 based, use T0 as shift count */ |
| 370 | 321 | |
| 371 | 322 | void OPPROTO op_shll_T1_T0(void) |
| ... | ... | @@ -573,83 +524,6 @@ void OPPROTO op_subl_T0_T1_usaturate(void) |
| 573 | 524 | FORCE_RET(); |
| 574 | 525 | } |
| 575 | 526 | |
| 576 | -/* Thumb shift by immediate */ | |
| 577 | -void OPPROTO op_shll_T0_im_thumb_cc(void) | |
| 578 | -{ | |
| 579 | - int shift; | |
| 580 | - shift = PARAM1; | |
| 581 | - if (shift != 0) { | |
| 582 | - env->CF = (T0 >> (32 - shift)) & 1; | |
| 583 | - T0 = T0 << shift; | |
| 584 | - } | |
| 585 | - env->NZF = T0; | |
| 586 | - FORCE_RET(); | |
| 587 | -} | |
| 588 | - | |
| 589 | -void OPPROTO op_shll_T0_im_thumb(void) | |
| 590 | -{ | |
| 591 | - T0 = T0 << PARAM1; | |
| 592 | - FORCE_RET(); | |
| 593 | -} | |
| 594 | - | |
| 595 | -void OPPROTO op_shrl_T0_im_thumb_cc(void) | |
| 596 | -{ | |
| 597 | - int shift; | |
| 598 | - | |
| 599 | - shift = PARAM1; | |
| 600 | - if (shift == 0) { | |
| 601 | - env->CF = ((uint32_t)T0) >> 31; | |
| 602 | - T0 = 0; | |
| 603 | - } else { | |
| 604 | - env->CF = (T0 >> (shift - 1)) & 1; | |
| 605 | - T0 = T0 >> shift; | |
| 606 | - } | |
| 607 | - env->NZF = T0; | |
| 608 | - FORCE_RET(); | |
| 609 | -} | |
| 610 | - | |
| 611 | -void OPPROTO op_shrl_T0_im_thumb(void) | |
| 612 | -{ | |
| 613 | - int shift; | |
| 614 | - | |
| 615 | - shift = PARAM1; | |
| 616 | - if (shift == 0) { | |
| 617 | - T0 = 0; | |
| 618 | - } else { | |
| 619 | - T0 = T0 >> shift; | |
| 620 | - } | |
| 621 | - FORCE_RET(); | |
| 622 | -} | |
| 623 | - | |
| 624 | -void OPPROTO op_sarl_T0_im_thumb_cc(void) | |
| 625 | -{ | |
| 626 | - int shift; | |
| 627 | - | |
| 628 | - shift = PARAM1; | |
| 629 | - if (shift == 0) { | |
| 630 | - T0 = ((int32_t)T0) >> 31; | |
| 631 | - env->CF = T0 & 1; | |
| 632 | - } else { | |
| 633 | - env->CF = (T0 >> (shift - 1)) & 1; | |
| 634 | - T0 = ((int32_t)T0) >> shift; | |
| 635 | - } | |
| 636 | - env->NZF = T0; | |
| 637 | - FORCE_RET(); | |
| 638 | -} | |
| 639 | - | |
| 640 | -void OPPROTO op_sarl_T0_im_thumb(void) | |
| 641 | -{ | |
| 642 | - int shift; | |
| 643 | - | |
| 644 | - shift = PARAM1; | |
| 645 | - if (shift == 0) { | |
| 646 | - env->CF = T0 & 1; | |
| 647 | - } else { | |
| 648 | - T0 = ((int32_t)T0) >> shift; | |
| 649 | - } | |
| 650 | - FORCE_RET(); | |
| 651 | -} | |
| 652 | - | |
| 653 | 527 | /* exceptions */ |
| 654 | 528 | |
| 655 | 529 | void OPPROTO op_swi(void) | ... | ... |
target-arm/translate.c
| ... | ... | @@ -228,12 +228,14 @@ static void gen_add16(TCGv t0, TCGv t1) |
| 228 | 228 | dead_tmp(t1); |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | +#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF)) | |
| 232 | + | |
| 231 | 233 | /* Set CF to the top bit of var. */ |
| 232 | 234 | static void gen_set_CF_bit31(TCGv var) |
| 233 | 235 | { |
| 234 | 236 | TCGv tmp = new_tmp(); |
| 235 | 237 | tcg_gen_shri_i32(tmp, var, 31); |
| 236 | - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, CF)); | |
| 238 | + gen_set_CF(var); | |
| 237 | 239 | dead_tmp(tmp); |
| 238 | 240 | } |
| 239 | 241 | |
| ... | ... | @@ -282,31 +284,67 @@ static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i) |
| 282 | 284 | dead_tmp(tmp); |
| 283 | 285 | } |
| 284 | 286 | |
| 285 | -/* Shift by immediate. Includes special handling for shift == 0. */ | |
| 286 | -static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift) | |
| 287 | +static void shifter_out_im(TCGv var, int shift) | |
| 287 | 288 | { |
| 288 | - if (shift != 0) { | |
| 289 | - switch (shiftop) { | |
| 290 | - case 0: tcg_gen_shli_i32(var, var, shift); break; | |
| 291 | - case 1: tcg_gen_shri_i32(var, var, shift); break; | |
| 292 | - case 2: tcg_gen_sari_i32(var, var, shift); break; | |
| 293 | - case 3: tcg_gen_rori_i32(var, var, shift); break; | |
| 294 | - } | |
| 289 | + TCGv tmp = new_tmp(); | |
| 290 | + if (shift == 0) { | |
| 291 | + tcg_gen_andi_i32(tmp, var, 1); | |
| 295 | 292 | } else { |
| 296 | - TCGv tmp; | |
| 293 | + tcg_gen_shri_i32(tmp, var, shift); | |
| 294 | + if (shift != 31); | |
| 295 | + tcg_gen_andi_i32(tmp, tmp, 1); | |
| 296 | + } | |
| 297 | + gen_set_CF(tmp); | |
| 298 | + dead_tmp(tmp); | |
| 299 | +} | |
| 297 | 300 | |
| 298 | - switch (shiftop) { | |
| 299 | - case 0: break; | |
| 300 | - case 1: tcg_gen_movi_i32(var, 0); break; | |
| 301 | - case 2: tcg_gen_sari_i32(var, var, 31); break; | |
| 302 | - case 3: /* rrx */ | |
| 303 | - tcg_gen_shri_i32(var, var, 1); | |
| 304 | - tmp = new_tmp(); | |
| 301 | +/* Shift by immediate. Includes special handling for shift == 0. */ | |
| 302 | +static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) | |
| 303 | +{ | |
| 304 | + switch (shiftop) { | |
| 305 | + case 0: /* LSL */ | |
| 306 | + if (shift != 0) { | |
| 307 | + if (flags) | |
| 308 | + shifter_out_im(var, 32 - shift); | |
| 309 | + tcg_gen_shli_i32(var, var, shift); | |
| 310 | + } | |
| 311 | + break; | |
| 312 | + case 1: /* LSR */ | |
| 313 | + if (shift == 0) { | |
| 314 | + if (flags) { | |
| 315 | + tcg_gen_shri_i32(var, var, 31); | |
| 316 | + gen_set_CF(var); | |
| 317 | + } | |
| 318 | + tcg_gen_movi_i32(var, 0); | |
| 319 | + } else { | |
| 320 | + if (flags) | |
| 321 | + shifter_out_im(var, shift - 1); | |
| 322 | + tcg_gen_shri_i32(var, var, shift); | |
| 323 | + } | |
| 324 | + break; | |
| 325 | + case 2: /* ASR */ | |
| 326 | + if (shift == 0) | |
| 327 | + shift = 32; | |
| 328 | + if (flags) | |
| 329 | + shifter_out_im(var, shift - 1); | |
| 330 | + if (shift == 32) | |
| 331 | + shift = 31; | |
| 332 | + tcg_gen_sari_i32(var, var, shift); | |
| 333 | + break; | |
| 334 | + case 3: /* ROR/RRX */ | |
| 335 | + if (shift != 0) { | |
| 336 | + if (flags) | |
| 337 | + shifter_out_im(var, shift - 1); | |
| 338 | + tcg_gen_rori_i32(var, var, shift); break; | |
| 339 | + } else { | |
| 340 | + TCGv tmp = new_tmp(); | |
| 305 | 341 | tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF)); |
| 342 | + if (flags) | |
| 343 | + shifter_out_im(var, 0); | |
| 344 | + tcg_gen_shri_i32(var, var, 1); | |
| 306 | 345 | tcg_gen_shli_i32(tmp, tmp, 31); |
| 307 | 346 | tcg_gen_or_i32(var, var, tmp); |
| 308 | 347 | dead_tmp(tmp); |
| 309 | - break; | |
| 310 | 348 | } |
| 311 | 349 | } |
| 312 | 350 | }; |
| ... | ... | @@ -392,20 +430,6 @@ const uint8_t table_logic_cc[16] = { |
| 392 | 430 | 1, /* mvn */ |
| 393 | 431 | }; |
| 394 | 432 | |
| 395 | -static GenOpFunc1 *gen_shift_T1_im_cc[4] = { | |
| 396 | - gen_op_shll_T1_im_cc, | |
| 397 | - gen_op_shrl_T1_im_cc, | |
| 398 | - gen_op_sarl_T1_im_cc, | |
| 399 | - gen_op_rorl_T1_im_cc, | |
| 400 | -}; | |
| 401 | - | |
| 402 | -static GenOpFunc *gen_shift_T1_0_cc[4] = { | |
| 403 | - NULL, | |
| 404 | - gen_op_shrl_T1_0_cc, | |
| 405 | - gen_op_sarl_T1_0_cc, | |
| 406 | - gen_op_rrxl_T1_cc, | |
| 407 | -}; | |
| 408 | - | |
| 409 | 433 | static GenOpFunc *gen_shift_T1_T0[4] = { |
| 410 | 434 | gen_op_shll_T1_T0, |
| 411 | 435 | gen_op_shrl_T1_T0, |
| ... | ... | @@ -420,18 +444,6 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = { |
| 420 | 444 | gen_op_rorl_T1_T0_cc, |
| 421 | 445 | }; |
| 422 | 446 | |
| 423 | -static GenOpFunc1 *gen_shift_T0_im_thumb_cc[3] = { | |
| 424 | - gen_op_shll_T0_im_thumb_cc, | |
| 425 | - gen_op_shrl_T0_im_thumb_cc, | |
| 426 | - gen_op_sarl_T0_im_thumb_cc, | |
| 427 | -}; | |
| 428 | - | |
| 429 | -static GenOpFunc1 *gen_shift_T0_im_thumb[3] = { | |
| 430 | - gen_op_shll_T0_im_thumb, | |
| 431 | - gen_op_shrl_T0_im_thumb, | |
| 432 | - gen_op_sarl_T0_im_thumb, | |
| 433 | -}; | |
| 434 | - | |
| 435 | 447 | /* Set PC and thumb state from T0. Clobbers T0. */ |
| 436 | 448 | static inline void gen_bx(DisasContext *s) |
| 437 | 449 | { |
| ... | ... | @@ -530,7 +542,7 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) |
| 530 | 542 | shift = (insn >> 7) & 0x1f; |
| 531 | 543 | shiftop = (insn >> 5) & 3; |
| 532 | 544 | offset = load_reg(s, rm); |
| 533 | - gen_arm_shift_im(offset, shiftop, shift); | |
| 545 | + gen_arm_shift_im(offset, shiftop, shift, 0); | |
| 534 | 546 | if (!(insn & (1 << 23))) |
| 535 | 547 | tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset); |
| 536 | 548 | else |
| ... | ... | @@ -5126,15 +5138,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
| 5126 | 5138 | shiftop = (insn >> 5) & 3; |
| 5127 | 5139 | if (!(insn & (1 << 4))) { |
| 5128 | 5140 | shift = (insn >> 7) & 0x1f; |
| 5129 | - if (logic_cc) { | |
| 5130 | - if (shift != 0) { | |
| 5131 | - gen_shift_T1_im_cc[shiftop](shift); | |
| 5132 | - } else if (shiftop != 0) { | |
| 5133 | - gen_shift_T1_0_cc[shiftop](); | |
| 5134 | - } | |
| 5135 | - } else { | |
| 5136 | - gen_arm_shift_im(cpu_T[1], shiftop, shift); | |
| 5137 | - } | |
| 5141 | + gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc); | |
| 5138 | 5142 | } else { |
| 5139 | 5143 | rs = (insn >> 8) & 0xf; |
| 5140 | 5144 | gen_movl_T0_reg(s, rs); |
| ... | ... | @@ -6243,15 +6247,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
| 6243 | 6247 | shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); |
| 6244 | 6248 | conds = (insn & (1 << 20)) != 0; |
| 6245 | 6249 | logic_cc = (conds && thumb2_logic_op(op)); |
| 6246 | - if (logic_cc) { | |
| 6247 | - if (shift != 0) { | |
| 6248 | - gen_shift_T1_im_cc[shiftop](shift); | |
| 6249 | - } else if (shiftop != 0) { | |
| 6250 | - gen_shift_T1_0_cc[shiftop](); | |
| 6251 | - } | |
| 6252 | - } else { | |
| 6253 | - gen_arm_shift_im(cpu_T[1], shiftop, shift); | |
| 6254 | - } | |
| 6250 | + gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc); | |
| 6255 | 6251 | if (gen_thumb2_data_op(s, op, conds, 0)) |
| 6256 | 6252 | goto illegal_op; |
| 6257 | 6253 | if (rd != 15) |
| ... | ... | @@ -6960,12 +6956,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
| 6960 | 6956 | /* shift immediate */ |
| 6961 | 6957 | rm = (insn >> 3) & 7; |
| 6962 | 6958 | shift = (insn >> 6) & 0x1f; |
| 6963 | - gen_movl_T0_reg(s, rm); | |
| 6964 | - if (s->condexec_mask) | |
| 6965 | - gen_shift_T0_im_thumb[op](shift); | |
| 6966 | - else | |
| 6967 | - gen_shift_T0_im_thumb_cc[op](shift); | |
| 6968 | - gen_movl_reg_T0(s, rd); | |
| 6959 | + tmp = load_reg(s, rm); | |
| 6960 | + gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0); | |
| 6961 | + if (!s->condexec_mask) | |
| 6962 | + gen_logic_CC(tmp); | |
| 6963 | + store_reg(s, rd, tmp); | |
| 6969 | 6964 | } |
| 6970 | 6965 | break; |
| 6971 | 6966 | case 2: case 3: | ... | ... |