diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-05-26 18:41:14 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-05-26 18:41:14 +0200 |
| commit | 9513053f740b71316b5d69f898ce6f242386128e (patch) | |
| tree | f13a474fb01f027bfd3394f2652b056dba04a8a2 /src | |
| parent | bfea73d5d8003ab48f078d64c5836b7691fc8fd3 (diff) | |
| download | box64-9513053f740b71316b5d69f898ce6f242386128e.tar.gz box64-9513053f740b71316b5d69f898ce6f242386128e.zip | |
[DYNAREC] Various small fixes and improvments to a few opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_00.c | 16 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_0f.c | 4 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_66.c | 69 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_67.c | 8 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_helper.h | 2 |
5 files changed, 47 insertions, 52 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index b1e757cf..d7828b60 100755 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -1512,7 +1512,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin u8 = F8; MOV32w(x2, u8); CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4); - WBACK; + SBACK(x1); break; case 3: INST_NAME("RCR Ed, Ib"); @@ -1523,7 +1523,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin u8 = F8; MOV32w(x2, u8); CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4); - WBACK; + SBACK(x1); break; case 4: case 6: @@ -1814,7 +1814,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOV32w(x2, 1); GETEDW(x4, x1, 0); CALL_(rcl32, ed, x4); - WBACK; + SBACK(x1); break; case 3: INST_NAME("RCR Ed, 1"); @@ -1824,7 +1824,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOV32w(x2, 1); GETEDW(x4, x1, 0); CALL_(rcr32, ed, x4); - WBACK; + SBACK(x1); break; case 4: case 6: @@ -1863,7 +1863,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } MOV64xw(x4, (rex.w?64:32)); SUBx_REG(x3, x4, x3); - GETEDW(x4, x2, 0); + GETED(0); if(!rex.w && MODREG) {MOVw_REG(ed, ed);} B_NEXT(cEQ); RORxw_REG(ed, ed, x3); @@ -1887,7 +1887,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f } - GETEDW(x4, x2, 0); + GETED(0); if(!rex.w && MODREG) {MOVw_REG(ed, ed);} B_NEXT(cEQ); RORxw_REG(ed, ed, x3); @@ -1918,7 +1918,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin if(!rex.w && MODREG) {MOVw_REG(ed, ed);} B_NEXT(cEQ); CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4); - WBACK; + SBACK(x1); break; case 3: INST_NAME("RCR Ed, CL"); @@ -1934,7 +1934,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin if(!rex.w && MODREG) {MOVw_REG(ed, ed);} B_NEXT(cEQ); CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4); - WBACK; + SBACK(x1); break; case 4: case 6: diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 2b1926b3..4a58bb70 100755 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -1110,7 +1110,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin GETGD; MOVxw_REG(x2, gd); CALL_(rex.w?((void*)shld64):((void*)shld32), ed, x4); - WBACK; + SBACK(x1); break; case 0xAB: @@ -1170,7 +1170,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin GETGD; MOVxw_REG(x2, gd); CALL_(rex.w?((void*)shrd64):((void*)shrd32), ed, x4); - WBACK; + SBACK(x1); break; case 0xAE: diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index 1559f1a5..7b1e9fca 100755 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -301,26 +301,17 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x69: - INST_NAME("IMUL Gw,Ew,Iw"); - SETFLAGS(X_ALL, SF_PENDING); - nextop = F8; - UFLAG_DF(x1, d_imul16); - GETSEW(x1, 2); - i32 = F16S; - MOV32w(x2, i32); - MULw(x2, x2, x1); - UFLAG_RES(x2); - gd=x2; - GWBACK; - break; - case 0x6B: - INST_NAME("IMUL Gw,Ew,Ib"); + if(opcode==0x69) { + INST_NAME("IMUL Gw,Ew,Iw"); + } else { + INST_NAME("IMUL Gw,Ew,Ib"); + } SETFLAGS(X_ALL, SF_PENDING); nextop = F8; UFLAG_DF(x1, d_imul16); - GETSEW(x1, 1); - i32 = F8S; + GETSEW(x1, (opcode==0x69)?2:1); + if(opcode==0x69) i32 = F16S; else i32 = F8S; MOV32w(x2, i32); MULw(x2, x2, x1); UFLAG_RES(x2); @@ -352,11 +343,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin nextop = F8; switch((nextop>>3)&7) { case 0: //ADD - if(opcode==0x81) { - INST_NAME("ADD Ew, Iw"); - } else { - INST_NAME("ADD Ew, Ib"); - } + if(opcode==0x81) {INST_NAME("ADD Ew, Iw");} else {INST_NAME("ADD Ew, Ib");} SETFLAGS(X_ALL, SF_SET_PENDING); GETEW(x1, (opcode==0x81)?2:1); if(opcode==0x81) i16 = F16S; else i16 = F8S; @@ -639,7 +626,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SETFLAGS(X_ALL, SF_PENDING); GETEW(x1, 1); u8 = F8; - MOV32w(x2, (u8&0x1f)); + UFLAG_IF {MOV32w(x2, (u8&0x1f));} UFLAG_OP12(ed, x2) LSLw_IMM(ed, ed, u8&0x1f); EWBACK; @@ -652,7 +639,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SETFLAGS(X_ALL, SF_PENDING); GETEW(x1, 1); u8 = F8; - MOV32w(x2, (u8&0x1f)); + UFLAG_IF {MOV32w(x2, (u8&0x1f));} UFLAG_OP12(ed, x2) LSRw_IMM(ed, ed, u8&0x1f); EWBACK; @@ -663,9 +650,9 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("SAR Ed, Ib"); SETFLAGS(X_ALL, SF_PENDING); UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");} - GETSEW(x1, 0); + GETSEW(x1, 1); u8 = F8; - MOV32w(x2, (u8&0x1f)); + UFLAG_IF {MOV32w(x2, (u8&0x1f));} UFLAG_OP12(ed, x2) ASRw_REG(ed, ed, x2); EWBACK; @@ -701,7 +688,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOV32w(x2, 1); } else { INST_NAME("ROL Ew, CL"); - ANDSw_mask(x2, xRCX, 0, 0b00100); + ANDw_mask(x2, xRCX, 0, 0b00100); } MESSAGE(LOG_DUMP, "Need Optimization\n"); SETFLAGS(X_OF|X_CF, SF_SET); @@ -715,7 +702,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOV32w(x2, 1); } else { INST_NAME("ROR Ew, CL"); - ANDSw_mask(x2, xRCX, 0, 0b00100); + ANDw_mask(x2, xRCX, 0, 0b00100); } MESSAGE(LOG_DUMP, "Need Optimization\n"); SETFLAGS(X_OF|X_CF, SF_SET); @@ -728,7 +715,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); SETFLAGS(X_OF|X_CF, SF_SET); - if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);} + if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDw_mask(x2, xRCX, 0, 0b00100);} GETEW(x1, 0); CALL_(rcl16, x1, x3); EWBACK; @@ -738,7 +725,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); SETFLAGS(X_OF|X_CF, SF_SET); - if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);} + if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDw_mask(x2, xRCX, 0, 0b00100);} GETEW(x1, 0); CALL_(rcr16, x1, x3); EWBACK; @@ -750,7 +737,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOV32w(x4, 1); } else { INST_NAME("SHL Ew, CL"); - ANDSw_mask(x4, xRCX, 0, 0b00100); + ANDw_mask(x4, xRCX, 0, 0b00100); } UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");} SETFLAGS(X_ALL, SF_PENDING); @@ -767,7 +754,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOV32w(x4, 1); } else { INST_NAME("SHR Ew, CL"); - ANDSw_mask(x4, xRCX, 0, 0b00100); + ANDw_mask(x4, xRCX, 0, 0b00100); } UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");} SETFLAGS(X_ALL, SF_PENDING); @@ -784,7 +771,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOV32w(x4, 1); } else { INST_NAME("SAR Ew, CL"); - ANDSw_mask(x4, xRCX, 0, 0b00100); + ANDw_mask(x4, xRCX, 0, 0b00100); } UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");} SETFLAGS(X_ALL, SF_PENDING); @@ -850,17 +837,25 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 6: INST_NAME("DIV Ew"); - MESSAGE(LOG_DUMP, "Need Optimization\n"); SETFLAGS(X_ALL, SF_SET); GETEW(x1, 0); - CALL(div16, -1); + UXTHw(x2, xRAX); + BFIw(x2, xRDX, 16, 16); + UDIVw(x3, x2, ed); + MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed) + BFIx(xRAX, x3, 0, 16); + BFIx(xRDX, x4, 0, 16); break; case 7: INST_NAME("IDIV Ew"); - MESSAGE(LOG_DUMP, "Need Optimization\n"); SETFLAGS(X_ALL, SF_SET); - GETEW(x1, 0); - CALL(idiv16, -1); + GETSEW(x1, 0); + UXTHw(x2, xRAX); + BFIw(x2, xRDX, 16, 16); + SDIVw(x3, x2, ed); + MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed) + BFIx(xRAX, x3, 0, 16); + BFIx(xRDX, x4, 0, 16); break; } break; diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index 7b379488..34138e82 100755 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -98,7 +98,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin if(MODREG) { v1 = mmx_get_reg(dyn, ninst, x1, x2, x3, nextop&7); // no rex.b on MMX v0 = mmx_get_reg_empty(dyn, ninst, x1, x2, x3, gd); - VMOVeD(v0, 0, v1, 0); + VMOV(v0, v1); } else { v0 = mmx_get_reg_empty(dyn, ninst, x1, x2, x3, gd); addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0); @@ -179,7 +179,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin u8 = F8; MOV32w(x2, u8); CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4); - WBACK; + SBACK(x1); break; case 3: INST_NAME("RCR Ed, Ib"); @@ -190,7 +190,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin u8 = F8; MOV32w(x2, u8); CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4); - WBACK; + SBACK(x1); break; case 4: case 6: @@ -302,7 +302,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 2: INST_NAME("NOT Ed"); - GETED32(4); + GETED32(0); MVNxw_REG(ed, ed); WBACK; break; diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 3e09bb60..c5abb1e9 100755 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -130,7 +130,7 @@ // Write back ed in wback (if wback not 0) #define WBACKw if(wback) {STRw_U12(ed, wback, fixedaddress);} // Send back wb to either ed or wback -#define SBACK(wb) if(wback) {STRxw(wb, wback, fixedaddress);} else {MOVxw_REG(ed, wb);} +#define SBACK(wb) if(wback) {STRxw_U12(wb, wback, fixedaddress);} else {MOVxw_REG(ed, wb);} //GETEDO can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI #define GETEDO(O, D) if(MODREG) { \ ed = xRAX+(nextop&7)+(rex.b<<3); \ |