diff options
| author | Leslie Zhai <zhaixiang@loongson.cn> | 2024-11-26 15:27:13 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-26 08:27:13 +0100 |
| commit | b207ecad6a35b43649496db5ea6e3042c773f1ac (patch) | |
| tree | 03487af1e9411cdac866c35ea5cb8e71a2aa9845 /src | |
| parent | 48461001d2ecf5f7f5c99a8c2be414761e298841 (diff) | |
| download | box64-b207ecad6a35b43649496db5ea6e3042c773f1ac.tar.gz box64-b207ecad6a35b43649496db5ea6e3042c773f1ac.zip | |
[LA64_DYNAREC] Added SBB opcodes (#2076)
* [LA64_DYNAREC] Added SBB opcodes * [LA64_DYNAREC] clang-format and fix LOCK ADC wrong ed
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 18 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_66.c | 37 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_67.c | 37 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f0.c | 2 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 22 |
5 files changed, 115 insertions, 1 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index c1ac8fa0..ab786d7b 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -243,6 +243,16 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_sbb32(dyn, ninst, rex, ed, gd, x3, x4, x5); WBACK; break; + case 0x1A: + INST_NAME("SBB Gb, Eb"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB(x2, 0); + GETGB(x1); + emit_sbb8(dyn, ninst, x1, x2, x6, x4, x5); + GBBACK(); + break; case 0x1B: INST_NAME("SBB Gd, Ed"); READFLAGS(X_CF); @@ -261,6 +271,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_sbb8c(dyn, ninst, x1, u8, x3, x4, x5, x6); BSTRINS_D(xRAX, x1, 7, 0); break; + case 0x1D: + INST_NAME("SBB EAX, Id"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + MOV64xw(x2, i64); + emit_sbb32(dyn, ninst, rex, xRAX, x2, x3, x4, x5); + break; case 0x20: INST_NAME("AND Eb, Gb"); SETFLAGS(X_ALL, SF_SET_PENDING); diff --git a/src/dynarec/la64/dynarec_la64_66.c b/src/dynarec/la64/dynarec_la64_66.c index d720b4cf..b23a13ac 100644 --- a/src/dynarec/la64/dynarec_la64_66.c +++ b/src/dynarec/la64/dynarec_la64_66.c @@ -159,6 +159,26 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_sbb16(dyn, ninst, x1, x2, x4, x5, x6); EWBACK; break; + case 0x1B: + INST_NAME("SBB Gw, Ew"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGW(x1); + GETEW(x2, 0); + emit_sbb16(dyn, ninst, x1, x2, x6, x4, x5); + GWBACK; + break; + case 0x1D: + INST_NAME("SBB AX, Iw"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + BSTRPICK_D(x1, xRAX, 15, 0); + u64 = F16; + MOV64x(x2, u64); + emit_sbb16(dyn, ninst, x1, x2, x3, x4, x5); + BSTRINSz(xRAX, x1, 15, 0); + break; case 0x21: INST_NAME("AND Ew, Gw"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -342,6 +362,23 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_adc16(dyn, ninst, x1, x5, x2, x4, x6); EWBACK; break; + case 3: // SBB + if (opcode == 0x81) { + INST_NAME("SBB Ew, Iw"); + } else { + INST_NAME("SBB Ew, Ib"); + } + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEW(x1, (opcode == 0x81) ? 2 : 1); + if (opcode == 0x81) + u64 = F16; + else + u64 = (uint16_t)(int16_t)F8S; + MOV64x(x5, u64); + emit_sbb16(dyn, ninst, x1, x5, x2, x4, x6); + EWBACK; + break; case 4: // AND if (opcode == 0x81) { INST_NAME("AND Ew, Iw"); diff --git a/src/dynarec/la64/dynarec_la64_67.c b/src/dynarec/la64/dynarec_la64_67.c index 0d69d45a..969c448b 100644 --- a/src/dynarec/la64/dynarec_la64_67.c +++ b/src/dynarec/la64/dynarec_la64_67.c @@ -62,6 +62,43 @@ uintptr_t dynarec64_67(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } switch(opcode) { + case 0x19: + INST_NAME("SBB Ed, Gd"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sbb32(dyn, ninst, rex, ed, gd, x3, x4, x5); + WBACK; + break; + case 0x1A: + INST_NAME("SBB Gb, Eb"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_sbb8(dyn, ninst, x1, x2, x3, x4, x5); + GBBACK(); + break; + case 0x1B: + INST_NAME("SBB Gd, Ed"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sbb32(dyn, ninst, rex, gd, ed, x3, x4, x5); + break; + case 0x1D: + INST_NAME("SBB EAX, Id"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + MOV64xw(x2, i64); + emit_sbb32(dyn, ninst, rex, xRAX, x2, x3, x4, x5); + break; case 0x88: INST_NAME("MOV Eb, Gb"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_f0.c b/src/dynarec/la64/dynarec_la64_f0.c index c92e9406..994cd0b5 100644 --- a/src/dynarec/la64/dynarec_la64_f0.c +++ b/src/dynarec/la64/dynarec_la64_f0.c @@ -410,7 +410,7 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETGD; SMDMB(); if (MODREG) { - ed = xRAX + (nextop & 7) + (rex.b << 3); + ed = TO_LA64((nextop & 7) + (rex.b << 3)); emit_adc32(dyn, ninst, rex, ed, gd, x3, x4, x5, x6); } else { addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 12ebe679..d66b6be8 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -250,6 +250,28 @@ wb1 = 1; \ ed = i; \ } +// GETEB32 will use i for ed, and can use r3 for wback. +#define GETEB32(i, D) \ + if (MODREG) { \ + if (rex.rex) { \ + wback = TO_LA64((nextop & 7) + (rex.b << 3)); \ + wb2 = 0; \ + } else { \ + wback = (nextop & 7); \ + wb2 = (wback >> 2) * 8; \ + wback = TO_LA64(wback & 3); \ + } \ + BSTRPICK_D(i, wback, wb2 + 7, wb2); \ + wb1 = 0; \ + ed = i; \ + } else { \ + SMREAD(); \ + addr = geted32(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \ + LD_BU(i, wback, fixedaddress); \ + wb1 = 1; \ + ed = i; \ + } + // GETGB will use i for gd #define GETGB(i) \ if (rex.rex) { \ |