From b1ff971a924160c8d416fb647c4a4e677a38fc64 Mon Sep 17 00:00:00 2001 From: Merry Date: Sat, 27 Jun 2020 10:51:10 +0100 Subject: [PATCH] backend/x64: Temporarily avoid use of DefineValue(Argument&) Issues with inappropriate values in upper bits of values --- src/backend/x64/emit_x64_data_processing.cpp | 21 +++++++++++++++--- src/backend/x64/emit_x64_saturation.cpp | 6 ++++- src/backend/x64/emit_x64_vector.cpp | 23 +++++++++----------- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/backend/x64/emit_x64_data_processing.cpp b/src/backend/x64/emit_x64_data_processing.cpp index 928ab516..7ab1d12a 100644 --- a/src/backend/x64/emit_x64_data_processing.cpp +++ b/src/backend/x64/emit_x64_data_processing.cpp @@ -51,7 +51,12 @@ void EmitX64::EmitPack2x64To1x128(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitLeastSignificantWord(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - ctx.reg_alloc.DefineValue(inst, args[0]); + + // TODO: DefineValue directly on Argument + const Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr(); + const Xbyak::Reg64 source = ctx.reg_alloc.UseGpr(args[0]); + code.mov(result.cvt32(), source.cvt32()); + ctx.reg_alloc.DefineValue(inst, result); } void EmitX64::EmitMostSignificantWord(EmitContext& ctx, IR::Inst* inst) { @@ -73,12 +78,22 @@ void EmitX64::EmitMostSignificantWord(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitLeastSignificantHalf(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - ctx.reg_alloc.DefineValue(inst, args[0]); + + // TODO: DefineValue directly on Argument + const Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr(); + const Xbyak::Reg64 source = ctx.reg_alloc.UseGpr(args[0]); + code.movzx(result.cvt32(), source.cvt16()); + ctx.reg_alloc.DefineValue(inst, result); } void EmitX64::EmitLeastSignificantByte(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - ctx.reg_alloc.DefineValue(inst, args[0]); + + // TODO: DefineValue directly on Argument + const Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr(); + const Xbyak::Reg64 source = ctx.reg_alloc.UseGpr(args[0]); + code.movzx(result.cvt32(), source.cvt8()); + ctx.reg_alloc.DefineValue(inst, result); } void EmitX64::EmitMostSignificantBit(EmitContext& ctx, IR::Inst* inst) { diff --git a/src/backend/x64/emit_x64_saturation.cpp b/src/backend/x64/emit_x64_saturation.cpp index c739c0af..c9d4c275 100644 --- a/src/backend/x64/emit_x64_saturation.cpp +++ b/src/backend/x64/emit_x64_saturation.cpp @@ -212,7 +212,11 @@ void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) { const auto no_overflow = IR::Value(false); overflow_inst->ReplaceUsesWith(no_overflow); } - ctx.reg_alloc.DefineValue(inst, args[0]); + // TODO: DefineValue directly on Argument + const Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr(); + const Xbyak::Reg64 source = ctx.reg_alloc.UseGpr(args[0]); + code.mov(result.cvt32(), source.cvt32()); + ctx.reg_alloc.DefineValue(inst, result); return; } diff --git a/src/backend/x64/emit_x64_vector.cpp b/src/backend/x64/emit_x64_vector.cpp index 9e19f052..b2d7e330 100644 --- a/src/backend/x64/emit_x64_vector.cpp +++ b/src/backend/x64/emit_x64_vector.cpp @@ -156,10 +156,7 @@ void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) { ASSERT(args[1].IsImmediate()); const u8 index = args[1].GetImmediateU8(); - if (index == 0) { - ctx.reg_alloc.DefineValue(inst, args[0]); - return; - } + // TODO: DefineValue directly on Argument for index == 0 const Xbyak::Xmm source = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Reg32 dest = ctx.reg_alloc.ScratchGpr().cvt32(); @@ -170,6 +167,8 @@ void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) { code.pextrw(dest, source, index / 2); if (index % 2 == 1) { code.shr(dest, 8); + } else { + code.and_(dest, 0xFF); // TODO: Remove when zext handling is corrected } } @@ -181,10 +180,7 @@ void EmitX64::EmitVectorGetElement16(EmitContext& ctx, IR::Inst* inst) { ASSERT(args[1].IsImmediate()); const u8 index = args[1].GetImmediateU8(); - if (index == 0) { - ctx.reg_alloc.DefineValue(inst, args[0]); - return; - } + // TODO: DefineValue directly on Argument for index == 0 const Xbyak::Xmm source = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Reg32 dest = ctx.reg_alloc.ScratchGpr().cvt32(); @@ -197,10 +193,7 @@ void EmitX64::EmitVectorGetElement32(EmitContext& ctx, IR::Inst* inst) { ASSERT(args[1].IsImmediate()); const u8 index = args[1].GetImmediateU8(); - if (index == 0) { - ctx.reg_alloc.DefineValue(inst, args[0]); - return; - } + // TODO: DefineValue directly on Argument for index == 0 const Xbyak::Reg32 dest = ctx.reg_alloc.ScratchGpr().cvt32(); @@ -222,7 +215,11 @@ void EmitX64::EmitVectorGetElement64(EmitContext& ctx, IR::Inst* inst) { const u8 index = args[1].GetImmediateU8(); if (index == 0) { - ctx.reg_alloc.DefineValue(inst, args[0]); + // TODO: DefineValue directly on Argument for index == 0 + const Xbyak::Reg64 dest = ctx.reg_alloc.ScratchGpr().cvt64(); + const Xbyak::Xmm source = ctx.reg_alloc.UseXmm(args[0]); + code.movq(dest, source); + ctx.reg_alloc.DefineValue(inst, dest); return; }