When emulating an ill-formed instruction, we should bail out instead of asserting and bringing down the whole process.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@132506 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/Utility/ARMUtils.h b/source/Plugins/Process/Utility/ARMUtils.h
index c8ffb93..fce066d 100644
--- a/source/Plugins/Process/Utility/ARMUtils.h
+++ b/source/Plugins/Process/Utility/ARMUtils.h
@@ -89,41 +89,61 @@
     }
 }
 
-static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out)
+static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
 {
-    //assert(amount > 0);
+    if (amount == 0) {
+        *success = false;
+        return 0;
+    }
+    *success = true;
     carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0;
     return value << amount;
 }
 
-static inline uint32_t LSL(const uint32_t value, const uint32_t amount)
+static inline uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success)
 {
-    //assert(amount >= 0);
+    *success = true;
     if (amount == 0)
         return value;
     uint32_t dont_care;
-    return LSL_C(value, amount, dont_care);
+    uint32_t result = LSL_C(value, amount, dont_care, success);
+    if (*success)
+        return result;
+    else
+        return 0;
 }
 
-static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out)
+static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
 {
-    //assert(amount > 0);
+    if (amount == 0) {
+        *success = false;
+        return 0;
+    }
+    *success = true;
     carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0;
     return value >> amount;
 }
 
-static inline uint32_t LSR(const uint32_t value, const uint32_t amount)
+static inline uint32_t LSR(const uint32_t value, const uint32_t amount, bool *success)
 {
-    //assert(amount >= 0);
+    *success = true;
     if (amount == 0)
         return value;
     uint32_t dont_care;
-    return LSR_C(value, amount, dont_care);
+    uint32_t result = LSR_C(value, amount, dont_care, success);
+    if (*success)
+        return result;
+    else
+        return 0;
 }
 
-static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out)
+static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
 {
-    //assert(amount > 0 && amount <= 32);
+    if (amount == 0 || amount > 32) {
+        *success = false;
+        return 0;
+    }
+    *success = true;
     bool negative = BitIsSet(value, 31);
     if (amount <= 32)
     {
@@ -138,81 +158,113 @@
     }
 }
 
-static inline uint32_t ASR(const uint32_t value, const uint32_t amount)
+static inline uint32_t ASR(const uint32_t value, const uint32_t amount, bool *success)
 {
-    //assert(amount >= 0);
+    *success = true;
     if (amount == 0)
         return value;
     uint32_t dont_care;
-    return ASR_C(value, amount, dont_care);
+    uint32_t result = ASR_C(value, amount, dont_care, success);
+    if (*success)
+        return result;
+    else
+        return 0;
 }
 
-static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out)
+static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
 {
-    //assert(amount > 0);
+    if (amount == 0) {
+        *success = false;
+        return 0;
+    }
+    *success = true;
     uint32_t amt = amount % 32;
     uint32_t result = Rotr32(value, amt);
     carry_out = Bit32(value, 31);
     return result;
 }
 
-static inline uint32_t ROR(const uint32_t value, const uint32_t amount)
+static inline uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success)
 {
-    //assert(amount >= 0);
+    *success = true;
     if (amount == 0)
         return value;
     uint32_t dont_care;
-    return ROR_C(value, amount, dont_care);
+    uint32_t result = ROR_C(value, amount, dont_care, success);
+    if (*success)
+        return result;
+    else
+        return 0;
 }
 
-static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out)
+static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out, bool *success)
 {
+    *success = true;
     carry_out = Bit32(value, 0);
     return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1);
 }
 
-static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in)
+static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, bool *success)
 {
+    *success = true;
     uint32_t dont_care;
-    return RRX_C(value, carry_in, dont_care);
+    uint32_t result = RRX_C(value, carry_in, dont_care, success);
+    if (*success)
+        return result;
+    else
+        return 0;
 }
 
 static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, const uint32_t amount,
-                               const uint32_t carry_in, uint32_t &carry_out)
+                               const uint32_t carry_in, uint32_t &carry_out, bool *success)
 {
-    //assert(type != SRType_RRX || amount == 1);
-    if (amount == 0)
-    {
+    if (type == SRType_RRX && amount != 1) {
+        *success = false;
+        return 0;
+    }
+    *success = true;
+
+    if (amount == 0) {
         carry_out = carry_in;
         return value;
     }
     uint32_t result;
     switch (type) {
     case SRType_LSL:
-        result = LSL_C(value, amount, carry_out);
+        result = LSL_C(value, amount, carry_out, success);
         break;
     case SRType_LSR:
-        result = LSR_C(value, amount, carry_out);
+        result = LSR_C(value, amount, carry_out, success);
         break;
     case SRType_ASR:
-        result = ASR_C(value, amount, carry_out);
+        result = ASR_C(value, amount, carry_out, success);
         break;
     case SRType_ROR:
-        result = ROR_C(value, amount, carry_out);
+        result = ROR_C(value, amount, carry_out, success);
         break;
     case SRType_RRX:
-        result = RRX_C(value, carry_in, carry_out);
+        result = RRX_C(value, carry_in, carry_out, success);
+        break;
+    default:
+        *success = false;
         break;
     }
-    return result;
+    if (*success)
+        return result;
+    else
+        return 0;
 }
 
 static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount,
-                             const uint32_t carry_in)
+                             const uint32_t carry_in, bool *success)
 {
     // Don't care about carry out in this case.
     uint32_t dont_care;
-    return Shift_C(value, type, amount, carry_in, dont_care);
+    uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success);
+    if (*success)
+        return result;
+    else
+        return 0;
 }
 
 static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)