427 |
save_npc(dc); |
save_npc(dc); |
428 |
} |
} |
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 |
|
|
444 |
static void gen_cond(int cond) |
static void gen_cond(int cond) |
445 |
{ |
{ |
446 |
switch (cond) { |
switch (cond) { |
539 |
} |
} |
540 |
} |
} |
541 |
|
|
542 |
|
/* XXX: potentially incorrect if dynamic npc */ |
543 |
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) |
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) |
544 |
{ |
{ |
545 |
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); |
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); |
548 |
if (cond == 0x0) { |
if (cond == 0x0) { |
549 |
/* unconditional not taken */ |
/* unconditional not taken */ |
550 |
if (a) { |
if (a) { |
551 |
dc->pc = dc->npc + 4; |
dc->pc = dc->npc + 4; |
552 |
dc->npc = dc->pc + 4; |
dc->npc = dc->pc + 4; |
553 |
} else { |
} else { |
554 |
dc->pc = dc->npc; |
dc->pc = dc->npc; |
578 |
} |
} |
579 |
} |
} |
580 |
|
|
581 |
|
/* XXX: potentially incorrect if dynamic npc */ |
582 |
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn) |
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn) |
583 |
{ |
{ |
584 |
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); |
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); |
625 |
return (x << len) >> len; |
return (x << len) >> len; |
626 |
} |
} |
627 |
|
|
628 |
|
/* before an instruction, dc->pc must be static */ |
629 |
static void disas_sparc_insn(DisasContext * dc) |
static void disas_sparc_insn(DisasContext * dc) |
630 |
{ |
{ |
631 |
unsigned int insn, opc, rs1, rs2, rd; |
unsigned int insn, opc, rs1, rs2, rd; |
686 |
gen_op_movl_T0_im(dc->pc); |
gen_op_movl_T0_im(dc->pc); |
687 |
gen_movl_T0_reg(15); |
gen_movl_T0_reg(15); |
688 |
target += dc->pc; |
target += dc->pc; |
689 |
dc->pc = dc->npc; |
gen_mov_pc_npc(dc); |
690 |
dc->npc = target; |
dc->npc = target; |
691 |
} |
} |
692 |
goto jmp_insn; |
goto jmp_insn; |
1190 |
switch (xop) { |
switch (xop) { |
1191 |
case 0x38: /* jmpl */ |
case 0x38: /* jmpl */ |
1192 |
{ |
{ |
|
gen_op_movl_npc_T0(); |
|
1193 |
if (rd != 0) { |
if (rd != 0) { |
1194 |
gen_op_movl_T0_im(dc->pc); |
gen_op_movl_T1_im(dc->pc); |
1195 |
gen_movl_T0_reg(rd); |
gen_movl_T1_reg(rd); |
1196 |
} |
} |
1197 |
dc->pc = dc->npc; |
gen_mov_pc_npc(dc); |
1198 |
|
gen_op_movl_npc_T0(); |
1199 |
dc->npc = DYNAMIC_PC; |
dc->npc = DYNAMIC_PC; |
1200 |
} |
} |
1201 |
goto jmp_insn; |
goto jmp_insn; |
1204 |
{ |
{ |
1205 |
if (!supervisor(dc)) |
if (!supervisor(dc)) |
1206 |
goto priv_insn; |
goto priv_insn; |
1207 |
|
gen_mov_pc_npc(dc); |
1208 |
gen_op_movl_npc_T0(); |
gen_op_movl_npc_T0(); |
1209 |
|
dc->npc = DYNAMIC_PC; |
1210 |
gen_op_rett(); |
gen_op_rett(); |
1211 |
} |
} |
1212 |
break; |
goto jmp_insn; |
1213 |
#endif |
#endif |
1214 |
case 0x3b: /* flush */ |
case 0x3b: /* flush */ |
1215 |
gen_op_flush_T0(); |
gen_op_flush_T0(); |
1624 |
env->user_mode_only = 1; |
env->user_mode_only = 1; |
1625 |
#else |
#else |
1626 |
env->psrs = 1; |
env->psrs = 1; |
1627 |
|
env->psrps = 1; |
1628 |
env->pc = 0xffd00000; |
env->pc = 0xffd00000; |
1629 |
env->gregs[1] = ram_size; |
env->gregs[1] = ram_size; |
1630 |
env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ |
env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ |