Merge pull request #3372 from alyssarosenzweig/opt/cmpxchg-review

Optimize GPR cmpxchg
This commit is contained in:
Ryan Houdek authored and GitHub committed 2024-01-15 05:11:12 -08:00
commit f956f008ea
3 files changed
+176 -152

No files matched your search

@@ -4265,6 +4265,13 @@ void OpDispatchBuilder::CMPXCHGOp(OpcodeArgs) {
// 0x80064000
if (Op->Dest.IsGPR()) {
// If the destination is also the accumulator, we get some algebraic
// simplifications. Not sure if this is actually hit but it's in
// InstCountCI.
bool Trivial = Op->Dest.Data.GPR.GPR == X86State::REG_RAX &&
!Op->Dest.IsGPRDirect() &&
!Op->Dest.Data.GPR.HighBits;
OrderedNode *Src1{};
OrderedNode *Src1Lower{};
@@ -4288,40 +4295,37 @@ void OpDispatchBuilder::CMPXCHGOp(OpcodeArgs) {
Src3Lower = Src3;
}
// If our destination is a GPR then this behaves differently
// RAX = RAX == Op1 ? RAX : Op1
// AKA if they match then don't touch RAX value
// Otherwise set it to the rm operand
OrderedNode *CASResult = _Select(FEXCore::IR::COND_EQ,
Src1Lower, Src3Lower,
Src3Lower, Src1Lower);
// Compare RAX with the destination, setting flags accordingly.
OrderedNode *Result = _Sub(IR::SizeToOpSize(GPRSize), Src3Lower, Src1Lower);
GenerateFlags_SUB(Op, Result, Src3Lower, Src1Lower);
CalculateDeferredFlags();
if (!Trivial) {
if (GPRSize == 8 && Size == 4) {
// This allows us to only hit the ZEXT case on failure
OrderedNode *RAXResult = _NZCVSelect(IR::i64Bit, CondClassType{COND_EQ},
Src3, Src1Lower);
// When the size is 4 we need to make sure not zext the GPR when the comparison fails
StoreGPRRegister(X86State::REG_RAX, RAXResult);
}
else {
StoreGPRRegister(X86State::REG_RAX, Src1Lower, Size);
}
}
// Op1 = RAX == Op1 ? Op2 : Op1
// If they match then set the rm operand to the input
// else don't set the rm operand
OrderedNode *DestResult = _Select(FEXCore::IR::COND_EQ,
Src1Lower, Src3Lower,
Src2, Src1);
OrderedNode *DestResult =
Trivial ? Src2 : _NZCVSelect(IR::i64Bit, CondClassType{COND_EQ}, Src2, Src1);
// Store in to GPR Dest
// Have to make sure this is after the result store in RAX for when Dest == RAX
if (GPRSize == 8 && Size == 4) {
// This allows us to only hit the ZEXT case on failure
OrderedNode *RAXResult = _Select(FEXCore::IR::COND_EQ,
CASResult, Src3Lower,
Src3, Src1Lower);
// When the size is 4 we need to make sure not zext the GPR when the comparison fails
StoreGPRRegister(X86State::REG_RAX, RAXResult);
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, DestResult, GPRSize, -1);
}
else {
StoreGPRRegister(X86State::REG_RAX, CASResult, Size);
} else {
StoreResult(GPRClass, Op, DestResult, -1);
}
OrderedNode *Result = _Sub(IR::SizeToOpSize(GPRSize), Src3Lower, CASResult);
GenerateFlags_SUB(Op, Result, Src3Lower, CASResult);
}
else {
HandledLock = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_LOCK;
+109 -67
View File
@@ -1025,27 +1025,100 @@
"ccmn xzr, #0, #nzCV, eq"
]
},
"cmpxchg cl, bl": {
"ExpectedInstructionCount": 14,
"ExpectedArm64ASM": [
"uxtb w20, w7",
"uxtb w21, w5",
"uxtb x22, w4",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmn wzr, w26, lsl #24",
"rmif x26, #7, #nzCv",
"eor w23, w22, w21",
"eor w22, w26, w22",
"and w22, w22, w23",
"rmif x22, #7, #nzcV",
"bfxil x4, x21, #0, #8",
"csel x20, x20, x21, eq",
"bfxil x5, x20, #0, #8"
]
},
"cmpxchg cx, bx": {
"ExpectedInstructionCount": 14,
"ExpectedArm64ASM": [
"uxth w20, w7",
"uxth w21, w5",
"uxth x22, w4",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmn wzr, w26, lsl #16",
"rmif x26, #15, #nzCv",
"eor w23, w22, w21",
"eor w22, w26, w22",
"and w22, w22, w23",
"rmif x22, #15, #nzcV",
"bfxil x4, x21, #0, #16",
"csel x20, x20, x21, eq",
"bfxil x5, x20, #0, #16"
]
},
"cmpxchg ecx, ebx": {
"ExpectedInstructionCount": 9,
"ExpectedArm64ASM": [
"mov w20, w7",
"mov w21, w5",
"mov w22, w4",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmp w22, w21",
"cfinv",
"csel x4, x4, x21, eq",
"csel x5, x20, x5, eq"
]
},
"cmpxchg rcx, rbx": {
"ExpectedInstructionCount": 7,
"ExpectedArm64ASM": [
"mov x20, x5",
"sub x26, x4, x20",
"eor x27, x4, x20",
"cmp x4, x20",
"cfinv",
"mov x4, x20",
"csel x5, x7, x20, eq"
]
},
"cmpxchg [rax], rbx": {
"ExpectedInstructionCount": 8,
"Comment": "0x0f 0xb1",
"ExpectedArm64ASM": [
"mov x20, x4",
"mov x1, x20",
"casal x1, x7, [x20]",
"mov x4, x1",
"sub x26, x20, x4",
"eor x27, x20, x4",
"cmp x20, x4",
"cfinv"
]
},
"cmpxchg al, bl": {
"ExpectedInstructionCount": 17,
"ExpectedInstructionCount": 12,
"Comment": "0x0f 0xb0",
"ExpectedArm64ASM": [
"uxtb w20, w7",
"uxtb w21, w4",
"uxtb x22, w4",
"cmp x21, x22",
"csel x23, x22, x21, eq",
"cmp x21, x22",
"csel w20, w20, w21, eq",
"bfxil x4, x23, #0, #8",
"bfxil x4, x20, #0, #8",
"sub x26, x22, x23",
"eor w27, w22, w23",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmn wzr, w26, lsl #24",
"rmif x26, #7, #nzCv",
"eor w20, w22, w23",
"eor w21, w26, w22",
"and w20, w21, w20",
"rmif x20, #7, #nzcV"
"eor w21, w22, w21",
"eor w22, w26, w22",
"and w21, w22, w21",
"rmif x21, #7, #nzcV",
"bfxil x4, x20, #0, #8"
]
},
"cmpxchg [rax], bl": {
@@ -1069,26 +1142,21 @@
]
},
"cmpxchg ax, bx": {
"ExpectedInstructionCount": 17,
"ExpectedInstructionCount": 12,
"Comment": "0x0f 0xb1",
"ExpectedArm64ASM": [
"uxth w20, w7",
"uxth w21, w4",
"uxth x22, w4",
"cmp x21, x22",
"csel x23, x22, x21, eq",
"cmp x21, x22",
"csel w20, w20, w21, eq",
"bfxil x4, x23, #0, #16",
"bfxil x4, x20, #0, #16",
"sub x26, x22, x23",
"eor w27, w22, w23",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmn wzr, w26, lsl #16",
"rmif x26, #15, #nzCv",
"eor w20, w22, w23",
"eor w21, w26, w22",
"and w20, w21, w20",
"rmif x20, #15, #nzcV"
"eor w21, w22, w21",
"eor w22, w26, w22",
"and w21, w22, w21",
"rmif x21, #15, #nzcV",
"bfxil x4, x20, #0, #16"
]
},
"cmpxchg [rax], bx": {
@@ -1112,24 +1180,17 @@
]
},
"cmpxchg eax, ebx": {
"ExpectedInstructionCount": 15,
"ExpectedInstructionCount": 8,
"Comment": "0x0f 0xb1",
"ExpectedArm64ASM": [
"mov w20, w7",
"mov x21, x4",
"mov w22, w21",
"mov w23, w21",
"cmp x22, x23",
"csel x24, x23, x22, eq",
"cmp x22, x23",
"csel x20, x20, x21, eq",
"cmp x24, x23",
"csel x4, x21, x22, eq",
"mov x4, x20",
"sub x26, x23, x24",
"eor w27, w23, w24",
"cmp w23, w24",
"cfinv"
"mov w21, w4",
"mov w22, w4",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmp w22, w21",
"cfinv",
"mov x4, x20"
]
},
"cmpxchg [rax], ebx": {
@@ -1150,34 +1211,15 @@
]
},
"cmpxchg rax, rbx": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 6,
"Comment": "0x0f 0xb1",
"ExpectedArm64ASM": [
"mov x20, x4",
"cmp x20, x20",
"csel x21, x20, x20, eq",
"cmp x20, x20",
"csel x22, x7, x20, eq",
"mov x4, x21",
"mov x4, x22",
"sub x26, x20, x21",
"eor x27, x20, x21",
"cmp x20, x21",
"cfinv"
]
},
"cmpxchg [rax], rbx": {
"ExpectedInstructionCount": 8,
"Comment": "0x0f 0xb1",
"ExpectedArm64ASM": [
"mov x20, x4",
"mov x1, x20",
"casal x1, x7, [x20]",
"mov x4, x1",
"sub x26, x20, x4",
"eor x27, x20, x4",
"cmp x20, x4",
"cfinv"
"mov x20, x7",
"sub x26, x4, x4",
"mov w27, #0x0",
"cmp x4, x4",
"cfinv",
"mov x4, x20"
]
},
"btr ax, bx": {
+39 -61
View File
@@ -1895,30 +1895,25 @@
]
},
"cmpxchg al, bl": {
"ExpectedInstructionCount": 21,
"ExpectedInstructionCount": 16,
"Comment": "0x0f 0xb0",
"ExpectedArm64ASM": [
"uxtb w20, w7",
"uxtb w21, w4",
"uxtb x22, w4",
"cmp x21, x22",
"csel x23, x22, x21, eq",
"cmp x21, x22",
"csel w20, w20, w21, eq",
"bfxil x4, x23, #0, #8",
"bfxil x4, x20, #0, #8",
"sub x26, x22, x23",
"eor w27, w22, w23",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmn wzr, w26, lsl #24",
"mrs x20, nzcv",
"ubfx x21, x26, #8, #1",
"orr w20, w20, w21, lsl #29",
"eor w21, w22, w23",
"mrs x23, nzcv",
"ubfx x24, x26, #8, #1",
"orr w23, w23, w24, lsl #29",
"eor w21, w22, w21",
"eor w22, w26, w22",
"and w21, w22, w21",
"ubfx x21, x21, #7, #1",
"orr w20, w20, w21, lsl #28",
"msr nzcv, x20"
"orr w21, w23, w21, lsl #28",
"msr nzcv, x21",
"bfxil x4, x20, #0, #8"
]
},
"cmpxchg [rax], bl": {
@@ -1946,30 +1941,25 @@
]
},
"cmpxchg ax, bx": {
"ExpectedInstructionCount": 21,
"ExpectedInstructionCount": 16,
"Comment": "0x0f 0xb1",
"ExpectedArm64ASM": [
"uxth w20, w7",
"uxth w21, w4",
"uxth x22, w4",
"cmp x21, x22",
"csel x23, x22, x21, eq",
"cmp x21, x22",
"csel w20, w20, w21, eq",
"bfxil x4, x23, #0, #16",
"bfxil x4, x20, #0, #16",
"sub x26, x22, x23",
"eor w27, w22, w23",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmn wzr, w26, lsl #16",
"mrs x20, nzcv",
"ubfx x21, x26, #16, #1",
"orr w20, w20, w21, lsl #29",
"eor w21, w22, w23",
"mrs x23, nzcv",
"ubfx x24, x26, #16, #1",
"orr w23, w23, w24, lsl #29",
"eor w21, w22, w21",
"eor w22, w26, w22",
"and w21, w22, w21",
"ubfx x21, x21, #15, #1",
"orr w20, w20, w21, lsl #28",
"msr nzcv, x20"
"orr w21, w23, w21, lsl #28",
"msr nzcv, x21",
"bfxil x4, x20, #0, #16"
]
},
"cmpxchg [rax], bx": {
@@ -1997,26 +1987,19 @@
]
},
"cmpxchg eax, ebx": {
"ExpectedInstructionCount": 17,
"ExpectedInstructionCount": 10,
"Comment": "0x0f 0xb1",
"ExpectedArm64ASM": [
"mov w20, w7",
"mov x21, x4",
"mov w22, w21",
"mov w23, w21",
"cmp x22, x23",
"csel x24, x23, x22, eq",
"cmp x22, x23",
"csel x20, x20, x21, eq",
"cmp x24, x23",
"csel x4, x21, x22, eq",
"mov x4, x20",
"sub x26, x23, x24",
"eor w27, w23, w24",
"cmp w23, w24",
"mrs x20, nzcv",
"eor w20, w20, #0x20000000",
"msr nzcv, x20"
"mov w21, w4",
"mov w22, w4",
"sub x26, x22, x21",
"eor w27, w22, w21",
"cmp w22, w21",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"msr nzcv, x21",
"mov x4, x20"
]
},
"cmpxchg [rax], ebx": {
@@ -2039,22 +2022,17 @@
]
},
"cmpxchg rax, rbx": {
"ExpectedInstructionCount": 13,
"ExpectedInstructionCount": 8,
"Comment": "0x0f 0xb1",
"ExpectedArm64ASM": [
"mov x20, x4",
"cmp x20, x20",
"csel x21, x20, x20, eq",
"cmp x20, x20",
"csel x22, x7, x20, eq",
"mov x4, x21",
"mov x4, x22",
"sub x26, x20, x21",
"eor x27, x20, x21",
"cmp x20, x21",
"mrs x20, nzcv",
"eor w20, w20, #0x20000000",
"msr nzcv, x20"
"mov x20, x7",
"sub x26, x4, x4",
"mov w27, #0x0",
"cmp x4, x4",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"msr nzcv, x21",
"mov x4, x20"
]
},
"cmpxchg [rax], rbx": {