arch-arm: FCVTZS instruction returns sign extension
authorJordi Vaquero <jordi.vaquero@metempsy.com>
Fri, 17 Apr 2020 14:29:53 +0000 (16:29 +0200)
committerJordi Vaquero <jordi.vaquero@metempsy.com>
Mon, 4 May 2020 21:12:25 +0000 (21:12 +0000)
This patch fix Fcvtzs instruction adding sign extension instead of
zero extension

Change-Id: I28cdca432fa6baa8a524de4c431f492f23f0e9a6
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28229
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/isa/insts/sve.isa

index aa4f194eebf327c4d24a6d44a311bd53cd581cf3..16597d6d643df9c72de27bddc785d422c849bb75 100644 (file)
@@ -1516,27 +1516,49 @@ let {{
     # Generates definitions for SVE floating-point conversions (always
     # unary, constructive, merging
     def sveCvtInst(name, Name, opClass, types, op, direction=CvtDir.Narrow,
-                   decoder='Generic'):
+                   decoder='Generic', signed=False):
         global header_output, exec_output, decoders
+
+        if signed:
+            mask = "SElement msk = mask(sizeof(DElement)*8);"
+            assign_code = '''
+                int sign_bit = bits(destElem, sizeof(DElement)*8 -1);
+                AA64FpDest_x%(bigElemSuffix)s[i] =
+                                    sign_bit? (destElem|~msk): destElem;
+                          '''  % {
+               'bigElemSuffix': 's' if direction == CvtDir.Narrow else 'd'
+               }
+        else:
+            mask = "";
+            assign_code = '''
+                AA64FpDest_x%(bigElemSuffix)s[i] = destElem;
+            '''  % {
+               'bigElemSuffix': 's' if direction == CvtDir.Narrow else 'd'
+                   }
+
         code = sveEnabledCheckCode + '''
         unsigned eCount = ArmStaticInst::getCurSveVecLen<%(bigElemType)s>(
                 xc->tcBase());
+        %(mask)s
         for (unsigned i = 0; i < eCount; i++) {
             SElement srcElem1 = AA64FpOp1_x%(bigElemSuffix)s[i] &
                     mask(sizeof(SElement) * 8);
             DElement destElem = 0;
             if (GpOp_x%(bigElemSuffix)s[i]) {
                 %(op)s
-                AA64FpDest_x%(bigElemSuffix)s[i] = destElem;
+                %(assign)s;
             } else {
                 AA64FpDest_x%(bigElemSuffix)s[i] =
                         AA64FpDestMerge_x%(bigElemSuffix)s[i];
             }
         }
-        ''' % {'op': op,
-               'bigElemType': 'SElement' if direction == CvtDir.Narrow
+        ''' % {'bigElemType': 'SElement' if direction == CvtDir.Narrow
                                          else 'DElement',
-               'bigElemSuffix': 's' if direction == CvtDir.Narrow else 'd'}
+               'op': op, 'mask': mask,
+               'bigElemSuffix': 's' if direction == CvtDir.Narrow else 'd',
+               'assign': assign_code
+               }
+
         iop = InstObjParams(name, 'Sve' + Name, 'SveUnaryPredOp',
                             {'code': code, 'op_class': opClass}, [])
         header_output += SveWideningUnaryPredOpDeclare.subst(iop)
@@ -2743,6 +2765,7 @@ let {{
         code = sveEnabledCheckCode + '''
         unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
                 xc->tcBase());
+
         ArmISA::VecRegContainer tmpVecC;
         auto auxDest = tmpVecC.as<Element>();
         int firstelem = -1, lastelem = -2;
@@ -3596,7 +3619,7 @@ let {{
                 'uint32_t, uint32_t',
                 'uint64_t, uint32_t',
                 'uint64_t, uint64_t'),
-               fcvtzsCode, CvtDir.Narrow)
+               fcvtzsCode, CvtDir.Narrow, signed=True)
     sveCvtInst('fcvtzs', 'FcvtzsWiden', 'SimdCvtOp',
                ('uint16_t, uint32_t',
                 'uint16_t, uint64_t',