diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-12-10 04:37:11 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-09 21:37:11 +0100 |
| commit | 0df1e38ded3e0ee608c90959b63b82901ef2c423 (patch) | |
| tree | 64858501053b8703ad48186719aa22a681e25c4a /src | |
| parent | 7344689ba63da491282020d5429e80385e63f314 (diff) | |
| download | box64-0df1e38ded3e0ee608c90959b63b82901ef2c423.tar.gz box64-0df1e38ded3e0ee608c90959b63b82901ef2c423.zip | |
[DYNAREC_RV64] Added more opcodes for flatout.exe (#1132)
* [DYNAREC_RV64] Fixed printer imm format typo * [DYNAREC_RV64] Added more DC opcodes * [DYNAREC_RV64] Added 9E SAHF opcode * [DYNAREC_RV64] Added 66 A1 MOV opcode * [DYNAREC_RV64] Added 0F 72 /6 PSLLD opcode * [DYNAREC_RV64] Added 0F 72 /2 PSRLD opcode * [DYNAREC_RV64] Added 0F F5 PMADDWD opcode * [DYNAREC_RV64] Added 0F 72 /4 PSRAD opcode * [DYNAREC_RV64] Added 0F FE PADDD opcode * [DYNAREC_RV64] Added 0F 73 opcodes * Fixed a bunch of mistakes * Fixed printer * Fix fix fix * Fixed printer again * Added 0F DB PAND opcode * Fixed 0F 6E MOVD opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 13 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 146 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 12 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_dc.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_printer.c | 5 |
6 files changed, 179 insertions, 13 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index bf1d1f73..bea16d2d 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -503,9 +503,20 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int jump_to_epilog(dyn, addr, 0, ninst); } break; + case 0x9E: + INST_NAME("SAHF"); + SETFLAGS(X_CF | X_PF | X_AF | X_ZF | X_SF, SF_SUBSET); + ADDI(x1, xZR, ~0b11010101); + AND(xFlags, xFlags, x1); + NOT(x1, x1); + SRLI(x2, xRAX, 8); + AND(x1, x1, x2); + OR(xFlags, xFlags, x1); + SET_DFNONE(); + break; case 0x9F: INST_NAME("LAHF"); - READFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF); + READFLAGS(X_CF | X_PF | X_AF | X_ZF | X_SF); ANDI(x1, xFlags, 0xFF); SLLI(x1, x1, 8); MOV64x(x2, 0xffffffffffff00ffLL); diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 360cd9dd..283b6793 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -827,17 +827,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni ed = xRAX + (nextop & 7) + (rex.b << 3); } else { addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 1, 0); - if (rex.w) { - LD(x4, ed, fixedaddress); - } else { - LW(x4, ed, fixedaddress); - } + LDxw(x4, ed, fixedaddress); ed = x4; } - if (rex.w) - SD(ed, gback, gdoffset + 0); - else - SW(ed, gback, gdoffset + 0); + SD(ed, gback, gdoffset + 0); break; case 0x6F: INST_NAME("MOVQ Gm, Em"); @@ -901,6 +894,94 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni DEFAULT; } break; + case 0x72: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 2: + INST_NAME("PSRLD Em, Ib"); + GETEM(x4, 1); + u8 = F8; + if (u8) { + if (u8 > 31) { + SD(xZR, wback, fixedaddress); + } else { + LD(x1, wback, fixedaddress); + SRLI(x2, x1, 32 + u8); + SRLIW(x1, x1, u8); + SW(x1, wback, fixedaddress); + SW(x2, wback, fixedaddress + 4); + } + } + break; + case 4: + INST_NAME("PSRAD Em, Ib"); + GETEM(x4, 1); + u8 = F8; + if (u8 > 31) u8 = 31; + if (u8) { + LD(x1, wback, fixedaddress); + SRAI(x2, x1, 32 + u8); + SRAIW(x1, x1, u8); + SW(x1, wback, fixedaddress); + SW(x2, wback, fixedaddress + 4); + } + break; + case 6: + INST_NAME("PSLLD Em, Ib"); + GETEM(x4, 1); + u8 = F8; + if (u8) { + if (u8 > 31) { + SD(xZR, wback, fixedaddress); + } else { + LD(x1, wback, fixedaddress); + SRLI(x2, x1, 32); + SLLIW(x1, x1, u8); + SLLIW(x2, x2, u8); + SW(x1, wback, fixedaddress); + SW(x2, wback, fixedaddress + 4); + } + } + break; + default: + DEFAULT; + } + break; + case 0x73: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 2: + INST_NAME("PSRLQ Em, Ib"); + GETEM(x4, 1); + u8 = F8; + if (u8) { + if (u8 > 63) { + SD(xZR, wback, fixedaddress); + } else if (u8) { + LD(x1, wback, fixedaddress); + SRLI(x1, x1, u8); + SD(x1, wback, fixedaddress); + } + } + break; + case 6: + INST_NAME("PSLLQ Em, Ib"); + GETEM(x4, 1); + u8 = F8; + if (u8) { + if (u8 > 63) { + SD(xZR, wback, fixedaddress); + } else { + LD(x1, wback, fixedaddress); + SLLI(x1, x1, u8); + SD(x1, wback, fixedaddress); + } + } + break; + default: + DEFAULT; + } + break; case 0x75: INST_NAME("PCMPEQW Gm,Em"); nextop = F8; @@ -916,6 +997,20 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emu->fpu_stack = 0;*/ // TODO: Check if something is needed here? break; + case 0x7E: + INST_NAME("MOVD Ed, Gm"); + nextop = F8; + GETGM(); + if ((nextop & 0xC0) == 0xC0) { + ed = xRAX + (nextop & 7) + (rex.b << 3); + LDxw(ed, gback, gdoffset); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, 0); + LDxw(x1, gback, gdoffset); + SDxw(x1, wback, fixedaddress); + SMWRITE2(); + } + break; case 0x7F: INST_NAME("MOVQ Em, Gm"); nextop = F8; @@ -1586,6 +1681,16 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni gd = xRAX + (opcode & 7) + (rex.b << 3); REV8xw(gd, gd, x1, x2, x3, x4); break; + case 0xDB: + INST_NAME("PAND Gm, Em"); + nextop = F8; + GETGM(); + GETEM(x4, 0); + LD(x1, wback, fixedaddress); + LD(x2, gback, gdoffset); + AND(x1, x1, x2); + SD(x1, gback, gdoffset); + break; case 0xE5: INST_NAME("PMULHW Gm,Em"); nextop = F8; @@ -1647,6 +1752,22 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SD(x3, gback, gdoffset + 0); } break; + case 0xF5: + INST_NAME("PMADDWD Gm, Em"); + nextop = F8; + GETGM(); + GETEM(x5, 0); + for (int i = 0; i < 2; ++i) { + LH(x1, gback, gdoffset + i * 4); + LH(x2, gback, gdoffset + i * 4 + 2); + LH(x3, wback, fixedaddress + i * 4); + LH(x4, wback, fixedaddress + i * 4 + 2); + MULW(x1, x1, x3); + MULW(x2, x2, x4); + ADDW(x1, x1, x2); + SW(x1, gback, gdoffset + i * 4); + } + break; case 0xF9: INST_NAME("PSUBW Gm, Em"); nextop = F8; @@ -1661,6 +1782,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETEM(x2, 0); MMX_LOOP_W(x3, x4, ADDW(x3, x3, x4)); break; + case 0xFE: + INST_NAME("PADDD Gm, Em"); + nextop = F8; + GETGM(); + GETEM(x2, 0); + MMX_LOOP_D(x3, x4, ADDW(x3, x3, x4)); + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index e78310f9..fdc2d7e4 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -607,7 +607,17 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni AND(x1, x1, x2); OR(xRAX, xRAX, x1); break; - + case 0xA1: + INST_NAME("MOV EAX,Od"); + if (rex.is32bits) u64 = F32; else u64 = F64; + MOV64z(x1, u64); + if (isLockAddress(u64)) lock = 1; else lock = 0; + SMREADLOCK(lock); + LHU(x2, x1, 0); + LUI(x3, 0xffff0); + AND(xRAX, xRAX, x3); + OR(xRAX, xRAX, x2); + break; case 0xA3: INST_NAME("MOV Od,EAX"); if(rex.is32bits) diff --git a/src/dynarec/rv64/dynarec_rv64_dc.c b/src/dynarec/rv64/dynarec_rv64_dc.c index 006587b3..dbf7b314 100644 --- a/src/dynarec/rv64/dynarec_rv64_dc.c +++ b/src/dynarec/rv64/dynarec_rv64_dc.c @@ -39,7 +39,13 @@ uintptr_t dynarec64_DC(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni switch(nextop) { case 0xC0 ... 0xC7: INST_NAME("FADD STx, ST0"); - DEFAULT; + v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + if (ST_IS_F(0)) { + FADDS(v1, v1, v2); + } else { + FADDD(v1, v1, v2); + } break; case 0xC8 ... 0xCF: INST_NAME("FMUL STx, ST0"); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index f6c5ea20..af6cc1a8 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -546,6 +546,14 @@ SSE_LOOP_DS_ITEM(GX1, EX1, F, 2) \ SSE_LOOP_DS_ITEM(GX1, EX1, F, 3) +#define MMX_LOOP_D(GX1, EX1, F) \ + for (int i = 0; i < 2; ++i) { \ + LWU(GX1, gback, gdoffset + i * 4); \ + LWU(EX1, wback, fixedaddress + i * 4); \ + F; \ + SW(GX1, gback, gdoffset + i * 4); \ + } + #define MMX_LOOP_W(GX1, EX1, F) \ for (int i = 0; i < 4; ++i) { \ LHU(GX1, gback, gdoffset + i * 2); \ diff --git a/src/dynarec/rv64/rv64_printer.c b/src/dynarec/rv64/rv64_printer.c index 9d526bce..54f1ad51 100644 --- a/src/dynarec/rv64/rv64_printer.c +++ b/src/dynarec/rv64/rv64_printer.c @@ -445,7 +445,7 @@ static inline insn_t insn_th2type_read(uint32_t data) #define PRINT_imm_rel() snprintf(buff, sizeof(buff), "%s\tpc%s0x%x # 0x%"PRIx64, insn.name, insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff #define PRINT_rd_immx() snprintf(buff, sizeof(buff), "%s\t%s, 0x%x", insn.name, RN(rd), insn.imm); return buff #define PRINT_rs1_rs2_imm() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s0x%x", insn.name, RN(rs1), RN(rs2), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm); return buff -#define PRINT_rs1_rs2_imm_rel() snprintf(buff, sizeof(buff), "%s\t%s, %s, pc%s0x%d # 0x%"PRIx64, insn.name, RN(rs1), RN(rs2), insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff +#define PRINT_rs1_rs2_imm_rel() snprintf(buff, sizeof(buff), "%s\t%s, %s, pc%s0x%x # 0x%"PRIx64, insn.name, RN(rs1), RN(rs2), insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff #define PRINT_fd_fs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, fpnames[insn.rd], fpnames[insn.rs1]); return buff #define PRINT_xd_fs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, gpnames[insn.rd], fpnames[insn.rs1]); return buff #define PRINT_fd_xs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, fpnames[insn.rd], gpnames[insn.rs1]); return buff @@ -1020,9 +1020,11 @@ const char* rv64_print(uint32_t data, uintptr_t addr) case 0x30: insn.name = "roriw"; insn.imm &= 0b11111; + break; default: goto unknown; } + break; } default: goto unknown; @@ -1295,6 +1297,7 @@ const char* rv64_print(uint32_t data, uintptr_t addr) goto unknown; } } + break; case 0x4: { switch (funct3) { case 0x0: |