diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-02-09 23:41:58 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-09 16:41:58 +0100 |
| commit | 099bd148cbb4b8ad11fe8f099701d9f4056ccd2a (patch) | |
| tree | 9c3fb8019c12e949ef6d813917aaab528fba39aa /src | |
| parent | 20885702b96118cd1b3a4e2dac41d4d028c49520 (diff) | |
| download | box64-099bd148cbb4b8ad11fe8f099701d9f4056ccd2a.tar.gz box64-099bd148cbb4b8ad11fe8f099701d9f4056ccd2a.zip | |
[LA64_DYNREC] Added more opcodes (#2338)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 11 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 34 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_660f.c | 14 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f30f.c | 11 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 12 |
5 files changed, 82 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 49e9bece..1751c759 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -2082,6 +2082,17 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni WBACK; if (!wback && !rex.w) ZEROUP(ed); break; + case 3: + INST_NAME("RCR Ed, 1"); + MESSAGE(LOG_DUMP, "Need Optimization\n"); + READFLAGS(X_CF); + SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION); + MOV32w(x2, 1); + GETEDW(x4, x1, 0); + CALL_(rex.w ? ((void*)rcr64) : ((void*)rcr32), ed, x4); + WBACK; + if (!wback && !rex.w) ZEROUP(ed); + break; case 4: case 6: INST_NAME("SHL Ed, 1"); diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index a260ccc6..e0366227 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -1165,6 +1165,40 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni DEFAULT; } break; + case 0xBB: + INST_NAME("BTC Ed, Gd"); + SETFLAGS(X_CF, SF_SUBSET, NAT_FLAGS_NOFUSION); + SET_DFNONE(); + nextop = F8; + GETGD; + if (MODREG) { + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + wback = 0; + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); + SRAIxw(x1, gd, 5 + rex.w); + ADDSL(x3, wback, x1, 2 + rex.w, x1); + LDxw(x1, x3, fixedaddress); + ed = x1; + wback = x3; + } + ANDI(x2, gd, rex.w ? 0x3f : 0x1f); + SRL_D(x4, ed, x2); + if (la64_lbt) + X64_SET_EFLAGS(x4, X_CF); + else + BSTRINS_D(xFlags, x4, F_CF, F_CF); + ADDI_D(x4, xZR, 1); + SLL_D(x4, x4, x2); + XOR(ed, ed, x4); + if (wback) { + SDxw(ed, wback, fixedaddress); + SMWRITE(); + } else if (!rex.w) { + ZEROUP(ed); + } + break; case 0xBC: INST_NAME("BSF Gd, Ed"); SETFLAGS(X_ZF, SF_SUBSET, NAT_FLAGS_NOFUSION); diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index 0094e20c..b672a1b4 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -1419,6 +1419,20 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int SMWRITE2(); } break; + case 0xA3: + INST_NAME("BT Ew, Gw"); + SETFLAGS(X_CF, SF_SUBSET, NAT_FLAGS_NOFUSION); + SET_DFNONE(); + nextop = F8; + GETEW(x1, 0); + GETGW(x2); + ANDI(gd, gd, 15); + SRL_D(x4, ed, gd); + if (la64_lbt) + X64_SET_EFLAGS(x4, X_CF); + else + BSTRINS_D(xFlags, x4, F_CF, F_CF); + break; case 0xAF: INST_NAME("IMUL Gw,Ew"); SETFLAGS(X_ALL, SF_PENDING, NAT_FLAGS_NOFUSION); diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c index 3ef072c2..e14b43f1 100644 --- a/src/dynarec/la64/dynarec_la64_f30f.c +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -184,6 +184,17 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int FSQRT_S(d1, d0); VEXTRINS_W(v0, d1, 0); break; + case 0x53: + INST_NAME("RCPSS Gx, Ex"); + nextop = F8; + GETGX(v0, 1); + GETEXSS(v1, 0, 0); + d1 = fpu_get_scratch(dyn); + LU12I_W(x3, 0x3f800); // 1.0f + MOVGR2FR_W(d1, x3); + FDIV_S(d1, d1, v1); + VEXTRINS_W(v0, d1, 0); + break; case 0x58: INST_NAME("ADDSS Gx, Ex"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 4bad8557..09d6cad5 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -88,6 +88,18 @@ LDxw(hint, wback, fixedaddress); \ ed = hint; \ } +// GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI +#define GETEDW(hint, ret, D) \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + MV(ret, ed); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 0, D); \ + ed = ret; \ + LDxw(ed, wback, fixedaddress); \ + } // GETEWW will use i for ed, and can use w for wback. #define GETEWW(w, i, D) \ if (MODREG) { \ |