BackendX64/EmitX64: Eliminate unnecessary MOVs in Add64, Mul, Mul64, SignExtendWordToLong, ZeroExtendWordToLong, Pack2x32To1x64
This commit is contained in:
parent
2b025183a2
commit
d80dcc5367
1 changed files with 23 additions and 16 deletions
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue