diff options
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 71 |
1 files changed, 56 insertions, 15 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index dc04a661..2dc8f66e 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -507,10 +507,23 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("XOR Eb, Gb"); SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETEB(x1, 0); - GETGB(x2); - emit_xor8(dyn, ninst, x1, x2, x4, x5); - EBBACK; + UFLAG_IF { + GETEB(x1, 0); + GETGB(x2); + emit_xor8(dyn, ninst, x1, x2, x4, x5); + EBBACK; + } else { + if(MODREG) { + GETGB(x2); + CALCEB(); + EORx_REG_LSL(wback, wback, x2, wb2); + } else { + GETEB(x1, 0); + CALCGB(); + EORw_REG_LSR(x1, x1, gb1, 8*gb2); + EBBACK; + } + } break; case 0x31: INST_NAME("XOR Ed, Gd"); @@ -525,10 +538,16 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("XOR Gb, Eb"); SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETEB(x2, 0); - GETGB(x1); - emit_xor8(dyn, ninst, x1, x2, x3, x4); - GBBACK; + UFLAG_IF { + GETEB(x2, 0); + GETGB(x1); + emit_xor8(dyn, ninst, x1, x2, x3, x4); + GBBACK; + } else { + GETEB(x2, 0); + CALCGB(); + EORx_REG_LSL(gb1, gb1, x2, gb2*8); + } break; case 0x33: INST_NAME("XOR Gd, Ed"); @@ -542,9 +561,19 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin 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); + UFLAG_IF { + UXTBw(x1, xRAX); + emit_xor8c(dyn, ninst, x1, u8, x3, x4); + BFIx(xRAX, x1, 0, 8); + } else { + int mask = convert_bitmask_x(u8); + if(mask) + EORx_mask(xRAX, xRAX, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F); + else { + MOV32w(x1, u8); + EORx_REG(xRAX, xRAX, x1); + } + } break; case 0x35: INST_NAME("XOR EAX, Id"); @@ -1107,10 +1136,22 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 6: //XOR INST_NAME("XOR Eb, Ib"); SETFLAGS(X_ALL, SF_SET_PENDING); - GETEB(x1, 1); - u8 = F8; - emit_xor8c(dyn, ninst, x1, u8, x2, x4); - EBBACK; + UFLAG_IF2(|| !MODREG) { + GETEB(x1, 1); + u8 = F8; + emit_xor8c(dyn, ninst, x1, u8, x2, x4); + EBBACK; + } else { + CALCEB(); + u8 = F8; + int mask = convert_bitmask_x(((uint32_t)u8)<<wb2); + if(mask) + EORx_mask(wback, wback, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F); + else { + MOV32w(x1, ((uint32_t)u8)<<wb2); + EORx_REG(wback, wback, x1); + } + } break; case 7: //CMP INST_NAME("CMP Eb, Ib"); |