diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-07-08 20:26:28 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-08 14:26:28 +0200 |
| commit | a7b912393c9bb865a18d8f95d42c14099ed10504 (patch) | |
| tree | e7deccb49bb774d3ef2f0abf80da6b56337687f5 /src | |
| parent | e82f17842edaf1664795f414042b154704b4569d (diff) | |
| download | box64-a7b912393c9bb865a18d8f95d42c14099ed10504.tar.gz box64-a7b912393c9bb865a18d8f95d42c14099ed10504.zip | |
[LA64_DYNAREC] Added more opcodes (#1654)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 9 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_64.c | 103 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f30f.c | 9 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 24 |
4 files changed, 145 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index ba441913..e7904928 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -641,6 +641,15 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_or8c(dyn, ninst, x1, u8, x2, x4, x5); EBBACK(); break; + case 3: // SBB + INST_NAME("SBB Eb, Ib"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEB(x1, 1); + u8 = F8; + emit_sbb8c(dyn, ninst, x1, u8, x2, x4, x5, x6); + EBBACK(); + break; case 4: // AND INST_NAME("AND Eb, Ib"); SETFLAGS(X_ALL, SF_SET_PENDING); diff --git a/src/dynarec/la64/dynarec_la64_64.c b/src/dynarec/la64/dynarec_la64_64.c index 0e7b96d6..892d3290 100644 --- a/src/dynarec/la64/dynarec_la64_64.c +++ b/src/dynarec/la64/dynarec_la64_64.c @@ -88,6 +88,81 @@ uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x66: addr = dynarec64_6664(dyn, addr, ip, ninst, rex, seg, ok, need_epilog); break; + case 0x80: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 0: // ADD + INST_NAME("ADD Eb, Ib"); + grab_segdata(dyn, addr, ninst, x1, seg); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEBO(x1, 1); + u8 = F8; + emit_add8c(dyn, ninst, x1, u8, x2, x4, x5); + EBBACK(); + break; + case 1: // OR + INST_NAME("OR Eb, Ib"); + grab_segdata(dyn, addr, ninst, x1, seg); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEBO(x1, 1); + u8 = F8; + emit_or8c(dyn, ninst, x1, u8, x2, x4, x5); + EBBACK(); + break; + case 3: // SBB + INST_NAME("SBB Eb, Ib"); + grab_segdata(dyn, addr, ninst, x1, seg); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEBO(x1, 1); + u8 = F8; + emit_sbb8c(dyn, ninst, x1, u8, x2, x4, x5, x6); + EBBACK(); + break; + case 4: // AND + INST_NAME("AND Eb, Ib"); + grab_segdata(dyn, addr, ninst, x1, seg); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEBO(x1, 1); + u8 = F8; + emit_and8c(dyn, ninst, x1, u8, x2, x4); + EBBACK(); + break; + case 5: // SUB + INST_NAME("SUB Eb, Ib"); + grab_segdata(dyn, addr, ninst, x1, seg); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEBO(x1, 1); + u8 = F8; + emit_sub8c(dyn, ninst, x1, u8, x2, x4, x5, x6); + EBBACK(); + break; + case 6: // XOR + INST_NAME("XOR Eb, Ib"); + grab_segdata(dyn, addr, ninst, x1, seg); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEBO(x1, 1); + u8 = F8; + emit_xor8c(dyn, ninst, x1, u8, x2, x4); + EBBACK(); + break; + case 7: // CMP + INST_NAME("CMP Eb, Ib"); + grab_segdata(dyn, addr, ninst, x1, seg); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEBO(x1, 1); + u8 = F8; + if (u8) { + MOV32w(x2, u8); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + } else { + emit_cmp8_0(dyn, ninst, x1, x3, x4); + } + break; + default: + DEFAULT; + } + break; case 0x81: case 0x83: nextop = F8; @@ -262,6 +337,34 @@ uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni LDxw(gd, x4, fixedaddress); } break; + case 0xC6: + INST_NAME("MOV Seg:Eb, Ib"); + grab_segdata(dyn, addr, ninst, x4, seg); + nextop = F8; + if (MODREG) { // reg <= u8 + u8 = F8; + if (!rex.rex) { + ed = (nextop & 7); + eb1 = TO_LA64(ed & 3); // Ax, Cx, Dx or Bx + eb2 = (ed & 4) >> 2; // L or H + } else { + eb1 = TO_LA64((nextop & 7) + (rex.b << 3)); + eb2 = 0; + } + MOV32w(x3, u8); + BSTRINS_D(eb1, x3, eb2 * 8 + 7, eb2 * 8); + } else { // mem <= u8 + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 1); + u8 = F8; + if (u8) { + ADDI_D(x3, xZR, u8); + ed = x3; + } else + ed = xZR; + STX_B(x3, wback, x4); + SMWRITE2(); + } + break; case 0xC7: INST_NAME("MOV Seg:Ed, Id"); 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 196e386f..333c7b62 100644 --- a/src/dynarec/la64/dynarec_la64_f30f.c +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -248,6 +248,15 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int VLD(v0, ed, fixedaddress); } break; + case 0x70: + INST_NAME("PSHUFHW Gx, Ex, Ib"); + nextop = F8; + GETEX(v1, 0, 1); + GETGX(v0, 1); + u8 = F8; + VSHUF4I_H(v0, v1, u8); + VEXTRINS_D(v0, v1, 0); // v0[63:0] = v1[63:0] + break; case 0x7E: INST_NAME("MOVQ Gx, Ex"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index dd961740..6ebfed29 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -297,6 +297,30 @@ gd = i; \ BSTRPICK_D(gd, gb1, gb2 + 7, gb2); +// GETEBO will use i for ed, i is also Offset, and can use r3 for wback. +#define GETEBO(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 = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \ + ADD_D(x3, wback, i); \ + if (wback != x3) wback = x3; \ + LD_B(i, wback, fixedaddress); \ + wb1 = 1; \ + ed = i; \ + } + // Get GX as a quad (might use x1) #define GETGX(a, w) \ gd = ((nextop & 0x38) >> 3) + (rex.r << 3); \ |