diff --git a/src/backend_x64/emit_x64_vector.cpp b/src/backend_x64/emit_x64_vector.cpp index fb536b3f..9c1c8ce9 100644 --- a/src/backend_x64/emit_x64_vector.cpp +++ b/src/backend_x64/emit_x64_vector.cpp @@ -475,6 +475,106 @@ void EmitX64::EmitVectorInterleaveLower64(EmitContext& ctx, IR::Inst* inst) { EmitVectorInterleaveLower(code, ctx, inst, 64); } +void EmitX64::EmitVectorLogicalShiftLeft8(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + const u8 shift_amount = args[1].GetImmediateU8(); + + // TODO: Optimize + for (size_t i = 0; i < shift_amount; ++i) { + code.paddb(result, result); + } + + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitX64::EmitVectorLogicalShiftLeft16(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + const u8 shift_amount = args[1].GetImmediateU8(); + + code.psllw(result, shift_amount); + + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitX64::EmitVectorLogicalShiftLeft32(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + const u8 shift_amount = args[1].GetImmediateU8(); + + code.pslld(result, shift_amount); + + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitX64::EmitVectorLogicalShiftLeft64(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + const u8 shift_amount = args[1].GetImmediateU8(); + + code.psllq(result, shift_amount); + + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitX64::EmitVectorLogicalShiftRight8(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + Xbyak::Xmm zeros = ctx.reg_alloc.ScratchXmm(); + Xbyak::Xmm mask = ctx.reg_alloc.ScratchXmm(); + const u8 shift_amount = args[1].GetImmediateU8(); + + // TODO: Optimize + code.pcmpeqb(mask, mask); // mask = 0xFF + code.paddb(mask, mask); // mask = 0xFE + code.pxor(zeros, zeros); + for (size_t i = 0; i < shift_amount; ++i) { + code.pand(result, mask); + code.pavgb(result, zeros); + } + + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitX64::EmitVectorLogicalShiftRight16(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + const u8 shift_amount = args[1].GetImmediateU8(); + + code.psrlw(result, shift_amount); + + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitX64::EmitVectorLogicalShiftRight32(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + const u8 shift_amount = args[1].GetImmediateU8(); + + code.psrld(result, shift_amount); + + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitX64::EmitVectorLogicalShiftRight64(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); + const u8 shift_amount = args[1].GetImmediateU8(); + + code.psrlq(result, shift_amount); + + ctx.reg_alloc.DefineValue(inst, result); +} + void EmitX64::EmitVectorNarrow16(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(args[0]); @@ -689,106 +789,6 @@ void EmitX64::EmitVectorPairedAdd64(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, a); } -void EmitX64::EmitVectorLogicalShiftLeft8(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - - Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - const u8 shift_amount = args[1].GetImmediateU8(); - - // TODO: Optimize - for (size_t i = 0; i < shift_amount; ++i) { - code.paddb(result, result); - } - - ctx.reg_alloc.DefineValue(inst, result); -} - -void EmitX64::EmitVectorLogicalShiftLeft16(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - - Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - const u8 shift_amount = args[1].GetImmediateU8(); - - code.psllw(result, shift_amount); - - ctx.reg_alloc.DefineValue(inst, result); -} - -void EmitX64::EmitVectorLogicalShiftLeft32(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - - Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - const u8 shift_amount = args[1].GetImmediateU8(); - - code.pslld(result, shift_amount); - - ctx.reg_alloc.DefineValue(inst, result); -} - -void EmitX64::EmitVectorLogicalShiftLeft64(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - - Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - const u8 shift_amount = args[1].GetImmediateU8(); - - code.psllq(result, shift_amount); - - ctx.reg_alloc.DefineValue(inst, result); -} - -void EmitX64::EmitVectorLogicalShiftRight8(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - - Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - Xbyak::Xmm zeros = ctx.reg_alloc.ScratchXmm(); - Xbyak::Xmm mask = ctx.reg_alloc.ScratchXmm(); - const u8 shift_amount = args[1].GetImmediateU8(); - - // TODO: Optimize - code.pcmpeqb(mask, mask); // mask = 0xFF - code.paddb(mask, mask); // mask = 0xFE - code.pxor(zeros, zeros); - for (size_t i = 0; i < shift_amount; ++i) { - code.pand(result, mask); - code.pavgb(result, zeros); - } - - ctx.reg_alloc.DefineValue(inst, result); -} - -void EmitX64::EmitVectorLogicalShiftRight16(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - - Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - const u8 shift_amount = args[1].GetImmediateU8(); - - code.psrlw(result, shift_amount); - - ctx.reg_alloc.DefineValue(inst, result); -} - -void EmitX64::EmitVectorLogicalShiftRight32(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - - Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - const u8 shift_amount = args[1].GetImmediateU8(); - - code.psrld(result, shift_amount); - - ctx.reg_alloc.DefineValue(inst, result); -} - -void EmitX64::EmitVectorLogicalShiftRight64(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - - Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - const u8 shift_amount = args[1].GetImmediateU8(); - - code.psrlq(result, shift_amount); - - ctx.reg_alloc.DefineValue(inst, result); -} - void EmitX64::EmitVectorSub8(EmitContext& ctx, IR::Inst* inst) { EmitVectorOperation(code, ctx, inst, &Xbyak::CodeGenerator::psubb); }