From d80dcc5367619f4adc8ccf2b7e5f4a101458b883 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Fri, 5 Aug 2016 15:27:29 +0100 Subject: [PATCH] BackendX64/EmitX64: Eliminate unnecessary MOVs in Add64, Mul, Mul64, SignExtendWordToLong, ZeroExtendWordToLong, Pack2x32To1x64 --- src/backend_x64/emit_x64.cpp | 39 +++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index 76afd2a3..ef453062 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -278,16 +278,18 @@ void EmitX64::EmitGetOverflowFromOp(IR::Block&, IR::Inst*) { } void EmitX64::EmitPack2x32To1x64(IR::Block&, IR::Inst* inst) { - auto lo = reg_alloc.UseRegister(inst->GetArg(0), any_gpr); - auto hi = reg_alloc.UseDefRegister(inst->GetArg(1), inst, any_gpr); - code->SHL(64, R(hi), Imm8(32)); - code->OR(64, R(hi), R(lo)); + OpArg hi; + X64Reg result; + std::tie(hi, result) = reg_alloc.UseDefOpArg(inst->GetArg(1), inst, any_gpr); + OpArg lo = reg_alloc.UseOpArg(inst->GetArg(0), any_gpr); + + code->MOVZX(64, 32, result, hi); + code->SHL(64, R(result), Imm8(32)); + code->OR(64, R(result), lo); } void EmitX64::EmitLeastSignificantWord(IR::Block&, IR::Inst* inst) { - // TODO: Optimize - auto u64 = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr); - code->MOVZX(64, 32, u64, R(u64)); + reg_alloc.RegisterAddDef(inst, inst->GetArg(0)); } void EmitX64::EmitMostSignificantWord(IR::Block&, IR::Inst* inst) { @@ -738,7 +740,7 @@ void EmitX64::EmitAdd64(IR::Block& block, IR::Inst* inst) { IR::Value b = inst->GetArg(1); X64Reg result = reg_alloc.UseDefRegister(a, inst, any_gpr); - OpArg op_arg = R(reg_alloc.UseRegister(b, any_gpr)); + OpArg op_arg = reg_alloc.UseOpArg(b, any_gpr); code->ADD(64, R(result), op_arg); } @@ -791,11 +793,12 @@ void EmitX64::EmitMul(IR::Block&, IR::Inst* inst) { IR::Value b = inst->GetArg(1); if (a.IsImmediate()) std::swap(a, b); + X64Reg result = reg_alloc.UseDefRegister(a, inst, any_gpr); if (b.IsImmediate()) { code->IMUL(32, result, R(result), Imm32(b.GetU32())); } else { - OpArg op_arg = R(reg_alloc.UseRegister(b.GetInst(), any_gpr)); + OpArg op_arg = reg_alloc.UseOpArg(b, any_gpr); code->IMUL(32, result, op_arg); } } @@ -803,8 +806,10 @@ void EmitX64::EmitMul(IR::Block&, IR::Inst* inst) { void EmitX64::EmitMul64(IR::Block&, IR::Inst* inst) { IR::Value a = inst->GetArg(0); IR::Value b = inst->GetArg(1); + X64Reg result = reg_alloc.UseDefRegister(a, inst, any_gpr); - OpArg op_arg = R(reg_alloc.UseRegister(b.GetInst(), any_gpr)); + OpArg op_arg = reg_alloc.UseOpArg(b, any_gpr); + code->IMUL(64, result, op_arg); } @@ -853,10 +858,11 @@ void EmitX64::EmitNot(IR::Block&, IR::Inst* inst) { } void EmitX64::EmitSignExtendWordToLong(IR::Block&, IR::Inst* inst) { - // TODO: Remove unnecessary mov that may occur here - X64Reg result = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr); + OpArg source; + X64Reg result; + std::tie(source, result) = reg_alloc.UseDefOpArg(inst->GetArg(0), inst, any_gpr); - code->MOVSX(64, 32, result, R(result)); + code->MOVSX(64, 32, result, source); } void EmitX64::EmitSignExtendHalfToWord(IR::Block&, IR::Inst* inst) { @@ -876,10 +882,11 @@ void EmitX64::EmitSignExtendByteToWord(IR::Block&, IR::Inst* inst) { } void EmitX64::EmitZeroExtendWordToLong(IR::Block&, IR::Inst* inst) { - // TODO: Remove unnecessary mov that may occur here - X64Reg result = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr); + OpArg source; + X64Reg result; + std::tie(source, result) = reg_alloc.UseDefOpArg(inst->GetArg(0), inst, any_gpr); - code->MOVZX(64, 32, result, R(result)); + code->MOVZX(64, 32, result, source); } void EmitX64::EmitZeroExtendHalfToWord(IR::Block&, IR::Inst* inst) {