diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-03-01 00:48:23 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-29 17:48:23 +0100 |
| commit | 92532b0fd1c14aefbd82aed93a04ce5b11e5abf7 (patch) | |
| tree | 7f1fe6773e3636fb067a800f5c8eacc0563f7331 | |
| parent | 8cba5d55cef4c9a0f047b6cd81e440144fb12e8f (diff) | |
| download | box64-92532b0fd1c14aefbd82aed93a04ce5b11e5abf7.tar.gz box64-92532b0fd1c14aefbd82aed93a04ce5b11e5abf7.zip | |
[LA64_DYNAREC] Added more opcodes and fixed more things (#1304)
* [LA64_DYNAREC] Fixed GETED macro * [LA64_DYNAREC] Added 81/83 /5 SUB opcode * Use xMASK when possible * Added 8B MOV opcode * Fix
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 28 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_emit_math.c | 10 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.c | 3 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 7 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 16 |
5 files changed, 45 insertions, 19 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 5eeba868..bcfd9e7b 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -177,6 +177,22 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni gd = TO_LA64((opcode & 0x07) + (rex.b << 3)); POP1z(gd); break; + case 0x81: + case 0x83: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 5: // SUB + if(opcode==0x81) {INST_NAME("SUB Ed, Id");} else {INST_NAME("SUB Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + emit_sub32c(dyn, ninst, rex, ed, i64, x3, x4, x5, x6); + WBACK; + break; + default: + DEFAULT; + } + break; case 0x89: INST_NAME("MOV Ed, Gd"); nextop = F8; @@ -193,6 +209,18 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SMWRITELOCK(lock); } break; + case 0x8B: + INST_NAME("MOV Gd, Ed"); + nextop=F8; + GETGD; + if(MODREG) { + MVxw(gd, xRAX + TO_LA64((nextop&7) + (rex.b<<3))); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0); + SMREADLOCK(lock); + LDxw(gd, ed, fixedaddress); + } + break; case 0x8D: INST_NAME("LEA Gd, Ed"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index e5efec62..b3db124c 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -55,9 +55,8 @@ void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s IFX(X_CF) { if (rex.w) { - MOV32w(x2, 0xffffffff); - AND(s5, x2, s1); - AND(s4, x2, s2); + AND(s5, xMASK, s1); + AND(s4, xMASK, s2); ADD_D(s5, s5, s4); SRLI_D(s3, s1, 0x20); SRLI_D(s4, s2, 0x20); @@ -171,9 +170,8 @@ void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i IFX(X_CF) { if (rex.w) { - MOV32w(x2, 0xffffffff); - AND(s5, x2, s1); - AND(s4, x2, s2); + AND(s5, xMASK, s1); + AND(s4, xMASK, s2); ADD_D(s5, s5, s4); SRLI_D(s3, s1, 0x20); SRLI_D(s4, s2, 0x20); diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index 5ab4e320..6de2422b 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -246,8 +246,7 @@ static uintptr_t geted_32(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_ } else { ret = TO_LA64((nextop & 7)); if (ret == hint) { - MOV32w(x2, 0xffffffff); - AND(hint, ret, x2); // to clear upper part + AND(hint, ret, xMASK); // to clear upper part } } } else { diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 33291b3a..5306814d 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -87,15 +87,12 @@ // GETED can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI #define GETED(D) \ if (MODREG) { \ - ed = TO_LA64((nextop & 7) + (rex.b << 3)); \ + ed = TO_LA64((nextop & 7) + (rex.b << 3)); \ wback = 0; \ } else { \ SMREAD(); \ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \ - if (rex.w) \ - LD_D(x1, wback, fixedaddress); \ - else \ - LD_W(x1, wback, fixedaddress); \ + LDxw(x1, wback, fixedaddress); \ ed = x1; \ } diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 5e826734..6adcdf7f 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -52,9 +52,9 @@ f24-f31 fs0-fs7 Static registers Callee #define xFlags 31 #define xRIP 20 // function to move from x86 regs number to LA64 reg number -#define TO_LA64(A) ((A)>7)?((A)+15):((A)+12) +#define TO_LA64(A) (((A)>7)?((A)+15):((A)+12)) // function to move from LA64 regs number to x86 reg number -#define FROM_LA64(A) ((A)>22)?((A)-15):((A)-12) +#define FROM_LA64(A) (((A)>22)?((A)-15):((A)-12)) // 32bits version #define wEAX xRAX #define wECX xRCX @@ -528,14 +528,12 @@ f24-f31 fs0-fs7 Static registers Callee if (rex.w) { \ MV(rd, rj); \ } else { \ - MOV32w(x2, 0xffffffff); \ - AND(rd, rj, x2); \ + AND(rd, rj, xMASK); \ } // rd = rj (pseudo instruction) #define MVz(rd, rj) \ if (rex.is32bits) { \ - MOV32w(x2, 0xffffffff); \ - AND(rd, rj, x2); \ + AND(rd, rj, xMASK); \ } else { \ MV(rd, rj); \ } @@ -565,6 +563,12 @@ f24-f31 fs0-fs7 Static registers Callee else \ ADD_D(rd, rj, rk); +#define LDxw(rd, rj, imm12) \ + if (rex.w) \ + LD_D(rd, rj, imm12); \ + else \ + LD_WU(rd, rj, imm12); + #define SDxw(rd, rj, imm12) \ if (rex.w) \ ST_D(rd, rj, imm12); \ |