diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-23 11:25:02 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-23 11:25:02 +0100 |
| commit | c9d593fa17916b0a542a801cafa4ea2a0d8c59bc (patch) | |
| tree | b147f7de6daf912473d11074d4e7013aced0140e /src | |
| parent | ed452e81ae59982da75774ad52f6bfafe24096fb (diff) | |
| download | box64-c9d593fa17916b0a542a801cafa4ea2a0d8c59bc.tar.gz box64-c9d593fa17916b0a542a801cafa4ea2a0d8c59bc.zip | |
[DYNAREC] Added F0 83 opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/dynarec_arm64_f0.c | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/src/dynarec/dynarec_arm64_f0.c b/src/dynarec/dynarec_arm64_f0.c index 5756db77..11939fc1 100644 --- a/src/dynarec/dynarec_arm64_f0.c +++ b/src/dynarec/dynarec_arm64_f0.c @@ -33,6 +33,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uint16_t u16; uint8_t gd, ed; uint8_t wback, wb1, wb2, gb1, gb2; + int64_t i64; int fixedaddress; MAYUSE(u16); MAYUSE(u8); @@ -148,6 +149,187 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; + case 0x81: + case 0x83: + nextop = F8; + switch((nextop>>3)&7) { + case 0: //ADD + if(opcode==0x81) { + INST_NAME("LOCK ADD Ed, Id"); + } else { + INST_NAME("LOCK ADD Ed, Ib"); + } + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i64 = F32S; else i64 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV64xw(x5, i64); + emit_add32(dyn, ninst, rex, ed, x5, x3, x4); + } else { + 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 + B_MARK(cNE); + MARKLOCK; + LDAXRxw(x1, wback); + emit_add32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRxw(x3, x1, wback); + CBNZx_MARKLOCK(x3); + B_NEXT_nocond; + MARK; // unaligned! also, not enough + LDRxw_U12(x1, wback, 0); + LDAXRB(x4, wback); + BFIxw(x1, x4, 0, 8); // re-inject + emit_add32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRB(x3, x1, wback); + CBNZx_MARK(x3); + STRxw_U12(x1, wback, 0); // put the whole value + } + break; + case 1: //OR + if(opcode==0x81) {INST_NAME("LOCK OR Ed, Id");} else {INST_NAME("LOCK OR Ed, Ib");} + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i64 = F32S; else i64 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV64xw(x5, i64); + emit_or32(dyn, ninst, rex, ed, x5, x3, x4); + } else { + 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); + MARKLOCK; + LDAXRxw(x1, wback); + emit_or32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRxw(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 2: //ADC + if(opcode==0x81) {INST_NAME("LOCK ADC Ed, Id");} else {INST_NAME("LOCK ADC Ed, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i64 = F32S; else i64 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV64xw(x5, i64); + emit_adc32(dyn, ninst, rex, ed, x5, x3, x4); + } else { + 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); + MARKLOCK; + LDAXRxw(x1, wback); + emit_adc32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRxw(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 3: //SBB + if(opcode==0x81) {INST_NAME("LOCK SBB Ed, Id");} else {INST_NAME("LOCK SBB Ed, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i64 = F32S; else i64 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV64xw(x5, i64); + emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4); + } else { + 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); + MARKLOCK; + LDAXRxw(x1, wback); + emit_sbb32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRxw(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 4: //AND + if(opcode==0x81) {INST_NAME("LOCK AND Ed, Id");} else {INST_NAME("LOCK AND Ed, Ib");} + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i64 = F32S; else i64 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV64xw(x5, i64); + emit_and32(dyn, ninst, rex, ed, x5, x3, x4); + } else { + 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); + MARKLOCK; + LDAXRxw(x1, wback); + emit_and32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRxw(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + case 5: //SUB + if(opcode==0x81) {INST_NAME("LOCK SUB Ed, Id");} else {INST_NAME("LOCK SUB Ed, Ib");} + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i64 = F32S; else i64 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV64xw(x5, i64); + emit_sub32(dyn, ninst, rex, ed, x5, x3, x4); + } else { + 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 + B_MARK(cNE); + MARKLOCK; + LDAXRxw(x1, wback); + emit_sub32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRxw(x3, x1, wback); + CBNZx_MARKLOCK(x3); + B_NEXT_nocond; + MARK; // unaligned! also, not enough + LDRxw_U12(x1, wback, 0); + LDAXRB(x4, wback); + BFIxw(x1, x4, 0, 8); // re-inject + emit_sub32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRB(x3, x1, wback); + CBNZx_MARK(x3); + STRxw_U12(x1, wback, 0); // put the whole value + } + break; + case 6: //XOR + if(opcode==0x81) {INST_NAME("LOCK XOR Ed, Id");} else {INST_NAME("LOCK XOR Ed, Ib");} + SETFLAGS(X_ALL, SF_SET); + if(MODREG) { + if(opcode==0x81) i64 = F32S; else i64 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + MOV64xw(x5, i64); + emit_xor32(dyn, ninst, rex, ed, x5, x3, x4); + } else { + 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); + MARKLOCK; + LDAXRxw(x1, wback); + emit_xor32(dyn, ninst, rex, x1, x5, x3, x4); + STLXRxw(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + break; + 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); + // No need to LOCK, this is readonly + if(opcode==0x81) i64 = F32S; else i64 = F8S; + if(i32) { + MOV64xw(x5, i64); + emit_cmp32(dyn, ninst, rex, ed, x5, x3, x4, x6); + } else { + emit_cmp32_0(dyn, ninst, rex, ed, x3, x4); + } + break; + } + break; + default: DEFAULT; } |