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