Merge pull request #438 from Sonicadvance1/psadw

Fixes PSADBW
This commit is contained in:
Ryan Houdek authored and GitHub committed 2020-09-28 13:43:59 -07:00
commit eedc4b0af2
5 files changed
+160 -36

No files matched your search

+3 -2
View File
@@ -2723,9 +2723,10 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
auto Src = GetSrc(Op->Header.Args[0].ID());
auto Dest = GetDst(Node);
vpxor(xmm15, xmm15, xmm15);
uint8_t Elements = OpSize / Op->Header.ElementSize;
switch (Op->Header.ElementSize) {
case 2: {
for (int i = 0; i < (Op->Header.Size / 4); ++i) {
for (int i = Elements; i > 1; i >>= 1) {
phaddw(Dest, Src);
Src = Dest;
}
@@ -2734,7 +2735,7 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
break;
}
case 4: {
for (int i = 0; i < (Op->Header.Size / 8); ++i) {
for (int i = Elements; i > 1; i >>= 1) {
phaddd(Dest, Src);
Src = Dest;
}
+25 -32
View File
@@ -7922,53 +7922,46 @@ void OpDispatchBuilder::FenceOp(OpcodeArgs) {
}
void OpDispatchBuilder::PSADBW(OpcodeArgs) {
// The documentation is actually incorrect in how this instruction operates
// It strongly implies that the `abs(dest[i] - src[i])` operates in 8bit space
// but it actually operates in more than 8bit space
// This can be seen with `abs(0 - 0xFF)` returning a different result depending
// on bit length
auto Size = GetSrcSize(Op);
OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1);
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
OrderedNode *SubResult = _VSub(Size, 1, Dest, Src);
OrderedNode *AbsResult = _VAbs(Size, 1, SubResult);
OrderedNode *Result{};
if (Size == 8) {
// First we need to extract the 8bit values and extend them to 16bits
OrderedNode *Result_Low = _VUXTL(Size, 1, AbsResult);
// Now extract the upper 8bits and extend to 16bits
OrderedNode *Result_High = _VUShrI(Size, 2, AbsResult, 8);
Dest = _VUXTL(Size*2, 1, Dest);
Src = _VUXTL(Size*2, 1, Src);
OrderedNode *SubResult = _VSub(Size*2, 2, Dest, Src);
OrderedNode *AbsResult = _VAbs(Size*2, 2, SubResult);
// Now vector-wide add the results for each
Result_Low = _VAddV(Size, 2, Result_Low);
Result_High = _VAddV(Size, 2, Result_High);
// Now add the two scalar results back together
// Easy with only 8 byte registers
Result = _VAdd(Size, 2, Result_Low, Result_High);
Result = _VAddV(Size * 2, 2, AbsResult);
}
else {
// For 16byte registers we need to do a bit more work
// First we need to extract the 8bit values and extend them to 16bits
OrderedNode *Result_Low_Low = _VUXTL(Size, 1, AbsResult);
//// Then we need to extract the upper 8 bits of the lower 64bit result and extend them to 16bits
OrderedNode *Result_Low_High = _VUShrI(Size, 2, AbsResult, 8);
OrderedNode *Dest_Low = _VUXTL(Size, 1, Dest);
OrderedNode *Dest_High = _VUXTL2(Size, 1, Dest);
// Now we need to extract the upper 64bits and do the same thing
OrderedNode *Result_High = _VExtractElement(Size, 8, AbsResult, 1);
OrderedNode *Result_High_Low = _VUXTL(Size, 1, Result_High);
OrderedNode *Result_High_High = _VUShrI(Size, 2, Result_High, 8);
OrderedNode *Src_Low = _VUXTL(Size, 1, Src);
OrderedNode *Src_High = _VUXTL2(Size, 1, Src);
OrderedNode *SubResult_Low = _VSub(Size, 2, Dest_Low, Src_Low);
OrderedNode *SubResult_High = _VSub(Size, 2, Dest_High, Src_High);
OrderedNode *AbsResult_Low = _VAbs(Size, 2, SubResult_Low);
OrderedNode *AbsResult_High = _VAbs(Size, 2, SubResult_High);
// Now vector pairwise add all four of these
Result_Low_Low = _VAddV(8, 2, Result_Low_Low);
Result_Low_High = _VAddV(8, 2, Result_Low_High);
OrderedNode * Result_Low = _VAddV(Size, 2, AbsResult_Low);
OrderedNode * Result_High = _VAddV(Size, 2, AbsResult_High);
Result_High_Low = _VAddV(8, 2, Result_High_Low);
Result_High_High = _VAddV(8, 2, Result_High_High);
//// Now add the low and high scalar results together
OrderedNode * Added_Result = _VAdd(8, 2, Result_Low_Low, Result_Low_High);
OrderedNode * Added_Result_High = _VAdd(8, 2, Result_High_Low, Result_High_High);
// Now generate a new 128bit value for this
Result = _VInsElement(Size, 8, 1, 0, Added_Result, Added_Result_High);
Result = _VInsElement(Size, 8, 1, 0, Result_Low, Result_High);
}
StoreResult(FPRClass, Op, Result, -1);
+52 -1
View File
@@ -1,7 +1,15 @@
%ifdef CONFIG
{
"RegData": {
"XMM0": ["0x100", "0x100"]
"XMM0": ["0x100", "0x100"],
"XMM1": ["0xC5", "0x88"],
"XMM2": ["0x66", "0x5A"],
"XMM3": ["0x6B", "0x68"],
"XMM4": ["0x60", "0x68"],
"XMM5": ["0x65", "0x65"],
"XMM6": ["0x33", "0x57"],
"XMM7": ["0x38", "0x5C"],
"XMM8": ["0x3B", "0x6D"]
},
"MemoryRegions": {
"0x100000000": "4096"
@@ -25,4 +33,47 @@ movaps xmm0, [rdx + 8 * 2]
psadbw xmm0, [rdx + 8 * 0]
lea rdx, [rel .data]
movaps xmm1, [rdx + 16 * 0]
movaps xmm2, [rdx + 16 * 1]
movaps xmm3, [rdx + 16 * 2]
movaps xmm4, [rdx + 16 * 3]
movaps xmm5, [rdx + 16 * 4]
movaps xmm6, [rdx + 16 * 5]
movaps xmm7, [rdx + 16 * 6]
movaps xmm8, [rdx + 16 * 7]
psadbw xmm1, [rdx + 16 * 8]
psadbw xmm2, [rdx + 16 * 9]
psadbw xmm3, [rdx + 16 * 10]
psadbw xmm4, [rdx + 16 * 11]
psadbw xmm5, [rdx + 16 * 12]
psadbw xmm6, [rdx + 16 * 13]
psadbw xmm7, [rdx + 16 * 14]
psadbw xmm8, [rdx + 16 * 15]
hlt
; align directive isn't aligning the data to 16bytes
nop
nop
; 256bytes of random data
.data:
db '\xe0\xfc\x2b\xa1\x06\x4f\x6c\xa7\x0f\x06\x6a\x1e\x7f\x76\x80\x9b'
db '\xe0\x56\xed\xaa\xf3\xc3\x68\x68\xde\xe6\xe6\x94\xe2\xe9\xfc\xf0'
db '\x6e\x35\xa8\x54\xd7\xab\x8b\x6c\x77\x5f\x92\xca\x25\xa6\x7e\x27'
db '\xc7\xcd\x73\xec\x95\xd6\x6f\x6a\xbb\xae\xf2\xbb\x27\xb9\xa1\xdd'
db '\x73\x4d\xd1\xc7\xd5\x2c\x31\x88\xfe\xe7\xdb\xfd\x1e\x1e\x09\x7f'
db '\x14\xfa\x4e\x95\xef\xe6\x9a\xf2\xa0\x42\x62\x9a\xa4\xa8\x73\x82'
db '\x0e\x0f\x16\x82\x38\x07\x12\x32\x07\x35\x92\xc1\x63\x07\x78\xb3'
db '\xcb\x46\x19\x57\x2b\x37\x2a\x46\x1f\x04\x0e\x79\x3d\xcd\x8d\xa3'
db '\x2b\xf3\x86\x2f\xab\xba\x57\x30\x2e\xd6\x2c\xf0\x46\x4f\x3f\xef'
db '\xef\xd1\xbb\x85\x34\x4b\x3c\xde\x9e\x48\xa3\xb9\x8d\x71\xe3\x9d'
db '\x09\x72\xfb\xde\x8a\x32\x50\x9d\x69\x98\xf1\xf6\x52\xeb\xf7\xee'
db '\xd6\x99\xc2\xff\x30\x1c\x02\xce\x70\x05\xb2\xf1\x56\x9c\x0e\xa6'
db '\x18\x62\xc4\xe2\x86\x38\x76\x30\x2f\xa1\xe4\xa7\x0e\x5d\x53\xeb'
db '\x14\x45\xe0\xb7\xe1\xe8\x02\x68\x1a\xfe\x8e\xc1\x8f\xf2\xeb\x46'
db '\x7f\x5d\x6a\x23\x46\x97\x2e\x03\x98\x12\x32\x8f\x54\x76\x59\xac'
db '\xc8\x76\x5f\xc8\x71\x0c\xd3\xb6\xc5\x19\xea\xab\xa6\x2c\x1d\x88'
+57 -1
View File
@@ -1,7 +1,14 @@
%ifdef CONFIG
{
"RegData": {
"MM0": "0x80"
"MM0": "0x0000000000000080",
"MM1": "0x0000000000000083",
"MM2": "0x0000000000000134",
"MM3": "0x0000000000000156",
"MM4": "0x0000000000000140",
"MM5": "0x000000000000013F",
"MM6": "0x000000000000008F",
"MM7": "0x00000000000000D1"
},
"MemoryRegions": {
"0x100000000": "4096"
@@ -15,9 +22,58 @@ mov rax, 0x4142434445464748
mov [rdx + 8 * 0], rax
mov rax, 0x5152535455565758
mov [rdx + 8 * 1], rax
mov rax, 0x912277A763B4EB8C
mov [rdx + 8 * 2], rax
mov rax, 0x589490D442F54AFD
mov [rdx + 8 * 3], rax
mov rax, 0xB5E43417A3F6706C
mov [rdx + 8 * 4], rax
mov rax, 0xB4F4B827515F5BFA
mov [rdx + 8 * 5], rax
mov rax, 0x52D0EF1BCB906B6A
mov [rdx + 8 * 6], rax
mov rax, 0x1D0FDF5D05D39C64
mov [rdx + 8 * 7], rax
mov rax, 0xAEFEDEA21EF08810
mov [rdx + 8 * 8], rax
mov rax, 0xF7D80319B125BDE5
movq mm0, [rdx + 8 * 1]
movq mm1, [rdx + 8 * 2]
movq mm2, [rdx + 8 * 3]
movq mm3, [rdx + 8 * 4]
movq mm4, [rdx + 8 * 5]
movq mm5, [rdx + 8 * 6]
movq mm6, [rdx + 8 * 7]
movq mm7, [rdx + 8 * 8]
psadbw mm0, [rdx + 8 * 0]
lea rdx, [rel .data]
movq mm1, [rdx + 8 * 0]
movq mm2, [rdx + 8 * 1]
movq mm3, [rdx + 8 * 2]
movq mm4, [rdx + 8 * 3]
movq mm5, [rdx + 8 * 4]
movq mm6, [rdx + 8 * 5]
movq mm7, [rdx + 8 * 6]
psadbw mm1, [rdx + 8 * 7]
psadbw mm2, [rdx + 8 * 8]
psadbw mm3, [rdx + 8 * 9]
psadbw mm4, [rdx + 8 * 10]
psadbw mm5, [rdx + 8 * 11]
psadbw mm6, [rdx + 8 * 12]
psadbw mm7, [rdx + 8 * 13]
hlt
.data:
; 128bytes of random numbers
db 'ba\xa7\x5e\xc8\x0f\x90\x25\xf1\xf8\x49\xbd\xab\x4d\x2b\xa1\xc4'
db 'e4\x69\xe3\x2a\x80\x8d\xd6\x0b\xb2\x6d\xea\xae\x2e\x23\xc2\x2c'
db 'f9\xc6\xee\x06\x53\x96\x00\xae\x8d\x06\xdc\xe1\x11\x06\x0c\x40'
db 'a5\x61\x83\x7c\x13\x25\x43\xea\xa7\x08\x52\xc4\x0f\x91\x2c\x2c'
db '5a\xe7\xcf\xf6\xe3\x6b\x9e\x9e\xd8\x85\xf7\xfd\x4a\x17\xb4\xc9'
db '16\x07\x13\x8c\x83\x89\xc3\x5e\x46\x63\x1a\x31\xb9\x2c\x72\x18'
db '23\xa2\xf0\x4d\x22\x2a\xe4\x86\x84\x1a\xae\xfc\x65\x49\x17\x8e'
db 'c8\xb0\xe3\x6c\xb3\xce\xa1\x2f\xce\x5f\xae\x06\xac\x28\x7d\xb5'
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"MM0": "0x00000000000007F8"
},
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif
mov rdx, 0xe0000000
mov rax, 0x0
mov [rdx + 8 * 0], rax
mov rax, -1
mov [rdx + 8 * 1], rax
movq mm0, [rdx + 8 * 0]
psadbw mm0, [rdx + 8 * 1]
hlt