OpcodeDispatcher: Improve output of MULX

We can cut down on a few of the generated moves. For
the case where both destinations alias one another,
we can just calculate the high part instead of both of them.
This commit is contained in:
Lioncache committed 2023-09-15 20:52:02 -04:00
1 parent 647629ac23
commit d4f87c7db1
2 files changed
+74 -9

No files matched your search

@@ -2711,15 +2711,29 @@ void OpDispatchBuilder::RORX(OpcodeArgs) {
void OpDispatchBuilder::MULX(OpcodeArgs) {
// RDX is the implied source operand in the instruction
const auto OperandSize = GetSrcSize(Op);
const auto OpSize = IR::SizeToOpSize(OperandSize);
OrderedNode* Src1 = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, -1);
OrderedNode* Src2 = LoadGPRRegister(X86State::REG_RDX, OperandSize);
// Src1 can be a memory operand, so ensure we constrain to the
// absolute width of the access in that scenario.
const auto GPRSize = CTX->GetGPRSize();
const auto Src1Size = Op->Src[1].IsGPR() ? GPRSize : OperandSize;
OrderedNode* ResultLo = _UMul(IR::SizeToOpSize(OperandSize), Src1, Src2);
OrderedNode* ResultHi = _UMulH(IR::SizeToOpSize(OperandSize), Src1, Src2);
OrderedNode* Src1 = LoadSource_WithOpSize(GPRClass, Op, Op->Src[1], Src1Size, Op->Flags, -1);
OrderedNode* Src2 = LoadGPRRegister(X86State::REG_RDX, GPRSize);
StoreResult(GPRClass, Op, Op->Src[0], ResultLo, -1);
StoreResult(GPRClass, Op, Op->Dest, ResultHi, -1);
// As per the Intel Software Development Manual, if the destination and
// first operand correspond to the same register, then the result
// will be the high half of the multiplication result.
if (Op->Dest.Data.GPR.GPR == Op->Src[0].Data.GPR.GPR) {
OrderedNode* ResultHi = _UMulH(OpSize, Src1, Src2);
StoreResult(GPRClass, Op, Op->Dest, ResultHi, -1);
} else {
OrderedNode* ResultLo = _UMul(OpSize, Src1, Src2);
OrderedNode* ResultHi = _UMulH(OpSize, Src1, Src2);
StoreResult(GPRClass, Op, Op->Src[0], ResultLo, -1);
StoreResult(GPRClass, Op, Op->Dest, ResultHi, -1);
}
}
void OpDispatchBuilder::PDEP(OpcodeArgs) {
+54 -3
View File
@@ -3916,6 +3916,34 @@
]
},
"mulx eax, ebx, ecx": {
"ExpectedInstructionCount": 5,
"Optimal": "No",
"Comment": [
"Map 2 0b11 0xf6 32-bit"
],
"ExpectedArm64ASM": [
"mul w7, w5, w6",
"ubfx x0, x5, #0, #32",
"ubfx x1, x6, #0, #32",
"mul x4, x0, x1",
"lsr x4, x4, #32"
]
},
"mulx eax, eax, ebx": {
"ExpectedInstructionCount": 4,
"Optimal": "No",
"Comment": [
"Same two destinations should only compute high part",
"Map 2 0b11 0xf6 32-bit"
],
"ExpectedArm64ASM": [
"ubfx x0, x7, #0, #32",
"ubfx x1, x6, #0, #32",
"mul x4, x0, x1",
"lsr x4, x4, #32"
]
},
"mulx eax, ebx, [ecx]": {
"ExpectedInstructionCount": 7,
"Optimal": "No",
"Comment": [
@@ -3923,10 +3951,10 @@
],
"ExpectedArm64ASM": [
"mov w20, w5",
"mov w21, w6",
"mul w7, w20, w21",
"ldr w20, [x20]",
"mul w7, w20, w6",
"ubfx x0, x20, #0, #32",
"ubfx x1, x21, #0, #32",
"ubfx x1, x6, #0, #32",
"mul x4, x0, x1",
"lsr x4, x4, #32"
]
@@ -3942,6 +3970,29 @@
"umulh x4, x5, x6"
]
},
"mulx rax, rax, rbx": {
"ExpectedInstructionCount": 1,
"Optimal": "Yes",
"Comment": [
"Same two destinations should only compute high part",
"Map 2 0b11 0xf6 64-bit"
],
"ExpectedArm64ASM": [
"umulh x4, x7, x6"
]
},
"mulx rax, rbx, [rcx]": {
"ExpectedInstructionCount": 3,
"Optimal": "Yes",
"Comment": [
"Map 2 0b11 0xf6 64-bit"
],
"ExpectedArm64ASM": [
"ldr x20, [x5]",
"mul x7, x20, x6",
"umulh x4, x20, x6"
]
},
"bextr eax, ebx, ecx": {
"ExpectedInstructionCount": 19,
"Optimal": "No",