arch-power: Fix shift instructions
authorSandipan Das <sandipan@linux.ibm.com>
Sat, 6 Feb 2021 11:51:41 +0000 (17:21 +0530)
committerSandipan Das <sandipan@linux.ibm.com>
Mon, 15 Feb 2021 08:32:38 +0000 (14:02 +0530)
Now that 64-bit registers are being used, the instructions
must use only the lower word of the operand to be shifted.
This fixes the following instructions.
  * Shift Left Word (slw[.])
  * Shift Right Word (srw[.])
  * Shift Right Algebraic Word (sraw[.])
  * Shift Right Algebraic Word Immediate (srawi[.])

Change-Id: Ibc3124b9e3a8660b0ff9d0178218e34bcc028310
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
src/arch/power/isa/decoder.isa

index 80886de93171a109039581b438aef27b9b7de425..84a76e7df6eb52bf3f0b2eb55c9aaaf62a3a3768 100644 (file)
@@ -588,62 +588,63 @@ decode PO default Unknown::unknown() {
         // Integer instructions with a shift value.
         format IntShiftOp {
             24: slw({{
-                if (Rb & 0x20) {
-                    Ra = 0;
-                } else {
-                    Ra = Rs << (Rb & 0x1f);
+                int32_t shift = Rb_sw;
+                uint32_t res = Rs_uw & ~((shift << 26) >> 31);
+                if (shift != 0) {
+                    shift = shift & 0x1f;
+                    res = res << shift;
                 }
+                Ra = res;
             }});
 
             536: srw({{
-                if (Rb & 0x20) {
-                    Ra = 0;
-                } else  {
-                    Ra = Rs >> (Rb & 0x1f);
+                int32_t shift = Rb_sw;
+                uint32_t res = Rs_uw & ~((shift << 26) >> 31);
+                if (shift != 0) {
+                    shift = shift & 0x1f;
+                    res = res >> shift;
                 }
+                Ra = res;
             }});
 
             792: sraw({{
-                int32_t s = Rs;
-                if (Rb == 0) {
-                    Ra = Rs;
-                    setCA = true;
-                } else if (Rb & 0x20) {
-                    if (s < 0) {
-                        Ra = (uint32_t)-1;
-                        if (s & 0x7fffffff) {
-                            setCA = true;
-                        } else {
-                            setCA = false;
-                        }
-                    } else {
-                        Ra = 0;
-                        setCA = false;
+                int32_t src = Rs_sw;
+                uint32_t shift = Rb_uw;
+                int64_t res;
+                if ((shift & 0x20) != 0) {
+                    res = src >> 31;
+                    if (res != 0) {
+                        setCA = true;
                     }
                 } else {
-                    Ra = s >> (Rb & 0x1f);
-                    if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) {
-                        setCA = true;
+                    if (shift != 0) {
+                        shift = shift & 0x1f;
+                        res = src >> shift;
+                        if (src < 0 && (src & mask(shift)) != 0) {
+                            setCA = true;
+                        }
                     } else {
-                        setCA = false;
+                        res = src;
                     }
                 }
-            }}, true);
+                Ra = res;
+            }},
+            true);
 
             824: srawi({{
-                if (sh == 0) {
-                    Ra = Rs;
-                    setCA = false;
-                } else {
-                    int32_t s = Rs;
-                    Ra = s >> sh;
-                    if (s < 0 && (s << (32 - sh)) != 0) {
+                int32_t src = Rs_sw;
+                int64_t res;
+                if (shift != 0) {
+                    res = src >> shift;
+                    if (src < 0 && (src & mask(shift)) != 0) {
                         setCA = true;
-                    } else {
-                        setCA = false;
                     }
+                } else {
+                    res = src;
                 }
-            }}, true);
+                Ra = res;
+            }},
+            true);
         }
 
         format StoreIndexOp {