Implement bitwise rotation instructions.

This commit is contained in:
Skyth 2024-09-15 22:04:40 +03:00
parent 7e6b92ac6e
commit 2dd35c4611
2 changed files with 44 additions and 6 deletions

View File

@ -10,6 +10,14 @@
#define TEST_FILE "default.xex"
static uint64_t computeMask(uint32_t mstart, uint32_t mstop)
{
mstart &= 0x3F;
mstop &= 0x3F;
uint64_t value = (UINT64_MAX >> mstart) ^ ((mstop >= 63) ? 0 : UINT64_MAX >> (mstop + 1));
return mstart <= mstop ? value : ~value;
}
int main()
{
const auto file = LoadFile(TEST_FILE).value();
@ -809,8 +817,6 @@ int main()
case PPC_INST_MTMSRD:
case PPC_INST_MTXER:
case PPC_INST_MULCHWU:
case PPC_INST_MULHHW:
break;
case PPC_INST_MULHW:
@ -878,13 +884,45 @@ int main()
break;
case PPC_INST_RLDICL:
println("\tctx.r{}.u64 = _rotl64(ctx.r{}.u64, {}) & 0x{:X};", insn.operands[0], insn.operands[1], insn.operands[2], computeMask(insn.operands[3], 63));
break;
case PPC_INST_RLDICR:
println("\tctx.r{}.u64 = _rotl64(ctx.r{}.u64, {}) & 0x{:X};", insn.operands[0], insn.operands[1], insn.operands[2], computeMask(0, insn.operands[3]));
break;
case PPC_INST_RLDIMI:
{
const uint64_t mask = computeMask(insn.operands[3], ~insn.operands[1]);
println("\tctx.r{}.u64 = (_rotl64(ctx.r{}.u64, {}) & 0x{:X}) | (ctx.r{}.u64 & 0x{:X});", insn.operands[0], insn.operands[1], insn.operands[2], mask, insn.operands[0], ~mask);
break;
}
case PPC_INST_RLWIMI:
{
const uint64_t mask = computeMask(insn.operands[3] + 32, insn.operands[4] + 32);
println("\tctx.r{}.u64 = (_rotl(ctx.r{}.u32, {}) & 0x{:X}) | (ctx.r{}.u64 & 0x{:X});", insn.operands[0], insn.operands[1], insn.operands[2], mask, insn.operands[0], ~mask);
break;
}
case PPC_INST_RLWINM:
println("\tctx.r{}.u64 = _rotl(ctx.r{}.u32, {}) & 0x{:X};", insn.operands[0], insn.operands[1], insn.operands[2], computeMask(insn.operands[3] + 32, insn.operands[4] + 32));
if (insn.opcode->opcode & 0x1)
println("\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
break;
case PPC_INST_ROTLDI:
println("\tctx.r{}.u64 = _rotl64(ctx.r{}.u64, {});", insn.operands[0], insn.operands[1], insn.operands[2]);
break;
case PPC_INST_ROTLW:
println("\tctx.r{}.u64 = _rotl(ctx.r{}.u32, ctx.r{}.u8 & 0x1F);", insn.operands[0], insn.operands[1], insn.operands[2]);
break;
case PPC_INST_ROTLWI:
println("\tctx.r{}.u64 = _rotl(ctx.r{}.u32, {});", insn.operands[0], insn.operands[1], insn.operands[2]);
if (insn.opcode->opcode & 0x1)
println("\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
break;
case PPC_INST_SLD:

View File

@ -2234,10 +2234,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{ "maclhwuo.", XO(4,396,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWUO },
{ "mulchw", XRC(4,168,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHW },
{ "mulchw.", XRC(4,168,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHW },
{ "mulchwu", XRC(4,136,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU },
{ "mulchwu.", XRC(4,136,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU },
{ "mulhhw", XRC(4,40,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW },
{ "mulhhw.", XRC(4,40,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW },
//{ "mulchwu", XRC(4,136,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU },
//{ "mulchwu.", XRC(4,136,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU },
//{ "mulhhw", XRC(4,40,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW },
//{ "mulhhw.", XRC(4,40,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW },
{ "mulhhwu", XRC(4,8,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHWU },
{ "mulhhwu.", XRC(4,8,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHWU },
{ "mullhw", XRC(4,424,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULLHW },