diff options
| author | wannacu <wannacu2049@gmail.com> | 2023-08-07 16:51:16 +0800 |
|---|---|---|
| committer | wannacu <wannacu2049@gmail.com> | 2023-08-07 17:07:31 +0800 |
| commit | 3308cc60e9ef645a6675ae993c82d4aa68dbcebf (patch) | |
| tree | d62ce13dac4ace30c5788b2ac8a02f7ac6bcf324 /src | |
| parent | e4b235378be84f434928fd5fbaa634e1da0b7edd (diff) | |
| download | box64-3308cc60e9ef645a6675ae993c82d4aa68dbcebf.tar.gz box64-3308cc60e9ef645a6675ae993c82d4aa68dbcebf.zip | |
[RV64_DYNAREC] Added movbe opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 32 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 127 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 38 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_emitter.h | 2 | ||||
| -rw-r--r-- | src/emu/x64run660f.c | 13 |
5 files changed, 210 insertions, 2 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index b4aa13fa..9f30df50 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -747,7 +747,37 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VEORQ(q0, q0, q1); } break; - + case 0xF0: + INST_NAME("MOVBE Gw, Ew"); + nextop=F8; + gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + REV16x(x1, ed); + BFIx(gd, x1, 0, 16); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0); + LDH(x1, ed, fixedaddress); + REV16x(x1, x1); + BFIx(gd, x1, 0, 16); + } + break; + case 0xF1: + INST_NAME("MOVBE Ew, Gw"); + nextop=F8; + gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + REV16x(x1, gd); + BFIx(ed, x1, 0, 16); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0); + REV16x(x1, gd); + STH(x1, ed, fixedaddress); + } + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 5c8d7b81..10c3e63d 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -316,7 +316,134 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SRLI(xRDX, x3, 32); AND(xRAX, x3, 32); // wipe upper part break; + case 0x38: + //SSE3 + nextop=F8; + switch(nextop) { + case 0xF0: + INST_NAME("MOVBE Gd, Ed"); + nextop=F8; + GETGD; + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LDxw(gd, ed, fixedaddress); + if (rv64_zbb) { + REV8(gd, gd); + if (!rex.w) { + SRLI(gd, gd, 32); + } + } else { + if (rex.w) { + LI(x2, 0xff); + SLLI(x1, gd, 56); + SRLI(x3, gd, 56); + SRLI(x4, gd, 40); + SLLI(x2, x2, 8); + AND(x4, x4, x2); + OR(x1, x1, x3); + OR(x1, x1, x4); + SLLI(x3, gd, 40); + SLLI(x4, x2, 40); + AND(x3, x3, x4); + OR(x1, x1, x3); + + SRLI(x3, gd, 24); + SLLI(x4, x2, 8); + AND(x3, x3, x4); + OR(x1, x1, x3); + SLLI(x3, gd, 24); + SLLI(x4, x2, 32); + AND(x3, x3, x4); + OR(x1, x1, x3); + + SRLI(x3, gd, 8); + SLLI(x4, x2, 16); + AND(x3, x3, x4); + OR(x1, x1, x3); + SLLI(x3, gd, 8); + SLLI(x4, x2, 24); + AND(x3, x3, x4); + OR(gd, x1, x3); + } else { + LI(x2, 0xff); + SLLIW(x2, x2, 8); + SLLIW(x1, gd, 24); + SRLIW(x3, gd, 24); + SRLIW(x4, gd, 8); + AND(x4, x4, x2); + OR(x1, x1, x3); + OR(x1, x1, x4); + SLLIW(gd, gd, 8); + LUI(x2, 0xff0); + AND(gd, gd, x2); + OR(gd, gd, x1); + } + } + break; + case 0xF1: + INST_NAME("MOVBE Ed, Gd"); + nextop=F8; + GETGD; + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0); + if (rv64_zbb) { + REV8(x1, gd); + if (!rex.w) { + SRLI(x1, x1, 32); + } + } else { + if (rex.w) { + LI(x2, 0xff); + SLLI(x1, gd, 56); + SRLI(x3, gd, 56); + SRLI(x4, gd, 40); + SLLI(x2, x2, 8); + AND(x4, x4, x2); + OR(x1, x1, x3); + OR(x1, x1, x4); + SLLI(x3, gd, 40); + SLLI(x4, x2, 40); + AND(x3, x3, x4); + OR(x1, x1, x3); + SRLI(x3, gd, 24); + SLLI(x4, x2, 8); + AND(x3, x3, x4); + OR(x1, x1, x3); + SLLI(x3, gd, 24); + SLLI(x4, x2, 32); + AND(x3, x3, x4); + OR(x1, x1, x3); + + SRLI(x3, gd, 8); + SLLI(x4, x2, 16); + AND(x3, x3, x4); + OR(x1, x1, x3); + SLLI(x3, gd, 8); + SLLI(x4, x2, 24); + AND(x3, x3, x4); + OR(x1, x1, x3); + } else { + LI(x2, 0xff); + SLLIW(x2, x2, 8); + SLLIW(x1, gd, 24); + SRLIW(x3, gd, 24); + SRLIW(x4, gd, 8); + AND(x4, x4, x2); + OR(x1, x1, x3); + OR(x1, x1, x4); + SLLIW(x3, gd, 8); + LUI(x2, 0xff0); + AND(x3, x3, x2); + OR(x1, x1, x3); + } + } + SDxw(x1, wback, fixedaddress); + break; + default: + DEFAULT; + } + break; #define GO(GETFLAGS, NO, YES, F) \ READFLAGS(F); \ diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 86bf0dbe..c60d214d 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -715,6 +715,44 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(x2, 0); SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4)); break; + case 0xF0: + INST_NAME("MOVBE Gw, Ew"); + nextop=F8; + GETGD; + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 1); + LHU(x1, ed, fixedaddress); + if (rv64_zbb) { + REV8(x1, x1); + SRLI(x1, x1, 48); + } else { + ANDI(x2, x1, 0xff); + SLLI(x2, x2, 8); + SRLI(x1, x1, 8); + OR(x1, x1, x2); + } + LUI(x2, 0xffff0); + AND(gd, gd, x2); + OR(gd, gd, x1); + break; + case 0xF1: + INST_NAME("MOVBE Ew, Gw"); + nextop=F8; + GETGD; + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 0, 1); + if (rv64_zbb) { + REV8(x1, gd); + SRLI(x1, x1, 48); + } else { + ANDI(x1, gd, 0xff); + SLLI(x1, x1, 8); + SRLI(x2, gd, 8); + ANDI(x2, x2, 0xff); + OR(x1, x1, x2); + } + SH(x1, wback, fixedaddress); + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index e9fa2f6d..6a5dd4bd 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -128,6 +128,8 @@ f28–31 ft8–11 FP temporaries Caller // RV32I // put imm20 in the [31:12] bits of rd, zero [11:0] and sign extend bits31 #define LUI(rd, imm20) EMIT(U_type((imm20)<<12, rd, 0b0110111)) + +#define LI(rd, imm12) if (imm12 < 0x800) { ADDI(rd, xZR, imm12);} else {LUI(rd, 1); ADDIW(rd, rd, -(0x1000 - imm12));} // put PC+imm20 in rd #define AUIPC(rd, imm20) EMIT(U_type((imm20)<<12, rd, 0b0010111)) diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c index 3083b7b0..902772e5 100644 --- a/src/emu/x64run660f.c +++ b/src/emu/x64run660f.c @@ -788,7 +788,18 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr) GX->q[0] ^= EX->q[0]; GX->q[1] ^= EX->q[1]; break; - + case 0xF0: /* MOVBE Gw, Ew */ + nextop = F8; + GETEX(0); + GETGX; + GX->uw[0] = __builtin_bswap16(EX->uw[0]); + break; + case 0xF1: /* MOVBE Ew, Gw */ + nextop = F8; + GETEX(0); + GETGX; + EX->uw[0] = __builtin_bswap16(GX->uw[0]); + break; default: return 0; } |