Skip to content

Commit 75464e9

Browse files
authored
[LA64_DYNAREC] Added PCMPESTRM/PCMPISTRM opcodes (#3988)
1 parent 49e2489 commit 75464e9

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

src/dynarec/la64/dynarec_la64_660f.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,62 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
13311331
MOV32w(x4, u8);
13321332
CALL4(const_native_pclmul, -1, x1, x2, x3, x4);
13331333
break;
1334+
case 0x60:
1335+
INST_NAME("PCMPESTRM Gx, Ex, Ib");
1336+
nextop = F8;
1337+
GETG;
1338+
u8 = geted_ib(dyn, addr, ninst, nextop);
1339+
SETFLAGS(X_ALL, SF_SET_DF, NAT_FLAGS_NOFUSION);
1340+
if (gd > 7) sse_reflect_reg(dyn, ninst, gd);
1341+
ADDI_D(x3, xEmu, offsetof(x64emu_t, xmm[gd]));
1342+
if (MODREG) {
1343+
ed = (nextop & 7) + (rex.b << 3);
1344+
if (ed > 7) sse_reflect_reg(dyn, ninst, ed);
1345+
ADDI_D(x1, xEmu, offsetof(x64emu_t, xmm[ed]));
1346+
ed = x1;
1347+
} else {
1348+
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 1);
1349+
}
1350+
SEXT_W(x2, xRDX);
1351+
SEXT_W(x4, xRAX);
1352+
u8 = F8;
1353+
MOV32w(x5, u8);
1354+
CALL6(const_sse42_compare_string_explicit_len, x1, ed, x2, x3, x4, x5, 0);
1355+
v0 = sse_get_reg_empty(dyn, ninst, x1, 0);
1356+
if (u8 & 0b1000000) {
1357+
v1 = fpu_get_scratch(dyn);
1358+
switch (u8 & 1) {
1359+
case 0b00:
1360+
VREPLGR2VR_B(v0, x1);
1361+
SRLI_D(x2, x1, 8);
1362+
VREPLGR2VR_B(v1, x2);
1363+
VEXTRINS_D(v0, v1, 0x10);
1364+
MOV64x(x2, 0x0001020304050607);
1365+
VREPLGR2VR_D(v1, x2);
1366+
VSLL_B(v0, v0, v1);
1367+
MOV32w(x2, 0x80);
1368+
VREPLGR2VR_B(v1, x2);
1369+
VAND_V(v0, v0, v1);
1370+
VSRAI_B(v0, v0, 7);
1371+
break;
1372+
case 0b01:
1373+
VREPLGR2VR_H(v0, x1);
1374+
MOV64x(x2, 0x000C000D000E000F);
1375+
VREPLGR2VR_D(v1, x2);
1376+
MOV64x(x2, 0x00080009000A000B);
1377+
VINSGR2VR_D(v1, x2, 1);
1378+
VSLL_H(v0, v0, v1);
1379+
MOV32w(x2, 0x80);
1380+
VREPLGR2VR_B(v1, x2);
1381+
VAND_V(v0, v0, v1);
1382+
VSRAI_H(v0, v0, 15);
1383+
break;
1384+
}
1385+
} else {
1386+
VXOR_V(v0, v0, v0);
1387+
VINSGR2VR_H(v0, x1, 0);
1388+
}
1389+
break;
13341390
case 0x61:
13351391
INST_NAME("PCMPESTRI Gx, Ex, Ib");
13361392
nextop = F8;
@@ -1367,6 +1423,59 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
13671423
CTZ_W(xRCX, x1);
13681424
}
13691425
break;
1426+
case 0x62:
1427+
INST_NAME("PCMPISTRM Gx, Ex, Ib");
1428+
SETFLAGS(X_ALL, SF_SET_DF, NAT_FLAGS_NOFUSION);
1429+
nextop = F8;
1430+
GETG;
1431+
if (gd > 7) sse_reflect_reg(dyn, ninst, gd);
1432+
if (MODREG) {
1433+
ed = (nextop & 7) + (rex.b << 3);
1434+
if (ed > 7) sse_reflect_reg(dyn, ninst, ed);
1435+
ADDI_D(x1, xEmu, offsetof(x64emu_t, xmm[ed]));
1436+
ed = x1;
1437+
} else {
1438+
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 1);
1439+
}
1440+
ADDI_D(x2, xEmu, offsetof(x64emu_t, xmm[gd]));
1441+
u8 = F8;
1442+
MOV32w(x3, u8);
1443+
CALL4(const_sse42_compare_string_implicit_len, x1, ed, x2, x3, 0);
1444+
v0 = sse_get_reg_empty(dyn, ninst, x1, 0);
1445+
if (u8 & 0b1000000) {
1446+
v1 = fpu_get_scratch(dyn);
1447+
switch (u8 & 1) {
1448+
case 0b00:
1449+
VREPLGR2VR_B(v0, x1);
1450+
SRLI_D(x2, x1, 8);
1451+
VREPLGR2VR_B(v1, x2);
1452+
VEXTRINS_D(v0, v1, 0x10);
1453+
MOV64x(x2, 0x0001020304050607);
1454+
VREPLGR2VR_D(v1, x2);
1455+
VSLL_B(v0, v0, v1);
1456+
MOV32w(x2, 0x80);
1457+
VREPLGR2VR_B(v1, x2);
1458+
VAND_V(v0, v0, v1);
1459+
VSRAI_B(v0, v0, 7);
1460+
break;
1461+
case 0b01:
1462+
VREPLGR2VR_H(v0, x1);
1463+
MOV64x(x2, 0x000C000D000E000F);
1464+
VREPLGR2VR_D(v1, x2);
1465+
MOV64x(x2, 0x00080009000A000B);
1466+
VINSGR2VR_D(v1, x2, 1);
1467+
VSLL_H(v0, v0, v1);
1468+
MOV32w(x2, 0x80);
1469+
VREPLGR2VR_B(v1, x2);
1470+
VAND_V(v0, v0, v1);
1471+
VSRAI_H(v0, v0, 15);
1472+
break;
1473+
}
1474+
} else {
1475+
VXOR_V(v0, v0, v0);
1476+
VINSGR2VR_H(v0, x1, 0);
1477+
}
1478+
break;
13701479
case 0x63:
13711480
INST_NAME("PCMPISTRI Gx, Ex, Ib");
13721481
SETFLAGS(X_ALL, SF_SET_DF, NAT_FLAGS_NOFUSION);

0 commit comments

Comments
 (0)