Skip to content

Commit

Permalink
[LA64_DYNAREC] Added more opcodes (#1590)
Browse files Browse the repository at this point in the history
  • Loading branch information
ksco authored Jun 17, 2024
1 parent 387c64b commit 95a4aaf
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 3 deletions.
146 changes: 146 additions & 0 deletions src/dynarec/la64/dynarec_la64_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,152 @@ uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEDO(x4, 0);
emit_xor32(dyn, ninst, rex, gd, ed, x3, x4);
break;
case 0x81:
case 0x83:
nextop = F8;
grab_segdata(dyn, addr, ninst, x6, seg);
switch ((nextop >> 3) & 7) {
case 0:
if (opcode == 0x81) {
INST_NAME("ADD Ed, Id");
} else {
INST_NAME("ADD Ed, Ib");
}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEDO(x6, (opcode == 0x81) ? 4 : 1);
if (opcode == 0x81)
i64 = F32S;
else
i64 = F8S;
emit_add32c(dyn, ninst, rex, ed, i64, x3, x4, x5, xMASK);
IFXA (X_CF, !la64_lbt)
REGENERATE_MASK(); // use xMASK as a scratch
WBACKO(x6);
break;
case 1:
if (opcode == 0x81) {
INST_NAME("OR Ed, Id");
} else {
INST_NAME("OR Ed, Ib");
}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEDO(x6, (opcode == 0x81) ? 4 : 1);
if (opcode == 0x81)
i64 = F32S;
else
i64 = F8S;
emit_or32c(dyn, ninst, rex, ed, i64, x3, x4);
WBACKO(x6);
break;
case 2:
if (opcode == 0x81) {
INST_NAME("ADC Ed, Id");
} else {
INST_NAME("ADC Ed, Ib");
}
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEDO(x6, (opcode == 0x81) ? 4 : 1);
if (opcode == 0x81)
i64 = F32S;
else
i64 = F8S;
MOV64xw(x5, i64);
IFXA (X_ALL, !la64_lbt)
ST_D(x6, xEmu, offsetof(x64emu_t, scratch));
emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x6, xMASK);
IFXA (X_ALL, !la64_lbt) {
LD_D(x6, xEmu, offsetof(x64emu_t, scratch));
REGENERATE_MASK(); // use xMASK as a scratch
}
WBACKO(x6);
break;
case 3:
if (opcode == 0x81) {
INST_NAME("SBB Ed, Id");
} else {
INST_NAME("SBB Ed, Ib");
}
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEDO(x6, (opcode == 0x81) ? 4 : 1);
if (opcode == 0x81)
i64 = F32S;
else
i64 = F8S;
MOV64xw(x5, i64);
emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4, xMASK);
IFXA (X_CF, !la64_lbt)
REGENERATE_MASK(); // use xMASK as a scratch
WBACKO(x6);
break;
case 4:
if (opcode == 0x81) {
INST_NAME("AND Ed, Id");
} else {
INST_NAME("AND Ed, Ib");
}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEDO(x6, (opcode == 0x81) ? 4 : 1);
if (opcode == 0x81)
i64 = F32S;
else
i64 = F8S;
emit_and32c(dyn, ninst, rex, ed, i64, x3, x4);
WBACKO(x6);
break;
case 5:
if (opcode == 0x81) {
INST_NAME("SUB Ed, Id");
} else {
INST_NAME("SUB Ed, Ib");
}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEDO(x6, (opcode == 0x81) ? 4 : 1);
if (opcode == 0x81)
i64 = F32S;
else
i64 = F8S;
emit_sub32c(dyn, ninst, rex, ed, i64, x3, x4, x5, xMASK);
IFXA (X_CF, !la64_lbt)
REGENERATE_MASK(); // use xMASK as a scratch
WBACKO(x6);
break;
case 6:
if (opcode == 0x81) {
INST_NAME("XOR Ed, Id");
} else {
INST_NAME("XOR Ed, Ib");
}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEDO(x6, (opcode == 0x81) ? 4 : 1);
if (opcode == 0x81)
i64 = F32S;
else
i64 = F8S;
emit_xor32c(dyn, ninst, rex, ed, i64, x3, x4);
WBACKO(x6);
break;
case 7:
if (opcode == 0x81) {
INST_NAME("CMP Ed, Id");
} else {
INST_NAME("CMP Ed, Ib");
}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEDO(x6, (opcode == 0x81) ? 4 : 1);
if (opcode == 0x81)
i64 = F32S;
else
i64 = F8S;
if (i64) {
MOV64xw(x2, i64);
emit_cmp32(dyn, ninst, rex, ed, x2, x3, x4, x5, x6);
} else
emit_cmp32_0(dyn, ninst, rex, ed, x3, x4);
break;
}
break;
case 0x89:
INST_NAME("MOV Seg:Ed, Gd");
grab_segdata(dyn, addr, ninst, x4, seg);
Expand Down
21 changes: 21 additions & 0 deletions src/dynarec/la64/dynarec_la64_660f.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
MAYUSE(j64);

switch (opcode) {
case 0x11:
INST_NAME("MOVUPD Ex,Gx");
nextop = F8;
GETG;
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
if (MODREG) {
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop & 7) + (rex.b << 3));
VOR_V(v1, v0, v0);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
VST(v0, ed, fixedaddress);
SMWRITE2();
}
break;
case 0x12:
INST_NAME("MOVLPD Gx, Eq");
nextop = F8;
Expand Down Expand Up @@ -915,6 +929,13 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
VXOR_V(q0, q0, q1);
}
break;
case 0xF4:
INST_NAME("PMULUDQ Gx,Ex");
nextop = F8;
GETGX(v0, 1);
GETEX(v1, 0, 0);
VMULWEV_D_WU(v0, v0, v1);
break;
case 0xF8:
INST_NAME("PSUBB Gx,Ex");
nextop = F8;
Expand Down
8 changes: 8 additions & 0 deletions src/dynarec/la64/dynarec_la64_f20f.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,14 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
VEXTRINS_D(v0, v1, 0);
MARK2;
break;
case 0x70:
INST_NAME("PSHUFLW Gx, Ex, Ib");
nextop = F8;
GETEX(v1, 0, 1);
GETGX(v0, 1);
u8 = F8;
VSHUF4I_H(v0, v1, u8);
break;
case 0xC2:
INST_NAME("CMPSD Gx, Ex, Ib");
nextop = F8;
Expand Down
4 changes: 1 addition & 3 deletions src/dynarec/la64/dynarec_la64_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,9 +685,7 @@ void call_c(dynarec_la64_t* dyn, int ninst, void* fnc, int reg, int ret, int sav
LD_D(xRIP, xEmu, offsetof(x64emu_t, ip));
#undef GO
}
// regenerate mask
ADDI_W(xMASK, xZR, -1);
LU32I_D(xMASK, 0);
REGENERATE_MASK();

fpu_popcache(dyn, ninst, reg, 0);
if (saveflags) {
Expand Down
13 changes: 13 additions & 0 deletions src/dynarec/la64/dynarec_la64_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@
ST_W(ed, wback, fixedaddress); \
SMWRITE(); \
}

#define WBACKO(O) \
if (wback) { \
SDXxw(ed, wback, O); \
SMWRITE2(); \
}

// GETSEW will use i for ed, and can use r3 for wback. This is the Signed version
#define GETSEW(i, D) \
if (MODREG) { \
Expand Down Expand Up @@ -1106,6 +1113,12 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
} \
} while (0)

#define REGENERATE_MASK() \
do { \
ADDI_W(xMASK, xZR, -1); \
LU32I_D(xMASK, 0); \
} while (0)

#define PURGE_YMM() /* TODO */

#endif //__DYNAREC_LA64_HELPER_H__
8 changes: 8 additions & 0 deletions src/dynarec/la64/la64_emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -2059,6 +2059,14 @@ LSX instruction starts with V, LASX instruction starts with XV.
ST_W(rd, rj, imm12); \
} while (0)

#define SDXxw(rd, rj, rk) \
do { \
if (rex.w) \
STX_D(rd, rj, rk); \
else \
STX_W(rd, rj, rk); \
} while (0)

#define SDz(rd, rj, imm12) \
do { \
if (rex.is32bits) \
Expand Down

0 comments on commit 95a4aaf

Please sign in to comment.