BackendX64/EmitX64: Eliminate unnecessary MOVs in Add64, Mul, Mul64, SignExtendWordToLong, ZeroExtendWordToLong, Pack2x32To1x64

This commit is contained in:
MerryMage 2016-08-05 15:27:29 +01:00
parent 2b025183a2
commit d80dcc5367

View file

@ -278,16 +278,18 @@ void EmitX64::EmitGetOverflowFromOp(IR::Block&, IR::Inst*) {
} }
void EmitX64::EmitPack2x32To1x64(IR::Block&, IR::Inst* inst) { void EmitX64::EmitPack2x32To1x64(IR::Block&, IR::Inst* inst) {
auto lo = reg_alloc.UseRegister(inst->GetArg(0), any_gpr); OpArg hi;
auto hi = reg_alloc.UseDefRegister(inst->GetArg(1), inst, any_gpr); X64Reg result;
code->SHL(64, R(hi), Imm8(32)); std::tie(hi, result) = reg_alloc.UseDefOpArg(inst->GetArg(1), inst, any_gpr);
code->OR(64, R(hi), R(lo)); 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) { void EmitX64::EmitLeastSignificantWord(IR::Block&, IR::Inst* inst) {
// TODO: Optimize reg_alloc.RegisterAddDef(inst, inst->GetArg(0));
auto u64 = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr);
code->MOVZX(64, 32, u64, R(u64));
} }
void EmitX64::EmitMostSignificantWord(IR::Block&, IR::Inst* inst) { 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); IR::Value b = inst->GetArg(1);
X64Reg result = reg_alloc.UseDefRegister(a, inst, any_gpr); 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); 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); IR::Value b = inst->GetArg(1);
if (a.IsImmediate()) if (a.IsImmediate())
std::swap(a, b); std::swap(a, b);
X64Reg result = reg_alloc.UseDefRegister(a, inst, any_gpr); X64Reg result = reg_alloc.UseDefRegister(a, inst, any_gpr);
if (b.IsImmediate()) { if (b.IsImmediate()) {
code->IMUL(32, result, R(result), Imm32(b.GetU32())); code->IMUL(32, result, R(result), Imm32(b.GetU32()));
} else { } 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); 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) { void EmitX64::EmitMul64(IR::Block&, IR::Inst* inst) {
IR::Value a = inst->GetArg(0); IR::Value a = inst->GetArg(0);
IR::Value b = inst->GetArg(1); IR::Value b = inst->GetArg(1);
X64Reg result = reg_alloc.UseDefRegister(a, inst, any_gpr); 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); 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) { void EmitX64::EmitSignExtendWordToLong(IR::Block&, IR::Inst* inst) {
// TODO: Remove unnecessary mov that may occur here OpArg source;
X64Reg result = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr); 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) { 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) { void EmitX64::EmitZeroExtendWordToLong(IR::Block&, IR::Inst* inst) {
// TODO: Remove unnecessary mov that may occur here OpArg source;
X64Reg result = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr); 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) { void EmitX64::EmitZeroExtendHalfToWord(IR::Block&, IR::Inst* inst) {