backend/x64: Temporarily avoid use of DefineValue(Argument&)

Issues with inappropriate values in upper bits of values
This commit is contained in:
Merry 2020-06-27 10:51:10 +01:00
parent 337498823c
commit b1ff971a92
3 changed files with 33 additions and 17 deletions

View file

@ -51,7 +51,12 @@ void EmitX64::EmitPack2x64To1x128(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitLeastSignificantWord(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitLeastSignificantWord(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(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) { 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) { void EmitX64::EmitLeastSignificantHalf(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(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) { void EmitX64::EmitLeastSignificantByte(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(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) { void EmitX64::EmitMostSignificantBit(EmitContext& ctx, IR::Inst* inst) {

View file

@ -212,7 +212,11 @@ void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) {
const auto no_overflow = IR::Value(false); const auto no_overflow = IR::Value(false);
overflow_inst->ReplaceUsesWith(no_overflow); 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; return;
} }

View file

@ -156,10 +156,7 @@ void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) {
ASSERT(args[1].IsImmediate()); ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8(); const u8 index = args[1].GetImmediateU8();
if (index == 0) { // TODO: DefineValue directly on Argument for index == 0
ctx.reg_alloc.DefineValue(inst, args[0]);
return;
}
const Xbyak::Xmm source = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm source = ctx.reg_alloc.UseXmm(args[0]);
const Xbyak::Reg32 dest = ctx.reg_alloc.ScratchGpr().cvt32(); 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); code.pextrw(dest, source, index / 2);
if (index % 2 == 1) { if (index % 2 == 1) {
code.shr(dest, 8); 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()); ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8(); const u8 index = args[1].GetImmediateU8();
if (index == 0) { // TODO: DefineValue directly on Argument for index == 0
ctx.reg_alloc.DefineValue(inst, args[0]);
return;
}
const Xbyak::Xmm source = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm source = ctx.reg_alloc.UseXmm(args[0]);
const Xbyak::Reg32 dest = ctx.reg_alloc.ScratchGpr().cvt32(); 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()); ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8(); const u8 index = args[1].GetImmediateU8();
if (index == 0) { // TODO: DefineValue directly on Argument for index == 0
ctx.reg_alloc.DefineValue(inst, args[0]);
return;
}
const Xbyak::Reg32 dest = ctx.reg_alloc.ScratchGpr().cvt32(); 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(); const u8 index = args[1].GetImmediateU8();
if (index == 0) { 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; return;
} }