about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-03-08 17:34:28 +0800
committerGitHub <noreply@github.com>2024-03-08 10:34:28 +0100
commit602c015321c5feca6570a47b4be5c63fe920232b (patch)
tree88451980d82ed5d38715cf3459b831b3ce101f2b /src
parent55c2c9ee59261540714c3861875d38d66e22ac37 (diff)
downloadbox64-602c015321c5feca6570a47b4be5c63fe920232b.tar.gz
box64-602c015321c5feca6570a47b4be5c63fe920232b.zip
[DYNAREC] Made shift operations handle count==0 more uniformly (#1345)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c244
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c88
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67.c80
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c42
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c79
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_shift.c10
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c82
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_67.c15
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_shift.c16
10 files changed, 378 insertions, 282 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index c1ee3648..d19bef46 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -756,7 +756,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0x62:
             if(rex.is32bits) {
                 // BOUND here
-                DEFAULT;                
+                DEFAULT;
             } else {
                 INST_NAME("BOUND Gd, Ed");
                 nextop = F8;
@@ -766,7 +766,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0x63:
             if(rex.is32bits) {
                 // ARPL here
-                DEFAULT;                
+                DEFAULT;
             } else {
                 INST_NAME("MOVSXD Gd, Ed");
                 nextop = F8;
@@ -1928,104 +1928,97 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {
                 case 0:
                     INST_NAME("ROL Eb, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    if(u8) {
-                        SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_CF | X_OF, SF_SUBSET_PENDING); // some flags are left undefined
                         GETEB(x1, 1);
-                        u8 = F8&0x1f;
-                        emit_rol8c(dyn, ninst, x1, u8, x4, x5);
-                        EBBACK;
-                    } else {
+                    } else
                         FAKEED;
-                        F8;
-                    }
+                    F8;
+                    emit_rol8c(dyn, ninst, x1, u8, x4, x5);
+                    if (u8) EBBACK;
                     break;
                 case 1:
                     INST_NAME("ROR Eb, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    if(u8) {
-                        SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_CF | X_OF, SF_SUBSET_PENDING);
                         GETEB(x1, 1);
-                        u8 = F8&0x1f;
-                        emit_ror8c(dyn, ninst, x1, u8, x4, x5);
-                        EBBACK;
-                    } else {
+                    } else
                         FAKEED;
-                        F8;
-                    }
+                    F8;
+                    emit_ror8c(dyn, ninst, x1, u8, x4, x5);
+                    if (u8) EBBACK;
                     break;
                 case 2:
                     INST_NAME("RCL Eb, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    if(u8) {
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
                         READFLAGS(X_CF);
-                        SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                        SETFLAGS(X_OF | X_CF, SF_SUBSET_PENDING);
                         GETEB(x1, 1);
-                        u8 = F8&0x1f;
-                        emit_rcl8c(dyn, ninst, x1, u8, x4, x5);
-                        EBBACK;
-                    } else {
+                    } else
                         FAKEED;
-                        F8;
-                    }
+                    F8;
+                    emit_rcl8c(dyn, ninst, x1, u8, x4, x5);
+                    if (u8) EBBACK;
                     break;
                 case 3:
                     INST_NAME("RCR Eb, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    if(u8) {
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
                         READFLAGS(X_CF);
-                        SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                        SETFLAGS(X_OF | X_CF, SF_SUBSET_PENDING);
                         GETEB(x1, 1);
-                        u8 = F8&0x1f;
-                        emit_rcr8c(dyn, ninst, x1, u8, x4, x5);
-                        EBBACK;
-                    } else {
+                    } else
                         FAKEED;
-                        F8;
-                    }
+                    F8;
+                    emit_rcr8c(dyn, ninst, x1, u8, x4, x5);
+                    if (u8) EBBACK;
                     break;
                 case 4:
                 case 6:
                     INST_NAME("SHL Eb, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    if(u8) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
                         GETEB(x1, 1);
-                        u8 = (F8)&0x1f;
-                        emit_shl8c(dyn, ninst, ed, u8, x4, x5);
-                        EBBACK;
-                    } else {
+                    } else
                         FAKEED;
-                        F8;
-                    }
+                    F8;
+                    emit_shl8c(dyn, ninst, ed, u8, x4, x5);
+                    if (u8) EBBACK;
                     break;
                 case 5:
                     INST_NAME("SHR Eb, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    if(u8) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
                         GETEB(x1, 1);
-                        u8 = (F8)&0x1f;
-                        emit_shr8c(dyn, ninst, ed, u8, x4, x5);
-                        EBBACK;
-                    } else {
+                    } else
                         FAKEED;
-                        F8;
-                    }
+                    F8;
+                    emit_shr8c(dyn, ninst, ed, u8, x4, x5);
+                    if (u8) EBBACK;
                     break;
                 case 7:
                     INST_NAME("SAR Eb, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    if(u8) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);
-                        GETSEB(x1, 1);
-                        u8 = (F8)&0x1f;
-                        emit_sar8c(dyn, ninst, ed, u8, x4, x5);
-                        EBBACK;
-                    } else {
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                        GETEB(x1, 1);
+                    } else
                         FAKEED;
-                        F8;
-                    }
+                    F8;
+                    emit_sar8c(dyn, ninst, ed, u8, x4, x5);
+                    if (u8) EBBACK;
                     break;
             }
             break;
@@ -2034,41 +2027,35 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {
                 case 0:
                     INST_NAME("ROL Ed, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
-                    if(u8) {
-                        SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_CF | X_OF, SF_SUBSET_PENDING);
                         GETED(1);
-                        u8 = (F8)&(rex.w?0x3f:0x1f);
-                        emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    } else
+                        FAKEED;
+                    F8;
+                    emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    if (u8) {
                         WBACK;
-                    } else {
-                        if(MODREG && ! rex.w && !rex.is32bits) {
-                            GETED(1);
-                            MOVw_REG(ed, ed);
-                        } else {
-                            FAKEED;
-                        }
-                        F8;
-                    }
+                    } else if (MODREG && !rex.w)
+                        MOVw_REG(ed, ed);
                     break;
                 case 1:
                     INST_NAME("ROR Ed, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
-                    if(u8) {
-                        SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_CF | X_OF, SF_SUBSET_PENDING);
                         GETED(1);
-                        u8 = (F8)&(rex.w?0x3f:0x1f);
-                        emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    } else
+                        FAKEED;
+                    F8;
+                    emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    if (u8) {
                         WBACK;
-                    } else {
-                        if(MODREG && ! rex.w && !rex.is32bits) {
-                            GETED(1);
-                            MOVw_REG(ed, ed);
-                        } else {
-                            FAKEED;
-                        }
-                        F8;
-                    }
+                    } else if (MODREG && !rex.w)
+                        MOVw_REG(ed, ed);
                     break;
                 case 2:
                     INST_NAME("RCL Ed, Ib");
@@ -2097,60 +2084,51 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 4:
                 case 6:
                     INST_NAME("SHL Ed, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
-                    if(u8) {
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
                         SETFLAGS(X_ALL, SF_SET_PENDING);
                         GETED(1);
-                        u8 = (F8)&(rex.w?0x3f:0x1f);
-                        emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    } else
+                        FAKEED;
+                    F8;
+                    emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    if (u8) {
                         WBACK;
-                    } else {
-                        if(MODREG && ! rex.w && !rex.is32bits) {
-                            GETED(1);
-                            MOVw_REG(ed, ed);
-                        } else {
-                            FAKEED;
-                        }
-                        F8;
-                    }
+                    } else if (MODREG && !rex.w)
+                        MOVw_REG(ed, ed);
                     break;
                 case 5:
                     INST_NAME("SHR Ed, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
-                    if(u8) {
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
                         SETFLAGS(X_ALL, SF_SET_PENDING);
                         GETED(1);
-                        u8 = (F8)&(rex.w?0x3f:0x1f);
-                        emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    } else
+                        FAKEED;
+                    F8;
+                    emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    if (u8) {
                         WBACK;
-                    } else {
-                        if(MODREG && ! rex.w && !rex.is32bits) {
-                            GETED(1);
-                            MOVw_REG(ed, ed);
-                        } else {
-                            FAKEED;
-                        }
-                        F8;
-                    }
+                    } else if (MODREG && !rex.w)
+                        MOVw_REG(ed, ed);
                     break;
                 case 7:
                     INST_NAME("SAR Ed, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
-                    if(u8) {
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
                         SETFLAGS(X_ALL, SF_SET_PENDING);
                         GETED(1);
-                        u8 = (F8)&(rex.w?0x3f:0x1f);
-                        emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    } else
+                        FAKEED;
+                    F8;
+                    emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    if (u8) {
                         WBACK;
-                    } else {
-                        if(MODREG && ! rex.w && !rex.is32bits) {
-                            GETED(1);
-                            MOVw_REG(ed, ed);
-                        } else {
-                            FAKEED;
-                        }
-                        F8;
-                    }
+                    } else if (MODREG && !rex.w)
+                        MOVw_REG(ed, ed);
                     break;
             }
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index ce0e14d3..c0960286 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -941,31 +941,29 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {

                 case 0:

                     INST_NAME("ROL Ew, Ib");

-                    u8 = geted_ib(dyn, addr, ninst, nextop)&15;

-                    if(u8) {

-                        SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_CF | ((u8 == 1) ? X_OF : 0), SF_SUBSET_PENDING);

                         GETEW(x1, 1);

-                        u8 = F8;

-                        emit_rol16c(dyn, ninst, x1, u8, x4, x5);

-                        EWBACK;

-                    } else {

+                    } else

                         FAKEED;

-                        F8;

-                    }

+                    F8;

+                    emit_rol16c(dyn, ninst, x1, u8, x4, x5);

+                    if (u8) EWBACK;

                     break;

                 case 1:

                     INST_NAME("ROR Ew, Ib");

-                    u8 = geted_ib(dyn, addr, ninst, nextop)&15;

-                    if(geted_ib(dyn, addr, ninst, nextop)&15) {

-                        SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_CF | ((u8 == 1) ? X_OF : 0), SF_SUBSET_PENDING);

                         GETEW(x1, 1);

-                        u8 = F8;

-                        emit_ror16c(dyn, ninst, x1, u8, x4, x5);

-                        EWBACK;

-                    } else {

+                    } else

                         FAKEED;

-                        F8;

-                    }

+                    F8;

+                    emit_ror16c(dyn, ninst, x1, u8, x4, x5);

+                    if (u8) EWBACK;

                     break;

                 case 2:

                     INST_NAME("RCL Ew, Ib");

@@ -1002,42 +1000,42 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 4:

                 case 6:

                     INST_NAME("SHL Ew, Ib");

-                    if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {

-                        SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined

                         GETEW(x1, 0);

-                        u8 = (F8)&0x1f;

-                        emit_shl16c(dyn, ninst, x1, u8, x5, x4);

-                        EWBACK;

-                    } else {

+                    } else

                         FAKEED;

-                        F8;

-                    }

+                    F8;

+                    emit_shl16c(dyn, ninst, x1, u8, x5, x4);

+                    if (u8) EWBACK;

                     break;

                 case 5:

-                    INST_NAME("SHR Ed, Ib");

-                    if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {

-                        SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined

+                    INST_NAME("SHR Ew, Ib");

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined

                         GETEW(x1, 0);

-                        u8 = (F8)&0x1f;

-                        emit_shr16c(dyn, ninst, x1, u8, x5, x4);

-                        EWBACK;

-                    } else {

+                    } else

                         FAKEED;

-                        F8;

-                    }

+                    F8;

+                    emit_shr16c(dyn, ninst, x1, u8, x5, x4);

+                    if (u8) EWBACK;

                     break;

                 case 7:

-                    INST_NAME("SAR Ed, Ib");

-                    if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {

-                        SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined

-                        GETSEW(x1, 0);

-                        u8 = (F8)&0x1f;

-                        emit_sar16c(dyn, ninst, x1, u8, x5, x4);

-                        EWBACK;

-                    } else {

+                    INST_NAME("SAR Ew, Ib");

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined

+                        GETEW(x1, 0);

+                    } else

                         FAKEED;

-                        F8;

-                    }

+                    F8;

+                    emit_sar16c(dyn, ninst, x1, u8, x5, x4);

+                    if (u8) EWBACK;

                     break;

             }

             break;

diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index 82dd7a27..bf44681a 100644
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -918,19 +918,35 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {

                 case 0:

                     INST_NAME("ROL Ed, Ib");

-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

-                    GETED32(1);

-                    u8 = (F8)&(rex.w?0x3f:0x1f);

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_OF | X_CF, SF_SUBSET_PENDING);

+                        GETED32(1);

+                    } else

+                        FAKEED;

+                    F8;

                     emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);

-                    if(u8) { WBACK; }

+                    if (u8) {

+                        WBACK;

+                    } else if (MODREG && !rex.w)

+                        MOVw_REG(ed, ed);

                     break;

                 case 1:

                     INST_NAME("ROR Ed, Ib");

-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

-                    GETED32(1);

-                    u8 = (F8)&(rex.w?0x3f:0x1f);

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_OF | X_CF, SF_SUBSET_PENDING);

+                        GETED32(1);

+                    } else

+                        FAKEED;

+                    F8;

                     emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);

-                    if(u8) { WBACK; }

+                    if (u8) {

+                        WBACK;

+                    } else if (MODREG && !rex.w)

+                        MOVw_REG(ed, ed);

                     break;

                 case 2:

                     INST_NAME("RCL Ed, Ib");

@@ -957,31 +973,51 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 4:

                 case 6:

                     INST_NAME("SHL Ed, Ib");

-                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined

-                    GETED32(1);

-                    u8 = (F8)&(rex.w?0x3f:0x1f);

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined

+                        GETED32(1);

+                    } else

+                        FAKEED;

+                    F8;

                     emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);

-                    WBACK;

+                    if (u8) {

+                        WBACK;

+                    } else if (MODREG && !rex.w)

+                        MOVw_REG(ed, ed);

                     break;

                 case 5:

                     INST_NAME("SHR Ed, Ib");

-                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined

-                    GETED32(1);

-                    u8 = (F8)&(rex.w?0x3f:0x1f);

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined

+                        GETED32(1);

+                    } else

+                        FAKEED;

+                    F8;

                     emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);

-                    if(u8) {

+                    if (u8) {

                         WBACK;

-                    }

+                    } else if (MODREG && !rex.w)

+                        MOVw_REG(ed, ed);

                     break;

                 case 7:

                     INST_NAME("SAR Ed, Ib");

-                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined

-                    GETED32(1);

-                    u8 = (F8)&(rex.w?0x3f:0x1f);

+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);

+                    // flags are not affected if count is 0, we make it a nop if possible.

+                    if (u8) {

+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined

+                        GETED32(1);

+                    } else

+                        FAKEED;

+                    F8;

                     emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);

-                    if(u8) {

+                    if (u8) {

                         WBACK;

-                    }

+                    } else if (MODREG && !rex.w)

+                        MOVw_REG(ed, ed);

                     break;

             }

             break;

diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index b8686477..3ce94c9d 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -82,6 +82,8 @@ void emit_shl32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
 // emit SHL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -185,6 +187,8 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
 // emit SHR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -238,6 +242,8 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 // emit SAR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -430,8 +436,7 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
 // emit SHR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
-    if(!c)
-        return;
+    if (!c) return;
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -505,8 +510,7 @@ void emit_sar8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
 // emit SAR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
-    if(!c)
-        return;
+    if (!c) return;
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -587,8 +591,7 @@ void emit_shl16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
 // emit SHL16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
-    if(!c)
-        return;
+    if (!c) return;
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -760,8 +763,7 @@ void emit_sar16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
 // emit SAR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_sar16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
-    if(!c)
-        return;
+    if (!c) return;
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -795,6 +797,9 @@ void emit_sar16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
 void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(rex); MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2));
@@ -827,6 +832,9 @@ void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2));
@@ -860,6 +868,9 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
@@ -890,6 +901,9 @@ void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
 void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
@@ -920,6 +934,9 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
 void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
@@ -950,6 +967,9 @@ void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
 void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
@@ -980,6 +1000,9 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
 void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -1014,6 +1037,9 @@ void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
 void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+
+    if (!c) return;
+
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index c0583e16..466a12a8 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -652,60 +652,51 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 case 4:
                 case 6:
                     INST_NAME("SHL Ed, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
-                    if(u8) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         GETED(1);
-                        u8 = (F8) & (rex.w ? 0x3f : 0x1f);
-                        emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4, x5);
+                    } else
+                        FAKEED;
+                    F8;
+                    emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4, x5);
+                    if (u8) {
                         WBACK;
-                    } else {
-                        if(MODREG && ! rex.w && !rex.is32bits) {
-                            GETED(1);
-                            AND(ed, ed, xMASK);
-                        } else {
-                            FAKEED;
-                        }
-                        F8;
-                    }
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 case 5:
                     INST_NAME("SHR Ed, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
-                        if(u8) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         GETED(1);
-                        u8 = (F8) & (rex.w ? 0x3f : 0x1f);
-                        emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    } else
+                        FAKEED;
+                    F8;
+                    emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    if (u8) {
                         WBACK;
-                    } else {
-                        if(MODREG && ! rex.w && !rex.is32bits) {
-                            GETED(1);
-                            AND(ed, ed, xMASK);
-                        } else {
-                            FAKEED;
-                        }
-                        F8;
-                    }
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 case 7:
                     INST_NAME("SAR Ed, Ib");
-                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
-                    if(u8) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         GETED(1);
-                        u8 = (F8) & (rex.w ? 0x3f : 0x1f);
-                        emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
-                        WBACK; 
-                    } else {
-                        if(MODREG && ! rex.w && !rex.is32bits) {
-                            GETED(1);
-                            AND(ed, ed, xMASK);
-                        } else {
-                            FAKEED;
-                        }
-                        F8;
-                    }
+                    } else
+                        FAKEED;
+                    F8;
+                    emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    if (u8) {
+                        WBACK;
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 default:
                     DEFAULT;
@@ -1180,4 +1171,4 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
     }
 
     return addr;
-}
\ No newline at end of file
+}
diff --git a/src/dynarec/la64/dynarec_la64_emit_shift.c b/src/dynarec/la64/dynarec_la64_emit_shift.c
index b4d7ccdd..f4a35991 100644
--- a/src/dynarec/la64/dynarec_la64_emit_shift.c
+++ b/src/dynarec/la64/dynarec_la64_emit_shift.c
@@ -91,11 +91,13 @@ void emit_shl32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
 // emit SHL32 instruction, from s1 , constant c, store result in s1 using s3, s4 and s5 as scratch
 void emit_shl32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4, int s5)
 {
+    if (!c) return;
+
     IFX(X_PEND) {
         if (c) {
             MOV64x(s3, c);
             SDxw(s3, xEmu, offsetof(x64emu_t, op2));
-        } else 
+        } else
             SDxw(xZR, xEmu, offsetof(x64emu_t, op2));
         SDxw(s1, xEmu, offsetof(x64emu_t, op1));
         SET_DF(s4, rex.w?d_shl64:d_shl32);
@@ -170,6 +172,8 @@ void emit_shl32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
 // emit SHR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_shr32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     IFX(X_PEND) {
         if (c) {
             MOV64x(s3, c);
@@ -251,6 +255,8 @@ void emit_shr32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
 // emit SAR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_sar32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     IFX(X_PEND) {
         if (c) {
             MOV64x(s3, c);
@@ -319,4 +325,4 @@ void emit_sar32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
-}
\ No newline at end of file
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index 1158eadf..8fb520a0 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -164,21 +164,35 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             switch((nextop>>3)&7) {
                 case 0:
                     INST_NAME("ROL Ed, Ib");
-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
-                    GETED(1);
-                    u8 = (F8)&(rex.w?0x3f:0x1f);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_OF | X_CF, SF_SUBSET_PENDING);
+                        GETED(1);
+                    } else
+                        FAKEED;
+                    F8;
                     emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
-                    if(u8) { WBACK; }
-                    if(!wback && !rex.w) ZEROUP(ed);
+                    if (u8) {
+                        WBACK;
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 case 1:
                     INST_NAME("ROR Ed, Ib");
-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
-                    GETED(1);
-                    u8 = (F8)&(rex.w?0x3f:0x1f);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_OF | X_CF, SF_SUBSET_PENDING);
+                        GETED(1);
+                    } else
+                        FAKEED;
+                    F8;
                     emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
-                    if(u8) { WBACK; }
-                    if(!wback && !rex.w) ZEROUP(ed);
+                    if (u8) {
+                        WBACK;
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 case 2:
                     INST_NAME("RCL Ed, Ib");
@@ -205,27 +219,51 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 case 4:
                 case 6:
                     INST_NAME("SHL Ed, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
-                    GETED(1);
-                    u8 = (F8)&(rex.w?0x3f:0x1f);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                        GETED(1);
+                    } else
+                        FAKEED;
+                    F8;
                     emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4, x5);
-                    if(u8) WBACK;
+                    if (u8) {
+                        WBACK;
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 case 5:
                     INST_NAME("SHR Ed, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
-                    GETED(1);
-                    u8 = (F8)&(rex.w?0x3f:0x1f);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                        GETED(1);
+                    } else
+                        FAKEED;
+                    F8;
                     emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
-                    if(u8) { WBACK; }
+                    if (u8) {
+                        WBACK;
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 case 7:
                     INST_NAME("SAR Ed, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
-                    GETED(1);
-                    u8 = (F8)&(rex.w?0x3f:0x1f);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                        GETED(1);
+                    } else
+                        FAKEED;
+                    F8;
                     emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
-                    if(u8) { WBACK; }
+                    if (u8) {
+                        WBACK;
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 default:
                     DEFAULT;
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index 419df8ff..24b3bfb0 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -1002,7 +1002,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     UFLAG_DF(x3, d_shl16);
                     break;
                 case 5:
-                    INST_NAME("SHR Ed, Ib");
+                    INST_NAME("SHR Ew, Ib");
                     UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}
                     SETFLAGS(X_ALL, SF_PENDING);
                     GETEW(x1, 1);
@@ -1015,7 +1015,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     UFLAG_DF(x3, d_shr16);
                     break;
                 case 7:
-                    INST_NAME("SAR Ed, Ib");
+                    INST_NAME("SAR Ew, Ib");
                     SETFLAGS(X_ALL, SF_PENDING);
                     UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}
                     GETSEW(x1, 1);
diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c
index effbb677..90f53b11 100644
--- a/src/dynarec/rv64/dynarec_rv64_67.c
+++ b/src/dynarec/rv64/dynarec_rv64_67.c
@@ -659,12 +659,19 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             switch ((nextop >> 3) & 7) {
                 case 5:
                     INST_NAME("SHR Ed, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
-                    GETED32(1);
-                    u8 = (F8) & (rex.w ? 0x3f : 0x1f);
+                    u8 = geted_ib(dyn, addr, ninst, nextop) & (rex.w ? 0x3f : 0x1f);
+                    // flags are not affected if count is 0, we make it a nop if possible.
+                    if (u8) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                        GETED32(1);
+                    } else
+                        FAKEED;
+                    F8;
                     emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
-                    if (u8)
+                    if (u8) {
                         WBACK;
+                    } else if (MODREG && !rex.w)
+                        ZEROUP(ed);
                     break;
                 default:
                     DEFAULT;
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
index 9008ca19..1db7344f 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
@@ -76,6 +76,8 @@ void emit_shl32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
 // emit SHL32 instruction, from s1 , constant c, store result in s1 using s3, s4 and s5 as scratch
 void emit_shl32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4, int s5)
 {
+    if (!c) return;
+
     CLEAR_FLAGS();
     IFX(X_PEND) {
         if (c) {
@@ -189,6 +191,8 @@ void emit_shr32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
 // emit SHR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_shr32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     CLEAR_FLAGS();
 
     IFX(X_PEND) {
@@ -251,6 +255,8 @@ void emit_shr32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
 // emit SAR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_sar32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     CLEAR_FLAGS();
 
     IFX(X_PEND) {
@@ -401,6 +407,8 @@ void emit_ror32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
 // emit ROL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     IFX(X_CF | X_OF) {
         ANDI(xFlags, xFlags, ~(1UL<<F_CF | 1UL<<F_OF2));
     }
@@ -427,6 +435,9 @@ void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         SRLIxw(s1, s1, (rex.w?64:32)-c);
         OR(s1, s3, s1);
     }
+
+    if (!rex.w) ZEROUP(s1);
+
     IFX(X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
@@ -448,6 +459,8 @@ void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
 // emit ROR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_ror32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
+    if (!c) return;
+
     IFX(X_CF | X_OF) {
         ANDI(xFlags, xFlags, ~(1UL<<F_CF | 1UL<<F_OF2));
     }
@@ -474,6 +487,9 @@ void emit_ror32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         SLLIxw(s1, s1, (rex.w?64:32)-c);
         OR(s1, s3, s1);
     }
+
+    if (!rex.w) ZEROUP(s1);
+
     IFX(X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }