mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 14:00:16 +02:00
Merge pull request #3093 from Sonicadvance1/optimize_blendp
OpcodeDispatcher: Optimize blendp{s,d}
This commit is contained in:
2 files changed
+152
-68
No files matched your search
@@ -4026,15 +4026,131 @@ void OpDispatchBuilder::AVXVectorRound<8, true>(OpcodeArgs);
|
||||
|
||||
template<size_t ElementSize>
|
||||
void OpDispatchBuilder::VectorBlend(OpcodeArgs) {
|
||||
const auto DstSize = GetDstSize(Op);
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
uint8_t Select = Op->Src[1].Data.Literal.Value;
|
||||
|
||||
OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1);
|
||||
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
for (size_t i = 0; i < (16 / ElementSize); ++i) {
|
||||
if (Select & (1 << i)) {
|
||||
// This could be optimized if it becomes costly
|
||||
Dest = _VInsElement(16, ElementSize, i, i, Dest, Src);
|
||||
|
||||
if constexpr (ElementSize == 4) {
|
||||
Select &= 0b1111;
|
||||
switch (Select) {
|
||||
case 0b0000:
|
||||
// No-op
|
||||
return;
|
||||
case 0b0001:
|
||||
// Dest[31:0] = Src[31:0]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 0, 0, Dest, Src);
|
||||
break;
|
||||
case 0b0010:
|
||||
// Dest[63:32] = Src[63:32]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 1, 1, Dest, Src);
|
||||
break;
|
||||
case 0b0011:
|
||||
// Dest[31:0] = Src[31:0]
|
||||
// Dest[63:32] = Src[63:32]
|
||||
Dest = _VInsElement(DstSize, 8, 0, 0, Dest, Src);
|
||||
break;
|
||||
case 0b0100:
|
||||
// Dest[95:64] = Src[95:64]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 2, 2, Dest, Src);
|
||||
break;
|
||||
case 0b0101:
|
||||
// Dest[31:0] = Src[31:0]
|
||||
// Dest[95:64] = Src[95:64]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 0, 0, Dest, Src);
|
||||
Dest = _VInsElement(DstSize, ElementSize, 2, 2, Dest, Src);
|
||||
break;
|
||||
case 0b0110:
|
||||
// Dest[63:32] = Src[63:32]
|
||||
// Dest[95:64] = Src[95:64]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 1, 1, Dest, Src);
|
||||
Dest = _VInsElement(DstSize, ElementSize, 2, 2, Dest, Src);
|
||||
break;
|
||||
case 0b0111:
|
||||
// Dest[31:0] = Src[31:0]
|
||||
// Dest[63:32] = Src[63:32]
|
||||
// Dest[95:64] = Src[95:64]
|
||||
Dest = _VInsElement(DstSize, 8, 0, 0, Dest, Src);
|
||||
Dest = _VInsElement(DstSize, ElementSize, 2, 2, Dest, Src);
|
||||
break;
|
||||
case 0b1000:
|
||||
// Dest[127:96] = Src[127:96]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 3, 3, Dest, Src);
|
||||
break;
|
||||
case 0b1001:
|
||||
// Dest[31:0] = Src[31:0]
|
||||
// Dest[127:96] = Src[127:96]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 0, 0, Dest, Src);
|
||||
Dest = _VInsElement(DstSize, ElementSize, 3, 3, Dest, Src);
|
||||
break;
|
||||
case 0b1010:
|
||||
// Dest[63:32] = Src[63:32]
|
||||
// Dest[127:96] = Src[127:96]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 1, 1, Dest, Src);
|
||||
Dest = _VInsElement(DstSize, ElementSize, 3, 3, Dest, Src);
|
||||
break;
|
||||
case 0b1011:
|
||||
// Dest[31:0] = Src[31:0]
|
||||
// Dest[63:32] = Src[63:32]
|
||||
// Dest[95:64] = Src[95:64]
|
||||
Dest = _VInsElement(DstSize, 8, 0, 0, Dest, Src);
|
||||
Dest = _VInsElement(DstSize, ElementSize, 3, 3, Dest, Src);
|
||||
break;
|
||||
case 0b1100:
|
||||
// Dest[95:64] = Src[95:64]
|
||||
// Dest[127:96] = Src[127:96]
|
||||
Dest = _VInsElement(DstSize, 8, 1, 1, Dest, Src);
|
||||
break;
|
||||
case 0b1101:
|
||||
// Dest[31:0] = Src[31:0]
|
||||
// Dest[95:64] = Src[95:64]
|
||||
// Dest[127:96] = Src[127:96]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 0, 0, Dest, Src);
|
||||
Dest = _VInsElement(DstSize, 8, 1, 1, Dest, Src);
|
||||
break;
|
||||
case 0b1110:
|
||||
// Dest[63:32] = Src[63:32]
|
||||
// Dest[95:64] = Src[95:64]
|
||||
// Dest[127:96] = Src[127:96]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 1, 1, Dest, Src);
|
||||
Dest = _VInsElement(DstSize, 8, 1, 1, Dest, Src);
|
||||
break;
|
||||
case 0b1111:
|
||||
// Copy
|
||||
Dest = Src;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else if constexpr (ElementSize == 8) {
|
||||
Select &= 0b11;
|
||||
switch (Select) {
|
||||
case 0b00:
|
||||
// No-op
|
||||
return;
|
||||
case 0b01:
|
||||
// Dest[63:0] = Src[63:0]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 0, 0, Dest, Src);
|
||||
break;
|
||||
case 0b10:
|
||||
// Dest[127:64] = Src[127:64]
|
||||
Dest = _VInsElement(DstSize, ElementSize, 1, 1, Dest, Src);
|
||||
break;
|
||||
case 0b11:
|
||||
// Copy
|
||||
Dest = Src;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < (16 / ElementSize); ++i) {
|
||||
if (Select & (1 << i)) {
|
||||
// This could be optimized if it becomes costly
|
||||
Dest = _VInsElement(16, ElementSize, i, i, Dest, Src);
|
||||
}
|
||||
}
|
||||
}
|
||||
StoreResult(FPRClass, Op, Dest, -1);
|
||||
|
||||
@@ -280,15 +280,12 @@
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 0000b": {
|
||||
"ExpectedInstructionCount": 2,
|
||||
"Optimal": "No",
|
||||
"ExpectedInstructionCount": 0,
|
||||
"Optimal": "Yes",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0c"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v2.16b, v16.16b",
|
||||
"mov v16.16b, v2.16b"
|
||||
]
|
||||
"ExpectedArm64ASM": []
|
||||
},
|
||||
"blendps xmm0, xmm1, 0001b": {
|
||||
"ExpectedInstructionCount": 1,
|
||||
@@ -311,18 +308,13 @@
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 0011b": {
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Optimal": "No",
|
||||
"ExpectedInstructionCount": 1,
|
||||
"Optimal": "Yes",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0c"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v0.16b, v16.16b",
|
||||
"mov v0.s[0], v17.s[0]",
|
||||
"mov v2.16b, v0.16b",
|
||||
"mov v0.16b, v2.16b",
|
||||
"mov v0.s[1], v17.s[1]",
|
||||
"mov v16.16b, v0.16b"
|
||||
"mov v16.d[0], v17.d[0]"
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 0100b": {
|
||||
@@ -366,16 +358,15 @@
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 0111b": {
|
||||
"ExpectedInstructionCount": 7,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Optimal": "No",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0c"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v0.16b, v16.16b",
|
||||
"mov v0.s[0], v17.s[0]",
|
||||
"mov v0.d[0], v17.d[0]",
|
||||
"mov v2.16b, v0.16b",
|
||||
"mov v2.s[1], v17.s[1]",
|
||||
"mov v0.16b, v2.16b",
|
||||
"mov v0.s[2], v17.s[2]",
|
||||
"mov v16.16b, v0.16b"
|
||||
@@ -422,22 +413,6 @@
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 1011b": {
|
||||
"ExpectedInstructionCount": 7,
|
||||
"Optimal": "No",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0c"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v0.16b, v16.16b",
|
||||
"mov v0.s[0], v17.s[0]",
|
||||
"mov v2.16b, v0.16b",
|
||||
"mov v2.s[1], v17.s[1]",
|
||||
"mov v0.16b, v2.16b",
|
||||
"mov v0.s[3], v17.s[3]",
|
||||
"mov v16.16b, v0.16b"
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 1100b": {
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Optimal": "No",
|
||||
"Comment": [
|
||||
@@ -445,15 +420,25 @@
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v0.16b, v16.16b",
|
||||
"mov v0.s[2], v17.s[2]",
|
||||
"mov v0.d[0], v17.d[0]",
|
||||
"mov v2.16b, v0.16b",
|
||||
"mov v0.16b, v2.16b",
|
||||
"mov v0.s[3], v17.s[3]",
|
||||
"mov v16.16b, v0.16b"
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 1100b": {
|
||||
"ExpectedInstructionCount": 1,
|
||||
"Optimal": "Yes",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0c"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v16.d[1], v17.d[1]"
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 1101b": {
|
||||
"ExpectedInstructionCount": 7,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Optimal": "No",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0c"
|
||||
@@ -462,14 +447,13 @@
|
||||
"mov v0.16b, v16.16b",
|
||||
"mov v0.s[0], v17.s[0]",
|
||||
"mov v2.16b, v0.16b",
|
||||
"mov v2.s[2], v17.s[2]",
|
||||
"mov v0.16b, v2.16b",
|
||||
"mov v0.s[3], v17.s[3]",
|
||||
"mov v0.d[1], v17.d[1]",
|
||||
"mov v16.16b, v0.16b"
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 1110b": {
|
||||
"ExpectedInstructionCount": 7,
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Optimal": "No",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0c"
|
||||
@@ -478,39 +462,28 @@
|
||||
"mov v0.16b, v16.16b",
|
||||
"mov v0.s[1], v17.s[1]",
|
||||
"mov v2.16b, v0.16b",
|
||||
"mov v2.s[2], v17.s[2]",
|
||||
"mov v0.16b, v2.16b",
|
||||
"mov v0.s[3], v17.s[3]",
|
||||
"mov v0.d[1], v17.d[1]",
|
||||
"mov v16.16b, v0.16b"
|
||||
]
|
||||
},
|
||||
"blendps xmm0, xmm1, 1111b": {
|
||||
"ExpectedInstructionCount": 8,
|
||||
"Optimal": "No",
|
||||
"ExpectedInstructionCount": 1,
|
||||
"Optimal": "Yes",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0c"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v0.16b, v16.16b",
|
||||
"mov v0.s[0], v17.s[0]",
|
||||
"mov v2.16b, v0.16b",
|
||||
"mov v2.s[1], v17.s[1]",
|
||||
"mov v2.s[2], v17.s[2]",
|
||||
"mov v0.16b, v2.16b",
|
||||
"mov v0.s[3], v17.s[3]",
|
||||
"mov v16.16b, v0.16b"
|
||||
"mov v16.16b, v17.16b"
|
||||
]
|
||||
},
|
||||
"blendpd xmm0, xmm1, 00b": {
|
||||
"ExpectedInstructionCount": 2,
|
||||
"Optimal": "No",
|
||||
"ExpectedInstructionCount": 0,
|
||||
"Optimal": "Yes",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0d"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v2.16b, v16.16b",
|
||||
"mov v16.16b, v2.16b"
|
||||
]
|
||||
"ExpectedArm64ASM": []
|
||||
},
|
||||
"blendpd xmm0, xmm1, 01b": {
|
||||
"ExpectedInstructionCount": 1,
|
||||
@@ -533,18 +506,13 @@
|
||||
]
|
||||
},
|
||||
"blendpd xmm0, xmm1, 11b": {
|
||||
"ExpectedInstructionCount": 6,
|
||||
"Optimal": "No",
|
||||
"ExpectedInstructionCount": 1,
|
||||
"Optimal": "Yes",
|
||||
"Comment": [
|
||||
"0x66 0x0f 0x3a 0x0d"
|
||||
],
|
||||
"ExpectedArm64ASM": [
|
||||
"mov v0.16b, v16.16b",
|
||||
"mov v0.d[0], v17.d[0]",
|
||||
"mov v2.16b, v0.16b",
|
||||
"mov v0.16b, v2.16b",
|
||||
"mov v0.d[1], v17.d[1]",
|
||||
"mov v16.16b, v0.16b"
|
||||
"mov v16.16b, v17.16b"
|
||||
]
|
||||
},
|
||||
"pblendw xmm0, xmm1, 00000000b": {
|
||||
|
||||
Reference in new issue
Block a user