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 */ |