mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-27 16:00:42 +01:00
Merge pull request #3372 from alyssarosenzweig/opt/cmpxchg-review
Optimize GPR cmpxchg
This commit is contained in:
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;
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
Reference in new issue
Block a user