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
| @@ -812,6 +812,11 @@ void OPPROTO op_movl_npc_T0(void) | @@ -812,6 +812,11 @@ void OPPROTO op_movl_npc_T0(void) | ||
| 812 | env->npc = T0; | 812 | env->npc = T0; |
| 813 | } | 813 | } |
| 814 | 814 | ||
| 815 | +void OPPROTO op_mov_pc_npc(void) | ||
| 816 | +{ | ||
| 817 | + env->pc = env->npc; | ||
| 818 | +} | ||
| 819 | + | ||
| 815 | void OPPROTO op_next_insn(void) | 820 | void OPPROTO op_next_insn(void) |
| 816 | { | 821 | { |
| 817 | env->pc = env->npc; | 822 | env->pc = env->npc; |
target-sparc/translate.c
| @@ -427,6 +427,20 @@ static inline void save_state(DisasContext * dc) | @@ -427,6 +427,20 @@ static inline void save_state(DisasContext * dc) | ||
| 427 | save_npc(dc); | 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 | static void gen_cond(int cond) | 444 | static void gen_cond(int cond) |
| 431 | { | 445 | { |
| 432 | switch (cond) { | 446 | switch (cond) { |
| @@ -525,6 +539,7 @@ static void gen_fcond(int 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 | static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) | 543 | static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) |
| 529 | { | 544 | { |
| 530 | unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); | 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,7 +548,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) | ||
| 533 | if (cond == 0x0) { | 548 | if (cond == 0x0) { |
| 534 | /* unconditional not taken */ | 549 | /* unconditional not taken */ |
| 535 | if (a) { | 550 | if (a) { |
| 536 | - dc->pc = dc->npc + 4; | 551 | + dc->pc = dc->npc + 4; |
| 537 | dc->npc = dc->pc + 4; | 552 | dc->npc = dc->pc + 4; |
| 538 | } else { | 553 | } else { |
| 539 | dc->pc = dc->npc; | 554 | dc->pc = dc->npc; |
| @@ -563,6 +578,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) | @@ -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 | static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn) | 582 | static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn) |
| 567 | { | 583 | { |
| 568 | unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); | 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,6 +625,7 @@ static int sign_extend(int x, int len) | ||
| 609 | return (x << len) >> len; | 625 | return (x << len) >> len; |
| 610 | } | 626 | } |
| 611 | 627 | ||
| 628 | +/* before an instruction, dc->pc must be static */ | ||
| 612 | static void disas_sparc_insn(DisasContext * dc) | 629 | static void disas_sparc_insn(DisasContext * dc) |
| 613 | { | 630 | { |
| 614 | unsigned int insn, opc, rs1, rs2, rd; | 631 | unsigned int insn, opc, rs1, rs2, rd; |
| @@ -669,7 +686,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -669,7 +686,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 669 | gen_op_movl_T0_im(dc->pc); | 686 | gen_op_movl_T0_im(dc->pc); |
| 670 | gen_movl_T0_reg(15); | 687 | gen_movl_T0_reg(15); |
| 671 | target += dc->pc; | 688 | target += dc->pc; |
| 672 | - dc->pc = dc->npc; | 689 | + gen_mov_pc_npc(dc); |
| 673 | dc->npc = target; | 690 | dc->npc = target; |
| 674 | } | 691 | } |
| 675 | goto jmp_insn; | 692 | goto jmp_insn; |
| @@ -1173,12 +1190,12 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -1173,12 +1190,12 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 1173 | switch (xop) { | 1190 | switch (xop) { |
| 1174 | case 0x38: /* jmpl */ | 1191 | case 0x38: /* jmpl */ |
| 1175 | { | 1192 | { |
| 1176 | - gen_op_movl_npc_T0(); | ||
| 1177 | if (rd != 0) { | 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 | dc->npc = DYNAMIC_PC; | 1199 | dc->npc = DYNAMIC_PC; |
| 1183 | } | 1200 | } |
| 1184 | goto jmp_insn; | 1201 | goto jmp_insn; |
| @@ -1187,10 +1204,12 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -1187,10 +1204,12 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 1187 | { | 1204 | { |
| 1188 | if (!supervisor(dc)) | 1205 | if (!supervisor(dc)) |
| 1189 | goto priv_insn; | 1206 | goto priv_insn; |
| 1207 | + gen_mov_pc_npc(dc); | ||
| 1190 | gen_op_movl_npc_T0(); | 1208 | gen_op_movl_npc_T0(); |
| 1209 | + dc->npc = DYNAMIC_PC; | ||
| 1191 | gen_op_rett(); | 1210 | gen_op_rett(); |
| 1192 | } | 1211 | } |
| 1193 | - break; | 1212 | + goto jmp_insn; |
| 1194 | #endif | 1213 | #endif |
| 1195 | case 0x3b: /* flush */ | 1214 | case 0x3b: /* flush */ |
| 1196 | gen_op_flush_T0(); | 1215 | gen_op_flush_T0(); |
| @@ -1605,6 +1624,7 @@ void cpu_reset(CPUSPARCState *env) | @@ -1605,6 +1624,7 @@ void cpu_reset(CPUSPARCState *env) | ||
| 1605 | env->user_mode_only = 1; | 1624 | env->user_mode_only = 1; |
| 1606 | #else | 1625 | #else |
| 1607 | env->psrs = 1; | 1626 | env->psrs = 1; |
| 1627 | + env->psrps = 1; | ||
| 1608 | env->pc = 0xffd00000; | 1628 | env->pc = 0xffd00000; |
| 1609 | env->gregs[1] = ram_size; | 1629 | env->gregs[1] = ram_size; |
| 1610 | env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ | 1630 | env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ |