Commit 0bee699e1db8170071902dbbde9c6b932883a897

Authored by bellard
1 parent 878d3096

fixed jmpl, rett and call


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1292 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/op.c
... ... @@ -812,6 +812,11 @@ void OPPROTO op_movl_npc_T0(void)
812 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 820 void OPPROTO op_next_insn(void)
816 821 {
817 822 env->pc = env->npc;
... ...
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 */
... ...