diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-04-17 10:55:03 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-04-17 10:55:03 +0200 |
| commit | aacc3920499736c5709fd3653dc65f0344bffb58 (patch) | |
| tree | 2eaa6ad48fef638b70c728ce08a37363f9327ba6 /src | |
| parent | 74b99b52ee801bd91676897043d8a52040bc4fec (diff) | |
| download | box64-aacc3920499736c5709fd3653dc65f0344bffb58.tar.gz box64-aacc3920499736c5709fd3653dc65f0344bffb58.zip | |
[DYNAREC] Better handling of opcodes with 66 F0 prefixes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_66.c | 5 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66f0.c | 328 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f0.c | 276 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_helper.h | 2 |
4 files changed, 335 insertions, 276 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index b3b34b49..11e576fa 100755 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -47,7 +47,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin rep = opcode-0xF1; opcode = F8; } - // REX prefix before the F0 are ignored + // REX prefix before the 66 are ignored rex.rex = 0; while(opcode>=0x40 && opcode<=0x4f) { rex.rex = opcode; @@ -798,6 +798,9 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; + case 0xF0: + return dynarec64_66F0(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + case 0xF7: nextop = F8; switch((nextop>>3)&7) { diff --git a/src/dynarec/arm64/dynarec_arm64_66f0.c b/src/dynarec/arm64/dynarec_arm64_66f0.c new file mode 100644 index 00000000..0bd95f48 --- /dev/null +++ b/src/dynarec/arm64/dynarec_arm64_66f0.c @@ -0,0 +1,328 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <pthread.h> +#include <errno.h> + +#include "debug.h" +#include "box64context.h" +#include "dynarec.h" +#include "emu/x64emu_private.h" +#include "emu/x64run_private.h" +#include "x64run.h" +#include "x64emu.h" +#include "box64stack.h" +#include "callback.h" +#include "emu/x64run_private.h" +#include "x64trace.h" +#include "dynarec_native.h" + +#include "arm64_printer.h" +#include "dynarec_arm64_private.h" +#include "dynarec_arm64_helper.h" +#include "dynarec_arm64_functions.h" + + +uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) +{ + (void)ip; (void)rep; (void)need_epilog; + + uint8_t opcode = F8; + uint8_t nextop; + uint8_t gd, ed, u8; + 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); + + while((opcode==0xF2) || (opcode==0xF3)) { + rep = opcode-0xF1; + opcode = F8; + } + // REX prefix before the F0/66 are ignored + rex.rex = 0; + while(opcode>=0x40 && opcode<=0x4f) { + rex.rex = opcode; + opcode = F8; + } + + switch(opcode) { + case 0x09: + INST_NAME("LOCK OR Ew, Gw"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGW(x5); + DMB_ISH(); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + 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, 0); + MARKLOCK; + LDAXRH(x1, wback); + emit_or16(dyn, ninst, x1, x5, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + DMB_ISH(); + break; + + case 0x81: + case 0x83: + nextop = F8; + DMB_ISH(); + 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_PENDING); + 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_PENDING); + 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_PENDING); + 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_PENDING); + 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_PENDING); + 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_PENDING); + 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_PENDING); + 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_PENDING); + GETEW(x6, (opcode==0x81)?2:1); + (void)wb1; + // 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; + } + DMB_ISH(); + break; + + case 0xFF: + nextop = F8; + switch((nextop>>3)&7) + { + case 0: // INC Ew + INST_NAME("LOCK INC Ew"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING); + DMB_ISH(); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + UXTHw(x6, ed); + emit_inc16(dyn, ninst, x6, x5, x3); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, 0); + MARKLOCK; + LDAXRH(x1, wback); + emit_inc16(dyn, ninst, x1, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + DMB_ISH(); + break; + case 1: //DEC Ew + INST_NAME("LOCK DEC Ew"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING); + DMB_ISH(); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + UXTHw(x6, ed); + emit_dec16(dyn, ninst, x6, x5, x3); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, 0); + MARKLOCK; + LDAXRH(x1, wback); + emit_dec16(dyn, ninst, x1, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + DMB_ISH(); + break; + default: + DEFAULT; + } + break; + + default: + DEFAULT; + } + return addr; +} diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c index 201fa33e..46bd8cc6 100644 --- a/src/dynarec/arm64/dynarec_arm64_f0.c +++ b/src/dynarec/arm64/dynarec_arm64_f0.c @@ -336,281 +336,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x66: - opcode = F8; - switch(opcode) { - case 0x09: - INST_NAME("LOCK OR Ew, Gw"); - SETFLAGS(X_ALL, SF_SET_PENDING); - nextop = F8; - GETGW(x5); - DMB_ISH(); - if(MODREG) { - ed = xRAX+(nextop&7)+(rex.b<<3); - 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, 0); - MARKLOCK; - LDAXRH(x1, wback); - emit_or16(dyn, ninst, x1, x5, x3, x4); - STLXRH(x3, x1, wback); - CBNZx_MARKLOCK(x3); - } - DMB_ISH(); - break; - - case 0x81: - case 0x83: - nextop = F8; - DMB_ISH(); - 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_PENDING); - 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_PENDING); - 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_PENDING); - 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_PENDING); - 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_PENDING); - 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_PENDING); - 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_PENDING); - 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_PENDING); - GETEW(x6, (opcode==0x81)?2:1); - (void)wb1; - // 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; - } - DMB_ISH(); - break; - - case 0xFF: - nextop = F8; - switch((nextop>>3)&7) - { - case 0: // INC Ew - INST_NAME("LOCK INC Ew"); - SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING); - DMB_ISH(); - if(MODREG) { - ed = xRAX+(nextop&7)+(rex.b<<3); - UXTHw(x6, ed); - emit_inc16(dyn, ninst, x6, x5, x3); - BFIx(ed, x6, 0, 16); - } else { - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, 0); - MARKLOCK; - LDAXRH(x1, wback); - emit_inc16(dyn, ninst, x1, x3, x4); - STLXRH(x3, x1, wback); - CBNZx_MARKLOCK(x3); - } - DMB_ISH(); - break; - case 1: //DEC Ew - INST_NAME("LOCK DEC Ew"); - SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING); - DMB_ISH(); - if(MODREG) { - ed = xRAX+(nextop&7)+(rex.b<<3); - UXTHw(x6, ed); - emit_dec16(dyn, ninst, x6, x5, x3); - BFIx(ed, x6, 0, 16); - } else { - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, 0); - MARKLOCK; - LDAXRH(x1, wback); - emit_dec16(dyn, ninst, x1, x3, x4); - STLXRH(x3, x1, wback); - CBNZx_MARKLOCK(x3); - } - DMB_ISH(); - break; - default: - DEFAULT; - } - break; - - default: - DEFAULT; - } - break; + return dynarec64_66F0(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); case 0x80: nextop = F8; diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index f730fdea..6c5068b0 100755 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -707,6 +707,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define dynarec64_F0 STEPNAME(dynarec64_F0) #define dynarec64_660F STEPNAME(dynarec64_660F) #define dynarec64_6664 STEPNAME(dynarec64_6664) +#define dynarec64_66F0 STEPNAME(dynarec64_66F0) #define dynarec64_F20F STEPNAME(dynarec64_F20F) #define dynarec64_F30F STEPNAME(dynarec64_F30F) @@ -1033,6 +1034,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); |