From 14d25fbad09b3272e1d094adb1c6a298ab7b5ecd Mon Sep 17 00:00:00 2001
From: Gabe Black <gblack@eecs.umich.edu>
Date: Wed, 2 Jun 2010 12:58:04 -0500
Subject: ARM: Don't rely on undefined behavior to get arithmetic right shift.
 Shifting to the right of a signed value when the MSB is one is technically
 undefined behavior, even though in my experience it's done the "right thing"
 and sign extended the value. This replaces the arithmetic right shift code in
 ARM that uses that coincidence with some code that relies on bit math.

---
 src/arch/arm/insts/static_inst.cc | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'src/arch')

diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index 41bfeac59..528111759 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -68,9 +68,9 @@ ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
             return base >> shamt;
       case ASR:
         if (shamt == 0)
-            return (int32_t)base >> 31;
+            return (base >> 31) | -((base & (1 << 31)) >> 31);
         else
-            return (int32_t)base >> shamt;
+            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
       case ROR:
         if (shamt == 0)
             return (cfval << 31) | (base >> 1); // RRX
@@ -106,9 +106,9 @@ ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
             return base >> shamt;
       case ASR:
         if (shamt >= 32)
-            return (int32_t)base >> 31;
+            return (base >> 31) | -((base & (1 << 31)) >> 31);
         else
-            return (int32_t)base >> shamt;
+            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
       case ROR:
         shamt = shamt & 0x1f;
         if (shamt == 0)
-- 
cgit v1.2.3