diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-16 12:35:41 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-16 12:35:41 +0100 |
| commit | dc06ca51a64fbb251e89726a0a0a6f2bbebf7c8c (patch) | |
| tree | c3d7077cdaf1f10b87fb619092d5b4048a7f1886 /src/dynarec | |
| parent | d76ea27c54878fb3880ca691fff14bb1b207f65e (diff) | |
| download | box64-dc06ca51a64fbb251e89726a0a0a6f2bbebf7c8c.tar.gz box64-dc06ca51a64fbb251e89726a0a0a6f2bbebf7c8c.zip | |
[ARM64_DYNAREC] Improved 0F A4 opcode
Diffstat (limited to 'src/dynarec')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index 19343416..7c626eb1 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -1056,8 +1056,7 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint MOV32w(s3, c); STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1)); STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2)); - // same flags computation as with shl64/shl32 - SET_DF(s4, rex.w?d_shl64:d_shl32); + SET_DF(s4, rex.w?d_shld64:d_shld32); } else IFX(X_ALL) { SET_DFNONE(s4); } @@ -1070,12 +1069,15 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint } return; } - IFX(X_CF|X_OF) { + IFX(X_CF) { LSRxw(s3, s1, (rex.w?64:32)-c); BFIxw(xFlags, s3, F_CF, 1); } - LSLxw(s3, s1, c); - ORRxw_REG_LSR(s1, s3, s2, (rex.w?64:32)-c); + IFX(X_OF) { + LSRxw(s3, s1, rex.w?63:31); + BFIw(xFlags, s3, F_OF, 1); // store current sign for later use + } + EXTRxw(s1, s1, s2, (rex.w?64:32)-c); IFX(X_PEND) { STRxw_U12(s1, xEmu, offsetof(x64emu_t, res)); @@ -1091,8 +1093,8 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint } IFX(X_OF) { if(c==1) { - UBFXxw(s3, s1, rex.w?63:31, 1); - EORxw_REG(s3, s3, xFlags); // CF is set if OF is asked + LSRxw(s3, s1, rex.w?63:31); + EORxw_REG_LSR(s3, s3, xFlags, F_OF); // OF is set if sign changed BFIw(xFlags, s3, F_OF, 1); } else { BFCw(xFlags, F_OF, 1); |