mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-02-04 02:51:18 +01:00
remove args, directly ref inst stuff
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <powah_emit.hpp>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
#include "dynarmic/frontend/A32/a32_types.h"
|
||||
#include "dynarmic/backend/ppc64/a32_core.h"
|
||||
#include "dynarmic/backend/ppc64/abi.h"
|
||||
#include "dynarmic/backend/ppc64/emit_context.h"
|
||||
@@ -76,13 +77,14 @@ void EmitIR<IR::Opcode::A32SetCheckBit>(powah::Context&, EmitContext&, IR::Inst*
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetRegister>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const index = ctx.reg_alloc.UseScratchGpr(args[1]);
|
||||
code.SLDI(index, index, 3);
|
||||
code.ADD(result, PPC64::RJIT, index);
|
||||
code.LD(result, result, offsetof(A32JitState, regs));
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
if (inst->GetArg(0).GetType() == IR::Type::A32Reg) {
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
code.ADDI(result, PPC64::RJIT, A32::RegNumber(inst->GetArg(0).GetA32RegRef()) * sizeof(u32));
|
||||
code.LD(result, result, offsetof(A32JitState, regs));
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
} else {
|
||||
ASSERT(false && "unimp");
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -102,13 +104,14 @@ void EmitIR<IR::Opcode::A32GetVector>(powah::Context&, EmitContext&, IR::Inst*)
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetRegister>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const index = ctx.reg_alloc.UseScratchGpr(args[1]);
|
||||
code.SLDI(index, index, 3);
|
||||
code.ADD(result, PPC64::RJIT, index);
|
||||
code.STD(result, result, offsetof(A32JitState, regs));
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
powah::GPR const value = ctx.reg_alloc.UseGpr(args[1]);
|
||||
if (inst->GetArg(0).GetType() == IR::Type::A32Reg) {
|
||||
powah::GPR const addr = ctx.reg_alloc.ScratchGpr();
|
||||
code.ADDI(addr, PPC64::RJIT, A32::RegNumber(inst->GetArg(0).GetA32RegRef()) * sizeof(u32));
|
||||
code.STD(value, addr, offsetof(A32JitState, regs));
|
||||
} else {
|
||||
ASSERT(false && "unimp");
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
|
||||
@@ -36,9 +36,8 @@ uint64_t f(uint64_t a) { return (uint16_t)a; }
|
||||
*/
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LeastSignificantHalf>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.RLWINM(result, source, 0, 0xffff);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
@@ -48,9 +47,8 @@ uint64_t f(uint64_t a) { return (uint8_t)a; }
|
||||
*/
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LeastSignificantByte>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.RLWINM(result, source, 0, 0xff);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
@@ -60,9 +58,8 @@ uint64_t f(uint64_t a) { return (uint32_t)(a >> 32); }
|
||||
*/
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MostSignificantWord>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.SRDI(result, source, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
@@ -72,9 +69,8 @@ uint64_t f(uint64_t a) { return ((uint32_t)a) >> 31; }
|
||||
*/
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MostSignificantBit>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.RLWINM(result, source, 1, 31, 31);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
@@ -84,9 +80,8 @@ uint64_t f(uint64_t a) { return a == 0; }
|
||||
*/
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::IsZero32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CNTLZD(result, source);
|
||||
code.SRDI(result, result, 6);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -97,9 +92,8 @@ uint64_t f(uint64_t a) { return (uint32_t)a == 0; }
|
||||
*/
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::IsZero64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CNTLZW(result, source);
|
||||
code.SRWI(result, result, 5);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -110,11 +104,10 @@ uint64_t f(uint64_t a) { return (a & 1) != 0; }
|
||||
*/
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::TestBit>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
if (args[1].IsImmediate()) {
|
||||
auto const shift = args[1].GetImmediateU8();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
if (inst->GetArg(1).IsImmediate()) {
|
||||
auto const shift = inst->GetArg(1).GetImmediateAsU64();
|
||||
if (shift > 0) {
|
||||
code.RLDICL(result, source, (64 - shift - 1) & 0x3f, 63);
|
||||
}
|
||||
@@ -138,11 +131,10 @@ uint64_t f(jit *p, uint64_t a, uint64_t b) {
|
||||
}
|
||||
*/
|
||||
static powah::GPR EmitConditionalSelectX(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const nzcv = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const then_ = ctx.reg_alloc.UseScratchGpr(args[1]);
|
||||
powah::GPR const else_ = ctx.reg_alloc.UseScratchGpr(args[2]);
|
||||
switch (args[0].GetImmediateCond()) {
|
||||
powah::GPR const then_ = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
powah::GPR const else_ = ctx.reg_alloc.UseGpr(args[2]);
|
||||
switch (inst->GetArg(0).GetCond()) {
|
||||
case IR::Cond::EQ: // Z == 1
|
||||
code.LD(nzcv, PPC64::RJIT, offsetof(A32JitState, cpsr_nzcv));
|
||||
code.ANDI_(nzcv, nzcv, 4);
|
||||
@@ -232,16 +224,18 @@ static powah::GPR EmitConditionalSelectX(powah::Context& code, EmitContext& ctx,
|
||||
} break;
|
||||
case IR::Cond::LE: { // Z == 1 || N != V
|
||||
powah::GPR const tmp = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const tmp2 = ctx.reg_alloc.ScratchGpr();
|
||||
powah::Label const l_ne = code.DefineLabel();
|
||||
code.MR(tmp2, then_);
|
||||
code.LD(nzcv, PPC64::RJIT, offsetof(A32JitState, cpsr_nzcv));
|
||||
code.ANDI_(tmp, nzcv, 4);
|
||||
code.BNE(powah::CR0, l_ne);
|
||||
code.SRWI(tmp, nzcv, 3);
|
||||
code.XOR(nzcv, tmp, nzcv);
|
||||
code.ANDI_(nzcv, nzcv, 1);
|
||||
code.ISELGT(then_, then_, else_);
|
||||
code.ISELGT(tmp2, then_, else_);
|
||||
code.LABEL(l_ne);
|
||||
code.MR(nzcv, then_);
|
||||
code.MR(nzcv, tmp2);
|
||||
} break;
|
||||
default:
|
||||
ASSERT(false && "unimp");
|
||||
@@ -271,10 +265,9 @@ void EmitIR<IR::Opcode::ConditionalSelectNZCV>(powah::Context& code, EmitContext
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeft32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.SLW(result, source, shift);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -282,20 +275,18 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(powah::Context& code, EmitContext& c
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeft64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.SLD(result, source, shift);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRight32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.SRW(result, source, shift);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -306,20 +297,18 @@ uint64_t f(uint64_t a, uint64_t s) { return a >> s; }
|
||||
*/
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRight64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.SRD(result, source, shift);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRight32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.SRAW(result, source, shift);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -327,10 +316,9 @@ void EmitIR<IR::Opcode::ArithmeticShiftRight32>(powah::Context& code, EmitContex
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRight64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const shift = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.SRAD(result, source, shift);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
@@ -338,10 +326,9 @@ void EmitIR<IR::Opcode::ArithmeticShiftRight64>(powah::Context& code, EmitContex
|
||||
// __builtin_rotateright32
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRight32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.NEG(result, src_a, powah::R0);
|
||||
code.ROTLW(result, result, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
@@ -350,10 +337,9 @@ void EmitIR<IR::Opcode::RotateRight32>(powah::Context& code, EmitContext& ctx, I
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRight64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.NEG(result, src_a, powah::R0);
|
||||
code.ROTLD(result, result, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -361,10 +347,9 @@ void EmitIR<IR::Opcode::RotateRight64>(powah::Context& code, EmitContext& ctx, I
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightExtended>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.NEG(result, src_a, powah::R0);
|
||||
code.ROTLD(result, result, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -372,9 +357,8 @@ void EmitIR<IR::Opcode::RotateRightExtended>(powah::Context& code, EmitContext&
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeftMasked32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.SLW(result, source, source);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -382,18 +366,16 @@ void EmitIR<IR::Opcode::LogicalShiftLeftMasked32>(powah::Context& code, EmitCont
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeftMasked64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.SLD(result, source, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRightMasked32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.SRW(result, source, source);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -401,18 +383,16 @@ void EmitIR<IR::Opcode::LogicalShiftRightMasked32>(powah::Context& code, EmitCon
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRightMasked64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.SRD(result, source, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.SRAW(result, source, source);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -420,19 +400,17 @@ void EmitIR<IR::Opcode::ArithmeticShiftRightMasked32>(powah::Context& code, Emit
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.SRAD(result, source, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightMasked32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.NEG(result, src_a, powah::R0);
|
||||
code.ROTLD(result, result, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
@@ -441,10 +419,9 @@ void EmitIR<IR::Opcode::RotateRightMasked32>(powah::Context& code, EmitContext&
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightMasked64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.NEG(result, src_a, powah::R0);
|
||||
code.ROTLD(result, result, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -452,10 +429,9 @@ void EmitIR<IR::Opcode::RotateRightMasked64>(powah::Context& code, EmitContext&
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Add32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.ADD(result, src_a, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -463,20 +439,18 @@ void EmitIR<IR::Opcode::Add32>(powah::Context& code, EmitContext& ctx, IR::Inst*
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Add64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.ADD(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Sub32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.SUBF(result, src_b, src_a);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -484,20 +458,18 @@ void EmitIR<IR::Opcode::Sub32>(powah::Context& code, EmitContext& ctx, IR::Inst*
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Sub64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.SUBF(result, src_b, src_a);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Mul32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.MULLW(result, src_a, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -505,40 +477,36 @@ void EmitIR<IR::Opcode::Mul32>(powah::Context& code, EmitContext& ctx, IR::Inst*
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Mul64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.MULLD(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedMultiplyHigh64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.MULLD(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedMultiplyHigh64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.MULLD(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedDiv32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.DIVDU(result, src_a, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -546,20 +514,18 @@ void EmitIR<IR::Opcode::UnsignedDiv32>(powah::Context& code, EmitContext& ctx, I
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedDiv64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.DIVDU(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedDiv32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.DIVW(result, src_a, src_b);
|
||||
code.EXTSW(result, result);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -567,40 +533,36 @@ void EmitIR<IR::Opcode::SignedDiv32>(powah::Context& code, EmitContext& ctx, IR:
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedDiv64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.DIVD(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::And32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.AND(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::And64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.AND(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AndNot32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.NAND(result, src_a, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -608,20 +570,18 @@ void EmitIR<IR::Opcode::AndNot32>(powah::Context& code, EmitContext& ctx, IR::In
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AndNot64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.NAND(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Eor32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.XOR(result, src_a, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -629,20 +589,18 @@ void EmitIR<IR::Opcode::Eor32>(powah::Context& code, EmitContext& ctx, IR::Inst*
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Eor64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.XOR(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Or32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.OR(result, src_a, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -650,19 +608,17 @@ void EmitIR<IR::Opcode::Or32>(powah::Context& code, EmitContext& ctx, IR::Inst*
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Or64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[1]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.OR(result, src_a, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Not32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.NOT(result, source);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -670,18 +626,16 @@ void EmitIR<IR::Opcode::Not32>(powah::Context& code, EmitContext& ctx, IR::Inst*
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Not64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.NOT(result, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendByteToWord>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.EXTSB(result, source);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -689,9 +643,8 @@ void EmitIR<IR::Opcode::SignExtendByteToWord>(powah::Context& code, EmitContext&
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendHalfToWord>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.EXTSH(result, source);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -699,36 +652,32 @@ void EmitIR<IR::Opcode::SignExtendHalfToWord>(powah::Context& code, EmitContext&
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendByteToLong>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.EXTSH(result, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendHalfToLong>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.EXTSB(result, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendWordToLong>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.EXTSW(result, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendByteToWord>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.RLWINM(result, source, 0, 0xff);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -736,9 +685,8 @@ void EmitIR<IR::Opcode::ZeroExtendByteToWord>(powah::Context& code, EmitContext&
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendHalfToWord>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.RLWINM(result, source, 0, 0xffff);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -746,28 +694,25 @@ void EmitIR<IR::Opcode::ZeroExtendHalfToWord>(powah::Context& code, EmitContext&
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendByteToLong>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.RLWINM(result, source, 0, 0xff);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendHalfToLong>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.RLWINM(result, source, 0, 0xffff);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendWordToLong>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.RLDICL(result, source, 0, 32);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
@@ -779,9 +724,8 @@ void EmitIR<IR::Opcode::ZeroExtendLongToQuad>(powah::Context& code, EmitContext&
|
||||
// __builtin_bswap32
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseWord>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
if (false) {
|
||||
//code.BRW(result, source);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
@@ -795,9 +739,8 @@ void EmitIR<IR::Opcode::ByteReverseWord>(powah::Context& code, EmitContext& ctx,
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseHalf>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
if (false) {
|
||||
//code.BRH(result, source);
|
||||
code.RLWINM(result, source, 0, 0xff);
|
||||
@@ -811,9 +754,8 @@ void EmitIR<IR::Opcode::ByteReverseHalf>(powah::Context& code, EmitContext& ctx,
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseDual>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
if (false) {
|
||||
//code.BRD(result, source);
|
||||
} else {
|
||||
@@ -837,9 +779,8 @@ void EmitIR<IR::Opcode::ByteReverseDual>(powah::Context& code, EmitContext& ctx,
|
||||
// __builtin_clz
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CountLeadingZeros32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CNTLZW(result, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
@@ -847,9 +788,8 @@ void EmitIR<IR::Opcode::CountLeadingZeros32>(powah::Context& code, EmitContext&
|
||||
// __builtin_clz
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CountLeadingZeros64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CNTLZD(result, source);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
@@ -876,10 +816,9 @@ void EmitIR<IR::Opcode::ReplicateBit64>(powah::Context& code, EmitContext& ctx,
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxSigned32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CMPD(powah::CR0, result, src_a);
|
||||
code.ISELGT(result, result, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
@@ -888,10 +827,9 @@ void EmitIR<IR::Opcode::MaxSigned32>(powah::Context& code, EmitContext& ctx, IR:
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxSigned64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CMPD(powah::CR0, result, src_a);
|
||||
code.ISELGT(result, result, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -899,10 +837,9 @@ void EmitIR<IR::Opcode::MaxSigned64>(powah::Context& code, EmitContext& ctx, IR:
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxUnsigned32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CMPLW(result, src_a);
|
||||
code.ISELGT(result, result, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
@@ -911,10 +848,9 @@ void EmitIR<IR::Opcode::MaxUnsigned32>(powah::Context& code, EmitContext& ctx, I
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxUnsigned64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CMPLD(result, src_a);
|
||||
code.ISELGT(result, result, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -922,10 +858,9 @@ void EmitIR<IR::Opcode::MaxUnsigned64>(powah::Context& code, EmitContext& ctx, I
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinSigned32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CMPW(powah::CR0, result, src_a);
|
||||
code.ISELGT(result, result, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
@@ -934,10 +869,9 @@ void EmitIR<IR::Opcode::MinSigned32>(powah::Context& code, EmitContext& ctx, IR:
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinSigned64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CMPD(powah::CR0, result, src_a);
|
||||
code.ISELGT(result, result, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
@@ -945,10 +879,9 @@ void EmitIR<IR::Opcode::MinSigned64>(powah::Context& code, EmitContext& ctx, IR:
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinUnsigned32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CMPLW(result, src_a);
|
||||
code.ISELGT(result, result, src_b);
|
||||
code.RLDICL(result, result, 0, 32);
|
||||
@@ -957,10 +890,9 @@ void EmitIR<IR::Opcode::MinUnsigned32>(powah::Context& code, EmitContext& ctx, I
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinUnsigned64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
powah::GPR const result = ctx.reg_alloc.ScratchGpr();
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(args[0]);
|
||||
powah::GPR const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
powah::GPR const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
code.CMPLD(result, src_a);
|
||||
code.ISELGT(result, result, src_b);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
|
||||
@@ -31,46 +31,28 @@ void HostLocInfo::UpdateUses() {
|
||||
}
|
||||
}
|
||||
|
||||
RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
||||
ArgumentInfo ret = {Argument{*this}, Argument{*this}, Argument{*this}, Argument{*this}};
|
||||
for (size_t i = 0; i < inst->NumArgs(); i++) {
|
||||
const IR::Value arg = inst->GetArg(i);
|
||||
ret[i].value = arg;
|
||||
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
|
||||
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
|
||||
ValueInfo(arg.GetInst()).uses_this_inst++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RegAlloc::IsValueLive(IR::Inst* inst) const {
|
||||
return !!ValueLocation(inst);
|
||||
}
|
||||
|
||||
void RegAlloc::UpdateAllUses() {
|
||||
for (auto& gpr : gprs) {
|
||||
for (auto& gpr : gprs)
|
||||
gpr.UpdateUses();
|
||||
}
|
||||
for (auto& fpr : fprs) {
|
||||
for (auto& fpr : fprs)
|
||||
fpr.UpdateUses();
|
||||
}
|
||||
for (auto& spill : spills) {
|
||||
for (auto& spill : spills)
|
||||
spill.UpdateUses();
|
||||
}
|
||||
}
|
||||
|
||||
void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
|
||||
void RegAlloc::DefineAsExisting(IR::Inst* inst, IR::Value arg) {
|
||||
ASSERT(!ValueLocation(inst));
|
||||
|
||||
if (arg.value.IsImmediate()) {
|
||||
inst->ReplaceUsesWith(arg.value);
|
||||
return;
|
||||
if (arg.IsImmediate()) {
|
||||
inst->ReplaceUsesWith(arg);
|
||||
} else {
|
||||
auto& info = ValueInfo(arg.GetInst());
|
||||
info.values.emplace_back(inst);
|
||||
info.expected_uses += inst->UseCount();
|
||||
}
|
||||
|
||||
auto& info = ValueInfo(arg.value.GetInst());
|
||||
info.values.emplace_back(inst);
|
||||
info.expected_uses += inst->UseCount();
|
||||
}
|
||||
|
||||
void RegAlloc::AssertNoMoreUses() const {
|
||||
@@ -129,8 +111,17 @@ std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static powah::GPR HostLocToReg(HostLoc h) noexcept {
|
||||
if (u8(h) >= u8(HostLoc::R0) && u8(h) <= u8(HostLoc::R31))
|
||||
inline bool HostLocIsGpr(HostLoc h) noexcept {
|
||||
return u8(h) >= u8(HostLoc::R0) && u8(h) <= u8(HostLoc::R31);
|
||||
}
|
||||
inline bool HostLocIsFpr(HostLoc h) noexcept {
|
||||
return u8(h) >= u8(HostLoc::FR0) && u8(h) <= u8(HostLoc::FR31);
|
||||
}
|
||||
inline bool HostLocIsVpr(HostLoc h) noexcept {
|
||||
return u8(h) >= u8(HostLoc::VR0) && u8(h) <= u8(HostLoc::VR31);
|
||||
}
|
||||
inline std::variant<powah::GPR, powah::FPR> HostLocToReg(HostLoc h) noexcept {
|
||||
if (HostLocIsGpr(h))
|
||||
return powah::GPR{uint32_t(h)};
|
||||
ASSERT(false && "unimp");
|
||||
}
|
||||
@@ -160,21 +151,30 @@ HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
|
||||
ASSERT(false && "unimp");
|
||||
}
|
||||
|
||||
/// @brief Defines a register temporal to use (and locks it)
|
||||
powah::GPR RegAlloc::ScratchGpr() {
|
||||
auto const r = AllocateRegister(gprs, PPC64::GPR_ORDER);
|
||||
return powah::GPR{*r};
|
||||
}
|
||||
|
||||
powah::GPR RegAlloc::UseGpr(Argument& arg) {
|
||||
ASSERT(!arg.allocated);
|
||||
arg.allocated = true;
|
||||
return ScratchGpr();
|
||||
}
|
||||
|
||||
powah::GPR RegAlloc::UseScratchGpr(Argument& arg) {
|
||||
ASSERT(!arg.allocated);
|
||||
arg.allocated = true;
|
||||
return ScratchGpr();
|
||||
/// @brief Uses the given GPR of the argument
|
||||
powah::GPR RegAlloc::UseGpr(IR::Value arg) {
|
||||
if (arg.IsImmediate()) {
|
||||
// HOLY SHIT EVIL HAXX
|
||||
auto const reg = ScratchGpr();
|
||||
auto const imm = arg.GetImmediateAsU64();
|
||||
if (imm >= 0xffff) {
|
||||
ASSERT(false && "big imms");
|
||||
} else {
|
||||
code.LI(reg, imm);
|
||||
}
|
||||
return reg;
|
||||
} else {
|
||||
ASSERT(arg.allocated && "undefined (non-imm) arg");
|
||||
auto const loc = ValueLocation(arg.GetInst());
|
||||
ASSERT(loc && HostLocIsGpr(*loc));
|
||||
return std::get<powah::GPR>(HostLocToReg(*loc));
|
||||
}
|
||||
}
|
||||
|
||||
void RegAlloc::DefineValue(IR::Inst* inst, powah::GPR const gpr) noexcept {
|
||||
@@ -182,22 +182,22 @@ void RegAlloc::DefineValue(IR::Inst* inst, powah::GPR const gpr) noexcept {
|
||||
ValueInfo(HostLoc(gpr.index)).values.push_back(inst);
|
||||
}
|
||||
|
||||
void RegAlloc::DefineValue(IR::Inst* inst, Argument& arg) noexcept {
|
||||
void RegAlloc::DefineValue(IR::Inst* inst, IR::Value arg) noexcept {
|
||||
ASSERT(!ValueLocation(inst) && "inst has already been defined");
|
||||
ASSERT(!arg.allocated);
|
||||
arg.allocated = true;
|
||||
ASSERT(!ValueLocation(inst) && "inst has already been defined");
|
||||
if (arg.value.IsImmediate()) {
|
||||
if (arg.IsImmediate()) {
|
||||
HostLoc const loc{u8(ScratchGpr().index)};
|
||||
ValueInfo(loc).values.push_back(inst);
|
||||
auto const value = arg.value.GetImmediateAsU64();
|
||||
auto const value = arg.GetImmediateAsU64();
|
||||
if (value >= 0x7fff) {
|
||||
ASSERT(false && "unimp");
|
||||
} else {
|
||||
//code.LI(HostLocToReg(loc), value);
|
||||
}
|
||||
} else {
|
||||
ASSERT(ValueLocation(arg.value.GetInst()) && "arg.value must already be defined");
|
||||
const HostLoc loc = *ValueLocation(arg.value.GetInst());
|
||||
ASSERT(ValueLocation(arg.GetInst()) && "arg must already be defined");
|
||||
const HostLoc loc = *ValueLocation(arg.GetInst());
|
||||
ValueInfo(loc).values.push_back(inst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,59 +24,14 @@ namespace Dynarmic::Backend::PPC64 {
|
||||
|
||||
class RegAlloc;
|
||||
|
||||
struct Argument {
|
||||
public:
|
||||
IR::Type GetType() const {
|
||||
return value.GetType();
|
||||
}
|
||||
bool IsImmediate() const {
|
||||
return value.IsImmediate();
|
||||
}
|
||||
bool GetImmediateU1() const {
|
||||
return value.GetU1();
|
||||
}
|
||||
u8 GetImmediateU8() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x100);
|
||||
return u8(imm);
|
||||
}
|
||||
u16 GetImmediateU16() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x10000);
|
||||
return u16(imm);
|
||||
}
|
||||
u32 GetImmediateU32() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x100000000);
|
||||
return u32(imm);
|
||||
}
|
||||
u64 GetImmediateU64() const {
|
||||
return value.GetImmediateAsU64();
|
||||
}
|
||||
IR::Cond GetImmediateCond() const {
|
||||
ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
|
||||
return value.GetCond();
|
||||
}
|
||||
IR::AccType GetImmediateAccType() const {
|
||||
ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
|
||||
return value.GetAccType();
|
||||
}
|
||||
private:
|
||||
friend class RegAlloc;
|
||||
explicit Argument(RegAlloc& reg_alloc) : reg_alloc{reg_alloc} {}
|
||||
RegAlloc& reg_alloc;
|
||||
IR::Value value;
|
||||
bool allocated = false;
|
||||
};
|
||||
|
||||
struct HostLocInfo final {
|
||||
std::vector<const IR::Inst*> values;
|
||||
size_t locked = 0;
|
||||
size_t uses_this_inst = 0;
|
||||
size_t accumulated_uses = 0;
|
||||
size_t expected_uses = 0;
|
||||
/// @brief Lock usage of this register UNTIL a DefineValue() is issued
|
||||
bool locked = false;
|
||||
bool realized = false;
|
||||
|
||||
bool Contains(const IR::Inst* value) const {
|
||||
return std::find(values.begin(), values.end(), value) != values.end();
|
||||
}
|
||||
@@ -98,17 +53,16 @@ public:
|
||||
|
||||
ArgumentInfo GetArgumentInfo(IR::Inst* inst);
|
||||
bool IsValueLive(IR::Inst* inst) const;
|
||||
void DefineAsExisting(IR::Inst* inst, Argument& arg);
|
||||
void DefineAsExisting(IR::Inst* inst, IR::Value arg);
|
||||
|
||||
void SpillAll();
|
||||
void UpdateAllUses();
|
||||
void AssertNoMoreUses() const;
|
||||
|
||||
powah::GPR ScratchGpr();
|
||||
powah::GPR UseGpr(Argument& arg);
|
||||
powah::GPR UseScratchGpr(Argument& arg);
|
||||
powah::GPR UseGpr(IR::Value arg);
|
||||
void DefineValue(IR::Inst* inst, powah::GPR const gpr) noexcept;
|
||||
void DefineValue(IR::Inst* inst, Argument& arg) noexcept;
|
||||
void DefineValue(IR::Inst* inst, IR::Value arg) noexcept;
|
||||
private:
|
||||
std::optional<u32> AllocateRegister(const std::array<HostLocInfo, 32>& regs, const std::vector<u32>& order) const;
|
||||
void SpillGpr(u32 index);
|
||||
|
||||
Reference in New Issue
Block a user