From 670b47149eccb38165396e59cd76af0c5aebf7c5 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 10 Feb 2018 10:28:38 +0000 Subject: [PATCH] IR: Implement VectorZeroExtend --- src/backend_x64/emit_x64_vector.cpp | 41 +++++++++++++++++++++++++++++ src/frontend/ir/ir_emitter.cpp | 15 +++++++++++ src/frontend/ir/ir_emitter.h | 1 + src/frontend/ir/opcodes.inc | 4 +++ 4 files changed, 61 insertions(+) diff --git a/src/backend_x64/emit_x64_vector.cpp b/src/backend_x64/emit_x64_vector.cpp index ddc72b83..adbae27e 100644 --- a/src/backend_x64/emit_x64_vector.cpp +++ b/src/backend_x64/emit_x64_vector.cpp @@ -634,6 +634,47 @@ void EmitX64::EmitVectorLogicalShiftLeft64(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, result); } +static void EmitVectorZeroExtend(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int size) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(args[0]); + const Xbyak::Xmm zeros = ctx.reg_alloc.ScratchXmm(); + + code.pxor(zeros, zeros); + switch (size) { + case 8: + code.punpcklbw(a, zeros); + break; + case 16: + code.punpcklwd(a, zeros); + break; + case 32: + code.punpckldq(a, zeros); + break; + case 64: + code.punpcklqdq(a, zeros); + break; + } + + ctx.reg_alloc.DefineValue(inst, a); +} + +void EmitX64::EmitVectorZeroExtend8(EmitContext& ctx, IR::Inst* inst) { + EmitVectorZeroExtend(code, ctx, inst, 8); +} + +void EmitX64::EmitVectorZeroExtend16(EmitContext& ctx, IR::Inst* inst) { + EmitVectorZeroExtend(code, ctx, inst, 16); +} + +void EmitX64::EmitVectorZeroExtend32(EmitContext& ctx, IR::Inst* inst) { + EmitVectorZeroExtend(code, ctx, inst, 32); +} + +void EmitX64::EmitVectorZeroExtend64(EmitContext& ctx, IR::Inst* inst) { + EmitVectorZeroExtend(code, ctx, inst, 64); +} + void EmitX64::EmitVectorZeroUpper(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 1f24d42b..eb0d0141 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -919,6 +919,21 @@ U128 IREmitter::VectorPairedAdd(size_t esize, const U128& a, const U128& b) { return {}; } +U128 IREmitter::VectorZeroExtend(size_t original_esize, const U128& a) { + switch (original_esize) { + case 8: + return Inst(Opcode::VectorZeroExtend8, a); + case 16: + return Inst(Opcode::VectorZeroExtend16, a); + case 32: + return Inst(Opcode::VectorZeroExtend32, a); + case 64: + return Inst(Opcode::VectorZeroExtend64, a); + } + UNREACHABLE(); + return {}; +} + U128 IREmitter::VectorZeroUpper(const U128& a) { return Inst(Opcode::VectorZeroUpper, a); } diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index 9055e2b9..c79f5f09 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -219,6 +219,7 @@ public: U128 VectorOr(const U128& a, const U128& b); U128 VectorPairedAdd(size_t esize, const U128& a, const U128& b); U128 VectorPairedAddLower(size_t esize, const U128& a, const U128& b); + U128 VectorZeroExtend(size_t original_esize, const U128& a); U128 VectorZeroUpper(const U128& a); U32U64 FPAbs(const U32U64& a); diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index aaec2ab9..52590a1e 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -233,6 +233,10 @@ OPCODE(VectorPairedAdd8, T::U128, T::U128, T::U128 OPCODE(VectorPairedAdd16, T::U128, T::U128, T::U128 ) OPCODE(VectorPairedAdd32, T::U128, T::U128, T::U128 ) OPCODE(VectorPairedAdd64, T::U128, T::U128, T::U128 ) +OPCODE(VectorZeroExtend8, T::U128, T::U128 ) +OPCODE(VectorZeroExtend16, T::U128, T::U128 ) +OPCODE(VectorZeroExtend32, T::U128, T::U128 ) +OPCODE(VectorZeroExtend64, T::U128, T::U128 ) OPCODE(VectorZeroUpper, T::U128, T::U128 ) // Floating-point operations