diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 31 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 46 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_emit_math.c | 9 |
3 files changed, 67 insertions, 19 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 586d2392..51818d83 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -1022,6 +1022,37 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni LD_BU(x2, x1, 0); BSTRINS_D(xRAX, x2, 7, 0); break; + case 0xA4: + if (rep) { + INST_NAME("REP MOVSB"); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1 << F_DF); + BNEZ_MARK2(x1); + MARK; // Part with DF==0 + LD_BU(x1, xRSI, 0); + ST_B(x1, xRDI, 0); + ADDI_D(xRSI, xRSI, 1); + ADDI_D(xRDI, xRDI, 1); + ADDI_D(xRCX, xRCX, -1); + BNEZ_MARK(xRCX); + B_NEXT_nocond; + MARK2; // Part with DF==1 + LD_BU(x1, xRSI, 0); + ST_B(x1, xRDI, 0); + ADDI_D(xRSI, xRSI, -1); + ADDI_D(xRDI, xRDI, -1); + ADDI_D(xRCX, xRCX, -1); + BNEZ_MARK2(xRCX); + // done + } else { + INST_NAME("MOVSB"); + GETDIR(x3, x1, 1); + LD_BU(x1, xRSI, 0); + ST_B(x1, xRDI, 0); + ADD_D(xRSI, xRSI, x3); + ADD_D(xRDI, xRDI, x3); + } + break; case 0xA5: if (rep) { INST_NAME("REP MOVSD"); diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index cf5db94b..7255c32e 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -66,21 +66,12 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(MODREG) { switch(nextop) { case 0xD0: - //TODO - DEFAULT; - /* - INST_NAME("FAKE xgetbv"); - nextop = F8; - addr = fakeed(dyn, addr, ninst, nextop); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state - GETIP(ip); - STORE_XEMU_CALL(); - CALL(native_ud, -1); - LOAD_XEMU_CALL(); - jump_to_epilog(dyn, 0, xRIP, ninst); - *need_epilog = 0; - *ok = 0; - */ + INST_NAME("XGETBV"); + BEQZ_MARK(xRCX); + EMIT(0); // Is there any assigned illegal instruction? + MARK; + MOV32w(xRAX, 0b111); + MOV32w(xRDX, 0); break; default: DEFAULT; @@ -544,6 +535,31 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni else BSTRINS_D(xFlags, x4, F_CF, F_CF); break; + case 0xAE: + nextop = F8; + if (MODREG) + switch (nextop) { + case 0xE8: + INST_NAME("LFENCE"); + SMDMB(); + break; + case 0xF0: + INST_NAME("MFENCE"); + SMDMB(); + break; + case 0xF8: + INST_NAME("SFENCE"); + SMDMB(); + break; + default: + DEFAULT; + } + else + switch ((nextop >> 3) & 7) { + default: + DEFAULT; + } + break; case 0xAF: INST_NAME("IMUL Gd, Ed"); SETFLAGS(X_ALL, SF_PENDING); diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index ad205467..b2caede0 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -1037,16 +1037,17 @@ void emit_adc32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s } if (la64_lbt) { + if (rex.w) + ADC_D(s1, s1, s2); + else + ADC_W(s1, s1, s2); + IFX (X_ALL) { if (rex.w) X64_ADC_D(s1, s2); else X64_ADC_W(s1, s2); } - if (rex.w) - ADC_D(s1, s1, s2); - else - ADC_W(s1, s1, s2); IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); |