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