Commit 6e295807acbaf7eb3200a685376fb968ebdb8571
1 parent
f2674e31
ARM fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@314 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
209 additions
and
58 deletions
arm-dis.c
| @@ -560,8 +560,8 @@ static arm_regname regnames[] = | @@ -560,8 +560,8 @@ static arm_regname regnames[] = | ||
| 560 | { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }} | 560 | { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }} |
| 561 | }; | 561 | }; |
| 562 | 562 | ||
| 563 | -/* Default to GCC register name set. */ | ||
| 564 | -static unsigned int regname_selected = 1; | 563 | +/* Default to STD register name set. */ |
| 564 | +static unsigned int regname_selected = 2; | ||
| 565 | 565 | ||
| 566 | #define NUM_ARM_REGNAMES NUM_ELEM (regnames) | 566 | #define NUM_ARM_REGNAMES NUM_ELEM (regnames) |
| 567 | #define arm_regnames regnames[regname_selected].reg_names | 567 | #define arm_regnames regnames[regname_selected].reg_names |
exec-arm.h
| @@ -30,3 +30,11 @@ register uint32_t T2 asm(AREG3); | @@ -30,3 +30,11 @@ register uint32_t T2 asm(AREG3); | ||
| 30 | void cpu_lock(void); | 30 | void cpu_lock(void); |
| 31 | void cpu_unlock(void); | 31 | void cpu_unlock(void); |
| 32 | void cpu_loop_exit(void); | 32 | void cpu_loop_exit(void); |
| 33 | + | ||
| 34 | +static inline int compute_cpsr(void) | ||
| 35 | +{ | ||
| 36 | + int ZF; | ||
| 37 | + ZF = (env->NZF == 0); | ||
| 38 | + return env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) | | ||
| 39 | + (env->CF << 29) | ((env->VF & 0x80000000) >> 3); | ||
| 40 | +} |
op-arm.c
| @@ -154,11 +154,11 @@ void OPPROTO op_adcl_T0_T1_cc(void) | @@ -154,11 +154,11 @@ void OPPROTO op_adcl_T0_T1_cc(void) | ||
| 154 | FORCE_RET(); | 154 | FORCE_RET(); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | -#define OPSUB(sub, sbc, T0, T1) \ | 157 | +#define OPSUB(sub, sbc, res, T0, T1) \ |
| 158 | \ | 158 | \ |
| 159 | void OPPROTO op_ ## sub ## l_T0_T1(void) \ | 159 | void OPPROTO op_ ## sub ## l_T0_T1(void) \ |
| 160 | { \ | 160 | { \ |
| 161 | - T0 -= T1; \ | 161 | + res = T0 - T1; \ |
| 162 | } \ | 162 | } \ |
| 163 | \ | 163 | \ |
| 164 | void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \ | 164 | void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \ |
| @@ -167,13 +167,14 @@ void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \ | @@ -167,13 +167,14 @@ void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \ | ||
| 167 | src1 = T0; \ | 167 | src1 = T0; \ |
| 168 | T0 -= T1; \ | 168 | T0 -= T1; \ |
| 169 | env->NZF = T0; \ | 169 | env->NZF = T0; \ |
| 170 | - env->CF = src1 < T1; \ | 170 | + env->CF = src1 >= T1; \ |
| 171 | env->VF = (src1 ^ T1) & (src1 ^ T0); \ | 171 | env->VF = (src1 ^ T1) & (src1 ^ T0); \ |
| 172 | + res = T0; \ | ||
| 172 | } \ | 173 | } \ |
| 173 | \ | 174 | \ |
| 174 | void OPPROTO op_ ## sbc ## l_T0_T1(void) \ | 175 | void OPPROTO op_ ## sbc ## l_T0_T1(void) \ |
| 175 | { \ | 176 | { \ |
| 176 | - T0 = T0 - T1 + env->CF - 1; \ | 177 | + res = T0 - T1 + env->CF - 1; \ |
| 177 | } \ | 178 | } \ |
| 178 | \ | 179 | \ |
| 179 | void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \ | 180 | void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \ |
| @@ -182,20 +183,20 @@ void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \ | @@ -182,20 +183,20 @@ void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \ | ||
| 182 | src1 = T0; \ | 183 | src1 = T0; \ |
| 183 | if (!env->CF) { \ | 184 | if (!env->CF) { \ |
| 184 | T0 = T0 - T1 - 1; \ | 185 | T0 = T0 - T1 - 1; \ |
| 185 | - T0 += T1; \ | ||
| 186 | - env->CF = src1 < T1; \ | 186 | + env->CF = src1 >= T1; \ |
| 187 | } else { \ | 187 | } else { \ |
| 188 | T0 = T0 - T1; \ | 188 | T0 = T0 - T1; \ |
| 189 | - env->CF = src1 <= T1; \ | 189 | + env->CF = src1 > T1; \ |
| 190 | } \ | 190 | } \ |
| 191 | env->VF = (src1 ^ T1) & (src1 ^ T0); \ | 191 | env->VF = (src1 ^ T1) & (src1 ^ T0); \ |
| 192 | env->NZF = T0; \ | 192 | env->NZF = T0; \ |
| 193 | + res = T0; \ | ||
| 193 | FORCE_RET(); \ | 194 | FORCE_RET(); \ |
| 194 | } | 195 | } |
| 195 | 196 | ||
| 196 | -OPSUB(sub, sbc, T0, T1) | 197 | +OPSUB(sub, sbc, T0, T0, T1) |
| 197 | 198 | ||
| 198 | -OPSUB(rsb, rsc, T1, T0) | 199 | +OPSUB(rsb, rsc, T0, T1, T0) |
| 199 | 200 | ||
| 200 | void OPPROTO op_andl_T0_T1(void) | 201 | void OPPROTO op_andl_T0_T1(void) |
| 201 | { | 202 | { |
| @@ -222,11 +223,16 @@ void OPPROTO op_notl_T1(void) | @@ -222,11 +223,16 @@ void OPPROTO op_notl_T1(void) | ||
| 222 | T1 = ~T1; | 223 | T1 = ~T1; |
| 223 | } | 224 | } |
| 224 | 225 | ||
| 225 | -void OPPROTO op_logic_cc(void) | 226 | +void OPPROTO op_logic_T0_cc(void) |
| 226 | { | 227 | { |
| 227 | env->NZF = T0; | 228 | env->NZF = T0; |
| 228 | } | 229 | } |
| 229 | 230 | ||
| 231 | +void OPPROTO op_logic_T1_cc(void) | ||
| 232 | +{ | ||
| 233 | + env->NZF = T1; | ||
| 234 | +} | ||
| 235 | + | ||
| 230 | #define EIP (env->regs[15]) | 236 | #define EIP (env->regs[15]) |
| 231 | 237 | ||
| 232 | void OPPROTO op_test_eq(void) | 238 | void OPPROTO op_test_eq(void) |
| @@ -334,10 +340,7 @@ void OPPROTO op_jmp(void) | @@ -334,10 +340,7 @@ void OPPROTO op_jmp(void) | ||
| 334 | 340 | ||
| 335 | void OPPROTO op_movl_T0_psr(void) | 341 | void OPPROTO op_movl_T0_psr(void) |
| 336 | { | 342 | { |
| 337 | - int ZF; | ||
| 338 | - ZF = (env->NZF == 0); | ||
| 339 | - T0 = env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) | | ||
| 340 | - (env->CF << 29) | ((env->VF & 0x80000000) >> 3); | 343 | + T0 = compute_cpsr(); |
| 341 | } | 344 | } |
| 342 | 345 | ||
| 343 | /* NOTE: N = 1 and Z = 1 cannot be stored currently */ | 346 | /* NOTE: N = 1 and Z = 1 cannot be stored currently */ |
translate-arm.c
| @@ -34,6 +34,8 @@ typedef struct DisasContext { | @@ -34,6 +34,8 @@ typedef struct DisasContext { | ||
| 34 | struct TranslationBlock *tb; | 34 | struct TranslationBlock *tb; |
| 35 | } DisasContext; | 35 | } DisasContext; |
| 36 | 36 | ||
| 37 | +#define DISAS_JUMP_NEXT 4 | ||
| 38 | + | ||
| 37 | /* XXX: move that elsewhere */ | 39 | /* XXX: move that elsewhere */ |
| 38 | static uint16_t *gen_opc_ptr; | 40 | static uint16_t *gen_opc_ptr; |
| 39 | static uint32_t *gen_opparam_ptr; | 41 | static uint32_t *gen_opparam_ptr; |
| @@ -333,10 +335,11 @@ static void disas_arm_insn(DisasContext *s) | @@ -333,10 +335,11 @@ static void disas_arm_insn(DisasContext *s) | ||
| 333 | /* if not always execute, we generate a conditional jump to | 335 | /* if not always execute, we generate a conditional jump to |
| 334 | next instruction */ | 336 | next instruction */ |
| 335 | gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc); | 337 | gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc); |
| 336 | - s->is_jmp = 1; | 338 | + s->is_jmp = DISAS_JUMP_NEXT; |
| 337 | } | 339 | } |
| 338 | - if ((insn & 0x0c000000) == 0 && | ||
| 339 | - (insn & 0x00000090) != 0x90) { | 340 | + if (((insn & 0x0e000000) == 0 && |
| 341 | + (insn & 0x00000090) != 0x90) || | ||
| 342 | + ((insn & 0x0e000000) == (1 << 25))) { | ||
| 340 | int set_cc, logic_cc, shiftop; | 343 | int set_cc, logic_cc, shiftop; |
| 341 | 344 | ||
| 342 | op1 = (insn >> 21) & 0xf; | 345 | op1 = (insn >> 21) & 0xf; |
| @@ -367,7 +370,7 @@ static void disas_arm_insn(DisasContext *s) | @@ -367,7 +370,7 @@ static void disas_arm_insn(DisasContext *s) | ||
| 367 | } | 370 | } |
| 368 | } | 371 | } |
| 369 | } else { | 372 | } else { |
| 370 | - rs = (insn >> 16) & 0xf; | 373 | + rs = (insn >> 8) & 0xf; |
| 371 | gen_movl_T0_reg(s, rs); | 374 | gen_movl_T0_reg(s, rs); |
| 372 | if (logic_cc) { | 375 | if (logic_cc) { |
| 373 | gen_shift_T1_T0_cc[shiftop](); | 376 | gen_shift_T1_T0_cc[shiftop](); |
| @@ -385,10 +388,14 @@ static void disas_arm_insn(DisasContext *s) | @@ -385,10 +388,14 @@ static void disas_arm_insn(DisasContext *s) | ||
| 385 | case 0x00: | 388 | case 0x00: |
| 386 | gen_op_andl_T0_T1(); | 389 | gen_op_andl_T0_T1(); |
| 387 | gen_movl_reg_T0(s, rd); | 390 | gen_movl_reg_T0(s, rd); |
| 391 | + if (logic_cc) | ||
| 392 | + gen_op_logic_T0_cc(); | ||
| 388 | break; | 393 | break; |
| 389 | case 0x01: | 394 | case 0x01: |
| 390 | gen_op_xorl_T0_T1(); | 395 | gen_op_xorl_T0_T1(); |
| 391 | gen_movl_reg_T0(s, rd); | 396 | gen_movl_reg_T0(s, rd); |
| 397 | + if (logic_cc) | ||
| 398 | + gen_op_logic_T0_cc(); | ||
| 392 | break; | 399 | break; |
| 393 | case 0x02: | 400 | case 0x02: |
| 394 | if (set_cc) | 401 | if (set_cc) |
| @@ -435,11 +442,13 @@ static void disas_arm_insn(DisasContext *s) | @@ -435,11 +442,13 @@ static void disas_arm_insn(DisasContext *s) | ||
| 435 | case 0x08: | 442 | case 0x08: |
| 436 | if (set_cc) { | 443 | if (set_cc) { |
| 437 | gen_op_andl_T0_T1(); | 444 | gen_op_andl_T0_T1(); |
| 445 | + gen_op_logic_T0_cc(); | ||
| 438 | } | 446 | } |
| 439 | break; | 447 | break; |
| 440 | case 0x09: | 448 | case 0x09: |
| 441 | if (set_cc) { | 449 | if (set_cc) { |
| 442 | gen_op_xorl_T0_T1(); | 450 | gen_op_xorl_T0_T1(); |
| 451 | + gen_op_logic_T0_cc(); | ||
| 443 | } | 452 | } |
| 444 | break; | 453 | break; |
| 445 | case 0x0a: | 454 | case 0x0a: |
| @@ -455,22 +464,28 @@ static void disas_arm_insn(DisasContext *s) | @@ -455,22 +464,28 @@ static void disas_arm_insn(DisasContext *s) | ||
| 455 | case 0x0c: | 464 | case 0x0c: |
| 456 | gen_op_orl_T0_T1(); | 465 | gen_op_orl_T0_T1(); |
| 457 | gen_movl_reg_T0(s, rd); | 466 | gen_movl_reg_T0(s, rd); |
| 467 | + if (logic_cc) | ||
| 468 | + gen_op_logic_T0_cc(); | ||
| 458 | break; | 469 | break; |
| 459 | case 0x0d: | 470 | case 0x0d: |
| 460 | gen_movl_reg_T1(s, rd); | 471 | gen_movl_reg_T1(s, rd); |
| 472 | + if (logic_cc) | ||
| 473 | + gen_op_logic_T1_cc(); | ||
| 461 | break; | 474 | break; |
| 462 | case 0x0e: | 475 | case 0x0e: |
| 463 | gen_op_bicl_T0_T1(); | 476 | gen_op_bicl_T0_T1(); |
| 464 | gen_movl_reg_T0(s, rd); | 477 | gen_movl_reg_T0(s, rd); |
| 478 | + if (logic_cc) | ||
| 479 | + gen_op_logic_T0_cc(); | ||
| 465 | break; | 480 | break; |
| 466 | default: | 481 | default: |
| 467 | case 0x0f: | 482 | case 0x0f: |
| 468 | gen_op_notl_T1(); | 483 | gen_op_notl_T1(); |
| 469 | gen_movl_reg_T1(s, rd); | 484 | gen_movl_reg_T1(s, rd); |
| 485 | + if (logic_cc) | ||
| 486 | + gen_op_logic_T1_cc(); | ||
| 470 | break; | 487 | break; |
| 471 | } | 488 | } |
| 472 | - if (logic_cc) | ||
| 473 | - gen_op_logic_cc(); | ||
| 474 | } else { | 489 | } else { |
| 475 | /* other instructions */ | 490 | /* other instructions */ |
| 476 | op1 = (insn >> 24) & 0xf; | 491 | op1 = (insn >> 24) & 0xf; |
| @@ -494,7 +509,7 @@ static void disas_arm_insn(DisasContext *s) | @@ -494,7 +509,7 @@ static void disas_arm_insn(DisasContext *s) | ||
| 494 | gen_op_addl_T0_T1(); | 509 | gen_op_addl_T0_T1(); |
| 495 | } | 510 | } |
| 496 | if (insn & (1 << 20)) | 511 | if (insn & (1 << 20)) |
| 497 | - gen_op_logic_cc(); | 512 | + gen_op_logic_T0_cc(); |
| 498 | gen_movl_reg_T0(s, rd); | 513 | gen_movl_reg_T0(s, rd); |
| 499 | } else { | 514 | } else { |
| 500 | /* 64 bit mul */ | 515 | /* 64 bit mul */ |
| @@ -551,10 +566,12 @@ static void disas_arm_insn(DisasContext *s) | @@ -551,10 +566,12 @@ static void disas_arm_insn(DisasContext *s) | ||
| 551 | /* store */ | 566 | /* store */ |
| 552 | gen_op_stw_T0_T1(); | 567 | gen_op_stw_T0_T1(); |
| 553 | } | 568 | } |
| 554 | - if (!(insn & (1 << 24))) | 569 | + if (!(insn & (1 << 24))) { |
| 555 | gen_add_datah_offset(s, insn); | 570 | gen_add_datah_offset(s, insn); |
| 556 | - if (insn & (1 << 21)) | ||
| 557 | gen_movl_reg_T1(s, rn); | 571 | gen_movl_reg_T1(s, rn); |
| 572 | + } else if (insn & (1 << 21)) { | ||
| 573 | + gen_movl_reg_T1(s, rn); | ||
| 574 | + } | ||
| 558 | } | 575 | } |
| 559 | break; | 576 | break; |
| 560 | case 0x4: | 577 | case 0x4: |
| @@ -582,40 +599,94 @@ static void disas_arm_insn(DisasContext *s) | @@ -582,40 +599,94 @@ static void disas_arm_insn(DisasContext *s) | ||
| 582 | else | 599 | else |
| 583 | gen_op_stl_T0_T1(); | 600 | gen_op_stl_T0_T1(); |
| 584 | } | 601 | } |
| 585 | - if (!(insn & (1 << 24))) | 602 | + if (!(insn & (1 << 24))) { |
| 586 | gen_add_data_offset(s, insn); | 603 | gen_add_data_offset(s, insn); |
| 587 | - if (insn & (1 << 21)) | ||
| 588 | gen_movl_reg_T1(s, rn); | 604 | gen_movl_reg_T1(s, rn); |
| 605 | + } else if (insn & (1 << 21)) | ||
| 606 | + gen_movl_reg_T1(s, rn); { | ||
| 607 | + } | ||
| 589 | break; | 608 | break; |
| 590 | case 0x08: | 609 | case 0x08: |
| 591 | case 0x09: | 610 | case 0x09: |
| 592 | - /* load/store multiple words */ | ||
| 593 | - if (insn & (1 << 22)) | ||
| 594 | - goto illegal_op; /* only usable in supervisor mode */ | ||
| 595 | - rn = (insn >> 16) & 0xf; | ||
| 596 | - gen_movl_T1_reg(s, rn); | ||
| 597 | - val = 4; | ||
| 598 | - if (!(insn & (1 << 23))) | ||
| 599 | - val = -val; | ||
| 600 | - for(i=0;i<16;i++) { | ||
| 601 | - if (insn & (1 << i)) { | ||
| 602 | - if (insn & (1 << 24)) | ||
| 603 | - gen_op_addl_T1_im(val); | ||
| 604 | - if (insn & (1 << 20)) { | ||
| 605 | - /* load */ | ||
| 606 | - gen_op_ldl_T0_T1(); | ||
| 607 | - gen_movl_reg_T0(s, i); | 611 | + { |
| 612 | + int j, n; | ||
| 613 | + /* load/store multiple words */ | ||
| 614 | + /* XXX: store correct base if write back */ | ||
| 615 | + if (insn & (1 << 22)) | ||
| 616 | + goto illegal_op; /* only usable in supervisor mode */ | ||
| 617 | + rn = (insn >> 16) & 0xf; | ||
| 618 | + gen_movl_T1_reg(s, rn); | ||
| 619 | + | ||
| 620 | + /* compute total size */ | ||
| 621 | + n = 0; | ||
| 622 | + for(i=0;i<16;i++) { | ||
| 623 | + if (insn & (1 << i)) | ||
| 624 | + n++; | ||
| 625 | + } | ||
| 626 | + /* XXX: test invalid n == 0 case ? */ | ||
| 627 | + if (insn & (1 << 23)) { | ||
| 628 | + if (insn & (1 << 24)) { | ||
| 629 | + /* pre increment */ | ||
| 630 | + gen_op_addl_T1_im(4); | ||
| 608 | } else { | 631 | } else { |
| 609 | - /* store */ | ||
| 610 | - gen_movl_T0_reg(s, i); | ||
| 611 | - gen_op_stl_T0_T1(); | 632 | + /* post increment */ |
| 633 | + } | ||
| 634 | + } else { | ||
| 635 | + if (insn & (1 << 24)) { | ||
| 636 | + /* pre decrement */ | ||
| 637 | + gen_op_addl_T1_im(-(n * 4)); | ||
| 638 | + } else { | ||
| 639 | + /* post decrement */ | ||
| 640 | + if (n != 1) | ||
| 641 | + gen_op_addl_T1_im(-((n - 1) * 4)); | ||
| 642 | + } | ||
| 643 | + } | ||
| 644 | + j = 0; | ||
| 645 | + for(i=0;i<16;i++) { | ||
| 646 | + if (insn & (1 << i)) { | ||
| 647 | + if (insn & (1 << 20)) { | ||
| 648 | + /* load */ | ||
| 649 | + gen_op_ldl_T0_T1(); | ||
| 650 | + gen_movl_reg_T0(s, i); | ||
| 651 | + } else { | ||
| 652 | + /* store */ | ||
| 653 | + if (i == 15) { | ||
| 654 | + /* special case: r15 = PC + 12 */ | ||
| 655 | + val = (long)s->pc + 8; | ||
| 656 | + gen_op_movl_TN_im[0](val); | ||
| 657 | + } else { | ||
| 658 | + gen_movl_T0_reg(s, i); | ||
| 659 | + } | ||
| 660 | + gen_op_stl_T0_T1(); | ||
| 661 | + } | ||
| 662 | + j++; | ||
| 663 | + /* no need to add after the last transfer */ | ||
| 664 | + if (j != n) | ||
| 665 | + gen_op_addl_T1_im(4); | ||
| 612 | } | 666 | } |
| 613 | - if (!(insn & (1 << 24))) | ||
| 614 | - gen_op_addl_T1_im(val); | 667 | + } |
| 668 | + if (insn & (1 << 21)) { | ||
| 669 | + /* write back */ | ||
| 670 | + if (insn & (1 << 23)) { | ||
| 671 | + if (insn & (1 << 24)) { | ||
| 672 | + /* pre increment */ | ||
| 673 | + } else { | ||
| 674 | + /* post increment */ | ||
| 675 | + gen_op_addl_T1_im(4); | ||
| 676 | + } | ||
| 677 | + } else { | ||
| 678 | + if (insn & (1 << 24)) { | ||
| 679 | + /* pre decrement */ | ||
| 680 | + if (n != 1) | ||
| 681 | + gen_op_addl_T1_im(-((n - 1) * 4)); | ||
| 682 | + } else { | ||
| 683 | + /* post decrement */ | ||
| 684 | + gen_op_addl_T1_im(-(n * 4)); | ||
| 685 | + } | ||
| 686 | + } | ||
| 687 | + gen_movl_reg_T1(s, rn); | ||
| 615 | } | 688 | } |
| 616 | } | 689 | } |
| 617 | - if (insn & (1 << 21)) | ||
| 618 | - gen_movl_reg_T1(s, rn); | ||
| 619 | break; | 690 | break; |
| 620 | case 0xa: | 691 | case 0xa: |
| 621 | case 0xb: | 692 | case 0xb: |
| @@ -641,6 +712,66 @@ static void disas_arm_insn(DisasContext *s) | @@ -641,6 +712,66 @@ static void disas_arm_insn(DisasContext *s) | ||
| 641 | gen_op_swi(); | 712 | gen_op_swi(); |
| 642 | s->is_jmp = DISAS_JUMP; | 713 | s->is_jmp = DISAS_JUMP; |
| 643 | break; | 714 | break; |
| 715 | + case 0xc: | ||
| 716 | + case 0xd: | ||
| 717 | + rd = (insn >> 12) & 0x7; | ||
| 718 | + rn = (insn >> 16) & 0xf; | ||
| 719 | + gen_movl_T1_reg(s, rn); | ||
| 720 | + val = (insn) & 0xff; | ||
| 721 | + if (!(insn & (1 << 23))) | ||
| 722 | + val = -val; | ||
| 723 | + switch((insn >> 8) & 0xf) { | ||
| 724 | + case 0x1: | ||
| 725 | + /* load/store */ | ||
| 726 | + if ((insn & (1 << 24))) | ||
| 727 | + gen_op_addl_T1_im(val); | ||
| 728 | + /* XXX: do it */ | ||
| 729 | + if (!(insn & (1 << 24))) | ||
| 730 | + gen_op_addl_T1_im(val); | ||
| 731 | + if (insn & (1 << 21)) | ||
| 732 | + gen_movl_reg_T1(s, rn); | ||
| 733 | + break; | ||
| 734 | + case 0x2: | ||
| 735 | + { | ||
| 736 | + int n, i; | ||
| 737 | + /* load store multiple */ | ||
| 738 | + if ((insn & (1 << 24))) | ||
| 739 | + gen_op_addl_T1_im(val); | ||
| 740 | + switch(insn & 0x00408000) { | ||
| 741 | + case 0x00008000: n = 1; break; | ||
| 742 | + case 0x00400000: n = 2; break; | ||
| 743 | + case 0x00408000: n = 3; break; | ||
| 744 | + default: n = 4; break; | ||
| 745 | + } | ||
| 746 | + for(i = 0;i < n; i++) { | ||
| 747 | + /* XXX: do it */ | ||
| 748 | + } | ||
| 749 | + if (!(insn & (1 << 24))) | ||
| 750 | + gen_op_addl_T1_im(val); | ||
| 751 | + if (insn & (1 << 21)) | ||
| 752 | + gen_movl_reg_T1(s, rn); | ||
| 753 | + } | ||
| 754 | + break; | ||
| 755 | + default: | ||
| 756 | + goto illegal_op; | ||
| 757 | + } | ||
| 758 | + break; | ||
| 759 | + case 0x0e: | ||
| 760 | + /* float ops */ | ||
| 761 | + /* XXX: do it */ | ||
| 762 | + switch((insn >> 20) & 0xf) { | ||
| 763 | + case 0x2: /* wfs */ | ||
| 764 | + break; | ||
| 765 | + case 0x3: /* rfs */ | ||
| 766 | + break; | ||
| 767 | + case 0x4: /* wfc */ | ||
| 768 | + break; | ||
| 769 | + case 0x5: /* rfc */ | ||
| 770 | + break; | ||
| 771 | + default: | ||
| 772 | + goto illegal_op; | ||
| 773 | + } | ||
| 774 | + break; | ||
| 644 | default: | 775 | default: |
| 645 | illegal_op: | 776 | illegal_op: |
| 646 | gen_op_movl_T0_im((long)s->pc - 4); | 777 | gen_op_movl_T0_im((long)s->pc - 4); |
| @@ -688,15 +819,19 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc | @@ -688,15 +819,19 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc | ||
| 688 | disas_arm_insn(dc); | 819 | disas_arm_insn(dc); |
| 689 | } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && | 820 | } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && |
| 690 | (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); | 821 | (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); |
| 691 | - /* we must store the eflags state if it is not already done */ | ||
| 692 | - if (dc->is_jmp != DISAS_TB_JUMP && | ||
| 693 | - dc->is_jmp != DISAS_JUMP) { | ||
| 694 | - gen_op_movl_T0_im((long)dc->pc - 4); | ||
| 695 | - gen_op_movl_reg_TN[0][15](); | ||
| 696 | - } | ||
| 697 | - if (dc->is_jmp != DISAS_TB_JUMP) { | 822 | + switch(dc->is_jmp) { |
| 823 | + case DISAS_JUMP_NEXT: | ||
| 824 | + case DISAS_NEXT: | ||
| 825 | + gen_op_jmp((long)dc->tb, (long)dc->pc); | ||
| 826 | + break; | ||
| 827 | + default: | ||
| 828 | + case DISAS_JUMP: | ||
| 698 | /* indicate that the hash table must be used to find the next TB */ | 829 | /* indicate that the hash table must be used to find the next TB */ |
| 699 | gen_op_movl_T0_0(); | 830 | gen_op_movl_T0_0(); |
| 831 | + break; | ||
| 832 | + case DISAS_TB_JUMP: | ||
| 833 | + /* nothing more to generate */ | ||
| 834 | + break; | ||
| 700 | } | 835 | } |
| 701 | *gen_opc_ptr = INDEX_op_end; | 836 | *gen_opc_ptr = INDEX_op_end; |
| 702 | 837 | ||
| @@ -756,5 +891,10 @@ void cpu_arm_dump_state(CPUARMState *env, FILE *f, int flags) | @@ -756,5 +891,10 @@ void cpu_arm_dump_state(CPUARMState *env, FILE *f, int flags) | ||
| 756 | else | 891 | else |
| 757 | fprintf(f, " "); | 892 | fprintf(f, " "); |
| 758 | } | 893 | } |
| 759 | - fprintf(f, "CPSR=%08x", env->cpsr); | 894 | + fprintf(f, "PSR=%08x %c%c%c%c\n", |
| 895 | + env->cpsr, | ||
| 896 | + env->cpsr & (1 << 31) ? 'N' : '-', | ||
| 897 | + env->cpsr & (1 << 30) ? 'Z' : '-', | ||
| 898 | + env->cpsr & (1 << 29) ? 'C' : '-', | ||
| 899 | + env->cpsr & (1 << 28) ? 'V' : '-'); | ||
| 760 | } | 900 | } |