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