From 132c78332065311c229ef92544739deecd726b0c Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 10 Feb 2018 16:47:36 +0000 Subject: [PATCH] IR: Implement VectorNarrow --- src/backend_x64/emit_x64_vector.cpp | 41 +++++++++++++++++++++++++++++ src/frontend/ir/ir_emitter.cpp | 13 +++++++++ src/frontend/ir/ir_emitter.h | 1 + src/frontend/ir/opcodes.inc | 3 +++ 4 files changed, 58 insertions(+) diff --git a/src/backend_x64/emit_x64_vector.cpp b/src/backend_x64/emit_x64_vector.cpp index adc78b61..a0e31765 100644 --- a/src/backend_x64/emit_x64_vector.cpp +++ b/src/backend_x64/emit_x64_vector.cpp @@ -414,6 +414,47 @@ void EmitX64::EmitVectorInterleaveLower64(EmitContext& ctx, IR::Inst* inst) { EmitVectorInterleaveLower(code, ctx, inst, 64); } +void EmitX64::EmitVectorNarrow16(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(args[0]); + Xbyak::Xmm zeros = ctx.reg_alloc.ScratchXmm(); + + // TODO: AVX512F implementation + + code.pxor(zeros, zeros); + code.pand(a, code.MConst(0x00FF00FF00FF00FF, 0x00FF00FF00FF00FF)); + code.packuswb(a, zeros); + + ctx.reg_alloc.DefineValue(inst, a); +} + +void EmitX64::EmitVectorNarrow32(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(args[0]); + Xbyak::Xmm zeros = ctx.reg_alloc.ScratchXmm(); + + // TODO: AVX512F implementation + + code.pxor(zeros, zeros); + code.pand(a, code.MConst(0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF)); + code.packusdw(a, zeros); + + ctx.reg_alloc.DefineValue(inst, a); +} + +void EmitX64::EmitVectorNarrow64(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(args[0]); + Xbyak::Xmm zeros = ctx.reg_alloc.ScratchXmm(); + + // TODO: AVX512F implementation + + code.pxor(zeros, zeros); + code.shufps(a, zeros, 0b00001000); + + ctx.reg_alloc.DefineValue(inst, a); +} + void EmitX64::EmitVectorNot(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index 5681e1b3..a56c9d4f 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -898,6 +898,19 @@ U128 IREmitter::VectorLogicalShiftRight(size_t esize, const U128& a, u8 shift_am return {}; } +U128 IREmitter::VectorNarrow(size_t original_esize, const U128& a) { + switch (original_esize) { + case 16: + return Inst(Opcode::VectorNarrow16, a); + case 32: + return Inst(Opcode::VectorNarrow32, a); + case 64: + return Inst(Opcode::VectorNarrow64, a); + } + UNREACHABLE(); + return {}; +} + U128 IREmitter::VectorNot(const U128& a) { return Inst(Opcode::VectorNot, a); } diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index 01928f57..e2de2c51 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -216,6 +216,7 @@ public: U128 VectorInterleaveLower(size_t esize, const U128& a, const U128& b); U128 VectorLogicalShiftLeft(size_t esize, const U128& a, u8 shift_amount); U128 VectorLogicalShiftRight(size_t esize, const U128& a, u8 shift_amount); + U128 VectorNarrow(size_t original_esize, const U128& a); U128 VectorNot(const U128& a); U128 VectorOr(const U128& a, const U128& b); U128 VectorPairedAdd(size_t esize, const U128& a, const U128& b); diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 4d1049b7..b113549f 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -228,6 +228,9 @@ OPCODE(VectorLogicalShiftRight8, T::U128, T::U128, T::U8 OPCODE(VectorLogicalShiftRight16, T::U128, T::U128, T::U8 ) OPCODE(VectorLogicalShiftRight32, T::U128, T::U128, T::U8 ) OPCODE(VectorLogicalShiftRight64, T::U128, T::U128, T::U8 ) +OPCODE(VectorNarrow16, T::U128, T::U128 ) +OPCODE(VectorNarrow32, T::U128, T::U128 ) +OPCODE(VectorNarrow64, T::U128, T::U128 ) OPCODE(VectorNot, T::U128, T::U128 ) OPCODE(VectorOr, T::U128, T::U128, T::U128 ) OPCODE(VectorPairedAddLower8, T::U128, T::U128, T::U128 )