diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64.cpp index 254b69ffe..6ac901991 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64.cpp @@ -22,12 +22,12 @@ static void EmitCondition(EmitContext& ctx, const IR::Inst* ref, Label& label, b ctx.Code().jmp(label); } } else { - const Operand& op = ctx.Def(cond.InstRecursive())[0]; - if (op.isREG()) { - Reg8 reg = op.getReg().cvt8(); + const OperandHolder& op = ctx.Def(cond.InstRecursive())[0]; + if (op.IsReg()) { + Reg8 reg = op.Reg().cvt8(); ctx.Code().test(reg, reg); } else { - ctx.Code().test(op, 0xff); + ctx.Code().test(op.Mem(), 0xff); } if (invert) { ctx.Code().jz(label); diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_bitwise_conversion.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_bitwise_conversion.cpp index 0a4ecc96b..751a78475 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_bitwise_conversion.cpp @@ -16,23 +16,23 @@ void EmitBitCastU16F16(EmitContext& ctx, const Operands& dest, const Operands& s } void EmitBitCastU32F32(EmitContext& ctx, const Operands& dest, const Operands& src) { - if (src[0].isMEM()) { + if (src[0].IsMem()) { MovGP(ctx, dest[0], src[0]); - } else if (dest[0].isMEM()) { - ctx.Code().movd(dest[0].getAddress(), src[0].getReg().cvt128()); + } else if (dest[0].IsMem()) { + ctx.Code().movd(dest[0].Mem(), src[0].Xmm()); } else { - ctx.Code().movd(dword[rsp - 4], src[0].getReg().cvt128()); + ctx.Code().movd(dword[rsp - 4], src[0].Xmm()); MovGP(ctx, dest[0], dword[rsp - 4]); } } void EmitBitCastU64F64(EmitContext& ctx, const Operands& dest, const Operands& src) { - if (src[0].isMEM()) { + if (src[0].IsMem()) { MovGP(ctx, dest[0], src[0]); - } else if (dest[0].isMEM()) { - ctx.Code().movq(dest[0].getAddress(), src[0].getReg().cvt128()); + } else if (dest[0].IsMem()) { + ctx.Code().movq(dest[0].Mem(), src[0].Xmm()); } else { - ctx.Code().movq(qword[rsp - 8], src[0].getReg().cvt128()); + ctx.Code().movq(qword[rsp - 8], src[0].Xmm()); MovGP(ctx, dest[0], qword[rsp - 8]); } } @@ -42,40 +42,40 @@ void EmitBitCastF16U16(EmitContext& ctx, const Operands& dest, const Operands& s } void EmitBitCastF32U32(EmitContext& ctx, const Operands& dest, const Operands& src) { - if (dest[0].isMEM()) { + if (dest[0].IsMem()) { MovGP(ctx, dest[0], src[0]); - } else if (src[0].isMEM()) { - ctx.Code().movd(dest[0].getReg().cvt128(), src[0].getAddress()); + } else if (src[0].IsMem()) { + ctx.Code().movd(dest[0].Xmm(), src[0].Mem()); } else { MovGP(ctx, dword[rsp - 4], src[0]); - ctx.Code().movd(dest[0].getReg().cvt128(), dword[rsp - 4]); + ctx.Code().movd(dest[0].Xmm(), dword[rsp - 4]); } } void EmitBitCastF64U64(EmitContext& ctx, const Operands& dest, const Operands& src) { - if (dest[0].isMEM()) { + if (dest[0].IsMem()) { MovGP(ctx, dest[0], src[0]); - } else if (src[0].isMEM()) { - ctx.Code().movq(dest[0].getReg().cvt128(), src[0].getAddress()); + } else if (src[0].IsMem()) { + ctx.Code().movq(dest[0].Xmm(), src[0].Mem()); } else { MovGP(ctx, qword[rsp - 8], src[0]); - ctx.Code().mov(dest[0].getReg().cvt128(), qword[rsp - 8]); + ctx.Code().mov(dest[0].Xmm(), qword[rsp - 8]); } } void EmitPackUint2x32(EmitContext& ctx, const Operands& dest, const Operands& src) { - const bool is_mem = dest[0].isMEM() && (src[0].isMEM() || src[1].isMEM()); - Reg tmp = is_mem ? ctx.TempGPReg() : dest[0].getReg(); + const bool is_mem = dest[0].IsMem() && (src[0].IsMem() || src[1].IsMem()); + Reg tmp = is_mem ? ctx.TempGPReg() : dest[0].Reg(); MovGP(ctx, tmp, src[1]); ctx.Code().shl(tmp, 32); - ctx.Code().or_(tmp, src[0]); + ctx.Code().or_(tmp, src[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitUnpackUint2x32(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg src0 = src[0].isMEM() ? ctx.TempGPReg() : src[0].getReg(); + Reg src0 = src[0].IsMem() ? ctx.TempGPReg() : src[0].Reg(); MovGP(ctx, src0, src[0]); - Reg dest1 = dest[1].isMEM() ? ctx.TempGPReg() : dest[1].getReg().changeBit(64); + Reg dest1 = dest[1].IsMem() ? ctx.TempGPReg() : dest[1].Reg().changeBit(64); MovGP(ctx, dest1, src0); ctx.Code().shr(dest1, 32); MovGP(ctx, dest[1], dest1); @@ -83,9 +83,9 @@ void EmitUnpackUint2x32(EmitContext& ctx, const Operands& dest, const Operands& } void EmitPackFloat2x32(EmitContext& ctx, const Operands& dest, const Operands& src) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, src[0]); - ctx.Code().pinsrd(tmp, src[1], 1); + ctx.Code().pinsrd(tmp, src[1].Op(), 1); MovFloat(ctx, dest[0], tmp); } diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_composite.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_composite.cpp index 2421553bd..1c7dd4730 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_composite.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_composite.cpp @@ -12,7 +12,7 @@ using namespace Xbyak::util; namespace { template -static const Operand& GetSuffleOperand(const Operands& comp1, const Operands& comp2, u32 index) { +static const OperandHolder& GetSuffleOperand(const Operands& comp1, const Operands& comp2, u32 index) { if (index < N) { return comp1[index]; } else { diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_context_get_set.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_context_get_set.cpp index 1eea0e7ee..f097d68ae 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_context_get_set.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_context_get_set.cpp @@ -61,11 +61,11 @@ void EmitReadConst(EmitContext& ctx, const Operands& dest, const Operands& base, Reg& tmp = ctx.TempGPReg(); MovGP(ctx, tmp, base[1]); ctx.Code().shl(tmp, 32); - ctx.Code().or_(tmp, base[0]); - if (offset[0].isMEM()) { - ctx.Code().add(tmp, offset[0]); + ctx.Code().or_(tmp, base[0].Op()); + if (offset[0].IsMem()) { + ctx.Code().add(tmp, offset[0].Mem()); } else { - ctx.Code().lea(tmp, ptr[tmp + offset[0].getReg().cvt64()]); + ctx.Code().lea(tmp, ptr[tmp + offset[0].Reg().cvt64()]); } MovGP(ctx, dest[0], dword[tmp]); } diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_convert.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_convert.cpp index 48ebf4fa5..69fc004d9 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_convert.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_convert.cpp @@ -11,64 +11,64 @@ using namespace Xbyak::util; void EmitConvertS16F16(EmitContext& ctx, const Operands& dest, const Operands& src) { Xmm tmp_xmm = ctx.TempXmmReg(); - Reg tmp_reg = dest[0].isMEM() ? ctx.TempGPReg().cvt32() : dest[0].getReg().cvt32(); - EmitInlineF16ToF32(ctx, tmp_xmm, src[0]); + Reg tmp_reg = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg().cvt32(); + EmitInlineF16ToF32(ctx, tmp_xmm, src[0].Op()); ctx.Code().cvttss2si(tmp_reg, tmp_xmm); ctx.Code().and_(tmp_reg, 0xFFFF); MovGP(ctx, dest[0], tmp_reg); } void EmitConvertS16F32(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt32() : dest[0].getReg().cvt32(); - ctx.Code().cvttss2si(tmp, src[0]); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg().cvt32(); + ctx.Code().cvttss2si(tmp, src[0].Op()); ctx.Code().and_(tmp, 0xFFFF); MovGP(ctx, dest[0], tmp); } void EmitConvertS16F64(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt32() : dest[0].getReg().cvt32(); - ctx.Code().cvttsd2si(tmp, src[0]); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg().cvt32(); + ctx.Code().cvttsd2si(tmp, src[0].Op()); ctx.Code().and_(tmp, 0xFFFF); MovGP(ctx, dest[0], tmp); } void EmitConvertS32F16(EmitContext& ctx, const Operands& dest, const Operands& src) { Xmm tmp_xmm = ctx.TempXmmReg(); - Reg tmp_reg = dest[0].isMEM() ? ctx.TempGPReg().cvt32() : dest[0].getReg().cvt32(); - EmitInlineF16ToF32(ctx, tmp_xmm, src[0]); + Reg tmp_reg = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); + EmitInlineF16ToF32(ctx, tmp_xmm, src[0].Op()); ctx.Code().cvttss2si(tmp_reg, tmp_xmm); MovGP(ctx, dest[0], tmp_reg); } void EmitConvertS32F32(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt32() : dest[0].getReg().cvt32(); - ctx.Code().cvttss2si(tmp, src[0]); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); + ctx.Code().cvttss2si(tmp, src[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitConvertS32F64(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt32() : dest[0].getReg().cvt32(); - ctx.Code().cvttsd2si(tmp, src[0]); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); + ctx.Code().cvttsd2si(tmp, src[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitConvertS64F16(EmitContext& ctx, const Operands& dest, const Operands& src) { Xmm tmp_xmm = ctx.TempXmmReg(); - Reg tmp_reg = dest[0].isMEM() ? ctx.TempGPReg() : dest[0].getReg(); - EmitInlineF16ToF32(ctx, tmp_xmm, src[0]); + Reg tmp_reg = dest[0].IsMem() ? ctx.TempGPReg() : dest[0].Reg(); + EmitInlineF16ToF32(ctx, tmp_xmm, src[0].Op()); ctx.Code().cvttss2si(tmp_reg, tmp_xmm); MovGP(ctx, dest[0], tmp_reg); } void EmitConvertS64F32(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg() : dest[0].getReg(); - ctx.Code().cvttss2si(tmp, src[0]); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg() : dest[0].Reg(); + ctx.Code().cvttss2si(tmp, src[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitConvertS64F64(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg() : dest[0].getReg(); - ctx.Code().cvttsd2si(tmp, src[0]); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg() : dest[0].Reg(); + ctx.Code().cvttsd2si(tmp, src[0].Op()); MovGP(ctx, dest[0], tmp); } @@ -117,51 +117,51 @@ void EmitConvertU32U64(EmitContext& ctx, const Operands& dest, const Operands& s } void EmitConvertF16F32(EmitContext& ctx, const Operands& dest, const Operands& src) { - EmitInlineF32ToF16(ctx, dest[0], src[0]); + EmitInlineF32ToF16(ctx, dest[0].Op(), src[0].Op()); } void EmitConvertF32F16(EmitContext& ctx, const Operands& dest, const Operands& src) { - EmitInlineF16ToF32(ctx, dest[0], src[0]); + EmitInlineF16ToF32(ctx, dest[0].Op(), src[0].Op()); } void EmitConvertF32F64(EmitContext& ctx, const Operands& dest, const Operands& src) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().cvtsd2ss(tmp, src[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().cvtsd2ss(tmp, src[0].Op()); MovFloat(ctx, dest[0], tmp); } void EmitConvertF64F32(EmitContext& ctx, const Operands& dest, const Operands& src) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().cvtss2sd(tmp, src[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().cvtss2sd(tmp, src[0].Op()); MovDouble(ctx, dest[0], tmp); } void EmitConvertF16S8(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp_reg = dest[0].isMEM() ? ctx.TempGPReg().cvt32() : dest[0].getReg().cvt32(); + Reg tmp_reg = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg().cvt32(); Xmm tmp_xmm = ctx.TempXmmReg(); - ctx.Code().movsx(tmp_reg, src[0]); + MovGP(ctx, tmp_reg, src[0]); ctx.Code().cvtsi2ss(tmp_xmm, tmp_reg); - EmitInlineF32ToF16(ctx, dest[0], tmp_xmm); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp_xmm); } void EmitConvertF16S16(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp_reg = dest[0].isMEM() ? ctx.TempGPReg().cvt32() : dest[0].getReg().cvt32(); + Reg tmp_reg = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg().cvt32(); Xmm tmp_xmm = ctx.TempXmmReg(); - ctx.Code().movsx(tmp_reg, src[0]); + MovGP(ctx, tmp_reg, src[0]); ctx.Code().cvtsi2ss(tmp_xmm, tmp_reg); - EmitInlineF32ToF16(ctx, dest[0], tmp_xmm); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp_xmm); } void EmitConvertF16S32(EmitContext& ctx, const Operands& dest, const Operands& src) { Xmm tmp = ctx.TempXmmReg(); - ctx.Code().cvtsi2ss(tmp, src[0]); - EmitInlineF32ToF16(ctx, dest[0], tmp); + ctx.Code().cvtsi2ss(tmp, src[0].Op()); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp); } void EmitConvertF16S64(EmitContext& ctx, const Operands& dest, const Operands& src) { Xmm tmp = ctx.TempXmmReg(); - ctx.Code().cvtsi2ss(tmp, src[0]); - EmitInlineF32ToF16(ctx, dest[0], tmp); + ctx.Code().cvtsi2ss(tmp, src[0].Op()); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp); } void EmitConvertF16U8(EmitContext& ctx, const Operands& dest, const Operands& src) { @@ -182,29 +182,29 @@ void EmitConvertF16U64(EmitContext& ctx, const Operands& dest, const Operands& s void EmitConvertF32S8(EmitContext& ctx, const Operands& dest, const Operands& src) { Reg tmp_reg = ctx.TempGPReg().cvt32(); - Xmm tmp_xmm = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().movsx(tmp_reg, src[0]); + Xmm tmp_xmm = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + MovGP(ctx, tmp_reg, src[0]); ctx.Code().cvtsi2ss(tmp_xmm, tmp_reg); MovFloat(ctx, dest[0], tmp_xmm); } void EmitConvertF32S16(EmitContext& ctx, const Operands& dest, const Operands& src) { Reg tmp_reg = ctx.TempGPReg().cvt32(); - Xmm tmp_xmm = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().movsx(tmp_reg, src[0]); + Xmm tmp_xmm = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + MovGP(ctx, tmp_reg, src[0]); ctx.Code().cvtsi2ss(tmp_xmm, tmp_reg); MovFloat(ctx, dest[0], tmp_xmm); } void EmitConvertF32S32(EmitContext& ctx, const Operands& dest, const Operands& src) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().cvtsi2ss(tmp, src[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().cvtsi2ss(tmp, src[0].Op()); MovFloat(ctx, dest[0], tmp); } void EmitConvertF32S64(EmitContext& ctx, const Operands& dest, const Operands& src) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().cvtsi2ss(tmp, src[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().cvtsi2ss(tmp, src[0].Op()); MovFloat(ctx, dest[0], tmp); } @@ -226,29 +226,29 @@ void EmitConvertF32U64(EmitContext& ctx, const Operands& dest, const Operands& s void EmitConvertF64S8(EmitContext& ctx, const Operands& dest, const Operands& src) { Reg tmp_reg = ctx.TempGPReg().cvt32(); - Xmm tmp_xmm = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().movsx(tmp_reg, src[0]); + Xmm tmp_xmm = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + MovGP(ctx, tmp_reg, src[0]); ctx.Code().cvtsi2sd(tmp_xmm, tmp_reg); MovDouble(ctx, dest[0], tmp_xmm); } void EmitConvertF64S16(EmitContext& ctx, const Operands& dest, const Operands& src) { Reg tmp_reg = ctx.TempGPReg().cvt32(); - Xmm tmp_xmm = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().movsx(tmp_reg, src[0]); + Xmm tmp_xmm = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + MovGP(ctx, tmp_reg, src[0]); ctx.Code().cvtsi2sd(tmp_xmm, tmp_reg); MovDouble(ctx, dest[0], tmp_xmm); } void EmitConvertF64S32(EmitContext& ctx, const Operands& dest, const Operands& src) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().cvtsi2sd(tmp, src[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().cvtsi2sd(tmp, src[0].Op()); MovDouble(ctx, dest[0], tmp); } void EmitConvertF64S64(EmitContext& ctx, const Operands& dest, const Operands& src) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().cvtsi2sd(tmp, src[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().cvtsi2sd(tmp, src[0].Op()); MovDouble(ctx, dest[0], tmp); } diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_floating_point.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_floating_point.cpp index 588b1ed2d..2a048dbcb 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_floating_point.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_floating_point.cpp @@ -13,57 +13,55 @@ using namespace Xbyak::util; void EmitFPAbs16(EmitContext& ctx, const Operands& dest, const Operands& src) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt16() : dest[0].getReg().cvt16(); - MovGP(ctx, tmp, src[0]); - ctx.Code().and_(tmp, 0x7FFF); - MovGP(ctx, dest[0], tmp); + MovGP(ctx, dest[0], src[0]); + ctx.Code().and_(dest[0].Op(), 0x7FFF); } void EmitFPAbs32(EmitContext& ctx, const Operands& dest, const Operands& src) { Reg reg_tmp = ctx.TempXmmReg(); - Xmm xmm_tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm xmm_tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); ctx.Code().mov(reg_tmp, 0x7FFFFFFF); ctx.Code().movd(xmm_tmp, reg_tmp); - ctx.Code().andps(xmm_tmp, src[0]); + ctx.Code().andps(xmm_tmp, src[0].Op()); MovFloat(ctx, dest[0], xmm_tmp); } void EmitFPAbs64(EmitContext& ctx, const Operands& dest, const Operands& src) { Reg reg_tmp = ctx.TempGPReg(); - Xmm xmm_tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm xmm_tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); ctx.Code().mov(reg_tmp, 0x7FFFFFFFFFFFFFFF); ctx.Code().movq(xmm_tmp, reg_tmp); - ctx.Code().andpd(xmm_tmp, src[0]); + ctx.Code().andpd(xmm_tmp, src[0].Op()); MovFloat(ctx, dest[0], xmm_tmp); } void EmitFPAdd16(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, op1[0]); - EmitInlineF16ToF32(ctx, tmp2, op2[0]); + EmitInlineF16ToF32(ctx, tmp1, op1[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, op2[0].Op()); ctx.Code().addss(tmp1, tmp2); - EmitInlineF32ToF16(ctx, dest[0], tmp1); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp1); } void EmitFPAdd32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, op1[0]); - ctx.Code().addss(tmp, op2[0]); + ctx.Code().addss(tmp, op2[0].Op()); MovFloat(ctx, dest[0], tmp); } void EmitFPAdd64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovDouble(ctx, tmp, op1[0]); - ctx.Code().addsd(tmp, op2[0]); + ctx.Code().addsd(tmp, op2[0].Op()); MovDouble(ctx, dest[0], tmp); } void EmitFPSub32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, op1[0]); - ctx.Code().subss(tmp, op2[0]); + ctx.Code().subss(tmp, op2[0].Op()); MovFloat(ctx, dest[0], tmp); } @@ -71,58 +69,54 @@ void EmitFPFma16(EmitContext& ctx, const Operands& dest, const Operands& op1, co Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); Xmm tmp3 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, op1[0]); - EmitInlineF16ToF32(ctx, tmp2, op2[0]); - EmitInlineF16ToF32(ctx, tmp3, op3[0]); + EmitInlineF16ToF32(ctx, tmp1, op1[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, op2[0].Op()); + EmitInlineF16ToF32(ctx, tmp3, op3[0].Op()); ctx.Code().vfmadd132ss(tmp3, tmp1, tmp2); - EmitInlineF32ToF16(ctx, dest[0], tmp3); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp3); } void EmitFPFma32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) { - Xmm tmp1 = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - Xmm tmp2 = op1[0].isMEM() ? ctx.TempXmmReg() : op1[0].getReg().cvt128(); - Xmm tmp3 = op2[0].isMEM() ? ctx.TempXmmReg() : op2[0].getReg().cvt128(); + Xmm tmp1 = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + Xmm tmp2 = op2[0].IsMem() ? ctx.TempXmmReg() : op2[0].Xmm(); MovFloat(ctx, tmp1, op3[0]); - MovFloat(ctx, tmp2, op1[0]); - MovFloat(ctx, tmp3, op2[0]); - ctx.Code().vfmadd132ss(tmp3, tmp1, tmp2); - MovFloat(ctx, dest[0], tmp3); + MovFloat(ctx, tmp2, op2[0]); + ctx.Code().vfmadd132ss(tmp2, tmp1, op1[0].Op()); + MovFloat(ctx, dest[0], tmp2); } void EmitFPFma64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) { - Xmm tmp1 = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - Xmm tmp2 = op1[0].isMEM() ? ctx.TempXmmReg() : op1[0].getReg().cvt128(); - Xmm tmp3 = op2[0].isMEM() ? ctx.TempXmmReg() : op2[0].getReg().cvt128(); + Xmm tmp1 = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + Xmm tmp2 = op2[0].IsMem() ? ctx.TempXmmReg() : op2[0].Xmm(); MovDouble(ctx, tmp1, op3[0]); - MovDouble(ctx, tmp2, op1[0]); - MovDouble(ctx, tmp3, op2[0]); - ctx.Code().vfmadd132sd(tmp3, tmp1, tmp2); - MovDouble(ctx, dest[0], tmp3); + MovDouble(ctx, tmp2, op2[0]); + ctx.Code().vfmadd132sd(tmp2, tmp1, op1[0].Op()); + MovDouble(ctx, dest[0], tmp2); } void EmitFPMax32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, bool is_legacy) { if (is_legacy) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - MovFloat(ctx, tmp1, op1[0]); - MovFloat(ctx, tmp2, op1[0]); - ctx.Code().maxss(tmp2, op2[0]); + MovFloat(ctx, tmp1, op1[0].Op()); + MovFloat(ctx, tmp2, op1[0].Op()); + ctx.Code().maxss(tmp2, op2[0].Op()); ctx.Code().cmpunordss(tmp1, tmp1); - ctx.Code().andps(tmp1, op2[0]); + ctx.Code().andps(tmp1, op2[0].Op()); ctx.Code().orps(tmp2, tmp1); MovFloat(ctx, dest[0], tmp2); } else { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, op1[0]); - ctx.Code().maxss(tmp, op2[0]); + ctx.Code().maxss(tmp, op2[0].Op()); MovFloat(ctx, dest[0], tmp); } } void EmitFPMax64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovDouble(ctx, tmp, op1[0]); - ctx.Code().maxsd(tmp, op2[0]); + ctx.Code().maxsd(tmp, op2[0].Op()); MovDouble(ctx, dest[0], tmp); } @@ -130,87 +124,85 @@ void EmitFPMin32(EmitContext& ctx, const Operands& dest, const Operands& op1, co if (is_legacy) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - MovFloat(ctx, tmp1, op1[0]); - MovFloat(ctx, tmp2, op1[0]); - ctx.Code().minss(tmp2, op2[0]); + MovFloat(ctx, tmp1, op1[0].Op()); + MovFloat(ctx, tmp2, op1[0].Op()); + ctx.Code().minss(tmp2, op2[0].Op()); ctx.Code().cmpunordss(tmp1, tmp1); - ctx.Code().andps(tmp1, op2[0]); + ctx.Code().andps(tmp1, op2[0].Op()); ctx.Code().orps(tmp2, tmp1); MovFloat(ctx, dest[0], tmp2); } else { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, op1[0]); - ctx.Code().minss(tmp, op2[0]); + ctx.Code().minss(tmp, op2[0].Op()); MovFloat(ctx, dest[0], tmp); } } void EmitFPMin64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovDouble(ctx, tmp, op1[0]); - ctx.Code().minsd(tmp, op2[0]); + ctx.Code().minsd(tmp, op2[0].Op()); MovDouble(ctx, dest[0], tmp); } void EmitFPMul16(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, op1[0]); - EmitInlineF16ToF32(ctx, tmp2, op2[0]); + EmitInlineF16ToF32(ctx, tmp1, op1[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, op2[0].Op()); ctx.Code().mulss(tmp1, tmp2); - EmitInlineF32ToF16(ctx, dest[0], tmp1); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp1); } void EmitFPMul32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, op1[0]); - ctx.Code().mulss(tmp, op2[0]); + ctx.Code().mulss(tmp, op2[0].Op()); MovFloat(ctx, dest[0], tmp); } void EmitFPMul64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovDouble(ctx, tmp, op1[0]); - ctx.Code().mulsd(tmp, op2[0]); + ctx.Code().mulsd(tmp, op2[0].Op()); MovDouble(ctx, dest[0], tmp); } void EmitFPDiv32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, op1[0]); - ctx.Code().divss(tmp, op2[0]); + ctx.Code().divss(tmp, op2[0].Op()); MovFloat(ctx, dest[0], tmp); } void EmitFPDiv64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovDouble(ctx, tmp, op1[0]); - ctx.Code().divsd(tmp, op2[0]); + ctx.Code().divsd(tmp, op2[0].Op()); MovDouble(ctx, dest[0], tmp); } void EmitFPNeg16(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt16() : dest[0].getReg().cvt16(); - MovGP(ctx, tmp, op1[0]); - ctx.Code().xor_(tmp, 0x8000); - MovGP(ctx, dest[0], tmp); + MovGP(ctx, dest[0], op1[0]); + ctx.Code().xor_(dest[0].Op(), 0x8000); } void EmitFPNeg32(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp_xmm = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp_xmm = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); Reg tmp_reg = ctx.TempGPReg().cvt32(); ctx.Code().mov(tmp_reg, 0x80000000); ctx.Code().movd(tmp_xmm, tmp_reg); - ctx.Code().xorps(tmp_xmm, op1[0]); + ctx.Code().xorps(tmp_xmm, op1[0].Op()); MovFloat(ctx, dest[0], tmp_xmm); } void EmitFPNeg64(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp_xmm = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp_xmm = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); Reg tmp_reg = ctx.TempXmmReg(); ctx.Code().mov(tmp_reg, 0x8000000000000000); ctx.Code().movq(tmp_xmm, tmp_reg); - ctx.Code().xorpd(tmp_xmm, op1[0]); + ctx.Code().xorpd(tmp_xmm, op1[0].Op()); MovDouble(ctx, dest[0], tmp_xmm); } @@ -236,39 +228,39 @@ void EmitFPLog2(EmitContext& ctx) { } void EmitFPRecip32(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().rcpss(tmp, op1[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().rcpss(tmp, op1[0].Op()); MovFloat(ctx, dest[0], tmp); } void EmitFPRecip64(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp_xmm = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp_xmm = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); Reg tmp_reg = ctx.TempGPReg(); ctx.Code().mov(tmp_reg, 1); ctx.Code().cvtsi2sd(tmp_xmm, tmp_reg); - ctx.Code().divsd(tmp_xmm, op1[0]); + ctx.Code().divsd(tmp_xmm, op1[0].Op()); MovDouble(ctx, dest[0], tmp_xmm); } void EmitFPRecipSqrt32(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().rsqrtss(tmp, op1[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().rsqrtss(tmp, op1[0].Op()); MovFloat(ctx, dest[0], tmp); } void EmitFPRecipSqrt64(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp_xmm = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp_xmm = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); Reg tmp_reg = ctx.TempGPReg(); ctx.Code().mov(tmp_reg, 1); ctx.Code().cvtsi2sd(tmp_xmm, tmp_reg); - ctx.Code().divsd(tmp_xmm, op1[0]); + ctx.Code().divsd(tmp_xmm, op1[0].Op()); ctx.Code().sqrtsd(tmp_xmm, tmp_xmm); MovDouble(ctx, dest[0], tmp_xmm); } void EmitFPSqrt(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().sqrtss(tmp, op1[0]); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().sqrtss(tmp, op1[0].Op()); MovFloat(ctx, dest[0], tmp); } @@ -288,84 +280,84 @@ void EmitFPClamp16(EmitContext& ctx, const Operands& dest, const Operands& op, c Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); Xmm tmp3 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, op[0]); - EmitInlineF16ToF32(ctx, tmp2, min[0]); - EmitInlineF16ToF32(ctx, tmp3, max[0]); + EmitInlineF16ToF32(ctx, tmp1, op[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, min[0].Op()); + EmitInlineF16ToF32(ctx, tmp3, max[0].Op()); ctx.Code().maxss(tmp1, tmp2); ctx.Code().minss(tmp1, tmp3); - EmitInlineF32ToF16(ctx, dest[0], tmp1); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp1); } void EmitFPClamp32(EmitContext& ctx, const Operands& dest, const Operands& op, const Operands& min, const Operands& max) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, op[0]); - ctx.Code().maxss(tmp, min[0]); - ctx.Code().minss(tmp, max[0]); + ctx.Code().maxss(tmp, min[0].Op()); + ctx.Code().minss(tmp, max[0].Op()); MovFloat(ctx, dest[0], tmp); } void EmitFPClamp64(EmitContext& ctx, const Operands& dest, const Operands& op, const Operands& min, const Operands& max) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovDouble(ctx, tmp, op[0]); - ctx.Code().maxsd(tmp, min[0]); - ctx.Code().minsd(tmp, max[0]); + ctx.Code().maxsd(tmp, min[0].Op()); + ctx.Code().minsd(tmp, max[0].Op()); MovDouble(ctx, dest[0], tmp); } void EmitFPRoundEven16(EmitContext& ctx, const Operands& dest, const Operands& op1) { Xmm tmp = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp, op1[0]); + EmitInlineF16ToF32(ctx, tmp, op1[0].Op()); ctx.Code().roundss(tmp, tmp, 0x00); - EmitInlineF32ToF16(ctx, dest[0], tmp); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp); } void EmitFPRoundEven32(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().roundss(tmp, op1[0], 0x00); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().roundss(tmp, op1[0].Op(), 0x00); MovFloat(ctx, dest[0], tmp); } void EmitFPRoundEven64(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().roundsd(tmp, op1[0], 0x00); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().roundsd(tmp, op1[0].Op(), 0x00); MovDouble(ctx, dest[0], tmp); } void EmitFPFloor16(EmitContext& ctx, const Operands& dest, const Operands& op1) { Xmm tmp = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp, op1[0]); + EmitInlineF16ToF32(ctx, tmp, op1[0].Op()); ctx.Code().roundss(tmp, tmp, 0x01); - EmitInlineF32ToF16(ctx, dest[0], tmp); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp); } void EmitFPFloor32(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().roundss(tmp, op1[0], 0x01); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().roundss(tmp, op1[0].Op(), 0x01); MovFloat(ctx, dest[0], tmp); } void EmitFPFloor64(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().roundsd(tmp, op1[0], 0x01); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().roundsd(tmp, op1[0].Op(), 0x01); MovDouble(ctx, dest[0], tmp); } void EmitFPCeil16(EmitContext& ctx, const Operands& dest, const Operands& op1) { Xmm tmp = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp, op1[0]); + EmitInlineF16ToF32(ctx, tmp, op1[0].Op()); ctx.Code().roundss(tmp, tmp, 0x02); - EmitInlineF32ToF16(ctx, dest[0], tmp); + EmitInlineF32ToF16(ctx, dest[0].Op(), tmp); } void EmitFPCeil32(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().roundss(tmp, op1[0], 0x02); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().roundss(tmp, op1[0].Op(), 0x02); MovFloat(ctx, dest[0], tmp); } void EmitFPCeil64(EmitContext& ctx, const Operands& dest, const Operands& op1) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); - ctx.Code().roundsd(tmp, op1[0], 0x02); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); + ctx.Code().roundsd(tmp, op1[0].Op(), 0x02); MovDouble(ctx, dest[0], tmp); } @@ -409,7 +401,7 @@ void EmitFPOrdEqual16(EmitContext& ctx, const Operands& dest, const Operands& lh Label not_nan; EmitFPUnordEqual16(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -417,7 +409,7 @@ void EmitFPOrdEqual32(EmitContext& ctx, const Operands& dest, const Operands& lh Label not_nan; EmitFPUnordEqual32(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -425,46 +417,46 @@ void EmitFPOrdEqual64(EmitContext& ctx, const Operands& dest, const Operands& lh Label not_nan; EmitFPUnordEqual64(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } void EmitFPUnordEqual16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, lhs[0]); - EmitInlineF16ToF32(ctx, tmp2, rhs[0]); + EmitInlineF16ToF32(ctx, tmp1, lhs[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, rhs[0].Op()); ctx.Code().ucomiss(tmp1, tmp2); - ctx.Code().sete(dest[0]); + ctx.Code().sete(dest[0].Op()); } void EmitFPUnordEqual32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovFloat(ctx, tmp, lhs[0]); - ctx.Code().ucomiss(tmp, rhs[0]); - ctx.Code().sete(dest[0]); + ctx.Code().ucomiss(tmp, rhs[0].Op()); + ctx.Code().sete(dest[0].Op()); } void EmitFPUnordEqual64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovDouble(ctx, tmp, lhs[0]); - ctx.Code().ucomisd(tmp, rhs[0]); - ctx.Code().sete(dest[0]); + ctx.Code().ucomisd(tmp, rhs[0].Op()); + ctx.Code().sete(dest[0].Op()); } void EmitFPOrdNotEqual16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Label not_nan; EmitFPUnordNotEqual16(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } void EmitFPOrdNotEqual32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Label not_nan; - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -472,38 +464,38 @@ void EmitFPOrdNotEqual64(EmitContext& ctx, const Operands& dest, const Operands& Label not_nan; EmitFPUnordNotEqual64(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } void EmitFPUnordNotEqual16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, lhs[0]); - EmitInlineF16ToF32(ctx, tmp2, rhs[0]); + EmitInlineF16ToF32(ctx, tmp1, lhs[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, rhs[0].Op()); ctx.Code().ucomiss(tmp1, tmp2); - ctx.Code().setne(dest[0]); + ctx.Code().setne(dest[0].Op()); } void EmitFPUnordNotEqual32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovFloat(ctx, tmp, lhs[0]); - ctx.Code().ucomiss(tmp, rhs[0]); - ctx.Code().setne(dest[0]); + ctx.Code().ucomiss(tmp, rhs[0].Op()); + ctx.Code().setne(dest[0].Op()); } void EmitFPUnordNotEqual64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovDouble(ctx, tmp, lhs[0]); - ctx.Code().ucomisd(tmp, rhs[0]); - ctx.Code().setne(dest[0]); + ctx.Code().ucomisd(tmp, rhs[0].Op()); + ctx.Code().setne(dest[0].Op()); } void EmitFPOrdLessThan16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Label not_nan; EmitFPUnordLessThan16(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -511,7 +503,7 @@ void EmitFPOrdLessThan32(EmitContext& ctx, const Operands& dest, const Operands& Label not_nan; EmitFPUnordLessThan32(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -519,38 +511,38 @@ void EmitFPOrdLessThan64(EmitContext& ctx, const Operands& dest, const Operands& Label not_nan; EmitFPUnordLessThan64(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } void EmitFPUnordLessThan16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, lhs[0]); - EmitInlineF16ToF32(ctx, tmp2, rhs[0]); + EmitInlineF16ToF32(ctx, tmp1, lhs[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, rhs[0].Op()); ctx.Code().ucomiss(tmp1, tmp2); - ctx.Code().setb(dest[0]); + ctx.Code().setb(dest[0].Op()); } void EmitFPUnordLessThan32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovFloat(ctx, tmp, lhs[0]); - ctx.Code().ucomiss(tmp, rhs[0]); - ctx.Code().setb(dest[0]); + ctx.Code().ucomiss(tmp, rhs[0].Op()); + ctx.Code().setb(dest[0].Op()); } void EmitFPUnordLessThan64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovDouble(ctx, tmp, lhs[0]); - ctx.Code().ucomisd(tmp, rhs[0]); - ctx.Code().setb(dest[0]); + ctx.Code().ucomisd(tmp, rhs[0].Op()); + ctx.Code().setb(dest[0].Op()); } void EmitFPOrdGreaterThan16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Label not_nan; EmitFPUnordGreaterThan16(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -558,7 +550,7 @@ void EmitFPOrdGreaterThan32(EmitContext& ctx, const Operands& dest, const Operan Label not_nan; EmitFPUnordGreaterThan32(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -566,38 +558,38 @@ void EmitFPOrdGreaterThan64(EmitContext& ctx, const Operands& dest, const Operan Label not_nan; EmitFPUnordGreaterThan64(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } void EmitFPUnordGreaterThan16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, lhs[0]); - EmitInlineF16ToF32(ctx, tmp2, rhs[0]); + EmitInlineF16ToF32(ctx, tmp1, lhs[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, rhs[0].Op()); ctx.Code().ucomiss(tmp1, tmp2); - ctx.Code().seta(dest[0]); + ctx.Code().seta(dest[0].Op()); } void EmitFPUnordGreaterThan32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovFloat(ctx, tmp, lhs[0]); - ctx.Code().ucomiss(tmp, rhs[0]); - ctx.Code().seta(dest[0]); + ctx.Code().ucomiss(tmp, rhs[0].Op()); + ctx.Code().seta(dest[0].Op()); } void EmitFPUnordGreaterThan64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovDouble(ctx, tmp, lhs[0]); - ctx.Code().ucomisd(tmp, rhs[0]); - ctx.Code().seta(dest[0]); + ctx.Code().ucomisd(tmp, rhs[0].Op()); + ctx.Code().seta(dest[0].Op()); } void EmitFPOrdLessThanEqual16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Label not_nan; EmitFPUnordLessThanEqual16(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -605,7 +597,7 @@ void EmitFPOrdLessThanEqual32(EmitContext& ctx, const Operands& dest, const Oper Label not_nan; EmitFPUnordLessThanEqual32(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -613,38 +605,38 @@ void EmitFPOrdLessThanEqual64(EmitContext& ctx, const Operands& dest, const Oper Label not_nan; EmitFPUnordLessThanEqual64(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } void EmitFPUnordLessThanEqual16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, lhs[0]); - EmitInlineF16ToF32(ctx, tmp2, rhs[0]); + EmitInlineF16ToF32(ctx, tmp1, lhs[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, rhs[0].Op()); ctx.Code().ucomiss(tmp1, tmp2); - ctx.Code().setbe(dest[0]); + ctx.Code().setbe(dest[0].Op()); } void EmitFPUnordLessThanEqual32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovFloat(ctx, tmp, lhs[0]); - ctx.Code().ucomiss(tmp, rhs[0]); - ctx.Code().setbe(dest[0]); + ctx.Code().ucomiss(tmp, rhs[0].Op()); + ctx.Code().setbe(dest[0].Op()); } void EmitFPUnordLessThanEqual64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovDouble(ctx, tmp, lhs[0]); - ctx.Code().ucomisd(tmp, rhs[0]); - ctx.Code().setbe(dest[0]); + ctx.Code().ucomisd(tmp, rhs[0].Op()); + ctx.Code().setbe(dest[0].Op()); } void EmitFPOrdGreaterThanEqual16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Label not_nan; EmitFPUnordGreaterThanEqual16(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -652,7 +644,7 @@ void EmitFPOrdGreaterThanEqual32(EmitContext& ctx, const Operands& dest, const O Label not_nan; EmitFPUnordGreaterThanEqual32(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } @@ -660,52 +652,52 @@ void EmitFPOrdGreaterThanEqual64(EmitContext& ctx, const Operands& dest, const O Label not_nan; EmitFPUnordGreaterThanEqual64(ctx, dest, lhs, rhs); ctx.Code().jnp(not_nan); - ctx.Code().mov(dest[0], 0); + ctx.Code().mov(dest[0].Op(), 0); ctx.Code().L(not_nan); } void EmitFPUnordGreaterThanEqual16(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { Xmm tmp1 = ctx.TempXmmReg(); Xmm tmp2 = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp1, lhs[0]); - EmitInlineF16ToF32(ctx, tmp2, rhs[0]); + EmitInlineF16ToF32(ctx, tmp1, lhs[0].Op()); + EmitInlineF16ToF32(ctx, tmp2, rhs[0].Op()); ctx.Code().ucomiss(tmp1, tmp2); - ctx.Code().setae(dest[0]); + ctx.Code().setae(dest[0].Op()); } void EmitFPUnordGreaterThanEqual32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovFloat(ctx, tmp, lhs[0]); - ctx.Code().ucomiss(tmp, rhs[0]); - ctx.Code().setae(dest[0]); + ctx.Code().ucomiss(tmp, rhs[0].Op()); + ctx.Code().setae(dest[0].Op()); } void EmitFPUnordGreaterThanEqual64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Xmm tmp = lhs[0].isMEM() ? ctx.TempXmmReg() : lhs[0].getReg().cvt128(); + Xmm tmp = lhs[0].IsMem() ? ctx.TempXmmReg() : lhs[0].Xmm(); MovDouble(ctx, tmp, lhs[0]); - ctx.Code().ucomisd(tmp, rhs[0]); - ctx.Code().setae(dest[0]); + ctx.Code().ucomisd(tmp, rhs[0].Op()); + ctx.Code().setae(dest[0].Op()); } void EmitFPIsNan16(EmitContext& ctx, const Operands& dest, const Operands& op) { Xmm tmp = ctx.TempXmmReg(); - EmitInlineF16ToF32(ctx, tmp, op[0]); + EmitInlineF16ToF32(ctx, tmp, op[0].Op()); ctx.Code().ucomiss(tmp, tmp); - ctx.Code().setp(dest[0]); + ctx.Code().setp(dest[0].Op()); } void EmitFPIsNan32(EmitContext& ctx, const Operands& dest, const Operands& op) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovFloat(ctx, tmp, op[0]); ctx.Code().ucomiss(tmp, tmp); - ctx.Code().setp(dest[0]); + ctx.Code().setp(dest[0].Op()); } void EmitFPIsNan64(EmitContext& ctx, const Operands& dest, const Operands& op) { - Xmm tmp = dest[0].isMEM() ? ctx.TempXmmReg() : dest[0].getReg().cvt128(); + Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm(); MovDouble(ctx, tmp, op[0]); ctx.Code().ucomisd(tmp, tmp); - ctx.Code().setp(dest[0]); + ctx.Code().setp(dest[0].Op()); } void EmitFPIsInf32(EmitContext& ctx) { diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_instructions.h b/src/shader_recompiler/backend/asm_x64/emit_x64_instructions.h index 0e88727b2..c85da6890 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_instructions.h +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_instructions.h @@ -6,6 +6,7 @@ #include #include #include "common/types.h" +#include "shader_recompiler/backend/asm_x64/x64_emit_context.h" namespace Shader::IR { enum class Attribute : u64; @@ -16,10 +17,6 @@ class Value; } // namespace Shader::IR namespace Shader::Backend::X64 { - -using Operands = boost::container::static_vector; - -class EmitContext; // Microinstruction emitters void EmitPhi(EmitContext& ctx); diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_integer.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_integer.cpp index 2cc3b7c7e..6251a174a 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_integer.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_integer.cpp @@ -12,8 +12,12 @@ using namespace Xbyak::util; namespace { -static bool EmitSaveRegTemp(EmitContext ctx, const Reg& save, const Operand& dest) { - if (dest.getIdx() == save.getIdx()) { +static bool IsReg(const OperandHolder& op, const Reg& reg) { + return op.IsReg() && op.Reg().getIdx() == reg.getIdx(); +} + +static bool EmitSaveRegTemp(EmitContext ctx, const Reg& save, const OperandHolder& dest) { + if (IsReg(dest, save)) { // Destination is reg, no need to save return false; } @@ -28,47 +32,47 @@ static void EmitRestoreRegTemp(EmitContext ctx, const Reg& save) { } // namespace void EmitIAdd32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - if (dest[0].isREG() && op1[0].isREG() && op2[0].isREG()) { - ctx.Code().lea(dest[0].getReg(), ptr[op1[0].getReg() + op2[0].getReg()]); + if (dest[0].IsReg() && op1[0].IsReg() && op2[0].IsReg()) { + ctx.Code().lea(dest[0].Reg(), ptr[op1[0].Reg() + op2[0].Reg()]); } else { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().add(tmp, op2[0]); + ctx.Code().add(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } } void EmitIAdd64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - if (dest[0].isREG() && op1[0].isREG() && op2[0].isREG()) { - ctx.Code().lea(dest[0].getReg(), ptr[op1[0].getReg() + op2[0].getReg()]); + if (dest[0].IsReg() && op1[0].IsReg() && op2[0].IsReg()) { + ctx.Code().lea(dest[0].Reg(), ptr[op1[0].Reg() + op2[0].Reg()]); } else { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false) : dest[0].getReg(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().add(tmp, op2[0]); + ctx.Code().add(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } } void EmitIAddCary32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); - Operand carry = dest[1]; - carry.setBit(1); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0]; + OperandHolder carry = dest[1]; + carry.Op().setBit(1); MovGP(ctx, tmp, op1[0]); - ctx.Code().add(tmp, op2[0]); - ctx.Code().setc(carry); + ctx.Code().add(tmp.Op(), op2[0].Op()); + ctx.Code().setc(carry.Op()); } void EmitISub32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().sub(tmp, op2[0]); + ctx.Code().sub(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitISub64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false) : dest[0].getReg(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().sub(tmp, op2[0]); + ctx.Code().sub(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } @@ -81,29 +85,29 @@ void EmitUMulExt(EmitContext& ctx) { } void EmitIMul32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); MovGP(ctx, tmp, op1[0]); - ctx.Code().imul(tmp, op2[0]); + ctx.Code().imul(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitIMul64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false) : dest[0].getReg(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg() : dest[0].Reg(); MovGP(ctx, tmp, op1[0]); - ctx.Code().imul(tmp, op2[0]); + ctx.Code().imul(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitSDiv32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { bool rax_saved = EmitSaveRegTemp(ctx, rax, dest[0]); bool rdx_saved = EmitSaveRegTemp(ctx, rdx, dest[0]); - Reg tmp = op2[0].getReg().cvt32(); - while (tmp.getIdx() == rax.getIdx()) { + OperandHolder tmp = op2[0]; + while (IsReg(tmp, rax)) { tmp = ctx.TempGPReg().cvt32(); } MovGP(ctx, tmp, op2[0]); MovGP(ctx, eax, op1[0]); - ctx.Code().idiv(tmp); + ctx.Code().idiv(tmp.Op()); MovGP(ctx, dest[0], eax); if (rdx_saved) { EmitRestoreRegTemp(ctx, rdx); @@ -116,13 +120,13 @@ void EmitSDiv32(EmitContext& ctx, const Operands& dest, const Operands& op1, con void EmitUDiv32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { bool rax_saved = EmitSaveRegTemp(ctx, rax, dest[0]); bool rdx_saved = EmitSaveRegTemp(ctx, rdx, dest[0]); - Reg tmp = op2[0].getReg().cvt32(); - while (tmp.getIdx() == rax.getIdx()) { + OperandHolder tmp = op2[0]; + while (IsReg(tmp, rax)) { tmp = ctx.TempGPReg().cvt32(); } MovGP(ctx, tmp, op2[0]); MovGP(ctx, eax, op1[0]); - ctx.Code().div(tmp); + ctx.Code().div(tmp.Op()); MovGP(ctx, dest[0], eax); if (rdx_saved) { EmitRestoreRegTemp(ctx, rdx); @@ -135,13 +139,13 @@ void EmitUDiv32(EmitContext& ctx, const Operands& dest, const Operands& op1, con void EmitSMod32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { bool rax_saved = EmitSaveRegTemp(ctx, rax, dest[0]); bool rdx_saved = EmitSaveRegTemp(ctx, rdx, dest[0]); - Reg tmp = op2[0].getReg().cvt32(); - while (tmp.getIdx() == rax.getIdx()) { + OperandHolder tmp = op2[0]; + while (IsReg(tmp, rax)) { tmp = ctx.TempGPReg().cvt32(); } MovGP(ctx, tmp, op2[0]); MovGP(ctx, eax, op1[0]); - ctx.Code().idiv(tmp); + ctx.Code().idiv(tmp.Op()); MovGP(ctx, dest[0], edx); if (rdx_saved) { EmitRestoreRegTemp(ctx, rdx); @@ -154,13 +158,13 @@ void EmitSMod32(EmitContext& ctx, const Operands& dest, const Operands& op1, con void EmitUMod32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { bool rax_saved = EmitSaveRegTemp(ctx, rax, dest[0]); bool rdx_saved = EmitSaveRegTemp(ctx, rdx, dest[0]); - Reg tmp = op2[0].getReg().cvt32(); - while (tmp.getIdx() == rax.getIdx()) { + OperandHolder tmp = op2[0]; + while (IsReg(tmp, rax)) { tmp = ctx.TempGPReg().cvt32(); } MovGP(ctx, tmp, op2[0]); MovGP(ctx, eax, op1[0]); - ctx.Code().div(tmp); + ctx.Code().div(tmp.Op()); MovGP(ctx, dest[0], edx); if (rdx_saved) { EmitRestoreRegTemp(ctx, rdx); @@ -171,36 +175,30 @@ void EmitUMod32(EmitContext& ctx, const Operands& dest, const Operands& op1, con } void EmitINeg32(EmitContext& ctx, const Operands& dest, const Operands& op) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); - MovGP(ctx, tmp, op[0]); - ctx.Code().neg(tmp); - MovGP(ctx, dest[0], tmp); + MovGP(ctx, dest[0], op[0]); + ctx.Code().neg(dest[0].Op()); } void EmitINeg64(EmitContext& ctx, const Operands& dest, const Operands& op) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false) : dest[0].getReg(); - MovGP(ctx, tmp, op[0]); - ctx.Code().neg(tmp); - MovGP(ctx, dest[0], tmp); + MovGP(ctx, dest[0], op[0]); + ctx.Code().neg(dest[0].Op()); } void EmitIAbs32(EmitContext& ctx, const Operands& dest, const Operands& op) { Label done; - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); - MovGP(ctx, tmp, op[0]); - ctx.Code().cmp(tmp, 0); + MovGP(ctx, dest[0], op[0]); + ctx.Code().cmp(dest[0].Op(), 0); ctx.Code().jns(done); - ctx.Code().neg(tmp); + ctx.Code().neg(dest[0].Op()); ctx.Code().L(done); - MovGP(ctx, dest[0], tmp); } void EmitShiftLeftLogical32(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& shift) { bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]); - Reg tmp = dest[0].getIdx() == rcx.getIdx() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg().cvt32() : dest[0]; MovGP(ctx, tmp, base[0]); MovGP(ctx, cl, shift[0]); - ctx.Code().shl(tmp, cl); + ctx.Code().shl(tmp.Op(), cl); MovGP(ctx, dest[0], tmp); if (rcx_saved) { EmitRestoreRegTemp(ctx, rcx); @@ -209,10 +207,10 @@ void EmitShiftLeftLogical32(EmitContext& ctx, const Operands& dest, const Operan void EmitShiftLeftLogical64(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& shift) { bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]); - Reg tmp = dest[0].getIdx() == rcx.getIdx() ? ctx.TempGPReg(false) : dest[0].getReg(); + OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg() : dest[0]; MovGP(ctx, tmp, base[0]); MovGP(ctx, cl, shift[0]); - ctx.Code().shl(tmp, cl); + ctx.Code().shl(tmp.Op(), cl); MovGP(ctx, dest[0], tmp); if (rcx_saved) { EmitRestoreRegTemp(ctx, rcx); @@ -221,10 +219,10 @@ void EmitShiftLeftLogical64(EmitContext& ctx, const Operands& dest, const Operan void EmitShiftRightLogical32(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& shift) { bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]); - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg().cvt32() : dest[0]; MovGP(ctx, tmp, base[0]); MovGP(ctx, cl, shift[0]); - ctx.Code().shr(tmp, cl); + ctx.Code().shr(tmp.Op(), cl); MovGP(ctx, dest[0], tmp); if (rcx_saved) { EmitRestoreRegTemp(ctx, rcx); @@ -233,10 +231,10 @@ void EmitShiftRightLogical32(EmitContext& ctx, const Operands& dest, const Opera void EmitShiftRightLogical64(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& shift) { bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]); - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false) : dest[0].getReg(); + OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg() : dest[0]; MovGP(ctx, tmp, base[0]); MovGP(ctx, cl, shift[0]); - ctx.Code().shr(tmp, cl); + ctx.Code().shr(tmp.Op(), cl); MovGP(ctx, dest[0], tmp); if (rcx_saved) { EmitRestoreRegTemp(ctx, rcx); @@ -245,10 +243,10 @@ void EmitShiftRightLogical64(EmitContext& ctx, const Operands& dest, const Opera void EmitShiftRightArithmetic32(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& shift) { bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]); - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg().cvt32() : dest[0]; MovGP(ctx, tmp, base[0]); MovGP(ctx, cl, shift[0]); - ctx.Code().sar(tmp, cl); + ctx.Code().sar(tmp.Op(), cl); MovGP(ctx, dest[0], tmp); if (rcx_saved) { EmitRestoreRegTemp(ctx, rcx); @@ -257,10 +255,10 @@ void EmitShiftRightArithmetic32(EmitContext& ctx, const Operands& dest, const Op void EmitShiftRightArithmetic64(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& shift) { bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]); - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false) : dest[0].getReg(); + OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg() : dest[0]; MovGP(ctx, tmp, base[0]); MovGP(ctx, cl, shift[0]); - ctx.Code().sar(tmp, cl); + ctx.Code().sar(tmp.Op(), cl); MovGP(ctx, dest[0], tmp); if (rcx_saved) { EmitRestoreRegTemp(ctx, rcx); @@ -268,37 +266,37 @@ void EmitShiftRightArithmetic64(EmitContext& ctx, const Operands& dest, const Op } void EmitBitwiseAnd32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().and_(tmp, op2[0]); + ctx.Code().and_(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitBitwiseAnd64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false) : dest[0].getReg(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().and_(tmp, op2[0]); + ctx.Code().and_(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitBitwiseOr32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().or_(tmp, op2[0]); + ctx.Code().or_(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitBitwiseOr64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false) : dest[0].getReg(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().or_(tmp, op2[0]); + ctx.Code().or_(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitBitwiseXor32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + OperandHolder tmp = op2[0].IsMem() && dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0]; MovGP(ctx, tmp, op1[0]); - ctx.Code().xor_(tmp, op2[0]); + ctx.Code().xor_(tmp.Op(), op2[0].Op()); MovGP(ctx, dest[0], tmp); } @@ -327,10 +325,8 @@ void EmitBitCount64(EmitContext& ctx) { } void EmitBitwiseNot32(EmitContext& ctx, const Operands& dest, const Operands& op) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); - MovGP(ctx, tmp, op[0]); - ctx.Code().not_(tmp); - MovGP(ctx, dest[0], tmp); + MovGP(ctx, dest[0], op[0]); + ctx.Code().not_(dest[0].Op()); } void EmitFindSMsb32(EmitContext& ctx) { @@ -350,153 +346,153 @@ void EmitFindILsb64(EmitContext& ctx) { } void EmitSMin32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); MovGP(ctx, tmp, op1[0]); - ctx.Code().cmp(tmp, op2[0]); - ctx.Code().cmovg(tmp, op2[0]); + ctx.Code().cmp(tmp, op2[0].Op()); + ctx.Code().cmovg(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitUMin32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); MovGP(ctx, tmp, op1[0]); - ctx.Code().cmp(tmp, op2[0]); - ctx.Code().cmova(tmp, op2[0]); + ctx.Code().cmp(tmp, op2[0].Op()); + ctx.Code().cmova(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitSMax32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); MovGP(ctx, tmp, op1[0]); - ctx.Code().cmp(tmp, op2[0]); - ctx.Code().cmovl(tmp, op2[0]); + ctx.Code().cmp(tmp, op2[0].Op()); + ctx.Code().cmovl(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitUMax32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); MovGP(ctx, tmp, op1[0]); - ctx.Code().cmp(tmp, op2[0]); - ctx.Code().cmovb(tmp, op2[0]); + ctx.Code().cmp(tmp, op2[0].Op()); + ctx.Code().cmovb(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitSClamp32(EmitContext& ctx, const Operands& dest, const Operands& value, const Operands& min, const Operands& max) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); MovGP(ctx, tmp, value[0]); - ctx.Code().cmp(tmp, min[0]); - ctx.Code().cmovl(tmp, min[0]); - ctx.Code().cmp(tmp, max[0]); - ctx.Code().cmovg(tmp, max[0]); + ctx.Code().cmp(tmp, min[0].Op()); + ctx.Code().cmovl(tmp, min[0].Op()); + ctx.Code().cmp(tmp, max[0].Op()); + ctx.Code().cmovg(tmp, max[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitUClamp32(EmitContext& ctx, const Operands& dest, const Operands& value, const Operands& min, const Operands& max) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg(false).cvt32() : dest[0].getReg().cvt32(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg(); MovGP(ctx, tmp, value[0]); - ctx.Code().cmp(tmp, min[0]); - ctx.Code().cmovb(tmp, min[0]); - ctx.Code().cmp(tmp, max[0]); - ctx.Code().cmova(tmp, max[0]); + ctx.Code().cmp(tmp, min[0].Op()); + ctx.Code().cmovb(tmp, min[0].Op()); + ctx.Code().cmp(tmp, max[0].Op()); + ctx.Code().cmova(tmp, max[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitSLessThan32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setl(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setl(dest[0].Op()); } void EmitSLessThan64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false) : lhs[0].getReg(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setl(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setl(dest[0].Op()); } void EmitULessThan32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setb(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setb(dest[0].Op()); } void EmitULessThan64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false) : lhs[0].getReg(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setb(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setb(dest[0].Op()); } void EmitIEqual32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().sete(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().sete(dest[0].Op()); } void EmitIEqual64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false) : lhs[0].getReg(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().sete(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().sete(dest[0].Op()); } void EmitSLessThanEqual(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setle(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setle(dest[0].Op()); } void EmitULessThanEqual(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setbe(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setbe(dest[0].Op()); } void EmitSGreaterThan(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setg(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setg(dest[0].Op()); } void EmitUGreaterThan(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().seta(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().seta(dest[0].Op()); } void EmitINotEqual32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setne(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setne(dest[0].Op()); } void EmitINotEqual64(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false) : lhs[0].getReg(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setne(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setne(dest[0].Op()); } void EmitSGreaterThanEqual(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setge(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setge(dest[0].Op()); } void EmitUGreaterThanEqual(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs) { - Reg tmp = lhs[0].isMEM() && rhs[0].isMEM() ? ctx.TempGPReg(false).cvt32() : lhs[0].getReg().cvt32(); + OperandHolder tmp = lhs[0].IsMem() && rhs[0].IsMem() ? ctx.TempGPReg().cvt32() : lhs[0]; MovGP(ctx, tmp, lhs[0]); - ctx.Code().cmp(tmp, rhs[0]); - ctx.Code().setae(dest[0]); + ctx.Code().cmp(tmp.Op(), rhs[0].Op()); + ctx.Code().setae(dest[0].Op()); } } // namespace Shader::Backend::X64 \ No newline at end of file diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_logical.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_logical.cpp index 30ec2eeeb..d1d7cfb74 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_logical.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_logical.cpp @@ -10,31 +10,29 @@ using namespace Xbyak; using namespace Xbyak::util; void EmitLogicalOr(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt8() : dest[0].getReg().cvt8(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt8() : dest[0].Reg().cvt8(); MovGP(ctx, tmp, op1[0]); - ctx.Code().or_(tmp, op2[0]); + ctx.Code().or_(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitLogicalAnd(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt8() : dest[0].getReg().cvt8(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt8() : dest[0].Reg().cvt8(); MovGP(ctx, tmp, op1[0]); - ctx.Code().and_(tmp, op2[0]); + ctx.Code().and_(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitLogicalXor(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt8() : dest[0].getReg().cvt8(); + Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt8() : dest[0].Reg().cvt8(); MovGP(ctx, tmp, op1[0]); - ctx.Code().xor_(tmp, op2[0]); + ctx.Code().xor_(tmp, op2[0].Op()); MovGP(ctx, dest[0], tmp); } void EmitLogicalNot(EmitContext& ctx, const Operands& dest, const Operands& op) { - Reg tmp = dest[0].isMEM() ? ctx.TempGPReg().cvt8() : dest[0].getReg().cvt8(); - MovGP(ctx, tmp, op[0]); - ctx.Code().not_(tmp); - MovGP(ctx, dest[0], tmp); + MovGP(ctx, dest[0], op[0]); + ctx.Code().not_(dest[0].Op()); } } // namespace Shader::Backend::X64 \ No newline at end of file diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_select.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_select.cpp index 56ecaee03..bc86ffcad 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_select.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_select.cpp @@ -11,7 +11,7 @@ using namespace Xbyak::util; void EmitSelectU1(EmitContext& ctx, const Operands& dest, const Operands& cond, const Operands& true_value, const Operands& false_value) { Label false_label, end_label; - Reg tmp = cond[0].isMEM() ? ctx.TempGPReg().cvt8() : cond[0].getReg().cvt8(); + Reg tmp = cond[0].IsMem() ? ctx.TempGPReg().cvt8() : cond[0].Reg().cvt8(); MovGP(ctx, tmp, cond[0]); ctx.Code().test(tmp, tmp); ctx.Code().jz(false_label); @@ -44,7 +44,7 @@ void EmitSelectF16(EmitContext& ctx, const Operands& dest, const Operands& cond, void EmitSelectF32(EmitContext& ctx, const Operands& dest, const Operands& cond, const Operands& true_value, const Operands& false_value) { Label false_label, end_label; - Reg tmp = cond[0].isMEM() ? ctx.TempGPReg().cvt8() : cond[0].getReg().cvt8(); + Reg tmp = cond[0].IsMem() ? ctx.TempGPReg().cvt8() : cond[0].Reg().cvt8(); MovGP(ctx, tmp, cond[0]); ctx.Code().test(tmp, tmp); ctx.Code().jz(false_label); @@ -57,7 +57,7 @@ void EmitSelectF32(EmitContext& ctx, const Operands& dest, const Operands& cond, void EmitSelectF64(EmitContext& ctx, const Operands& dest, const Operands& cond, const Operands& true_value, const Operands& false_value) { Label false_label, end_label; - Reg tmp = cond[0].isMEM() ? ctx.TempGPReg().cvt8() : cond[0].getReg().cvt8(); + Reg tmp = cond[0].IsMem() ? ctx.TempGPReg().cvt8() : cond[0].Reg().cvt8(); MovGP(ctx, tmp, cond[0]); ctx.Code().test(tmp, tmp); ctx.Code().jz(false_label); diff --git a/src/shader_recompiler/backend/asm_x64/emit_x64_special.cpp b/src/shader_recompiler/backend/asm_x64/emit_x64_special.cpp index acae51f66..16a406a81 100644 --- a/src/shader_recompiler/backend/asm_x64/emit_x64_special.cpp +++ b/src/shader_recompiler/backend/asm_x64/emit_x64_special.cpp @@ -30,7 +30,7 @@ void EmitDiscard(EmitContext& ctx) { } void EmitDiscardCond(EmitContext& ctx, const Operands& condition) { - Reg tmp = condition[0].isMEM() ? ctx.TempGPReg().cvt8() : condition[0].getReg().cvt8(); + Reg tmp = condition[0].IsMem() ? ctx.TempGPReg().cvt8() : condition[0].Reg().cvt8(); MovGP(ctx, tmp, condition[0]); ctx.Code().test(tmp, tmp); ctx.Code().jnz(ctx.EndLabel()); diff --git a/src/shader_recompiler/backend/asm_x64/x64_emit_context.cpp b/src/shader_recompiler/backend/asm_x64/x64_emit_context.cpp index 0b03b2e75..ee104fe89 100644 --- a/src/shader_recompiler/backend/asm_x64/x64_emit_context.cpp +++ b/src/shader_recompiler/backend/asm_x64/x64_emit_context.cpp @@ -76,19 +76,19 @@ Operands EmitContext::Def(const IR::Value& value) { switch (value.Type()) { case IR::Type::U1: operands.push_back(TempGPReg().cvt8()); - code.mov(operands.back(), value.U1()); + code.mov(operands.back().Reg(), value.U1()); break; case IR::Type::U8: operands.push_back(TempGPReg().cvt8()); - code.mov(operands.back(), value.U8()); + code.mov(operands.back().Reg(), value.U8()); break; case IR::Type::U16: operands.push_back(TempGPReg().cvt16()); - code.mov(operands.back(), value.U16()); + code.mov(operands.back().Reg(), value.U16()); break; case IR::Type::U32: operands.push_back(TempGPReg().cvt32()); - code.mov(operands.back(), value.U32()); + code.mov(operands.back().Reg(), value.U32()); break; case IR::Type::F32: { code.mov(tmp.cvt32(), std::bit_cast(value.F32())); @@ -99,7 +99,7 @@ Operands EmitContext::Def(const IR::Value& value) { } case IR::Type::U64: operands.push_back(TempGPReg()); - code.mov(operands.back(), value.U64()); + code.mov(operands.back().Reg(), value.U64()); break; case IR::Type::F64: { code.mov(tmp, std::bit_cast(value.F64())); @@ -110,19 +110,19 @@ Operands EmitContext::Def(const IR::Value& value) { } case IR::Type::ScalarReg: operands.push_back(TempGPReg().cvt32()); - code.mov(operands.back(), std::bit_cast(value.ScalarReg())); + code.mov(operands.back().Reg(), std::bit_cast(value.ScalarReg())); break; case IR::Type::VectorReg: operands.push_back(TempXmmReg().cvt32()); - code.mov(operands.back(), std::bit_cast(value.VectorReg())); + code.mov(operands.back().Reg(), std::bit_cast(value.VectorReg())); break; case IR::Type::Attribute: operands.push_back(TempGPReg()); - code.mov(operands.back(), std::bit_cast(value.Attribute())); + code.mov(operands.back().Reg(), std::bit_cast(value.Attribute())); break; case IR::Type::Patch: operands.push_back(TempGPReg()); - code.mov(operands.back(), std::bit_cast(value.Patch())); + code.mov(operands.back().Reg(), std::bit_cast(value.Patch())); break; default: UNREACHABLE_MSG("Unsupported value type: {}", IR::NameOf(value.Type())); @@ -195,7 +195,7 @@ void EmitContext::SpillInst(RegAllocContext& ctx, const ActiveInstInterval& inte ctx.active_spill_intervals.push_back(interval); } else { Operands& operands = inst_to_operands[spill_candidate->inst]; - Reg reg = operands[spill_candidate->component].getReg(); + Reg reg = operands[spill_candidate->component].Reg(); inst_to_operands[interval.inst][interval.component] = reg.isXMM() ? reg : ResizeRegToType(reg, interval.inst); operands[spill_candidate->component] = get_operand(spill_candidate->inst); @@ -288,7 +288,7 @@ void EmitContext::AllocateRegisters() { // Free old interval resources for (auto it = ctx.active_gp_intervals.begin(); it != ctx.active_gp_intervals.end();) { if (it->end < interval.start) { - Reg64 reg = inst_to_operands[it->inst][it->component].getReg().cvt64(); + Reg64 reg = inst_to_operands[it->inst][it->component].Reg().cvt64(); ctx.free_gp_regs.push_back(reg); it = ctx.active_gp_intervals.erase(it); } else { @@ -297,7 +297,7 @@ void EmitContext::AllocateRegisters() { } for (auto it = ctx.active_xmm_intervals.begin(); it != ctx.active_xmm_intervals.end();) { if (it->end < interval.start) { - Xmm reg = inst_to_operands[it->inst][it->component].getReg().cvt128(); + Xmm reg = inst_to_operands[it->inst][it->component].Xmm(); ctx.free_xmm_regs.push_back(reg); it = ctx.active_xmm_intervals.erase(it); } else { @@ -307,7 +307,7 @@ void EmitContext::AllocateRegisters() { for (auto it = ctx.active_spill_intervals.begin(); it != ctx.active_spill_intervals.end();) { if (it->end < interval.start) { - const Address& addr = inst_to_operands[it->inst][it->component].getAddress(); + const Address& addr = inst_to_operands[it->inst][it->component].Mem(); ctx.free_stack_slots.push_back(addr.getDisp()); it = ctx.active_spill_intervals.erase(it); } else { diff --git a/src/shader_recompiler/backend/asm_x64/x64_emit_context.h b/src/shader_recompiler/backend/asm_x64/x64_emit_context.h index 994fc6f6a..ce9921233 100644 --- a/src/shader_recompiler/backend/asm_x64/x64_emit_context.h +++ b/src/shader_recompiler/backend/asm_x64/x64_emit_context.h @@ -11,7 +11,78 @@ namespace Shader::Backend::X64 { -using Operands = boost::container::static_vector; +class OperandHolder { +public: + OperandHolder() : op() {} + OperandHolder(const OperandHolder&) = default; + OperandHolder(OperandHolder&&) = default; + OperandHolder& operator=(const OperandHolder&) = default; + OperandHolder& operator=(OperandHolder&&) = default; + + OperandHolder(const Xbyak::Reg& reg_) : reg(reg_) {} + OperandHolder(const Xbyak::Xmm& xmm_) : xmm(xmm_) {} + OperandHolder(const Xbyak::Address& mem_) : mem(mem_) {} + OperandHolder(const Xbyak::Operand& op_) : op(op_) {} + + [[nodiscard]] inline Xbyak::Operand& Op() { + return op; + } + + [[nodiscard]] inline const Xbyak::Operand& Op() const { + return op; + } + + [[nodiscard]] inline Xbyak::Reg& Reg() { + ASSERT(IsReg()); + return reg; + } + + [[nodiscard]] inline const Xbyak::Reg& Reg() const { + ASSERT(IsReg()); + return reg; + } + + [[nodiscard]] inline Xbyak::Xmm& Xmm() { + ASSERT(IsXmm()); + return xmm; + } + + [[nodiscard]] inline const Xbyak::Xmm& Xmm() const { + ASSERT(IsXmm()); + return xmm; + } + + [[nodiscard]] inline Xbyak::Address& Mem() { + ASSERT(IsMem()); + return mem; + } + + [[nodiscard]] inline const Xbyak::Address& Mem() const { + ASSERT(IsMem()); + return mem; + } + + [[nodiscard]] inline bool IsReg() const { + return op.isREG(); + } + + [[nodiscard]] inline bool IsXmm() const { + return op.isXMM(); + } + + [[nodiscard]] inline bool IsMem() const { + return op.isMEM(); + } +private: + union { + Xbyak::Operand op; + Xbyak::Reg reg; + Xbyak::Xmm xmm; + Xbyak::Address mem; + }; +}; + +using Operands = boost::container::static_vector; class EmitContext { public: diff --git a/src/shader_recompiler/backend/asm_x64/x64_utils.cpp b/src/shader_recompiler/backend/asm_x64/x64_utils.cpp index b93583696..aedd12547 100644 --- a/src/shader_recompiler/backend/asm_x64/x64_utils.cpp +++ b/src/shader_recompiler/backend/asm_x64/x64_utils.cpp @@ -107,63 +107,73 @@ Reg ResizeRegToType(const Reg& reg, const IR::Value& value) { return reg; } -void MovFloat(EmitContext& ctx, const Xbyak::Operand& dst, const Xbyak::Operand& src) { +void MovFloat(EmitContext& ctx, const OperandHolder& dst, const OperandHolder& src) { CodeGenerator& c = ctx.Code(); - if (src == dst) { + if (src.Op() == dst.Op()) { return; } - if (src.isMEM() && dst.isMEM()) { + if (src.IsMem() && dst.IsMem()) { Reg tmp = ctx.TempGPReg(false).cvt32(); - c.mov(tmp, src); - c.mov(dst, tmp); - } else if (src.isMEM() && dst.isXMM()) { - c.movss(dst.getReg().cvt128(), src.getAddress()); - } else if (src.isXMM() && dst.isMEM()) { - c.movss(dst.getAddress(), src.getReg().cvt128()); - } else if (src.isXMM() && dst.isXMM()) { - c.movaps(dst.getReg().cvt128(), src.getReg().cvt128()); + c.mov(tmp, src.Mem()); + c.mov(dst.Mem(), tmp); + } else if (src.IsMem() && dst.IsXmm()) { + c.movss(dst.Xmm(), src.Mem()); + } else if (src.IsXmm() && dst.IsMem()) { + c.movss(dst.Mem(), src.Xmm()); + } else if (src.IsXmm() && dst.IsXmm()) { + c.movaps(dst.Xmm(), src.Xmm()); } else { - UNREACHABLE_MSG("Unsupported mov float {} {}", src.toString(), dst.toString()); + UNREACHABLE_MSG("Unsupported mov float {} {}", src.Op().toString(), dst.Op().toString()); } } -void MovDouble(EmitContext& ctx, const Xbyak::Operand& dst, const Xbyak::Operand& src) { +void MovDouble(EmitContext& ctx, const OperandHolder& dst, const OperandHolder& src) { CodeGenerator& c = ctx.Code(); - if (src == dst) { + if (src.Op() == dst.Op()) { return; } - if (src.isMEM() && dst.isMEM()) { + if (src.IsMem() && dst.IsMem()) { const Reg64& tmp = ctx.TempGPReg(false); - c.mov(tmp, src); - c.mov(dst, tmp); - } else if (src.isMEM() && dst.isXMM()) { - c.movsd(dst.getReg().cvt128(), src.getAddress()); - } else if (src.isXMM() && dst.isMEM()) { - c.movsd(dst.getAddress(), src.getReg().cvt128()); - } else if (src.isXMM() && dst.isXMM()) { - c.movapd(dst.getReg().cvt128(), src.getReg().cvt128()); + c.mov(tmp, src.Mem()); + c.mov(dst.Mem(), tmp); + } else if (src.IsMem() && dst.IsXmm()) { + c.movsd(dst.Xmm(), src.Mem()); + } else if (src.IsXmm() && dst.IsMem()) { + c.movsd(dst.Mem(), src.Xmm()); + } else if (src.IsXmm() && dst.IsXmm()) { + c.movapd(dst.Xmm(), src.Xmm()); } else { - UNREACHABLE_MSG("Unsupported mov double {} {}", src.toString(), dst.toString()); + UNREACHABLE_MSG("Unsupported mov double {} {}", src.Op().toString(), dst.Op().toString()); } } -void MovGP(EmitContext& ctx, const Xbyak::Operand& dst, const Xbyak::Operand& src) { +void MovGP(EmitContext& ctx, const OperandHolder& dst, const OperandHolder& src) { CodeGenerator& c = ctx.Code(); - if (src == dst) { + if (src.Op() == dst.Op()) { return; } - Reg tmp = dst.isMEM() ? ctx.TempGPReg(false).changeBit(dst.getBit()) : dst.getReg(); - if (src.getBit() < dst.getBit() && !src.isBit(32)) { - c.movzx(tmp, src); - } else if (src.getBit() > dst.getBit()) { - Operand src_tmp = src; - src_tmp.setBit(dst.getBit()); - c.mov(tmp, src_tmp); + const bool is_mem2mem = src.IsMem() && dst.IsMem(); + const u32 src_bit = src.Op().getBit(); + const u32 dst_bit = dst.Op().getBit(); + OperandHolder tmp = is_mem2mem ? ctx.TempGPReg(false).changeBit(dst_bit) : dst; + if (src_bit < dst_bit) { + if (!dst.IsMem() && !src.Op().isBit(32)) { + c.movzx(tmp.Reg(), src.Op()); + } else { + if (dst.IsMem()) { + c.mov(tmp.Op(), 0); + } + c.mov(tmp.Op(), src.Op()); + } + } else if (src_bit > dst_bit) { + OperandHolder src_tmp = src; + src_tmp.Op().setBit(dst_bit); + c.mov(tmp.Op(), src_tmp.Op()); } else { - c.mov(tmp, src); + c.mov(tmp.Op(), src.Op()); } - if (dst.isMEM()) { - c.mov(dst, tmp); + if (is_mem2mem) { + c.mov(dst.Op(), tmp.Op()); } } @@ -194,56 +204,56 @@ void MovValue(EmitContext& ctx, const Operands& dst, const IR::Value& src) { } } else { CodeGenerator& c = ctx.Code(); - const bool is_mem = dst[0].isMEM(); + const bool is_mem = dst[0].IsMem(); Reg64& tmp = ctx.TempGPReg(false); switch (src.Type()) { case IR::Type::U1: - c.mov(is_mem ? tmp.cvt8() : dst[0], src.U1()); + c.mov(is_mem ? tmp.cvt8() : dst[0].Reg(), src.U1()); break; case IR::Type::U8: - c.mov(is_mem ? tmp.cvt8() : dst[0], src.U8()); + c.mov(is_mem ? tmp.cvt8() : dst[0].Reg(), src.U8()); break; case IR::Type::U16: - c.mov(is_mem ? tmp.cvt16() : dst[0], src.U16()); + c.mov(is_mem ? tmp.cvt16() : dst[0].Reg(), src.U16()); break; case IR::Type::U32: - c.mov(is_mem ? tmp.cvt32() : dst[0], src.U32()); + c.mov(is_mem ? tmp.cvt32() : dst[0].Reg(), src.U32()); break; case IR::Type::F32: - c.mov(tmp.cvt32(), std::bit_cast(src.F32())); + c.mov(tmp.cvt32(), static_cast(src.F32())); if (!is_mem) { - c.movd(dst[0].getReg().cvt128(), tmp.cvt32()); + c.movd(dst[0].Xmm(), tmp.cvt32()); return; } break; case IR::Type::U64: - c.mov(is_mem ? tmp : dst[0], src.U64()); + c.mov(is_mem ? tmp : dst[0].Reg(), src.U64()); break; case IR::Type::F64: - c.mov(tmp, std::bit_cast(src.F64())); + c.mov(tmp, static_cast(src.F64())); if (!is_mem) { - c.movq(dst[0].getReg().cvt128(), tmp); + c.movq(dst[0].Xmm(), tmp); return; } break; case IR::Type::ScalarReg: - c.mov(is_mem ? tmp.cvt32() : dst[0], std::bit_cast(src.ScalarReg())); + c.mov(is_mem ? tmp.cvt32() : dst[0].Reg(), static_cast(src.ScalarReg())); break; case IR::Type::VectorReg: - c.mov(is_mem ? tmp.cvt32() : dst[0], std::bit_cast(src.VectorReg())); + c.mov(is_mem ? tmp.cvt32() : dst[0].Reg(), static_cast(src.VectorReg())); break; case IR::Type::Attribute: - c.mov(is_mem ? tmp : dst[0], std::bit_cast(src.Attribute())); + c.mov(is_mem ? tmp : dst[0].Reg(), std::bit_cast(src.Attribute())); break; case IR::Type::Patch: - c.mov(is_mem ? tmp : dst[0], std::bit_cast(src.Patch())); + c.mov(is_mem ? tmp : dst[0].Reg(), std::bit_cast(src.Patch())); break; default: UNREACHABLE_MSG("Unsupported type {}", IR::NameOf(src.Type())); break; } if (is_mem) { - c.mov(dst[0], tmp); + c.mov(dst[0].Mem(), tmp); } } } diff --git a/src/shader_recompiler/backend/asm_x64/x64_utils.h b/src/shader_recompiler/backend/asm_x64/x64_utils.h index 1c513234a..4782c0150 100644 --- a/src/shader_recompiler/backend/asm_x64/x64_utils.h +++ b/src/shader_recompiler/backend/asm_x64/x64_utils.h @@ -14,9 +14,9 @@ bool IsFloatingType(const IR::Value& value); size_t GetRegBytesOfType(const IR::Value& value); u8 GetNumComponentsOfType(const IR::Value& value); Xbyak::Reg ResizeRegToType(const Xbyak::Reg& reg, const IR::Value& value); -void MovFloat(EmitContext& ctx, const Xbyak::Operand& dst, const Xbyak::Operand& src); -void MovDouble(EmitContext& ctx, const Xbyak::Operand& dst, const Xbyak::Operand& src); -void MovGP(EmitContext& ctx, const Xbyak::Operand& dst, const Xbyak::Operand& src); +void MovFloat(EmitContext& ctx, const OperandHolder& dst, const OperandHolder& src); +void MovDouble(EmitContext& ctx, const OperandHolder& dst, const OperandHolder& src); +void MovGP(EmitContext& ctx, const OperandHolder& dst, const OperandHolder& src); void MovValue(EmitContext& ctx, const Operands& dst, const IR::Value& src); void EmitInlineF16ToF32(EmitContext& ctx, const Xbyak::Operand& dest, const Xbyak::Operand& src); void EmitInlineF32ToF16(EmitContext& ctx, const Xbyak::Operand& dest, const Xbyak::Operand& src);