ARM: Implement the unsigned saturating instructions.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:06 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:06 +0000 (12:58 -0500)
src/arch/arm/insts/static_inst.hh
src/arch/arm/isa/insts/data.isa

index 634cf08127dcec0846967430becdbfa4db2570ed..3ff1d20cd42a3808b1021d14a349ce883d91419c 100644 (file)
@@ -77,6 +77,23 @@ class ArmStaticInst : public StaticInst
         }
     }
 
+    template<int width>
+    static bool
+    uSaturateOp(uint32_t &res, int64_t op1, int64_t op2, bool sub=false)
+    {
+        int64_t midRes = sub ? (op1 - op2) : (op1 + op2);
+        if (midRes >= (1 << width)) {
+            res = (1 << width) - 1;
+            return true;
+        } else if (midRes < 0) {
+            res = 0;
+            return true;
+        } else {
+            res = midRes;
+            return false;
+        }
+    }
+
     // Constructor
     ArmStaticInst(const char *mnem, ExtMachInst _machInst,
                   OpClass __opClass)
index 206c218e1abb0619b0bae45ef7ddc9e8c75b167a..04e62f27bff8c83aa0c275502964fdc27c97fab4 100644 (file)
@@ -428,4 +428,77 @@ let {{
             Dest = resTemp;
             resTemp = geBits;
         ''', flagType="ge", buildNonCc=False)
+
+    buildRegDataInst("uqadd16", '''
+            uint32_t midRes;
+            for (unsigned i = 0; i < 2; i++) {
+                int high = (i + 1) * 16 - 1;
+                int low = i * 16;
+                uint64_t arg1 = bits(Op1, high, low);
+                uint64_t arg2 = bits(Op2, high, low);
+                uSaturateOp<16>(midRes, arg1, arg2);
+                replaceBits(resTemp, high, low, midRes);
+            }
+            Dest = resTemp;
+        ''', flagType="none", buildCc=False)
+    buildRegDataInst("uqadd8", '''
+            uint32_t midRes;
+            for (unsigned i = 0; i < 4; i++) {
+                int high = (i + 1) * 8 - 1;
+                int low = i * 8;
+                uint64_t arg1 = bits(Op1, high, low);
+                uint64_t arg2 = bits(Op2, high, low);
+                uSaturateOp<8>(midRes, arg1, arg2);
+                replaceBits(resTemp, high, low, midRes);
+            }
+            Dest = resTemp;
+        ''', flagType="none", buildCc=False)
+    buildRegDataInst("uqsub16", '''
+            uint32_t midRes;
+            for (unsigned i = 0; i < 2; i++) {
+                 int high = (i + 1) * 16 - 1;
+                 int low = i * 16;
+                 uint64_t arg1 = bits(Op1, high, low);
+                 uint64_t arg2 = bits(Op2, high, low);
+                 uSaturateOp<16>(midRes, arg1, arg2, true);
+                 replaceBits(resTemp, high, low, midRes);
+            }
+            Dest = resTemp;
+        ''', flagType="none", buildCc=False)
+    buildRegDataInst("uqsub8", '''
+            uint32_t midRes;
+            for (unsigned i = 0; i < 4; i++) {
+                 int high = (i + 1) * 8 - 1;
+                 int low = i * 8;
+                 uint64_t arg1 = bits(Op1, high, low);
+                 uint64_t arg2 = bits(Op2, high, low);
+                 uSaturateOp<8>(midRes, arg1, arg2, true);
+                 replaceBits(resTemp, high, low, midRes);
+            }
+            Dest = resTemp;
+        ''', flagType="none", buildCc=False)
+    buildRegDataInst("uqasx", '''
+            uint32_t midRes;
+            uint64_t arg1Low = bits(Op1.sw, 15, 0);
+            uint64_t arg1High = bits(Op1.sw, 31, 16);
+            uint64_t arg2Low = bits(Op2.sw, 15, 0);
+            uint64_t arg2High = bits(Op2.sw, 31, 16);
+            uSaturateOp<16>(midRes, arg1Low, arg2High, true);
+            replaceBits(resTemp, 15, 0, midRes);
+            uSaturateOp<16>(midRes, arg1High, arg2Low);
+            replaceBits(resTemp, 31, 16, midRes);
+            Dest = resTemp;
+        ''', flagType="none", buildCc=False)
+    buildRegDataInst("uqsax", '''
+            uint32_t midRes;
+            uint64_t arg1Low = bits(Op1.sw, 15, 0);
+            uint64_t arg1High = bits(Op1.sw, 31, 16);
+            uint64_t arg2Low = bits(Op2.sw, 15, 0);
+            uint64_t arg2High = bits(Op2.sw, 31, 16);
+            uSaturateOp<16>(midRes, arg1Low, arg2High);
+            replaceBits(resTemp, 15, 0, midRes);
+            uSaturateOp<16>(midRes, arg1High, arg2Low, true);
+            replaceBits(resTemp, 31, 16, midRes);
+            Dest = resTemp;
+        ''', flagType="none", buildCc=False)
 }};