arch-arm: Implement ARMv8.3-JSConv
[gem5.git] / src / arch / arm / isa / insts / fp64.isa
index 95dec5062d6e2d280b66fda5b9ddeb715f76cf4d..409780aa0bd1ab45cd3149cded82b743e7d01f6f 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2012-2013 ARM Limited
+// Copyright (c) 2012-2013, 2016-2018 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -44,6 +44,11 @@ let {{
     decoder_output = ""
     exec_output = ""
 
+    zeroSveVecRegUpperPartCode = '''
+        ArmISA::ISA::zeroSveVecRegUpperPart(%s,
+            ArmStaticInst::getCurSveVecLen<uint64_t>(xc->tcBase()));
+    '''
+
     fmovImmSCode = vfp64EnabledCheckCode + '''
         AA64FpDestP0_uw = bits(imm, 31, 0);
         AA64FpDestP1_uw = 0;
@@ -52,7 +57,8 @@ let {{
     '''
     fmovImmSIop = InstObjParams("fmov", "FmovImmS", "FpRegImmOp",
                                 { "code": fmovImmSCode,
-                                  "op_class": "SimdFloatMiscOp" }, [])
+                                  "op_class": "FloatMiscOp" }, [])
+    fmovImmSIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
     header_output  += FpRegImmOpDeclare.subst(fmovImmSIop);
     decoder_output += FpRegImmOpConstructor.subst(fmovImmSIop);
     exec_output    += BasicExecute.subst(fmovImmSIop);
@@ -65,7 +71,8 @@ let {{
     '''
     fmovImmDIop = InstObjParams("fmov", "FmovImmD", "FpRegImmOp",
                                 { "code": fmovImmDCode,
-                                  "op_class": "SimdFloatMiscOp" }, [])
+                                  "op_class": "FloatMiscOp" }, [])
+    fmovImmDIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
     header_output  += FpRegImmOpDeclare.subst(fmovImmDIop);
     decoder_output += AA64FpRegImmOpConstructor.subst(fmovImmDIop);
     exec_output    += BasicExecute.subst(fmovImmDIop);
@@ -78,7 +85,8 @@ let {{
     '''
     fmovRegSIop = InstObjParams("fmov", "FmovRegS", "FpRegRegOp",
                                 { "code": fmovRegSCode,
-                                  "op_class": "SimdFloatMiscOp" }, [])
+                                  "op_class": "FloatMiscOp" }, [])
+    fmovRegSIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
     header_output  += FpRegRegOpDeclare.subst(fmovRegSIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegSIop);
     exec_output    += BasicExecute.subst(fmovRegSIop);
@@ -91,7 +99,8 @@ let {{
     '''
     fmovRegDIop = InstObjParams("fmov", "FmovRegD", "FpRegRegOp",
                                 { "code": fmovRegDCode,
-                                  "op_class": "SimdFloatMiscOp" }, [])
+                                  "op_class": "FloatMiscOp" }, [])
+    fmovRegDIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
     header_output  += FpRegRegOpDeclare.subst(fmovRegDIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegDIop);
     exec_output    += BasicExecute.subst(fmovRegDIop);
@@ -104,7 +113,9 @@ let {{
     '''
     fmovCoreRegWIop = InstObjParams("fmov", "FmovCoreRegW", "FpRegRegOp",
                                     { "code": fmovCoreRegWCode,
-                                      "op_class": "SimdFloatMiscOp" }, [])
+                                      "op_class": "FloatMiscOp" }, [])
+    fmovCoreRegWIop.snippets["code"] += zeroSveVecRegUpperPartCode % \
+        "AA64FpDest"
     header_output  += FpRegRegOpDeclare.subst(fmovCoreRegWIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegWIop);
     exec_output    += BasicExecute.subst(fmovCoreRegWIop);
@@ -117,18 +128,24 @@ let {{
     '''
     fmovCoreRegXIop = InstObjParams("fmov", "FmovCoreRegX", "FpRegRegOp",
                                     { "code": fmovCoreRegXCode,
-                                      "op_class": "SimdFloatMiscOp" }, [])
+                                      "op_class": "FloatMiscOp" }, [])
+    fmovCoreRegXIop.snippets["code"] += zeroSveVecRegUpperPartCode % \
+        "AA64FpDest"
     header_output  += FpRegRegOpDeclare.subst(fmovCoreRegXIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegXIop);
     exec_output    += BasicExecute.subst(fmovCoreRegXIop);
 
     fmovUCoreRegXCode = vfp64EnabledCheckCode + '''
+        /* Explicitly merge with previous value */
+        AA64FpDestP0_uw = AA64FpDestP0_uw;
+        AA64FpDestP1_uw = AA64FpDestP1_uw;
         AA64FpDestP2_uw = XOp1_ud;
-        AA64FpDestP3_uw = XOp1_ud >> 32;
-    '''
+        AA64FpDestP3_uw = XOp1_ud >> 32;'''
     fmovUCoreRegXIop = InstObjParams("fmov", "FmovUCoreRegX", "FpRegRegOp",
                                     { "code": fmovUCoreRegXCode,
-                                      "op_class": "SimdFloatMiscOp" }, [])
+                                      "op_class": "FloatMiscOp" }, [])
+    fmovUCoreRegXIop.snippets["code"] += zeroSveVecRegUpperPartCode % \
+        "AA64FpDest"
     header_output  += FpRegRegOpDeclare.subst(fmovUCoreRegXIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fmovUCoreRegXIop);
     exec_output    += BasicExecute.subst(fmovUCoreRegXIop);
@@ -138,7 +155,7 @@ let {{
     '''
     fmovRegCoreWIop = InstObjParams("fmov", "FmovRegCoreW", "FpRegRegOp",
                                      { "code": fmovRegCoreWCode,
-                                       "op_class": "SimdFloatMiscOp" }, [])
+                                       "op_class": "FloatMiscOp" }, [])
     header_output  += FpRegRegOpDeclare.subst(fmovRegCoreWIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreWIop);
     exec_output    += BasicExecute.subst(fmovRegCoreWIop);
@@ -148,7 +165,7 @@ let {{
     '''
     fmovRegCoreXIop = InstObjParams("fmov", "FmovRegCoreX", "FpRegRegOp",
                                      { "code": fmovRegCoreXCode,
-                                       "op_class": "SimdFloatMiscOp" }, [])
+                                       "op_class": "FloatMiscOp" }, [])
     header_output  += FpRegRegOpDeclare.subst(fmovRegCoreXIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreXIop);
     exec_output    += BasicExecute.subst(fmovRegCoreXIop);
@@ -158,7 +175,7 @@ let {{
     '''
     fmovURegCoreXIop = InstObjParams("fmov", "FmovURegCoreX", "FpRegRegOp",
                                     { "code":     fmovURegCoreXCode,
-                                      "op_class": "SimdFloatMiscOp" }, [])
+                                      "op_class": "FloatMiscOp" }, [])
     header_output  += FpRegRegOpDeclare.subst(fmovURegCoreXIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fmovURegCoreXIop);
     exec_output    += BasicExecute.subst(fmovURegCoreXIop);
@@ -170,6 +187,34 @@ let {{
     decoder_output = ""
     exec_output = ""
 
+    halfIntConvCode = vfp64EnabledCheckCode + '''
+        FPSCR fpscr = (FPSCR) FpscrExc;
+        uint16_t cOp1  = AA64FpOp1P0_uw;
+        uint16_t cDest = %(op)s;
+        AA64FpDestP0_uw = cDest;
+        AA64FpDestP1_uw = 0;
+        AA64FpDestP2_uw = 0;
+        AA64FpDestP3_uw = 0;
+        FpscrExc = fpscr;
+    '''
+
+    halfIntConvCode2 = vfp64EnabledCheckCode + '''
+        FPSCR fpscr = (FPSCR) FpscrExc;
+        uint16_t cOp1  = AA64FpOp1P0_uw;
+        uint16_t cOp2  = AA64FpOp2P0_uw;
+        uint16_t cDest = %(op)s;
+        AA64FpDestP0_uw = cDest;
+        AA64FpDestP1_uw = 0;
+        AA64FpDestP2_uw = 0;
+        AA64FpDestP3_uw = 0;
+        FpscrExc = fpscr;
+    '''
+
+    halfBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \
+                "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
+    halfUnaryOp = "unaryOp(fpscr, AA64FpOp1P0," + \
+                  "%(func)s, fpscr.fz, fpscr.rMode)"
+
     singleIntConvCode = vfp64EnabledCheckCode + '''
         FPSCR fpscr = (FPSCR) FpscrExc;
         uint32_t cOp1  = AA64FpOp1P0_uw;
@@ -230,23 +275,23 @@ let {{
                 fpscr.fz, fpscr.rMode)
     '''
 
-    def buildTernaryFpOp(name, opClass, sOp, dOp):
+    def buildTernaryFpOp(name, opClass, hOp, sOp, dOp):
         global header_output, decoder_output, exec_output
-        for isDouble in True, False:
+        for suffix in "D", "S", "H":
             code = vfp64EnabledCheckCode + '''
                 FPSCR fpscr = (FPSCR) FpscrExc;
             '''
-            if isDouble:
+            if suffix == "H":
                 code += '''
-                    uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
-                    uint64_t cOp2 = AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32;
-                    uint64_t cOp3 = AA64FpOp3P0_uw | (uint64_t)AA64FpOp3P1_uw << 32;
-                    uint64_t cDest;
-                ''' "cDest = " + dOp + ";" + '''
+                    uint16_t cOp1 = AA64FpOp1P0_uw;
+                    uint16_t cOp2 = AA64FpOp2P0_uw;
+                    uint16_t cOp3 = AA64FpOp3P0_uw;
+                    uint16_t cDest;
+                ''' "cDest = " + hOp + ";" + '''
                     AA64FpDestP0_uw = cDest;
-                    AA64FpDestP1_uw = cDest >> 32;
+                    AA64FpDestP1_uw = 0;
                 '''
-            else:
+            elif suffix == "S":
                 code += '''
                     uint32_t cOp1 = AA64FpOp1P0_uw;
                     uint32_t cOp2 = AA64FpOp2P0_uw;
@@ -256,125 +301,174 @@ let {{
                     AA64FpDestP0_uw = cDest;
                     AA64FpDestP1_uw = 0;
                 '''
+            elif suffix == "D":
+                code += '''
+                    uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
+                    uint64_t cOp2 = AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32;
+                    uint64_t cOp3 = AA64FpOp3P0_uw | (uint64_t)AA64FpOp3P1_uw << 32;
+                    uint64_t cDest;
+                ''' "cDest = " + dOp + ";" + '''
+                    AA64FpDestP0_uw = cDest;
+                    AA64FpDestP1_uw = cDest >> 32;
+                '''
             code += '''
                 AA64FpDestP2_uw = 0;
                 AA64FpDestP3_uw = 0;
                 FpscrExc = fpscr;
             '''
 
-            iop = InstObjParams(name.lower(), name + ("D" if isDouble else "S"),
+            iop = InstObjParams(name.lower(), name + suffix,
                                 "FpRegRegRegRegOp",
                                 { "code": code, "op_class": opClass }, [])
+            iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
 
             header_output  += AA64FpRegRegRegRegOpDeclare.subst(iop)
             decoder_output += AA64FpRegRegRegRegOpConstructor.subst(iop)
             exec_output    += BasicExecute.subst(iop)
 
-    buildTernaryFpOp("FMAdd", "SimdFloatMultAccOp",
+    buildTernaryFpOp("FMAdd", "FloatMultAccOp",
+                     "fplibMulAdd<uint16_t>(cOp3, cOp1, cOp2, fpscr)",
                      "fplibMulAdd<uint32_t>(cOp3, cOp1, cOp2, fpscr)",
                      "fplibMulAdd<uint64_t>(cOp3, cOp1, cOp2, fpscr)" )
-    buildTernaryFpOp("FMSub", "SimdFloatMultAccOp",
-                     "fplibMulAdd<uint32_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
-                     "fplibMulAdd<uint64_t>(cOp3, fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
-    buildTernaryFpOp("FNMAdd", "SimdFloatMultAccOp",
-                     "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
-                     "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
-    buildTernaryFpOp("FNMSub", "SimdFloatMultAccOp",
-                     "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)",
-                     "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), cOp1, cOp2, fpscr)" )
-
-    def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
+    buildTernaryFpOp("FMSub", "FloatMultAccOp",
+        "fplibMulAdd<uint16_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
+        "fplibMulAdd<uint32_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
+        "fplibMulAdd<uint64_t>(cOp3, fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
+    buildTernaryFpOp("FNMAdd", "FloatMultAccOp",
+                     "fplibMulAdd<uint16_t>(fplibNeg<uint16_t>(cOp3), " +
+                     "fplibNeg<uint16_t>(cOp1), cOp2, fpscr)",
+                     "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), " +
+                     "fplibNeg<uint32_t>(cOp1), cOp2, fpscr)",
+                     "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), " +
+                     "fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
+    buildTernaryFpOp("FNMSub", "FloatMultAccOp",
+        "fplibMulAdd<uint16_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)",
+        "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)",
+        "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), cOp1, cOp2, fpscr)" )
+
+    def buildBinFpOp(name, Name, base, opClass, halfOp, singleOp, doubleOp):
         global header_output, decoder_output, exec_output
 
+        code = halfIntConvCode2 % { "op": halfOp }
+        hIop = InstObjParams(name, Name + "H", base,
+                { "code": code,
+                  "op_class": opClass }, [])
+        hIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
+
         code = singleIntConvCode2 % { "op": singleOp }
         sIop = InstObjParams(name, Name + "S", base,
                 { "code": code,
                   "op_class": opClass }, [])
+        sIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
 
         code = doubleIntConvCode2 % { "op": doubleOp }
         dIop = InstObjParams(name, Name + "D", base,
                 { "code": code,
                   "op_class": opClass }, [])
+        dIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
 
         declareTempl     = eval(         base + "Declare");
         constructorTempl = eval("AA64" + base + "Constructor");
 
-        for iop in sIop, dIop:
+        for iop in hIop, sIop, dIop:
             header_output  += declareTempl.subst(iop)
             decoder_output += constructorTempl.subst(iop)
             exec_output    += BasicExecute.subst(iop)
 
-    buildBinFpOp("fadd", "FAdd", "FpRegRegRegOp", "SimdFloatAddOp",
+    buildBinFpOp("fadd", "FAdd", "FpRegRegRegOp", "FloatAddOp",
+                 "fplibAdd<uint16_t>(cOp1, cOp2, fpscr)",
                  "fplibAdd<uint32_t>(cOp1, cOp2, fpscr)",
                  "fplibAdd<uint64_t>(cOp1, cOp2, fpscr)")
-    buildBinFpOp("fsub", "FSub", "FpRegRegRegOp", "SimdFloatAddOp",
+    buildBinFpOp("fsub", "FSub", "FpRegRegRegOp", "FloatAddOp",
+                 "fplibSub<uint16_t>(cOp1, cOp2, fpscr)",
                  "fplibSub<uint32_t>(cOp1, cOp2, fpscr)",
                  "fplibSub<uint64_t>(cOp1, cOp2, fpscr)")
-    buildBinFpOp("fdiv", "FDiv", "FpRegRegRegOp", "SimdFloatDivOp",
+    buildBinFpOp("fdiv", "FDiv", "FpRegRegRegOp", "FloatDivOp",
+                 "fplibDiv<uint16_t>(cOp1, cOp2, fpscr)",
                  "fplibDiv<uint32_t>(cOp1, cOp2, fpscr)",
                  "fplibDiv<uint64_t>(cOp1, cOp2, fpscr)")
-    buildBinFpOp("fmul", "FMul", "FpRegRegRegOp", "SimdFloatMultOp",
+    buildBinFpOp("fmul", "FMul", "FpRegRegRegOp", "FloatMultOp",
+                 "fplibMul<uint16_t>(cOp1, cOp2, fpscr)",
                  "fplibMul<uint32_t>(cOp1, cOp2, fpscr)",
                  "fplibMul<uint64_t>(cOp1, cOp2, fpscr)")
-    buildBinFpOp("fnmul", "FNMul", "FpRegRegRegOp", "SimdFloatMultOp",
+    buildBinFpOp("fnmul", "FNMul", "FpRegRegRegOp", "FloatMultOp",
+                 "fplibNeg<uint16_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))",
                  "fplibNeg<uint32_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))",
                  "fplibNeg<uint64_t>(fplibMul<uint64_t>(cOp1, cOp2, fpscr))")
-    buildBinFpOp("fmin", "FMin", "FpRegRegRegOp", "SimdFloatCmpOp",
+    buildBinFpOp("fmin", "FMin", "FpRegRegRegOp", "FloatCmpOp",
+                 "fplibMin<uint16_t>(cOp1, cOp2, fpscr)",
                  "fplibMin<uint32_t>(cOp1, cOp2, fpscr)",
                  "fplibMin<uint64_t>(cOp1, cOp2, fpscr)")
-    buildBinFpOp("fmax", "FMax", "FpRegRegRegOp", "SimdFloatCmpOp",
+    buildBinFpOp("fmax", "FMax", "FpRegRegRegOp", "FloatCmpOp",
+                 "fplibMax<uint16_t>(cOp1, cOp2, fpscr)",
                  "fplibMax<uint32_t>(cOp1, cOp2, fpscr)",
                  "fplibMax<uint64_t>(cOp1, cOp2, fpscr)")
-    buildBinFpOp("fminnm", "FMinNM", "FpRegRegRegOp", "SimdFloatCmpOp",
+    buildBinFpOp("fminnm", "FMinNM", "FpRegRegRegOp", "FloatCmpOp",
+                 "fplibMinNum<uint16_t>(cOp1, cOp2, fpscr)",
                  "fplibMinNum<uint32_t>(cOp1, cOp2, fpscr)",
                  "fplibMinNum<uint64_t>(cOp1, cOp2, fpscr)")
-    buildBinFpOp("fmaxnm", "FMaxNM", "FpRegRegRegOp", "SimdFloatCmpOp",
+    buildBinFpOp("fmaxnm", "FMaxNM", "FpRegRegRegOp", "FloatCmpOp",
+                 "fplibMaxNum<uint16_t>(cOp1, cOp2, fpscr)",
                  "fplibMaxNum<uint32_t>(cOp1, cOp2, fpscr)",
                  "fplibMaxNum<uint64_t>(cOp1, cOp2, fpscr)")
 
-    def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
+    def buildUnaryFpOp(name, Name, base, opClass,
+                       halfOp, singleOp, doubleOp = None):
         if doubleOp is None:
             doubleOp = singleOp
         global header_output, decoder_output, exec_output
 
+        code = halfIntConvCode % { "op": halfOp }
+        hIop = InstObjParams(name, Name + "H", base,
+                { "code": code,
+                  "op_class": opClass }, [])
+        hIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
         code = singleIntConvCode % { "op": singleOp }
         sIop = InstObjParams(name, Name + "S", base,
                 { "code": code,
                   "op_class": opClass }, [])
+        sIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
         code = doubleIntConvCode % { "op": doubleOp }
         dIop = InstObjParams(name, Name + "D", base,
                 { "code": code,
                   "op_class": opClass }, [])
+        dIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
 
         declareTempl     = eval(         base + "Declare");
         constructorTempl = eval("AA64" + base + "Constructor");
 
-        for iop in sIop, dIop:
+        for iop in hIop, sIop, dIop:
             header_output  += declareTempl.subst(iop)
             decoder_output += constructorTempl.subst(iop)
             exec_output    += BasicExecute.subst(iop)
 
-    buildUnaryFpOp("fsqrt", "FSqrt", "FpRegRegOp", "SimdFloatSqrtOp",
-                   "fplibSqrt<uint32_t>(cOp1, fpscr)", "fplibSqrt<uint64_t>(cOp1, fpscr)")
+    buildUnaryFpOp("fsqrt", "FSqrt", "FpRegRegOp", "FloatSqrtOp",
+                   "fplibSqrt<uint16_t>(cOp1, fpscr)",
+                   "fplibSqrt<uint32_t>(cOp1, fpscr)",
+                   "fplibSqrt<uint64_t>(cOp1, fpscr)")
 
-    def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
+    def buildSimpleUnaryFpOp(name, Name, base, opClass, halfOp, singleOp,
                              doubleOp = None, isIntConv = True):
         if doubleOp is None:
             doubleOp = singleOp
         global header_output, decoder_output, exec_output
 
         if isIntConv:
+            hCode = halfIntConvCode
             sCode = singleIntConvCode
             dCode = doubleIntConvCode
         else:
+            hCode = halfCode
             sCode = singleCode
             dCode = doubleCode
 
-        for code, op, suffix in [[sCode, singleOp, "S"],
+        for code, op, suffix in [[hCode, halfOp, "H"],
+                                 [sCode, singleOp, "S"],
                                  [dCode, doubleOp, "D"]]:
             iop = InstObjParams(name, Name + suffix, base,
                 { "code": code % { "op": op },
                   "op_class": opClass }, [])
+            iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
 
             declareTempl     = eval(         base + "Declare");
             constructorTempl = eval("AA64" + base + "Constructor");
@@ -383,31 +477,42 @@ let {{
             decoder_output += constructorTempl.subst(iop)
             exec_output    += BasicExecute.subst(iop)
 
-    buildSimpleUnaryFpOp("fneg", "FNeg", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibNeg<uint32_t>(cOp1)", "fplibNeg<uint64_t>(cOp1)")
-    buildSimpleUnaryFpOp("fabs", "FAbs", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibAbs<uint32_t>(cOp1)", "fplibAbs<uint64_t>(cOp1)")
-    buildSimpleUnaryFpOp("frintn", "FRIntN", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)",
-                         "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)")
-    buildSimpleUnaryFpOp("frintp", "FRIntP", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibRoundInt<uint32_t>(cOp1, FPRounding_POSINF, false, fpscr)",
-                         "fplibRoundInt<uint64_t>(cOp1, FPRounding_POSINF, false, fpscr)")
-    buildSimpleUnaryFpOp("frintm", "FRIntM", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibRoundInt<uint32_t>(cOp1, FPRounding_NEGINF, false, fpscr)",
-                         "fplibRoundInt<uint64_t>(cOp1, FPRounding_NEGINF, false, fpscr)")
-    buildSimpleUnaryFpOp("frintz", "FRIntZ", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibRoundInt<uint32_t>(cOp1, FPRounding_ZERO, false, fpscr)",
-                         "fplibRoundInt<uint64_t>(cOp1, FPRounding_ZERO, false, fpscr)")
-    buildSimpleUnaryFpOp("frinta", "FRIntA", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)",
-                         "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)")
-    buildSimpleUnaryFpOp("frinti", "FRIntI", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), false, fpscr)",
-                         "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), false, fpscr)")
-    buildSimpleUnaryFpOp("frintx", "FRIntX", "FpRegRegOp", "SimdFloatMiscOp",
-                         "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), true, fpscr)",
-                         "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), true, fpscr)")
+    buildSimpleUnaryFpOp("fneg", "FNeg", "FpRegRegOp", "FloatMiscOp",
+                         "fplibNeg<uint16_t>(cOp1)",
+                         "fplibNeg<uint32_t>(cOp1)",
+                         "fplibNeg<uint64_t>(cOp1)")
+    buildSimpleUnaryFpOp("fabs", "FAbs", "FpRegRegOp", "FloatMiscOp",
+                         "fplibAbs<uint16_t>(cOp1)",
+                         "fplibAbs<uint32_t>(cOp1)",
+                         "fplibAbs<uint64_t>(cOp1)")
+    buildSimpleUnaryFpOp("frintn", "FRIntN", "FpRegRegOp", "FloatMiscOp",
+        "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)",
+        "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)",
+        "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)")
+    buildSimpleUnaryFpOp("frintp", "FRIntP", "FpRegRegOp", "FloatMiscOp",
+        "fplibRoundInt<uint16_t>(cOp1, FPRounding_POSINF, false, fpscr)",
+        "fplibRoundInt<uint32_t>(cOp1, FPRounding_POSINF, false, fpscr)",
+        "fplibRoundInt<uint64_t>(cOp1, FPRounding_POSINF, false, fpscr)")
+    buildSimpleUnaryFpOp("frintm", "FRIntM", "FpRegRegOp", "FloatMiscOp",
+        "fplibRoundInt<uint16_t>(cOp1, FPRounding_NEGINF, false, fpscr)",
+        "fplibRoundInt<uint32_t>(cOp1, FPRounding_NEGINF, false, fpscr)",
+        "fplibRoundInt<uint64_t>(cOp1, FPRounding_NEGINF, false, fpscr)")
+    buildSimpleUnaryFpOp("frintz", "FRIntZ", "FpRegRegOp", "FloatMiscOp",
+        "fplibRoundInt<uint16_t>(cOp1, FPRounding_ZERO, false, fpscr)",
+        "fplibRoundInt<uint32_t>(cOp1, FPRounding_ZERO, false, fpscr)",
+        "fplibRoundInt<uint64_t>(cOp1, FPRounding_ZERO, false, fpscr)")
+    buildSimpleUnaryFpOp("frinta", "FRIntA", "FpRegRegOp", "FloatMiscOp",
+        "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)",
+        "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)",
+        "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)")
+    buildSimpleUnaryFpOp("frinti", "FRIntI", "FpRegRegOp", "FloatMiscOp",
+        "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), false, fpscr)",
+        "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), false, fpscr)",
+        "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), false, fpscr)")
+    buildSimpleUnaryFpOp("frintx", "FRIntX", "FpRegRegOp", "FloatMiscOp",
+        "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), true, fpscr)",
+        "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), true, fpscr)",
+        "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), true, fpscr)")
 }};
 
 let {{
@@ -451,8 +556,11 @@ let {{
                 instName = "Fcvt%s%sIntFp%s" %(regL, us, "D" if isDouble else "S")
                 mnem     = "%scvtf" %(us.lower())
                 fcvtIntFpDIop = InstObjParams(mnem, instName, "FpRegRegOp",
-                                                { "code": fcvtIntFpDCode,
-                                                  "op_class": "SimdFloatCvtOp" }, [])
+                                              { "code": fcvtIntFpDCode,
+                                                "op_class": "FloatCvtOp" }, [])
+                fcvtIntFpDIop.snippets["code"] += \
+                        zeroSveVecRegUpperPartCode % "AA64FpDest"
+
                 header_output  += FpRegRegOpDeclare.subst(fcvtIntFpDIop);
                 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtIntFpDIop);
                 exec_output    += BasicExecute.subst(fcvtIntFpDIop);
@@ -491,7 +599,7 @@ let {{
             mnem     = "fcvt%s%s" %(rmode, "s" if isSigned else "u")
             fcvtFpIntIop = InstObjParams(mnem, instName, "FpRegRegOp",
                                         { "code": fcvtFpIntCode,
-                                        "op_class": "SimdFloatCvtOp" }, [])
+                                        "op_class": "FloatCvtOp" }, [])
             header_output  += FpRegRegOpDeclare.subst(fcvtFpIntIop);
             decoder_output += FpRegRegOpConstructor.subst(fcvtFpIntIop);
             exec_output    += BasicExecute.subst(fcvtFpIntIop);
@@ -514,7 +622,8 @@ let {{
     '''
     fcvtFpSFpDIop = InstObjParams("fcvt", "FCvtFpSFpD", "FpRegRegOp",
                                      { "code": fcvtFpSFpDCode,
-                                       "op_class": "SimdFloatCvtOp" }, [])
+                                       "op_class": "FloatCvtOp" }, [])
+    fcvtFpSFpDIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
     header_output  += FpRegRegOpDeclare.subst(fcvtFpSFpDIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpSFpDIop);
     exec_output    += BasicExecute.subst(fcvtFpSFpDIop);
@@ -531,7 +640,8 @@ let {{
     '''
     fcvtFpDFpSIop = InstObjParams("fcvt", "FcvtFpDFpS", "FpRegRegOp",
                                  {"code":     fcvtFpDFpSCode,
-                                  "op_class": "SimdFloatCvtOp" }, [])
+                                  "op_class": "FloatCvtOp" }, [])
+    fcvtFpDFpSIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
     header_output  += FpRegRegOpDeclare.subst(fcvtFpDFpSIop);
     decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpDFpSIop);
     exec_output    += BasicExecute.subst(fcvtFpDFpSIop);
@@ -563,7 +673,9 @@ let {{
         instName = "FcvtFpHFp%s" %("D" if isDouble else "S")
         fcvtFpHFpIop = InstObjParams("fcvt", instName, "FpRegRegOp",
                                      { "code": code,
-                                       "op_class": "SimdFloatCvtOp" }, [])
+                                       "op_class": "FloatCvtOp" }, [])
+        fcvtFpHFpIop.snippets["code"] += zeroSveVecRegUpperPartCode % \
+                "AA64FpDest"
         header_output  += FpRegRegOpDeclare.subst(fcvtFpHFpIop);
         decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpHFpIop);
         exec_output    += BasicExecute.subst(fcvtFpHFpIop);
@@ -586,7 +698,9 @@ let {{
         instName = "FcvtFp%sFpH" %("D" if isDouble else "S")
         fcvtFpFpHIop = InstObjParams("fcvt", instName, "FpRegRegOp",
                                      { "code": code,
-                                       "op_class": "SimdFloatCvtOp" }, [])
+                                       "op_class": "FloatCvtOp" }, [])
+        fcvtFpFpHIop.snippets["code"] += zeroSveVecRegUpperPartCode % \
+                "AA64FpDest"
         header_output  += FpRegRegOpDeclare.subst(fcvtFpFpHIop);
         decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpFpHIop);
         exec_output    += BasicExecute.subst(fcvtFpFpHIop);
@@ -626,7 +740,7 @@ let {{
         fcmpIop = InstObjParams("fcmp%s" %(""  if isQuiet else "e"), instName,
                                 "FpReg%sOp" %(typeName),
                                {"code":     fcmpCode,
-                                "op_class": "SimdFloatCmpOp"}, [])
+                                "op_class": "FloatCmpOp"}, [])
 
         declareTemp     = eval("FpReg%sOpDeclare"         %(typeName));
         constructorTemp = eval("AA64FpReg%sOpConstructor" %(typeName));
@@ -673,7 +787,7 @@ let {{
         fccmpIop = InstObjParams("fccmp%s" %(""  if isQuiet  else "e"),
                                  instName, "FpCondCompRegOp",
                                 {"code":           fccmpCode,
-                                 "op_class":       "SimdFloatCmpOp"}, [])
+                                 "op_class":       "FloatCmpOp"}, [])
         header_output  += DataXCondCompRegDeclare.subst(fccmpIop);
         decoder_output += DataXCondCompRegConstructor.subst(fccmpIop);
         exec_output    += BasicExecute.subst(fccmpIop);
@@ -718,11 +832,34 @@ let {{
         mnem = "fcvtz%s" %("s" if isSigned else "u")
         fcvtFpFixedIop = InstObjParams(mnem, instName, "FpRegRegImmOp",
                                        { "code": fcvtFpFixedCode,
-                                         "op_class": "SimdFloatCvtOp" }, [])
+                                         "op_class": "FloatCvtOp" }, [])
         header_output  += FpRegRegImmOpDeclare.subst(fcvtFpFixedIop);
         decoder_output += AA64FpRegRegImmOpConstructor.subst(fcvtFpFixedIop);
         exec_output    += BasicExecute.subst(fcvtFpFixedIop);
 
+    def buildFpJsCvtFixedOp():
+        global header_output, decoder_output, exec_output
+
+        fcvtFpFixedCode = vfp64EnabledCheckCode + '''
+            FPSCR fpscr = (FPSCR) FpscrExc;
+            uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32;
+            uint8_t nz;
+            WDest = fplibFPToFixedJS(cOp1, fpscr, true, nz);
+            CondCodesNZ = nz;
+            CondCodesV = 0;
+            CondCodesC = 0;
+            FpscrExc = fpscr;
+        ''';
+
+        instName = "FJcvtFpSFixedDW"
+        mnem = "fjcvtzs"
+        fcvtFpFixedIop = InstObjParams(mnem, instName, "FpRegRegOp",
+                                       { "code": fcvtFpFixedCode,
+                                         "op_class": "FloatCvtOp" }, [])
+        header_output  += FpRegRegOpDeclare.subst(fcvtFpFixedIop);
+        decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpFixedIop);
+        exec_output    += BasicExecute.subst(fcvtFpFixedIop);
+
     # Generates the variants of the fixed to floating point instructions
     def buildFixedCvtFpOp(isSigned, isDouble, isXReg):
         global header_output, decoder_output, exec_output
@@ -759,7 +896,9 @@ let {{
         mnem = "%scvtf" %("s" if isSigned else "u")
         fcvtFixedFpIop = InstObjParams(mnem, instName, "FpRegRegImmOp",
                                        { "code":     fcvtFixedFpCode,
-                                         "op_class": "SimdFloatCvtOp" }, [])
+                                         "op_class": "FloatCvtOp" }, [])
+        fcvtFixedFpIop.snippets["code"] += zeroSveVecRegUpperPartCode % \
+                "AA64FpDest"
         header_output  += FpRegRegImmOpDeclare.subst(fcvtFixedFpIop);
         decoder_output += FpRegRegImmOpConstructor.subst(fcvtFixedFpIop);
         exec_output    += BasicExecute.subst(fcvtFixedFpIop);
@@ -770,6 +909,7 @@ let {{
             for isSigned in True, False:
                 buildFpCvtFixedOp(isSigned, isDouble, isXReg)
                 buildFixedCvtFpOp(isSigned, isDouble, isXReg)
+    buildFpJsCvtFixedOp();
 }};
 
 let {{
@@ -804,7 +944,9 @@ let {{
         '''
 
         iop = InstObjParams("fcsel", "FCSel%s" %("D" if isDouble else "S"),
-                            "FpCondSelOp", code)
+                            "FpCondSelOp", { "code":     code,
+                                             "op_class": "FloatCvtOp" })
+        iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest"
         header_output  += DataXCondSelDeclare.subst(iop)
         decoder_output += DataXCondSelConstructor.subst(iop)
         exec_output    += BasicExecute.subst(iop)