From 28ccd85e5c378a7ad60e82b56f674dffd6906b23 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 24 Jan 2018 15:54:11 +0000 Subject: [PATCH] IR: Add IR instruction ZeroExtendToQuad --- src/backend_x64/emit_x64_data_processing.cpp | 12 ++++++++++++ src/backend_x64/reg_alloc.cpp | 9 +++------ src/frontend/ir/ir_emitter.cpp | 4 ++++ src/frontend/ir/ir_emitter.h | 1 + src/frontend/ir/opcodes.inc | 1 + 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/backend_x64/emit_x64_data_processing.cpp b/src/backend_x64/emit_x64_data_processing.cpp index b074cc9c..4011816e 100644 --- a/src/backend_x64/emit_x64_data_processing.cpp +++ b/src/backend_x64/emit_x64_data_processing.cpp @@ -1090,6 +1090,18 @@ void EmitX64::EmitZeroExtendWordToLong(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, result); } +void EmitX64::EmitZeroExtendLongToQuad(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + if (args[0].IsInGpr()) { + // We let the register allocator automatically zero extend this when necessary + ctx.reg_alloc.DefineValue(inst, args[0]); + } else { + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + code->movq(result, result); + ctx.reg_alloc.DefineValue(inst, result); + } +} + void EmitX64::EmitByteReverseWord(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32(); diff --git a/src/backend_x64/reg_alloc.cpp b/src/backend_x64/reg_alloc.cpp index 20daac21..b9e492b2 100644 --- a/src/backend_x64/reg_alloc.cpp +++ b/src/backend_x64/reg_alloc.cpp @@ -559,22 +559,19 @@ void RegAlloc::EmitMove(HostLoc to, HostLoc from) { if (HostLocIsXMM(to) && HostLocIsXMM(from)) { code->movaps(HostLocToXmm(to), HostLocToXmm(from)); } else if (HostLocIsGPR(to) && HostLocIsGPR(from)) { - ASSERT(bit_width != 128); - if (bit_width == 64) { + if (bit_width >= 64) { code->mov(HostLocToReg64(to), HostLocToReg64(from)); } else { code->mov(HostLocToReg64(to).cvt32(), HostLocToReg64(from).cvt32()); } } else if (HostLocIsXMM(to) && HostLocIsGPR(from)) { - ASSERT(bit_width != 128); - if (bit_width == 64) { + if (bit_width >= 64) { code->movq(HostLocToXmm(to), HostLocToReg64(from)); } else { code->movd(HostLocToXmm(to), HostLocToReg64(from).cvt32()); } } else if (HostLocIsGPR(to) && HostLocIsXMM(from)) { - ASSERT(bit_width != 128); - if (bit_width == 64) { + if (bit_width >= 64) { code->movq(HostLocToReg64(to), HostLocToXmm(from)); } else { code->movd(HostLocToReg64(to).cvt32(), HostLocToXmm(from)); diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index 83794313..3cb2f564 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -396,6 +396,10 @@ U32 IREmitter::ZeroExtendToWord(const UAny& a) { } } +U128 IREmitter::ZeroExtendToQuad(const UAny& a) { + return Inst(Opcode::ZeroExtendLongToQuad, ZeroExtendToLong(a)); +} + U64 IREmitter::ZeroExtendWordToLong(const U32& a) { return Inst(Opcode::ZeroExtendWordToLong, a); } diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index e46abcb3..7087d9eb 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -125,6 +125,7 @@ public: U64 SignExtendWordToLong(const U32& a); U32 ZeroExtendToWord(const UAny& a); U64 ZeroExtendToLong(const UAny& a); + U128 ZeroExtendToQuad(const UAny& a); U32 ZeroExtendByteToWord(const U8& a); U32 ZeroExtendHalfToWord(const U16& a); U64 ZeroExtendWordToLong(const U32& a); diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 90868828..eebf95fc 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -112,6 +112,7 @@ OPCODE(ZeroExtendHalfToWord, T::U32, T::U16 OPCODE(ZeroExtendByteToLong, T::U64, T::U8 ) OPCODE(ZeroExtendHalfToLong, T::U64, T::U16 ) OPCODE(ZeroExtendWordToLong, T::U64, T::U32 ) +OPCODE(ZeroExtendLongToQuad, T::U128, T::U64 ) OPCODE(ByteReverseWord, T::U32, T::U32 ) OPCODE(ByteReverseHalf, T::U16, T::U16 ) OPCODE(ByteReverseDual, T::U64, T::U64 )