Commit 0bee699e1db8170071902dbbde9c6b932883a897
1 parent
878d3096
fixed jmpl, rett and call
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1292 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
32 additions
and
7 deletions
target-sparc/op.c
target-sparc/translate.c
... | ... | @@ -427,6 +427,20 @@ static inline void save_state(DisasContext * dc) |
427 | 427 | save_npc(dc); |
428 | 428 | } |
429 | 429 | |
430 | +static inline void gen_mov_pc_npc(DisasContext * dc) | |
431 | +{ | |
432 | + if (dc->npc == JUMP_PC) { | |
433 | + gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]); | |
434 | + gen_op_mov_pc_npc(); | |
435 | + dc->pc = DYNAMIC_PC; | |
436 | + } else if (dc->npc == DYNAMIC_PC) { | |
437 | + gen_op_mov_pc_npc(); | |
438 | + dc->pc = DYNAMIC_PC; | |
439 | + } else { | |
440 | + dc->pc = dc->npc; | |
441 | + } | |
442 | +} | |
443 | + | |
430 | 444 | static void gen_cond(int cond) |
431 | 445 | { |
432 | 446 | switch (cond) { |
... | ... | @@ -525,6 +539,7 @@ static void gen_fcond(int cond) |
525 | 539 | } |
526 | 540 | } |
527 | 541 | |
542 | +/* XXX: potentially incorrect if dynamic npc */ | |
528 | 543 | static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) |
529 | 544 | { |
530 | 545 | unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); |
... | ... | @@ -533,7 +548,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) |
533 | 548 | if (cond == 0x0) { |
534 | 549 | /* unconditional not taken */ |
535 | 550 | if (a) { |
536 | - dc->pc = dc->npc + 4; | |
551 | + dc->pc = dc->npc + 4; | |
537 | 552 | dc->npc = dc->pc + 4; |
538 | 553 | } else { |
539 | 554 | dc->pc = dc->npc; |
... | ... | @@ -563,6 +578,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) |
563 | 578 | } |
564 | 579 | } |
565 | 580 | |
581 | +/* XXX: potentially incorrect if dynamic npc */ | |
566 | 582 | static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn) |
567 | 583 | { |
568 | 584 | unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); |
... | ... | @@ -609,6 +625,7 @@ static int sign_extend(int x, int len) |
609 | 625 | return (x << len) >> len; |
610 | 626 | } |
611 | 627 | |
628 | +/* before an instruction, dc->pc must be static */ | |
612 | 629 | static void disas_sparc_insn(DisasContext * dc) |
613 | 630 | { |
614 | 631 | unsigned int insn, opc, rs1, rs2, rd; |
... | ... | @@ -669,7 +686,7 @@ static void disas_sparc_insn(DisasContext * dc) |
669 | 686 | gen_op_movl_T0_im(dc->pc); |
670 | 687 | gen_movl_T0_reg(15); |
671 | 688 | target += dc->pc; |
672 | - dc->pc = dc->npc; | |
689 | + gen_mov_pc_npc(dc); | |
673 | 690 | dc->npc = target; |
674 | 691 | } |
675 | 692 | goto jmp_insn; |
... | ... | @@ -1173,12 +1190,12 @@ static void disas_sparc_insn(DisasContext * dc) |
1173 | 1190 | switch (xop) { |
1174 | 1191 | case 0x38: /* jmpl */ |
1175 | 1192 | { |
1176 | - gen_op_movl_npc_T0(); | |
1177 | 1193 | if (rd != 0) { |
1178 | - gen_op_movl_T0_im(dc->pc); | |
1179 | - gen_movl_T0_reg(rd); | |
1194 | + gen_op_movl_T1_im(dc->pc); | |
1195 | + gen_movl_T1_reg(rd); | |
1180 | 1196 | } |
1181 | - dc->pc = dc->npc; | |
1197 | + gen_mov_pc_npc(dc); | |
1198 | + gen_op_movl_npc_T0(); | |
1182 | 1199 | dc->npc = DYNAMIC_PC; |
1183 | 1200 | } |
1184 | 1201 | goto jmp_insn; |
... | ... | @@ -1187,10 +1204,12 @@ static void disas_sparc_insn(DisasContext * dc) |
1187 | 1204 | { |
1188 | 1205 | if (!supervisor(dc)) |
1189 | 1206 | goto priv_insn; |
1207 | + gen_mov_pc_npc(dc); | |
1190 | 1208 | gen_op_movl_npc_T0(); |
1209 | + dc->npc = DYNAMIC_PC; | |
1191 | 1210 | gen_op_rett(); |
1192 | 1211 | } |
1193 | - break; | |
1212 | + goto jmp_insn; | |
1194 | 1213 | #endif |
1195 | 1214 | case 0x3b: /* flush */ |
1196 | 1215 | gen_op_flush_T0(); |
... | ... | @@ -1605,6 +1624,7 @@ void cpu_reset(CPUSPARCState *env) |
1605 | 1624 | env->user_mode_only = 1; |
1606 | 1625 | #else |
1607 | 1626 | env->psrs = 1; |
1627 | + env->psrps = 1; | |
1608 | 1628 | env->pc = 0xffd00000; |
1609 | 1629 | env->gregs[1] = ram_size; |
1610 | 1630 | env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ | ... | ... |