diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-07-03 13:19:57 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-07-03 13:19:57 +0200 |
| commit | d9707926faa80a1c25609e7a7dfa40d82d43f0a1 (patch) | |
| tree | 0f47655284b00ed02a47f86f3cffa76f161a0f75 /src | |
| parent | e38c663dea00999db39aa6747d8ba18cd4806647 (diff) | |
| download | box64-d9707926faa80a1c25609e7a7dfa40d82d43f0a1.tar.gz box64-d9707926faa80a1c25609e7a7dfa40d82d43f0a1.zip | |
[DYNAREC] Added most 67 00-3C opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_67.c | 420 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_helper.h | 19 |
2 files changed, 438 insertions, 1 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index e69c6549..7157a5e8 100755 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -38,7 +38,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uint8_t opcode = F8; uint8_t nextop; - uint8_t gd, ed, wback, wb; + uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2; int64_t fixedaddress; int8_t i8; uint8_t u8; @@ -66,6 +66,105 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } switch(opcode) { + case 0x00: + INST_NAME("ADD Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_add8(dyn, ninst, x1, x2, x4, x5); + EBBACK; + break; + case 0x01: + INST_NAME("ADD Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_add32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x02: + INST_NAME("ADD Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_add8(dyn, ninst, x1, x2, x3, x4); + GBBACK; + break; + case 0x03: + INST_NAME("ADD Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_add32(dyn, ninst, rex, gd, ed, x3, x4); + break; + case 0x04: + INST_NAME("ADD AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + UXTBw(x1, xRAX); + emit_add8c(dyn, ninst, x1, u8, x3, x4); + BFIx(xRAX, x1, 0, 8); + break; + case 0x05: + INST_NAME("ADD EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_add32c(dyn, ninst, rex, xRAX, i64, x3, x4, x5); + break; + + case 0x08: + INST_NAME("OR Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_or8(dyn, ninst, x1, x2, x4, x2); + EBBACK; + break; + case 0x09: + INST_NAME("OR Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_or32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x0A: + INST_NAME("OR Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_or8(dyn, ninst, x1, x2, x3, x4); + GBBACK; + break; + case 0x0B: + INST_NAME("OR Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_or32(dyn, ninst, rex, gd, ed, x3, x4); + break; + case 0x0C: + INST_NAME("OR AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + UXTBw(x1, xRAX); + emit_or8c(dyn, ninst, x1, u8, x3, x4); + BFIx(xRAX, x1, 0, 8); + break; + case 0x0D: + INST_NAME("OR EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_or32c(dyn, ninst, rex, xRAX, i64, x3, x4); + break; case 0x0F: opcode=F8; @@ -126,6 +225,325 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; + case 0x10: + INST_NAME("ADC Eb, Gb"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_adc8(dyn, ninst, x1, x2, x4, x5); + EBBACK; + break; + case 0x11: + INST_NAME("ADC Ed, Gd"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_adc32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x12: + INST_NAME("ADC Gb, Eb"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_adc8(dyn, ninst, x1, x2, x4, x3); + GBBACK; + break; + case 0x13: + INST_NAME("ADC Gd, Ed"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_adc32(dyn, ninst, rex, gd, ed, x3, x4); + break; + case 0x14: + INST_NAME("ADC AL, Ib"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + UXTBw(x1, xRAX); + emit_adc8c(dyn, ninst, x1, u8, x3, x4, x5); + BFIx(xRAX, x1, 0, 8); + break; + case 0x15: + INST_NAME("ADC EAX, Id"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + MOV64xw(x1, i64); + emit_adc32(dyn, ninst, rex, xRAX, x1, x3, x4); + break; + + case 0x18: + INST_NAME("SBB Eb, Gb"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_sbb8(dyn, ninst, x1, x2, x4, x5); + EBBACK; + break; + case 0x19: + INST_NAME("SBB Ed, Gd"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sbb32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x1A: + INST_NAME("SBB Gb, Eb"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_sbb8(dyn, ninst, x1, x2, x3, x4); + GBBACK; + break; + case 0x1B: + INST_NAME("SBB Gd, Ed"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sbb32(dyn, ninst, rex, gd, ed, x3, x4); + break; + case 0x1C: + INST_NAME("SBB AL, Ib"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + UXTBw(x1, xRAX); + emit_sbb8c(dyn, ninst, x1, u8, x3, x4, x5); + BFIx(xRAX, x1, 0, 8); + break; + case 0x1D: + INST_NAME("SBB EAX, Id"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + MOV64xw(x2, i64); + emit_sbb32(dyn, ninst, rex, xRAX, x2, x3, x4); + break; + + case 0x20: + INST_NAME("AND Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_and8(dyn, ninst, x1, x2, x4, x5); + EBBACK; + break; + case 0x21: + INST_NAME("AND Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_and32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x22: + INST_NAME("AND Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_and8(dyn, ninst, x1, x2, x3, x4); + GBBACK; + break; + case 0x23: + INST_NAME("AND Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_and32(dyn, ninst, rex, gd, ed, x3, x4); + break; + case 0x24: + INST_NAME("AND AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + UXTBw(x1, xRAX); + emit_and8c(dyn, ninst, x1, u8, x3, x4); + BFIx(xRAX, x1, 0, 8); + break; + case 0x25: + INST_NAME("AND EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_and32c(dyn, ninst, rex, xRAX, i64, x3, x4); + break; + + case 0x28: + INST_NAME("SUB Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_sub8(dyn, ninst, x1, x2, x4, x5); + EBBACK; + break; + case 0x29: + INST_NAME("SUB Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sub32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x2A: + INST_NAME("SUB Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_sub8(dyn, ninst, x1, x2, x3, x4); + GBBACK; + break; + case 0x2B: + INST_NAME("SUB Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sub32(dyn, ninst, rex, gd, ed, x3, x4); + break; + case 0x2C: + INST_NAME("SUB AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + UXTBw(x1, xRAX); + emit_sub8c(dyn, ninst, x1, u8, x3, x4, x5); + BFIx(xRAX, x1, 0, 8); + break; + case 0x2D: + INST_NAME("SUB EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_sub32c(dyn, ninst, rex, xRAX, i64, x3, x4, x5); + break; + + case 0x30: + INST_NAME("XOR Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_xor8(dyn, ninst, x1, x2, x4, x5); + EBBACK; + break; + case 0x31: + INST_NAME("XOR Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_xor32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x32: + INST_NAME("XOR Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_xor8(dyn, ninst, x1, x2, x3, x4); + GBBACK; + break; + case 0x33: + INST_NAME("XOR Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_xor32(dyn, ninst, rex, gd, ed, x3, x4); + break; + case 0x34: + INST_NAME("XOR AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + UXTBw(x1, xRAX); + emit_xor8c(dyn, ninst, x1, u8, x3, x4); + BFIx(xRAX, x1, 0, 8); + break; + case 0x35: + INST_NAME("XOR EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_xor32c(dyn, ninst, rex, xRAX, i64, x3, x4); + break; + + case 0x38: + INST_NAME("CMP Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5); + break; + case 0x39: + INST_NAME("CMP Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_cmp32(dyn, ninst, rex, ed, gd, x3, x4, x5); + break; + case 0x3A: + INST_NAME("CMP Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5); + break; + case 0x3B: + INST_NAME("CMP Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_cmp32(dyn, ninst, rex, gd, ed, x3, x4, x5); + break; + case 0x3C: + INST_NAME("CMP AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + UXTBw(x1, xRAX); + if(u8) { + MOV32w(x2, u8); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5); + } else { + emit_cmp8_0(dyn, ninst, x1, x3, x4); + } + break; + case 0x3D: + INST_NAME("CMP EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + if(i64) { + MOV64xw(x2, i64); + emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5); + } else + emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4); + break; + case 0x81: case 0x83: nextop = F8; diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index dcec9d6f..51cf5ec7 100755 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -272,6 +272,25 @@ wb1 = 1; \ ed = i; \ } +//GETEB will use i for ed, and can use r3 for wback. +#define GETEB32(i, D) if(MODREG) { \ + if(rex.rex) { \ + wback = xRAX+(nextop&7)+(rex.b<<3); \ + wb2 = 0; \ + } else { \ + wback = (nextop&7); \ + wb2 = (wback>>2)*8; \ + wback = xRAX+(wback&3); \ + } \ + UBFXx(i, wback, wb2, 8); \ + wb1 = 0; \ + ed = i; \ + } else { \ + addr = geted32(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff, 0, rex, NULL, 0, D); \ + LDRB_U12(i, wback, fixedaddress); \ + wb1 = 1; \ + ed = i; \ + } // Write eb (ed) back to original register / memory #define EBBACK if(wb1) {STRB_U12(ed, wback, fixedaddress);} else {BFIx(wback, ed, wb2, 8);} //GETGB will use i for gd |