diff --git a/src/backend_x64/a64_emit_x64.cpp b/src/backend_x64/a64_emit_x64.cpp index 88d5f7c6..4c53f0db 100644 --- a/src/backend_x64/a64_emit_x64.cpp +++ b/src/backend_x64/a64_emit_x64.cpp @@ -164,6 +164,15 @@ void A64EmitX64::EmitA64GetX(A64EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, result); } +void A64EmitX64::EmitA64GetS(A64EmitContext& ctx, IR::Inst* inst) { + A64::Vec vec = inst->GetArg(0).GetA64VecRef(); + auto addr = qword[r15 + offsetof(A64JitState, vec) + sizeof(u64) * 2 * static_cast(vec)]; + + Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(); + code->movd(result, addr); + ctx.reg_alloc.DefineValue(inst, result); +} + void A64EmitX64::EmitA64GetD(A64EmitContext& ctx, IR::Inst* inst) { A64::Vec vec = inst->GetArg(0).GetA64VecRef(); auto addr = qword[r15 + offsetof(A64JitState, vec) + sizeof(u64) * 2 * static_cast(vec)]; diff --git a/src/frontend/A64/ir_emitter.cpp b/src/frontend/A64/ir_emitter.cpp index 458dbf94..a46515ac 100644 --- a/src/frontend/A64/ir_emitter.cpp +++ b/src/frontend/A64/ir_emitter.cpp @@ -93,6 +93,10 @@ IR::U64 IREmitter::GetX(Reg reg) { return Inst(Opcode::A64GetX, IR::Value(reg)); } +IR::U128 IREmitter::GetS(Vec vec) { + return Inst(Opcode::A64GetS, IR::Value(vec)); +} + IR::U128 IREmitter::GetD(Vec vec) { return Inst(Opcode::A64GetD, IR::Value(vec)); } @@ -117,6 +121,10 @@ void IREmitter::SetX(const Reg reg, const IR::U64& value) { Inst(Opcode::A64SetX, IR::Value(reg), value); } +void IREmitter::SetS(const Vec vec, const IR::U128& value) { + Inst(Opcode::A64SetS, IR::Value(vec), value); +} + void IREmitter::SetD(const Vec vec, const IR::U128& value) { Inst(Opcode::A64SetD, IR::Value(vec), value); } diff --git a/src/frontend/A64/ir_emitter.h b/src/frontend/A64/ir_emitter.h index 8805708f..eb76fca8 100644 --- a/src/frontend/A64/ir_emitter.h +++ b/src/frontend/A64/ir_emitter.h @@ -52,11 +52,13 @@ public: IR::U32 GetW(Reg source_reg); IR::U64 GetX(Reg source_reg); + IR::U128 GetS(Vec source_vec); IR::U128 GetD(Vec source_vec); IR::U128 GetQ(Vec source_vec); IR::U64 GetSP(); void SetW(Reg dest_reg, const IR::U32& value); void SetX(Reg dest_reg, const IR::U64& value); + void SetS(Vec dest_vec, const IR::U128& value); void SetD(Vec dest_vec, const IR::U128& value); void SetQ(Vec dest_vec, const IR::U128& value); void SetSP(const IR::U64& value); diff --git a/src/frontend/A64/translate/impl/impl.cpp b/src/frontend/A64/translate/impl/impl.cpp index efb06cdb..81973685 100644 --- a/src/frontend/A64/translate/impl/impl.cpp +++ b/src/frontend/A64/translate/impl/impl.cpp @@ -124,6 +124,8 @@ void TranslatorVisitor::SP(size_t bitsize, IR::U32U64 value) { IR::U128 TranslatorVisitor::V(size_t bitsize, Vec vec) { switch (bitsize) { + case 32: + return ir.GetS(vec); case 64: return ir.GetD(vec); case 128: @@ -135,6 +137,9 @@ IR::U128 TranslatorVisitor::V(size_t bitsize, Vec vec) { void TranslatorVisitor::V(size_t bitsize, Vec vec, IR::U128 value) { switch (bitsize) { + case 32: + ir.SetS(vec, value); + return; case 64: ir.SetD(vec, value); return; diff --git a/src/frontend/ir/microinstruction.cpp b/src/frontend/ir/microinstruction.cpp index c32e188e..e5cbb981 100644 --- a/src/frontend/ir/microinstruction.cpp +++ b/src/frontend/ir/microinstruction.cpp @@ -150,6 +150,7 @@ bool Inst::ReadsFromCoreRegister() const { case Opcode::A32GetExtendedRegister64: case Opcode::A64GetW: case Opcode::A64GetX: + case Opcode::A64GetS: case Opcode::A64GetD: case Opcode::A64GetQ: case Opcode::A64GetSP: @@ -168,6 +169,7 @@ bool Inst::WritesToCoreRegister() const { case Opcode::A32BXWritePC: case Opcode::A64SetW: case Opcode::A64SetX: + case Opcode::A64SetS: case Opcode::A64SetD: case Opcode::A64SetQ: case Opcode::A64SetSP: diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 5678d34f..71540285 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -42,7 +42,7 @@ A64OPC(GetW, T::U32, T::A64Reg A64OPC(GetX, T::U64, T::A64Reg ) //A64OPC(GetB, T::U128, T::A64Vec ) //A64OPC(GetH, T::U128, T::A64Vec ) -//A64OPC(GetS, T::U128, T::A64Vec ) +A64OPC(GetS, T::U128, T::A64Vec ) A64OPC(GetD, T::U128, T::A64Vec ) A64OPC(GetQ, T::U128, T::A64Vec ) A64OPC(GetSP, T::U64, ) @@ -50,7 +50,7 @@ A64OPC(SetW, T::Void, T::A64Reg, T::U32 A64OPC(SetX, T::Void, T::A64Reg, T::U64 ) //A64OPC(SetB, T::Void, T::A64Vec, T::U8 ) //A64OPC(SetH, T::Void, T::A64Vec, T::U16 ) -//A64OPC(SetS, T::Void, T::A64Vec, T::U32 ) +A64OPC(SetS, T::Void, T::A64Vec, T::U128 ) A64OPC(SetD, T::Void, T::A64Vec, T::U128 ) A64OPC(SetQ, T::Void, T::A64Vec, T::U128 ) A64OPC(SetSP, T::Void, T::U64 )