Further DTC expansion

This commit is contained in:
dingusdev 2020-11-26 19:33:40 -07:00
parent 6356e5b4f9
commit cae2a12b71
3 changed files with 338 additions and 66 deletions

View File

@ -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);

View File

@ -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, {})

View File

@ -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
};