Further DTC expansion
This commit is contained in:
parent
6356e5b4f9
commit
cae2a12b71
|
@ -110,8 +110,33 @@ void NuInterpExec(uint32_t next_pc) {
|
|||
{CAST(crorc), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(cror), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(bcctr), {InstrOps::opBrRel, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(bcctrl), {InstrOps::opBrRel, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(cmp), {InstrOps::opCrfDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(tw), {InstrOps::opTOAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(subfc), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(subfcdot), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(addc), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(addcdot), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(mulhwu), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(mulhwudot), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(mfcr), {InstrOps::opD, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lwarx), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lwzx), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(slw), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(slwdot), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(cntlzw), {InstrOps::opSA, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(cntlzwdot), {InstrOps::opSA, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(ppc_and), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(anddot), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(cmpl), {InstrOps::opCrfDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(subf), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(subfdot), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(dcbst), {InstrOps::opAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lwzux), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(andc), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(andcdot), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(mulhw), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(mulhwdot), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
/*
|
||||
|
||||
{CAST(lbzux), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
|
@ -127,10 +152,7 @@ void NuInterpExec(uint32_t next_pc) {
|
|||
{CAST(lhzx), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lswi), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lswx), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lwarx), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lwbrx), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lwzx), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(lwzux), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
|
||||
{CAST(add), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(adddot), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
|
@ -143,8 +165,6 @@ void NuInterpExec(uint32_t next_pc) {
|
|||
{CAST(addzedot), {InstrOps::opDA, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(and), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(anddot), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(andc), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(andcdot), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(divw), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(divwdot), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(divwu), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
|
@ -152,8 +172,6 @@ void NuInterpExec(uint32_t next_pc) {
|
|||
{CAST(eieio), {InstrOps::opNone, CFlowType::CFL_NONE, 1}},
|
||||
|
||||
{CAST(cmpl), {InstrOps::opCrfDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(cntlzw), {InstrOps::opSA, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(cntlzwdot), {InstrOps::opSA, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(eqv), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(eqvdot), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(extsb), {InstrOps::opSA, CFlowType::CFL_NONE, 1}},
|
||||
|
@ -166,7 +184,6 @@ void NuInterpExec(uint32_t next_pc) {
|
|||
{CAST(isync), {InstrOps::opNone, CFlowType::CFL_NONE, 1}},
|
||||
|
||||
{CAST(mtcrf), {InstrOps::opNone, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(mulhw), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(mulhwu), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(mullw), {InstrOps::opDAB, CFlowType::CFL_NONE, 1}},
|
||||
{CAST(nand), {InstrOps::opSAB, CFlowType::CFL_NONE, 1}},
|
||||
|
@ -262,14 +279,20 @@ void NuInterpExec(uint32_t next_pc) {
|
|||
/* pre-decode operands, immediate values etc. */
|
||||
switch (p_instr->info.ops_fmt) {
|
||||
case InstrOps::opDA:
|
||||
case InstrOps::opSA:
|
||||
c_instr->d1 = REG_D(opcode);
|
||||
c_instr->d2 = REG_A(opcode);
|
||||
break;
|
||||
case InstrOps::opDAB:
|
||||
case InstrOps::opSAB:
|
||||
c_instr->d1 = REG_D(opcode);
|
||||
c_instr->d2 = REG_A(opcode);
|
||||
c_instr->d3 = REG_B(opcode);
|
||||
break;
|
||||
case InstrOps::opAB:
|
||||
c_instr->d2 = REG_A(opcode);
|
||||
c_instr->d3 = REG_B(opcode);
|
||||
break;
|
||||
case InstrOps::opTOAB:
|
||||
c_instr->d1 = REG_TO(opcode);
|
||||
c_instr->d2 = REG_A(opcode);
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#define ppc_carry(a, b) (b < a) ? ppc_state.spr[SPR::XER] |= 0x20000000UL : ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL
|
||||
#define ppc_carry_sub(a, b) (b >= a) ? ppc_state.spr[SPR::XER] |= 0x20000000UL : ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL
|
||||
#define ppc_setsoov(a, b, d) ((a ^ b) & (a ^ d) & 0x80000000UL) ? ppc_state.spr[SPR::XER] |= 0xC0000000UL : ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL
|
||||
|
||||
GEN_OP(addi, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d2] + code->simm;
|
||||
NEXT;
|
||||
|
@ -110,6 +114,10 @@ GEN_OP(mtspr, {
|
|||
NEXT;
|
||||
})
|
||||
|
||||
GEN_OP(mfspr, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.spr[code->uimm];
|
||||
})
|
||||
|
||||
GEN_OP(bdnz, {
|
||||
if (--ppc_state.spr[SPR::CTR]) {
|
||||
#if defined(USE_DTC)
|
||||
|
@ -334,24 +342,15 @@ GEN_OP(lhzu, {
|
|||
})
|
||||
|
||||
GEN_OP(lha, {
|
||||
if ((code->d2 != code->d1) || code->d2 != 0) {
|
||||
uint32_t ea = ((code->d2) ? ppc_state.gpr[code->d2] : 0) + code->simm;
|
||||
ppc_state.gpr[code->d1] = (uint32_t)(uint16_t)(mem_grab_word(ea));
|
||||
ppc_state.gpr[code->d2] = ppc_effective_address;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
|
||||
}
|
||||
uint32_t ea = ((code->d2) ? ppc_state.gpr[code->d2] : 0) + code->simm;
|
||||
ppc_state.gpr[code->d1] = (int32_t)(int16_t)mem_grab_word(ea);
|
||||
NEXT;
|
||||
})
|
||||
|
||||
GEN_OP(lhau, {
|
||||
if ((code->d2 != code->d1) || code->d2 != 0) {
|
||||
uint32_t ea = ((code->d2) ? ppc_state.gpr[code->d2] : 0) + code->simm;
|
||||
ppc_state.gpr[code->d1] = (uint32_t)(uint16_t)(mem_grab_word(ea));
|
||||
ppc_state.gpr[code->d2] = ppc_effective_address;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
|
||||
}
|
||||
GEN_OP(lhaux, {
|
||||
uint32_t ea = ((code->d2) ? ppc_state.gpr[code->d2] : 0) + ppc_state.gpr[code->d3];
|
||||
ppc_state.gpr[code->d1] = (int32_t)(int16_t)mem_grab_word(ea);
|
||||
ppc_state.gpr[code->d2] = ea;
|
||||
NEXT;
|
||||
})
|
||||
|
||||
|
@ -589,69 +588,34 @@ GEN_OP(tw, {
|
|||
|
||||
GEN_OP(subfc, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d3] - ppc_state.gpr[code->d2];
|
||||
|
||||
if (ppc_state.gpr[code->d1] >= ppc_state.gpr[code->d2]) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
ppc_carry_sub(ppc_state.gpr[code->d2], ppc_state.gpr[code->d3]);
|
||||
})
|
||||
|
||||
GEN_OP(subfcdot, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d3] - ppc_state.gpr[code->d2];
|
||||
|
||||
if (ppc_state.gpr[code->d1] >= ppc_state.gpr[code->d2]) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
|
||||
ppc_carry_sub(ppc_state.gpr[code->d2], ppc_state.gpr[code->d3]);
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(addc, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d3] + ppc_state.gpr[code->d2];
|
||||
|
||||
if (ppc_state.gpr[code->d2] < ppc_state.gpr[code->d1]) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
ppc_carry(ppc_state.gpr[code->d2], ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(addcdot, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d3] + ppc_state.gpr[code->d2];
|
||||
|
||||
if (ppc_state.gpr[code->d2] < ppc_state.gpr[code->d1]) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
|
||||
ppc_carry(ppc_state.gpr[code->d2], ppc_state.gpr[code->d1]);
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(mulhwu, {
|
||||
uint64_t product = (uint64_t)ppc_state.gpr[code->d3] * (uint64_t)ppc_state.gpr[code->d2];
|
||||
ppc_state.gpr[code->d1] = (uint32_t)(product >> 32);
|
||||
|
||||
if (ppc_state.gpr[code->d2] < ppc_state.gpr[code->d1]) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
})
|
||||
|
||||
GEN_OP(mulhwudot, {
|
||||
uint64_t product = (uint64_t)ppc_state.gpr[code->d3] * (uint64_t)ppc_state.gpr[code->d2];
|
||||
ppc_state.gpr[code->d1] = (uint32_t)(product >> 32);
|
||||
|
||||
if (ppc_state.gpr[code->d2] < ppc_state.gpr[code->d1]) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
|
@ -845,6 +809,22 @@ GEN_OP(slwdot, {
|
|||
ppc_changecrf0(ppc_state.gpr[code->d2]);
|
||||
})
|
||||
|
||||
GEN_OP(srw, {
|
||||
ppc_state.gpr[code->d2] =
|
||||
((ppc_state.gpr[code->d3] > 0x1F)
|
||||
? 0
|
||||
: ppc_state.gpr[code->d1] >> (ppc_state.gpr[code->d3] & 0x1F));
|
||||
})
|
||||
|
||||
GEN_OP(srwdot, {
|
||||
ppc_state.gpr[code->d2] =
|
||||
((ppc_state.gpr[code->d3] > 0x1F)
|
||||
? 0
|
||||
: ppc_state.gpr[code->d1] >> (ppc_state.gpr[code->d3] & 0x1F));
|
||||
|
||||
ppc_changecrf0(ppc_state.gpr[code->d2]);
|
||||
})
|
||||
|
||||
GEN_OP(cntlzw, {
|
||||
uint32_t lead = 0;
|
||||
uint32_t bit_check = ppc_state.gpr[code->d1];
|
||||
|
@ -893,6 +873,51 @@ GEN_OP(anddot, {
|
|||
ppc_changecrf0(ppc_state.gpr[code->d2]);
|
||||
})
|
||||
|
||||
GEN_OP(orc, {
|
||||
ppc_state.gpr[code->d2] = ppc_state.gpr[code->d1] | ~(ppc_state.gpr[code->d3]);
|
||||
})
|
||||
|
||||
GEN_OP(orcdot, {
|
||||
ppc_state.gpr[code->d2] = ppc_state.gpr[code->d1] | ~(ppc_state.gpr[code->d3]);
|
||||
ppc_changecrf0(ppc_state.gpr[code->d2]);
|
||||
})
|
||||
|
||||
GEN_OP(ppc_or, {
|
||||
ppc_state.gpr[code->d2] = ppc_state.gpr[code->d1] | ppc_state.gpr[code->d3];
|
||||
})
|
||||
|
||||
GEN_OP(ordot, {
|
||||
ppc_state.gpr[code->d2] = ppc_state.gpr[code->d1] | ppc_state.gpr[code->d3];
|
||||
ppc_changecrf0(ppc_state.gpr[code->d2]);
|
||||
})
|
||||
|
||||
GEN_OP(xor, {
|
||||
ppc_state.gpr[code->d2] = ppc_state.gpr[code->d1] ^ ppc_state.gpr[code->d3];
|
||||
})
|
||||
|
||||
GEN_OP(xordot, {
|
||||
ppc_state.gpr[code->d2] = ppc_state.gpr[code->d1] ^ ppc_state.gpr[code->d3];
|
||||
ppc_changecrf0(ppc_state.gpr[code->d2]);
|
||||
})
|
||||
|
||||
GEN_OP(eqv, {
|
||||
ppc_state.gpr[code->d2] = ~(ppc_state.gpr[code->d1] ^ ppc_state.gpr[code->d3]);
|
||||
})
|
||||
|
||||
GEN_OP(eqvdot, {
|
||||
ppc_state.gpr[code->d2] = ~(ppc_state.gpr[code->d1] ^ ppc_state.gpr[code->d3]);
|
||||
ppc_changecrf0(ppc_state.gpr[code->d2]);
|
||||
})
|
||||
|
||||
GEN_OP(nand, {
|
||||
ppc_state.gpr[code->d2] = ~(ppc_state.gpr[code->d1] & ppc_state.gpr[code->d3]);
|
||||
})
|
||||
|
||||
GEN_OP(nanddot, {
|
||||
ppc_state.gpr[code->d2] = ~(ppc_state.gpr[code->d1] & ppc_state.gpr[code->d3]);
|
||||
ppc_changecrf0(ppc_state.gpr[code->d2]);
|
||||
})
|
||||
|
||||
GEN_OP(cmpl, {
|
||||
xercon = (ppc_state.spr[SPR::XER] & 0x80000000UL) >> 3;
|
||||
cmp_c = (ppc_state.gpr[code->d2] == ppc_state.gpr[code->d3])
|
||||
|
@ -944,6 +969,38 @@ GEN_OP(mulhwdot, {
|
|||
ppc_changecrf0(ppc_result_d);
|
||||
})
|
||||
|
||||
GEN_OP(mullw, {
|
||||
int64_t product = (int64_t)(int32_t)ppc_state.gpr[code->d2] * (int64_t)(int32_t)ppc_state.gpr[code->d3];
|
||||
ppc_state.gpr[code->d1] = (uint32_t)product;
|
||||
})
|
||||
|
||||
GEN_OP(mullwdot, {
|
||||
int64_t product = (int64_t)(int32_t)ppc_state.gpr[code->d2] * (int64_t)(int32_t)ppc_state.gpr[code->d3];
|
||||
ppc_state.gpr[code->d1] = (uint32_t)product;
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(mullwo, {
|
||||
int64_t product = (int64_t)(int32_t)ppc_state.gpr[code->d2] * (int64_t)(int32_t)ppc_state.gpr[code->d3];
|
||||
ppc_state.gpr[code->d1] = (uint32_t)product;
|
||||
if (product != (int64_t)(int32_t)product) {
|
||||
ppc_state.spr[SPR::XER] |= 0xC0000000;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
|
||||
}
|
||||
})
|
||||
|
||||
GEN_OP(mullwodot, {
|
||||
int64_t product = (int64_t)(int32_t)ppc_state.gpr[code->d2] * (int64_t)(int32_t)ppc_state.gpr[code->d3];
|
||||
ppc_state.gpr[code->d1] = (uint32_t)product;
|
||||
if (product != (int64_t)(int32_t)product) {
|
||||
ppc_state.spr[SPR::XER] |= 0xC0000000;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
|
||||
}
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(subfco, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d3] - ppc_state.gpr[code->d2];
|
||||
|
||||
|
@ -1060,7 +1117,7 @@ GEN_OP(extshdot, {
|
|||
|
||||
GEN_OP(divwu, {
|
||||
if (!ppc_state.gpr[code->d3]) { /* division by zero */
|
||||
ppc_result_d = 0;
|
||||
ppc_state.gpr[code->d1] = 0;
|
||||
ppc_state.spr[SPR::XER] |= 0xC0000000;
|
||||
} else {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d2] / ppc_state.gpr[code->d3];
|
||||
|
@ -1142,14 +1199,23 @@ GEN_OP(dcbz, {
|
|||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
GEN_OP(mcrxr, {
|
||||
ppc_state.cr = (ppc_state.cr & ~(0xF0000000UL >> ppc_state.gpr[code->d1])) |
|
||||
((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> ppc_state.gpr[code->d1]);
|
||||
ppc_state.spr[SPR::XER] &= 0x0FFFFFFF;
|
||||
})
|
||||
|
||||
GEN_OP(subfze, {
|
||||
ppc_state.gpr[code->d1] = ~ppc_state.gpr[code->d2] + (ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_carry(~ppc_state.gpr[code->d2], ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(subfzedot, {
|
||||
ppc_state.gpr[code->d1] = ~ppc_state.gpr[code->d2] + (ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_carry(~ppc_state.gpr[code->d2], ppc_result_d);
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(mtsrin, {
|
||||
if ((ppc_state.msr & 0x4000) == 0) {
|
||||
uint32_t selection = ppc_state.gpr[code->d2] >> 28;
|
||||
|
@ -1364,4 +1430,184 @@ GEN_OP(stbx, {
|
|||
mem_write_byte(ppc_effective_address, ppc_result_d);
|
||||
})
|
||||
|
||||
GEN_OP(tlbie, {})
|
||||
GEN_OP(subfme, {
|
||||
uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_state.gpr[code->d1] = ~ppc_state.gpr[code->d2] + grab_xer - 1;
|
||||
ppc_carry(~ppc_state.gpr[code->d2], ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(subfmedot, {
|
||||
uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_state.gpr[code->d1] = ~ppc_state.gpr[code->d2] + grab_xer - 1;
|
||||
ppc_carry(~ppc_state.gpr[code->d2], ppc_state.gpr[code->d1]);
|
||||
ppc_setsoov(0xFFFFFFFF, ppc_state.gpr[code->d2], ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(subfzeo, {
|
||||
ppc_state.gpr[code->d1] = ~ppc_state.gpr[code->d2] + (ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_carry(~ppc_state.gpr[code->d2], ppc_result_d);
|
||||
ppc_setsoov(0, ppc_state.gpr[code->d2], ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(subfzeodot, {
|
||||
ppc_state.gpr[code->d1] = ~ppc_state.gpr[code->d2] + (ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_carry(~ppc_state.gpr[code->d2], ppc_result_d);
|
||||
ppc_setsoov(0, ppc_state.gpr[code->d2], ppc_state.gpr[code->d1]);
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(addme, {
|
||||
uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d2] + xer_ca - 1;
|
||||
|
||||
if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_state.gpr[code->d2])) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
})
|
||||
|
||||
GEN_OP(addmedot, {
|
||||
uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d2] + xer_ca - 1;
|
||||
|
||||
if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_state.gpr[code->d1] < ppc_state.gpr[code->d2])) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
})
|
||||
|
||||
GEN_OP(addmeo, {
|
||||
uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d2] + xer_ca - 1;
|
||||
|
||||
if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_state.gpr[code->d1] < ppc_state.gpr[code->d2])) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
|
||||
ppc_setsoov(ppc_state.gpr[code->d2], 0, ppc_result_d);
|
||||
})
|
||||
|
||||
GEN_OP(addmeodot, {
|
||||
uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d2] + xer_ca - 1;
|
||||
|
||||
if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_state.gpr[code->d1] < ppc_state.gpr[code->d2])) {
|
||||
ppc_state.spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
|
||||
ppc_setsoov(ppc_state.gpr[code->d2], 0, ppc_state.gpr[code->d1]);
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(subfo, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d3] - ppc_state.gpr[code->d2];
|
||||
|
||||
if ((ppc_state.gpr[code->d2] ^ ppc_state.gpr[code->d3]) &
|
||||
(ppc_state.gpr[code->d2] ^ ppc_state.gpr[code->d1]) & 0x80000000UL) {
|
||||
ppc_state.spr[SPR::XER] |= 0xC0000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
|
||||
}
|
||||
})
|
||||
|
||||
GEN_OP(subfodot, {
|
||||
ppc_state.gpr[code->d1] = ppc_state.gpr[code->d3] - ppc_state.gpr[code->d2];
|
||||
|
||||
if ((ppc_state.gpr[code->d2] ^ ppc_state.gpr[code->d3]) &
|
||||
(ppc_state.gpr[code->d2] ^ ppc_state.gpr[code->d1]) & 0x80000000UL) {
|
||||
ppc_state.spr[SPR::XER] |= 0xC0000000UL;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
|
||||
}
|
||||
|
||||
ppc_changecrf0(ppc_state.gpr[code->d1]);
|
||||
})
|
||||
|
||||
GEN_OP(lhzx, {
|
||||
ppc_effective_address = ((code->d2) ? ppc_state.gpr[code->d2] : 0) + ppc_state.gpr[code->d3];
|
||||
ppc_state.gpr[code->d1] = mem_grab_word(ppc_effective_address);
|
||||
})
|
||||
|
||||
GEN_OP(lhzux, {
|
||||
if ((code->d2 != code->d1) || code->d2 != 0) {
|
||||
ppc_effective_address = ppc_state.gpr[code->d2] + ppc_state.gpr[code->d3];
|
||||
ppc_state.gpr[code->d1] = mem_grab_word(ppc_effective_address);
|
||||
ppc_state.gpr[code->d2] = ppc_effective_address;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
GEN_OP(lhau, {
|
||||
if ((code->d2 != code->d1) || code->d2 != 0) {
|
||||
uint32_t ea = ((code->d2) ? ppc_state.gpr[code->d2] : 0) + code->simm;
|
||||
uint16_t val = mem_grab_word(ea);
|
||||
ppc_state.gpr[code->d1] = (int32_t)(int16_t)val;
|
||||
ppc_state.gpr[code->d2] = ea;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
|
||||
}
|
||||
NEXT;
|
||||
})
|
||||
|
||||
GEN_OP(lhax, {
|
||||
uint32_t ea = ((code->d2) ? ppc_state.gpr[code->d2] : 0) + ppc_state.gpr[code->d3];
|
||||
uint16_t val = mem_grab_word(ea);
|
||||
ppc_state.gpr[code->d1] = (int32_t)(int16_t)val;
|
||||
})
|
||||
|
||||
GEN_OP(sthx, {
|
||||
mem_write_word(((
|
||||
(code->d2) ? ppc_state.gpr[code->d2] : 0) + ppc_state.gpr[code->d3]),
|
||||
ppc_state.gpr[code->d1]);
|
||||
NEXT;
|
||||
})
|
||||
|
||||
GEN_OP(sthux, {
|
||||
uint32_t ea = ((code->d2) ? ppc_state.gpr[code->d2] : 0) + ppc_state.gpr[code->d3];
|
||||
mem_write_word(ea, ppc_state.gpr[code->d1]);
|
||||
ppc_state.gpr[code->d2] = ea;
|
||||
NEXT;
|
||||
})
|
||||
|
||||
GEN_OP(lfdx, {
|
||||
uint32_t ea = (reg_a > 0) ? ppc_result_a + ppc_result_b : ppc_result_b;
|
||||
uint64_t grab_flt = mem_grab_qword(ppc_effective_address);
|
||||
ppc_state.fpr[code->d1].int64_r = grab_flt;
|
||||
ppc_state.fpr[code->d1].dbl64_r = *(double*)&grab_flt;
|
||||
|
||||
})
|
||||
|
||||
GEN_OP(lfdux, {
|
||||
if (code->d2 == 0) {
|
||||
uint32_t ea = code->d1 + ppc_state.gpr[code->d3];
|
||||
uint64_t grab_flt = mem_grab_qword(ppc_effective_address);
|
||||
ppc_state.fpr[code->d1].int64_r = grab_flt;
|
||||
ppc_state.fpr[code->d1].dbl64_r = *(double*)&grab_flt;
|
||||
ppc_state.gpr[code->d2] = ppc_effective_address;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000);
|
||||
}
|
||||
})
|
||||
|
||||
GEN_OP(tlbie, {})
|
||||
|
||||
GEN_OP(lscbx, {})
|
||||
|
||||
GEN_OP(lscbxdot, {})
|
||||
|
||||
GEN_OP(dcbi, {})
|
||||
|
||||
GEN_OP(tlbsync, {})
|
||||
|
||||
GEN_OP(ppc_sync, {})
|
|
@ -9,6 +9,7 @@ enum class InstrOps {
|
|||
opNone,
|
||||
opDA,
|
||||
opDAB,
|
||||
opAB,
|
||||
opDASimm,
|
||||
opSAUimm,
|
||||
opSASh,
|
||||
|
@ -25,6 +26,8 @@ enum class InstrOps {
|
|||
opDSR,
|
||||
opDB,
|
||||
opSASimm,
|
||||
opSA,
|
||||
opSAB,
|
||||
opTOAB
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue