diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-21 22:08:58 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-21 22:08:58 +0100 |
| commit | 8bd81dffcfa97a0014ec64efdbfc411fa144524f (patch) | |
| tree | 04f6f2e97333dcb222874975dbba526f10b18145 | |
| parent | 79ca411d6a5d35e66842b3886d2c6077ef85b58a (diff) | |
| download | box64-8bd81dffcfa97a0014ec64efdbfc411fa144524f.tar.gz box64-8bd81dffcfa97a0014ec64efdbfc411fa144524f.zip | |
[DYNAREC] Complete 81/833 opcodes, plus various bugfixes
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 39 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 30 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_0f.c | 6 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_660f.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_f30f.c | 4 |
5 files changed, 68 insertions, 13 deletions
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index 46e1feae..b068b9d8 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -265,7 +265,17 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) else snprintf(buff, sizeof(buff), "STR%c %s, [%s]", size?'H':'B', Xt[Rt], XtSp[Rn]); return buff; - } // --- MOV (REGS: see Logic MOV==ORR, MVN==ORN) + } + if(isMask(opcode, "1011100110iiiiiiiiiiiinnnnnttttt", &a)) { + int offset = imm<<2; + if(!offset) + snprintf(buff, sizeof(buff), "LDRSW %s, [%s]", Xt[Rt], XtSp[Rn]); + else + snprintf(buff, sizeof(buff), "LDRSW %s, [%s, #%d]", Xt[Rt], XtSp[Rn], offset); + return buff; + } + + // --- MOV (REGS: see Logic MOV==ORR, MVN==ORN) if(isMask(opcode, "f10100101wwiiiiiiiiiiiiiiiiddddd", &a)) { if(!hw) snprintf(buff, sizeof(buff), "MOVZ %s, 0x%x", sf?Xt[Rd]:Wt[Rd], imm); @@ -582,6 +592,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) return buff; } + if(isMask(opcode, "f0011010110mmmmm001011nnnnnddddd", &a)) { + snprintf(buff, sizeof(buff), "ROR %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm]); + return buff; + } + if(isMask(opcode, "f0011010110mmmmm001001nnnnnddddd", &a)) { snprintf(buff, sizeof(buff), "LSR %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm]); return buff; @@ -893,6 +908,28 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) return buff; } + // FMOV + if(isMask(opcode, "00011110pp100000010000nnnnnddddd", &a)) { + int type = a.p; + char s = (type==0)?'S':((type==1)?'D':'?'); + snprintf(buff, sizeof(buff), "FMOV %c%d, %c%d", s, Rd, s, Rn); + return buff; + } + if(isMask(opcode, "f0011110pp10x11c000000nnnnnddddd", &a)) { + int type = a.p; + int rmode = a.x; + int opcd = 6+a.c; + if(sf==0 && type==0 && rmode==0 && opcd==7) {snprintf(buff, sizeof(buff), "FMOV S%d, %s", Rd, Wt[Rn]);} + else if(sf==0 && type==0 && rmode==0 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, S%d", Wt[Rn], Rd);} + else if(sf==1 && type==1 && rmode==0 && opcd==7) {snprintf(buff, sizeof(buff), "FMOV D%d, %s", Rd, Xt[Rn]);} + else if(sf==1 && type==2 && rmode==1 && opcd==7) {snprintf(buff, sizeof(buff), "FMOV V%d.D[1], %s", Rd, Xt[Rn]);} + else if(sf==1 && type==1 && rmode==0 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, S%d", Xt[Rn], Rd);} + else if(sf==1 && type==2 && rmode==1 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, V%d.D[1]", Xt[Rn], Rd);} + else snprintf(buff, sizeof(buff), "FMOV ????"); + return buff; + } + + snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode)); return buff; diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 2b9cc55b..9ad7516b 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -531,14 +531,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin if(MODREG) { // reg <= reg SXTWx(gd, xRAX+(nextop&7)+(rex.b<<3)); } else { // mem <= reg - addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<2, 3, rex, 0, 0); LDRSW_U12(gd, ed, fixedaddress); } } else { if(MODREG) { // reg <= reg MOVw_REG(gd, xRAX+(nextop&7)+(rex.b<<3)); } else { // mem <= reg - addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<2, 3, rex, 0, 0); LDRw_U12(gd, ed, fixedaddress); } } @@ -756,7 +756,26 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin emit_or32c(dyn, ninst, rex, ed, i64, x3, x4); WBACK; break; - + case 2: //ADC + if(opcode==0x81) {INST_NAME("ADC Ed, Id");} else {INST_NAME("ADC Ed, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET); + GETED((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + MOV64xw(x5, i64); + emit_adc32(dyn, ninst, rex, ed, x5, x3, x4); + WBACK; + break; + case 3: //SBB + if(opcode==0x81) {INST_NAME("SBB Ed, Id");} else {INST_NAME("SBB Ed, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET); + GETED((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + MOV64xw(x5, i64); + emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4); + WBACK; + break; case 4: //AND if(opcode==0x81) {INST_NAME("AND Ed, Id");} else {INST_NAME("AND Ed, Ib");} SETFLAGS(X_ALL, SF_SET); @@ -792,9 +811,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else emit_cmp32_0(dyn, ninst, rex, ed, x3, x4); break; - - default: - DEFAULT; } break; case 0x84: @@ -880,6 +896,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin addr = geted(dyn, addr, ninst, nextop, &ed, gd, &fixedaddress, 0, 0, rex, 0, 0); if(gd!=ed) { // it's sometimes used as a 3 bytes NOP MOVxw_REG(gd, ed); + } else if(ed>=xRAX && !rex.w) { + MOVw(gd, gd); //truncate the higher 32bits as asked } } break; diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c index 9ce1951f..6e65208e 100755 --- a/src/dynarec/dynarec_arm64_0f.c +++ b/src/dynarec/dynarec_arm64_0f.c @@ -165,12 +165,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin nextop = F8; GETGX(v0); if(MODREG) { - s0 = sse_get_reg(dyn, ninst, x1, nextop&7); + s0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3)); } else { - parity = getedparity(dyn, ninst, addr, nextop, 2, 0); + parity = getedparity(dyn, ninst, addr, nextop, 3, 0); s0 = fpu_get_scratch(dyn); if(parity) { - addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 3, rex, 0, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<2, 3, rex, 0, 0); VLDR32_U12(s0, ed, fixedaddress); } else { GETED(0); diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c index ee6fa45d..a55e89c8 100755 --- a/src/dynarec/dynarec_arm64_660f.c +++ b/src/dynarec/dynarec_arm64_660f.c @@ -122,7 +122,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n if(MODREG) { \ ed = xRAX+(nextop&7)+(rex.b<<3); \ } else { \ - addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); \ + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<1, 1, rex, 0, 0); \ LDRH_U12(x1, ed, fixedaddress); \ ed = x1; \ } \ diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c index 21b3531e..16937842 100755 --- a/src/dynarec/dynarec_arm64_f30f.c +++ b/src/dynarec/dynarec_arm64_f30f.c @@ -77,7 +77,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VMOVeS(v0, 0, q0, 0); } else { v0 = sse_get_reg_empty(dyn, ninst, x1, gd); - addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 3, rex, 0, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0); LDRw_U12(x2, ed, fixedaddress); // to avoid bus errors VEORQ(v0, v0, v0); VMOVQSfrom(v0, 0, x2); @@ -93,7 +93,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VMOVeS(q0, 0, v0, 0); } else { VMOVSto(x2, v0, 0); - addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 3, rex, 0, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0); STRw_U12(x2, ed, fixedaddress); } break; |