ARM: Implement the unsigned 8 bit and 16 bit vector adds and subtracts.
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/isa/insts/data.isa

index 04e62f27bff8c83aa0c275502964fdc27c97fab4..4efbae574f414b82b35f2d6d09f55f331f5ff24d 100644 (file)
@@ -501,4 +501,109 @@ let {{
             replaceBits(resTemp, 31, 16, midRes);
             Dest = resTemp;
         ''', flagType="none", buildCc=False)
+
+    buildRegDataInst("uadd16", '''
+            uint32_t geBits = 0;
+            resTemp = 0;
+            for (unsigned i = 0; i < 2; i++) {
+                int high = (i + 1) * 16 - 1;
+                int low = i * 16;
+                int32_t midRes = bits(Op1, high, low) +
+                                 bits(Op2, high, low);
+                if (midRes >= 0x10000) {
+                    geBits = geBits | (0x3 << (i * 2));
+                }
+                replaceBits(resTemp, high, low, midRes);
+            }
+            Dest = resTemp;
+            resTemp = geBits;
+        ''', flagType="ge", buildNonCc=False)
+    buildRegDataInst("uadd8", '''
+            uint32_t geBits = 0;
+            resTemp = 0;
+            for (unsigned i = 0; i < 4; i++) {
+                int high = (i + 1) * 8 - 1;
+                int low = i * 8;
+                int32_t midRes = bits(Op1, high, low) +
+                                 bits(Op2, high, low);
+                if (midRes >= 0x100) {
+                    geBits = geBits | (1 << i);
+                }
+                replaceBits(resTemp, high, low, midRes);
+            }
+            Dest = resTemp;
+            resTemp = geBits;
+        ''', flagType="ge", buildNonCc=False)
+    buildRegDataInst("usub16", '''
+            uint32_t geBits = 0;
+            resTemp = 0;
+            for (unsigned i = 0; i < 2; i++) {
+                int high = (i + 1) * 16 - 1;
+                int low = i * 16;
+                int32_t midRes = bits(Op1, high, low) -
+                                 bits(Op2, high, low);
+                if (midRes >= 0) {
+                    geBits = geBits | (0x3 << (i * 2));
+                }
+                replaceBits(resTemp, high, low, midRes);
+            }
+            Dest = resTemp;
+            resTemp = geBits;
+        ''', flagType="ge", buildNonCc=False)
+    buildRegDataInst("usub8", '''
+            uint32_t geBits = 0;
+            resTemp = 0;
+            for (unsigned i = 0; i < 4; i++) {
+                int high = (i + 1) * 8 - 1;
+                int low = i * 8;
+                int32_t midRes = bits(Op1, high, low) -
+                                 bits(Op2, high, low);
+                if (midRes >= 0) {
+                    geBits = geBits | (1 << i);
+                }
+                replaceBits(resTemp, high, low, midRes);
+            }
+            Dest = resTemp;
+            resTemp = geBits;
+        ''', flagType="ge", buildNonCc=False)
+    buildRegDataInst("uasx", '''
+            int32_t midRes, geBits = 0;
+            resTemp = 0;
+            int64_t arg1Low = bits(Op1.sw, 15, 0);
+            int64_t arg1High = bits(Op1.sw, 31, 16);
+            int64_t arg2Low = bits(Op2.sw, 15, 0);
+            int64_t arg2High = bits(Op2.sw, 31, 16);
+            midRes = arg1Low - arg2High;
+            if (midRes >= 0) {
+                geBits = geBits | 0x3;
+            }
+            replaceBits(resTemp, 15, 0, midRes);
+            midRes = arg1High + arg2Low;
+            if (midRes >= 0x10000) {
+                geBits = geBits | 0xc;
+            }
+            replaceBits(resTemp, 31, 16, midRes);
+            Dest = resTemp;
+            resTemp = geBits;
+        ''', flagType="ge", buildNonCc=False)
+    buildRegDataInst("usax", '''
+            int32_t midRes, geBits = 0;
+            resTemp = 0;
+            int64_t arg1Low = bits(Op1.sw, 15, 0);
+            int64_t arg1High = bits(Op1.sw, 31, 16);
+            int64_t arg2Low = bits(Op2.sw, 15, 0);
+            int64_t arg2High = bits(Op2.sw, 31, 16);
+            midRes = arg1Low + arg2High;
+            if (midRes >= 0x10000) {
+                geBits = geBits | 0x3;
+            }
+            replaceBits(resTemp, 15, 0, midRes);
+            midRes = arg1High - arg2Low;
+            if (midRes >= 0) {
+                geBits = geBits | 0xc;
+            }
+            replaceBits(resTemp, 31, 16, midRes);
+            Dest = resTemp;
+            resTemp = geBits;
+        ''', flagType="ge", buildNonCc=False)
 }};