From 45015d6106133b940cbb5f24e08aac4d70bd7de8 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 24 Mar 2023 20:12:42 +0800 Subject: [RV64_DYNAREC] Added more opcodes & some fixes & some optimizations (#632) * [RV64_DYNAREC] Added 66 D1,D3 SAR opcode * [RV64_DYNAREC] Added 66 F7 /7 IDIV opcode * [RV64_DYNAREC] Fixed 32 XOR opcode * [RV64_DYNAREC] Some small optims * [RV64_DYNAREC] Added 66 33 XOR opcode * [RV64_DYNAREC] Added 66 81,83 /6 XOR opcode * [RV64_DYNAREC] Added 66 31 XOR opcode * [RV64_DYNAREC] Fixed a typo in IDIV opcode * [RV64_DYNAREC] Added A4 REP MOVSB opcode * [RV64_DYNAREC] Fixed 66 35 XOR opcode * [RV64_DYNAREC] Added 66 39 CMP opcode * [RV64_DYNAREC] Added F6 /7 IDIV opcode * [RV64_DYNAREC] Added 1C SBB opcode * [RV64_DYNAREC] Added 66 05 ADD opcode --- src/dynarec/rv64/dynarec_rv64_00.c | 50 +++++++++++++++++- src/dynarec/rv64/dynarec_rv64_66.c | 97 ++++++++++++++++++++++++++++++++-- src/dynarec/rv64/dynarec_rv64_helper.h | 10 +--- 3 files changed, 144 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index e1455292..fb259259 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -153,6 +153,16 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_sbb32(dyn, ninst, rex, ed, gd, x3, x4, x5); WBACK; break; + case 0x1C: + INST_NAME("SBB AL, Ib"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + ANDI(x1, xRAX, 0xff); + emit_sbb8c(dyn, ninst, x1, u8, x3, x4, x5, x6); + ANDI(xRAX, xRAX, ~0xff); + OR(xRAX, xRAX, x1); + break; case 0x20: INST_NAME("AND Eb, Gb"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -244,7 +254,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETEB(x1, 0); GETGB(x3); - emit_xor8(dyn, ninst, x1, x3, x4, x5); + emit_xor8(dyn, ninst, x3, x1, x4, x5); GBBACK(x5); break; case 0x33: @@ -742,6 +752,37 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni ZEROUP(xRDX); } break; + case 0xA4: + if(rep) { + INST_NAME("REP MOVSB"); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1<>3)&7) { + case 7: + if(opcode==0xD1) { + INST_NAME("SAR Ew, 1"); + MOV32w(x4, 1); + } else { + INST_NAME("SAR Ew, CL"); + ANDI(x4, xRCX, 0x1f); + } + UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");} + SETFLAGS(X_ALL, SF_PENDING); + GETSEW(x1, 0); + UFLAG_OP12(ed, x4) + SRA(ed, ed, x4); + EWBACK; + UFLAG_RES(ed); + UFLAG_DF(x3, d_sar16); + break; + default: + DEFAULT; + } + break; case 0xF7: nextop = F8; switch((nextop>>3)&7) { @@ -454,6 +523,26 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni OR(xRAX, xRAX, x3); OR(xRDX, xRDX, x4); break; + case 7: + INST_NAME("IDIV Ew"); + SETFLAGS(X_ALL, SF_SET); + GETSEW(x1, 0); + SLLI(x2, xRAX, 48); + SLLI(x3, xRDX, 48); + SRLI(x2, x2, 48); + SRLI(x3, x3, 32); + OR(x2, x2, x3); + DIVW(x3, x2, ed); + REMW(x4, x2, ed); + MOV64x(x5, ~0xffff); + AND(xRAX, xRAX, x5); + AND(xRDX, xRDX, x5); + NOT(x5, x5); + AND(x3, x3, x5); + AND(x4, x4, x5); + OR(xRAX, xRAX, x3); + OR(xRDX, xRDX, x4); + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index bcdbc840..55467e89 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -181,9 +181,7 @@ wb2 = (wback>>2)*8; \ wback = xRAX+(wback&3); \ } \ - MV(i, wback); \ - if (wb2) SRLI(i, i, wb2); \ - ANDI(i, i, 0xff); \ + if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else ANDI(i, wback, 0xff); \ wb1 = 0; \ ed = i; \ } else { \ @@ -226,21 +224,17 @@ gb1 = xRAX+(gd&3); \ } \ gd = i; \ - MV(gd, gb1); \ - if (gb2) SRLI(gd, gd, gb2*8); \ - ANDI(gd, gd, 0xff); + if (gb2) {MV(gd, gb1); SRLI(gd, gd, 8); ANDI(gd, gd, 0xff);} else ANDI(gd, gb1, 0xff); // Write gb (gd) back to original register / memory, using s1 as scratch #define GBBACK(s1) if(gb2) { \ assert(gb2 == 8); \ MOV64x(s1, 0xffffffffffff00ffLL); \ AND(gb1, gb1, s1); \ - ANDI(gd, gd, 0xff); \ SLLI(s1, gd, 8); \ OR(gb1, gb1, s1); \ } else { \ ANDI(gb1, gb1, ~0xff); \ - ANDI(gd, gd, 0xff); \ OR(gb1, gb1, gd); \ } -- cgit 1.4.1