diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-06-07 10:08:46 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-06-07 10:08:46 +0200 |
| commit | 3b39d1270db80523e415a362512f82d993a1da07 (patch) | |
| tree | c5d726e1f72d4d51295132ce4d6181e5b64dee84 /src | |
| parent | d5b286c050833acec49dba33ad6b92b4196f1b45 (diff) | |
| download | box64-3b39d1270db80523e415a362512f82d993a1da07.tar.gz box64-3b39d1270db80523e415a362512f82d993a1da07.zip | |
[DYNAREC] Added 66 F0 81/83 opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/dynarec_arm64_f0.c | 214 |
1 files changed, 210 insertions, 4 deletions
diff --git a/src/dynarec/dynarec_arm64_f0.c b/src/dynarec/dynarec_arm64_f0.c index 40fa330a..820940e3 100644 --- a/src/dynarec/dynarec_arm64_f0.c +++ b/src/dynarec/dynarec_arm64_f0.c @@ -30,11 +30,13 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uint8_t opcode = F8; uint8_t nextop; uint8_t gd, ed; - uint8_t wback, wb2, gb1, gb2; + uint8_t wback, wb1, wb2, gb1, gb2; + int32_t i32; int64_t i64, j64; int64_t fixedaddress; MAYUSE(gb1); MAYUSE(gb2); + MAYUSE(wb1); MAYUSE(wb2); MAYUSE(j64); @@ -229,6 +231,210 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; + case 0x66: + opcode = F8; + switch(opcode) { + case 0x81: + case 0x83: + nextop = F8; + switch((nextop>>3)&7) { + case 0: //ADD + if(opcode==0x81) { + INST_NAME("LOCK ADD Ew, Iw"); + } else { + INST_NAME("LOCK ADD Ew, Iw"); + } + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i32 = F16S; else i32 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV32w(x5, i32); + UXTHw(x6, ed); + emit_add16(dyn, ninst, x6, x5, x3, x4); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?2:1); + if(opcode==0x81) i32 = F32S; else i32 = F8S; + MOV32w(x5, i32); + TSTx_mask(wback, 1, 0, 0); // mask=1 + B_MARK(cNE); + MARKLOCK; + LDAXRH(x1, wback); + emit_add16(dyn, ninst, x1, x5, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + B_NEXT_nocond; + MARK; // unaligned! also, not enough + LDRH_U12(x1, wback, 0); + LDAXRB(x4, wback); + BFIw(x1, x4, 0, 8); // re-inject + emit_add16(dyn, ninst, x1, x5, x3, x4); + STLXRB(x3, x1, wback); + CBNZx_MARK(x3); + STRH_U12(x1, wback, 0); // put the whole value + } + break; + case 1: //OR + if(opcode==0x81) {INST_NAME("LOCK OR Ew, Iw");} else {INST_NAME("LOCK OR Ew, Iw");} + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i32 = F16S; else i32 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV32w(x5, i32); + UXTHw(x6, ed); + emit_or16(dyn, ninst, x6, x5, x3, x4); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?2:1); + if(opcode==0x81) i32 = F16S; else i32 = F8S; + MOV32w(x5, i32); + MARKLOCK; + LDAXRH(x1, wback); + emit_or16(dyn, ninst, x1, x5, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 2: //ADC + if(opcode==0x81) {INST_NAME("LOCK ADC Ew, Iw");} else {INST_NAME("LOCK ADC Ew, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i32 = F16S; else i32 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV32w(x5, i32); + UXTHw(x6, ed); + emit_adc16(dyn, ninst, x6, x5, x3, x4); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?2:1); + if(opcode==0x81) i32 = F16S; else i32 = F8S; + MOV32w(x5, i32); + MARKLOCK; + LDAXRH(x1, wback); + emit_adc16(dyn, ninst, x1, x5, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 3: //SBB + if(opcode==0x81) {INST_NAME("LOCK SBB Ew, Iw");} else {INST_NAME("LOCK SBB Ew, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i32 = F16S; else i32 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV32w(x5, i32); + UXTHw(x6, ed); + emit_sbb16(dyn, ninst, x6, x5, x3, x4); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?2:1); + if(opcode==0x81) i32 = F16S; else i32 = F8S; + MOV32w(x5, i32); + MARKLOCK; + LDAXRH(x1, wback); + emit_sbb16(dyn, ninst, x1, x5, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 4: //AND + if(opcode==0x81) {INST_NAME("LOCK AND Ew, Iw");} else {INST_NAME("LOCK AND Ew, Ib");} + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i32 = F16S; else i32 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV32w(x5, i32); + UXTHw(x6, ed); + emit_and16(dyn, ninst, x6, x5, x3, x4); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?2:1); + if(opcode==0x81) i32 = F16S; else i32 = F8S; + MOV32w(x5, i32); + MARKLOCK; + LDAXRH(x1, wback); + emit_and16(dyn, ninst, x1, x5, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 5: //SUB + if(opcode==0x81) {INST_NAME("LOCK SUB Ew, Iw");} else {INST_NAME("LOCK SUB Ew, Ib");} + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i32 = F16S; else i32 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV32w(x5, i32); + UXTHw(x6, ed); + emit_sub16(dyn, ninst, x6, x5, x3, x4); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?2:1); + if(opcode==0x81) i32 = F16S; else i32 = F8S; + MOV32w(x5, i32); + TSTx_mask(wback, 1, 0, 0); // mask=1 + B_MARK(cNE); + MARKLOCK; + LDAXRH(x1, wback); + emit_sub16(dyn, ninst, x1, x5, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + B_NEXT_nocond; + MARK; // unaligned! also, not enough + LDRH_U12(x1, wback, 0); + LDAXRB(x4, wback); + BFIw(x1, x4, 0, 8); // re-inject + emit_sub16(dyn, ninst, x1, x5, x3, x4); + STLXRB(x3, x1, wback); + CBNZx_MARK(x3); + STRH_U12(x1, wback, 0); // put the whole value + } + break; + case 6: //XOR + if(opcode==0x81) {INST_NAME("LOCK XOR Ew, Iw");} else {INST_NAME("LOCK XOR Ew, Ib");} + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i32 = F16S; else i32 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV32w(x5, i32); + UXTHw(x6, ed); + emit_xor16(dyn, ninst, x6, x5, x3, x4); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?2:1); + if(opcode==0x81) i32 = F16S; else i32 = F8S; + MOV32w(x5, i32); + MARKLOCK; + LDAXRH(x1, wback); + emit_xor16(dyn, ninst, x1, x5, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 7: //CMP + if(opcode==0x81) {INST_NAME("(LOCK) CMP Ew, Iw");} else {INST_NAME("(LOCK) CMP Ew, Ib");} + SETFLAGS(X_ALL, SF_SET); + GETEW(x6, (opcode==0x81)?2:1); + // No need to LOCK, this is readonly + if(opcode==0x81) i32 = F16S; else i32 = F8S; + if(i32) { + MOV32w(x5, i32); + UXTHw(x6, ed); + emit_cmp16(dyn, ninst, x6, x5, x3, x4, x6); + BFIx(ed, x6, 0, 16); + } else { + emit_cmp16_0(dyn, ninst, ed, x3, x4); + } + break; + } + break; + default: + DEFAULT; + } + break; + case 0x81: case 0x83: nextop = F8; @@ -249,7 +455,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; MOV64xw(x5, i64); - TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7 + TSTx_mask(wback, 1, 0, 0); // mask=1 B_MARK(cNE); MARKLOCK; LDAXRxw(x1, wback); @@ -357,7 +563,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; MOV64xw(x5, i64); - TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7 + TSTx_mask(wback, 1, 0, 0); // mask=1 B_MARK(cNE); MARKLOCK; LDAXRxw(x1, wback); @@ -397,7 +603,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 7: //CMP if(opcode==0x81) {INST_NAME("(LOCK) CMP Ed, Id");} else {INST_NAME("(LOCK) CMP Ed, Ib");} SETFLAGS(X_ALL, SF_SET); - GETED(0); + GETED((opcode==0x81)?4:1); // No need to LOCK, this is readonly if(opcode==0x81) i64 = F32S; else i64 = F8S; if(i64) { |