unsigned int mode;
int l1;
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
+ && !((dc->env->pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ }
+
mode = dc->opcode & 3;
switch (mode) {
case 0:
{
TCGv t0, t1;
unsigned int sr, to, rn;
+ int mem_index = cpu_mmu_index(dc->env);
sr = dc->imm & ((1 << 14) - 1);
to = dc->imm & (1 << 14);
LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set",
dc->rd, dc->imm);
+
+ if (!(dc->env->pvr.regs[2] & PVR2_USE_MSR_INSTR)) {
+ /* nop??? */
+ return;
+ }
+
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && mem_index == MMU_USER_IDX && (dc->imm != 4 && dc->imm != 0)) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
+
if (dc->rd)
msr_read(dc, cpu_R[dc->rd]);
return;
}
+ if (to) {
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && mem_index == MMU_USER_IDX) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
+ }
+
#if !defined(CONFIG_USER_ONLY)
/* Catch read/writes to the mmu block. */
if ((sr & ~0xff) == 0x1000) {
TCGv d[2];
unsigned int subcode;
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
+ && !(dc->env->pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
+
subcode = dc->imm & 3;
d[0] = tcg_temp_new();
d[1] = tcg_temp_new();
goto done;
}
+ /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2. */
+ if (subcode >= 1 && subcode <= 3
+ && !((dc->env->pvr.regs[2] & PVR2_USE_MUL64_MASK))) {
+ /* nop??? */
+ }
+
switch (subcode) {
case 0:
LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
u = dc->imm & 2;
LOG_DIS("div\n");
+ if (!(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
+ && !((dc->env->pvr.regs[0] & PVR0_USE_DIV_MASK))) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ }
+
/* FIXME: support div by zero exceptions. */
if (u)
gen_helper_divu(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
TCGv t0;
unsigned int s, t;
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
+ && !(dc->env->pvr.regs[0] & PVR0_USE_BARREL_MASK)) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
+
s = dc->imm & (1 << 10);
t = dc->imm & (1 << 9);
{
TCGv t0, t1;
unsigned int op;
+ int mem_index = cpu_mmu_index(dc->env);
op = dc->ir & ((1 << 8) - 1);
switch (op) {
case 0x64:
/* wdc. */
LOG_DIS("wdc r%d\n", dc->ra);
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && mem_index == MMU_USER_IDX) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
break;
case 0x68:
/* wic. */
LOG_DIS("wic r%d\n", dc->ra);
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && mem_index == MMU_USER_IDX) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
break;
default:
cpu_abort(dc->env, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
static void dec_rts(DisasContext *dc)
{
unsigned int b_bit, i_bit, e_bit;
+ int mem_index = cpu_mmu_index(dc->env);
i_bit = dc->ir & (1 << 21);
b_bit = dc->ir & (1 << 22);
if (i_bit) {
LOG_DIS("rtid ir=%x\n", dc->ir);
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && mem_index == MMU_USER_IDX) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ }
dc->tb_flags |= DRTI_FLAG;
} else if (b_bit) {
LOG_DIS("rtbd ir=%x\n", dc->ir);
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && mem_index == MMU_USER_IDX) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ }
dc->tb_flags |= DRTB_FLAG;
} else if (e_bit) {
LOG_DIS("rted ir=%x\n", dc->ir);
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && mem_index == MMU_USER_IDX) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ }
dc->tb_flags |= DRTE_FLAG;
} else
LOG_DIS("rts ir=%x\n", dc->ir);
tcg_gen_add_tl(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
}
+static void dec_fpu(DisasContext *dc)
+{
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
+ && !((dc->env->pvr.regs[2] & PVR2_USE_FPU_MASK))) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
+
+ qemu_log ("unimplemented FPU insn pc=%x opc=%x\n", dc->pc, dc->opcode);
+ dc->abort_at_next_insn = 1;
+}
+
static void dec_null(DisasContext *dc)
{
qemu_log ("unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
{DEC_BR, dec_br},
{DEC_BCC, dec_bcc},
{DEC_RTS, dec_rts},
+ {DEC_FPU, dec_fpu},
{DEC_MUL, dec_mul},
{DEC_DIV, dec_div},
{DEC_MSR, dec_msr},
if (dc->ir)
dc->nr_nops = 0;
else {
+ if ((dc->tb_flags & MSR_EE_FLAG)
+ && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
+ && !(dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
+
LOG_DIS("nr_nops=%d\t", dc->nr_nops);
dc->nr_nops++;
if (dc->nr_nops > 4)
}
}
-
static void check_breakpoint(CPUState *env, DisasContext *dc)
{
CPUBreakpoint *bp;