diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c | 125 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f30f.c | 4 |
2 files changed, 127 insertions, 2 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c b/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c index b3cfb048..05bad3e7 100644 --- a/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c @@ -105,6 +105,131 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, SD(xZR, gyback, gyoffset); SD(xZR, gyback, gyoffset + 8); break; + case 0x5D: + INST_NAME("VMINSS Gx, Vx, Ex"); + nextop = F8; + GETGX(); + GETEX(x1, 0, 1); + GETVX(); + GETGY(); + d0 = fpu_get_scratch(dyn); + d1 = fpu_get_scratch(dyn); + FLW(d0, vback, vxoffset); + FLW(d1, wback, fixedaddress); + FEQS(x2, d0, d0); + FEQS(x3, d1, d1); + AND(x2, x2, x3); + BEQ_MARK(x2, xZR); + FLES(x2, d1, d0); + BEQ_MARK2(x2, xZR); + MARK; + FMVS(d0, d1); + MARK2; + FSW(d0, gback, gdoffset); + if (gd != vex.v) { + LWU(x2, vback, vxoffset + 4); + SW(x2, gback, gdoffset + 4); + LD(x2, vback, vxoffset + 8); + SD(x2, gback, gdoffset + 8); + } + SD(xZR, gyback, gyoffset); + SD(xZR, gyback, gyoffset + 8); + break; + case 0x5F: + INST_NAME("VMAXSS Gx, Vx, Ex"); + nextop = F8; + GETGX(); + GETEX(x1, 0, 1); + GETVX(); + GETGY(); + d0 = fpu_get_scratch(dyn); + d1 = fpu_get_scratch(dyn); + FLW(d0, vback, vxoffset); + FLW(d1, wback, fixedaddress); + FEQS(x2, d0, d0); + FEQS(x3, d1, d1); + AND(x2, x2, x3); + BEQ_MARK(x2, xZR); + FLES(x2, d0, d1); + BEQ_MARK2(x2, xZR); + MARK; + FMVS(d0, d1); + MARK2; + FSW(d0, gback, gdoffset); + if (gd != vex.v) { + LWU(x2, vback, vxoffset + 4); + SW(x2, gback, gdoffset + 4); + LD(x2, vback, vxoffset + 8); + SD(x2, gback, gdoffset + 8); + } + SD(xZR, gyback, gyoffset); + SD(xZR, gyback, gyoffset + 8); + break; + case 0xC2: + INST_NAME("VCMPSS Gx, Vx, Ex, Ib"); + nextop = F8; + GETEX(x1, 0, 1); + GETGX(); + GETVX(); + GETGY(); + d0 = fpu_get_scratch(dyn); + d1 = fpu_get_scratch(dyn); + FLW(d0, vback, vxoffset); + FLW(d1, wback, fixedaddress); + u8 = F8; + if ((u8 & 7) == 0) { // Equal + FEQS(x2, d0, d1); + } else if ((u8 & 7) == 4) { // Not Equal or unordered + FEQS(x2, d0, d1); + XORI(x2, x2, 1); + } else { + // x2 = !(isnan(d0) || isnan(d1)) + FEQS(x3, d0, d0); + FEQS(x2, d1, d1); + AND(x2, x2, x3); + + switch (u8 & 7) { + case 1: + BEQ_MARK(x2, xZR); + FLTS(x2, d0, d1); + break; // Less than + case 2: + BEQ_MARK(x2, xZR); + FLES(x2, d0, d1); + break; // Less or equal + case 3: XORI(x2, x2, 1); break; // NaN + case 5: { // Greater or equal or unordered + BEQ_MARK2(x2, xZR); + FLES(x2, d1, d0); + B_MARK_nocond; + break; + } + case 6: { // Greater or unordered, test inverted, N!=V so unordered or less than (inverted) + BEQ_MARK2(x2, xZR); + FLTS(x2, d1, d0); + B_MARK_nocond; + break; + } + case 7: break; // Not NaN + } + + MARK2; + if ((u8 & 7) == 5 || (u8 & 7) == 6) { + MOV32w(x2, 1); + } + MARK; + } + NEG(x2, x2); + SW(x2, gback, gdoffset); + if (gd != vex.v) { + LWU(x2, vback, vxoffset + 4); + SW(x2, gback, gdoffset + 4); + LD(x2, vback, vxoffset + 8); + SD(x2, gback, gdoffset + 8); + } + SD(xZR, gyback, gyoffset); + SD(xZR, gyback, gyoffset + 8); + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c index 50e19353..a6c8ad55 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f.c @@ -303,7 +303,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int FEQS(x3, d1, d1); AND(x2, x2, x3); BEQ_MARK(x2, xZR); - FLTS(x2, d1, d0); + FLES(x2, d1, d0); BEQ_MARK2(x2, xZR); MARK; FMVS(d0, d1); @@ -336,7 +336,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int FEQS(x3, d1, d1); AND(x2, x2, x3); BEQ_MARK(x2, xZR); - FLTS(x2, d0, d1); + FLES(x2, d0, d1); BEQ_MARK2(x2, xZR); MARK; FMVS(d0, d1); |