diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index b326c71c0..7cc3938eb 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -1218,6 +1218,26 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni VEXTRINS_D(v0, q1, 0x11); // v0[127:64] = q1[127:64] } break; + case 0xC7: + // rep has no impact here + nextop = F8; + if (MODREG) { + switch ((nextop >> 3) & 7) { + default: + DEFAULT; + } + } else { + switch ((nextop >> 3) & 7) { + case 4: + INST_NAME("Unsupported XSAVEC Ed"); + FAKEED; + UDF(); + break; + default: + DEFAULT; + } + } + break; case 0xC8: case 0xC9: case 0xCA: diff --git a/src/dynarec/la64/dynarec_la64_64.c b/src/dynarec/la64/dynarec_la64_64.c index 9351017fa..f1151e106 100644 --- a/src/dynarec/la64/dynarec_la64_64.c +++ b/src/dynarec/la64/dynarec_la64_64.c @@ -359,6 +359,23 @@ uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } } break; + case 0x8E: + INST_NAME("MOV Seg, Ew"); + grab_segdata(dyn, addr, ninst, x4, seg); + nextop = F8; + u8 = (nextop & 0x38) >> 3; + if ((nextop & 0xC0) == 0xC0) { + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 0, 0); + ADDz(x4, wback, x4); + LD_HU(x1, x4, 0); + ed = x1; + } + ST_H(ed, xEmu, offsetof(x64emu_t, segs[u8])); + ST_W(xZR, xEmu, offsetof(x64emu_t, segs_serial[u8])); + break; case 0xA1: INST_NAME("MOV EAX, FS:Od"); grab_segdata(dyn, addr, ninst, x4, seg); diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c index 3eabd50b7..64aefdff2 100644 --- a/src/dynarec/la64/dynarec_la64_f30f.c +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -331,6 +331,33 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int SMWRITE2(); } break; + case 0xAE: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 2: + INST_NAME("(unsupported) WRFSBASE Ed"); + FAKEED; + UDF(); + break; + case 3: + INST_NAME("(unsupported) WRGSBASE Ed"); + FAKEED; + UDF(); + break; + case 5: + INST_NAME("(unsupported) INCSSPD/INCSSPQ Ed"); + FAKEED; + UDF(); + break; + case 6: + INST_NAME("(unsupported) UMONITOR Ed"); + FAKEED; + UDF(); + break; + default: + DEFAULT; + } + break; case 0xB8: INST_NAME("POPCNT Gd, Ed"); SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 2d48879cd..1cccad6af 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -274,6 +274,11 @@ f24-f31 fs0-fs7 Static registers Callee #define NOP() ANDI(xZR, xZR, 0) +#define BREAK() EMIT(0b1010100) + +// there is no UDF instruction, use BREAK instead is an acceptable offer +#define UDF() BREAK() + // tmp = SLL(GR[rj][31:0], GR[rk][4:0]) // GR[rd] = SignExtend(tmp[31:0], GRLEN) #define SLL_W(rd, rj, rk) EMIT(type_3R(0b00000000000101110, rk, rj, rd))