changeset 520509f3e66c in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=520509f3e66c
description:
        isa,arm: Add missing AArch32 FP instructions

        This commit adds missing non-predicated, scalar floating point
        instructions.  Specifically VRINT* floating point integer rounding
        instructions and VSEL* floating point conditional selects.

        Change-Id: I23cbd1389f151389ac8beb28a7d18d5f93d000e7
        Reviewed-by: Andreas Sandberg <andreas.sandb...@arm.com>
        Reviewed-by: Nathanael Premillieu <nathanael.premill...@arm.com>

diffstat:

 src/arch/arm/insts/vfp.cc          |  15 +++++
 src/arch/arm/insts/vfp.hh          |  21 ++++++++
 src/arch/arm/isa/formats/fp.isa    |  98 +++++++++++++++++++++++++++++++++++++-
 src/arch/arm/isa/insts/fp.isa      |  62 +++++++++++++++++++++++-
 src/arch/arm/isa/templates/vfp.isa |  27 ++++++++++
 5 files changed, 220 insertions(+), 3 deletions(-)

diffs (289 lines):

diff -r 6ce719503eae -r 520509f3e66c src/arch/arm/insts/vfp.cc
--- a/src/arch/arm/insts/vfp.cc Thu Oct 13 03:17:19 2016 -0400
+++ b/src/arch/arm/insts/vfp.cc Thu Oct 13 19:22:10 2016 +0100
@@ -123,6 +123,21 @@
 }
 
 std::string
+FpRegRegRegCondOp::generateDisassembly(Addr pc, const SymbolTable *symtab)
+    const
+{
+    std::stringstream ss;
+    printMnemonic(ss);
+    printCondition(ss, cond);
+    printReg(ss, dest + FP_Reg_Base);
+    ss << ", ";
+    printReg(ss, op1 + FP_Reg_Base);
+    ss << ", ";
+    printReg(ss, op2 + FP_Reg_Base);
+    return ss.str();
+}
+
+std::string
 FpRegRegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
 {
     std::stringstream ss;
diff -r 6ce719503eae -r 520509f3e66c src/arch/arm/insts/vfp.hh
--- a/src/arch/arm/insts/vfp.hh Thu Oct 13 03:17:19 2016 -0400
+++ b/src/arch/arm/insts/vfp.hh Thu Oct 13 19:22:10 2016 +0100
@@ -979,6 +979,27 @@
     std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
 };
 
+class FpRegRegRegCondOp : public FpOp
+{
+  protected:
+    IntRegIndex dest;
+    IntRegIndex op1;
+    IntRegIndex op2;
+    ConditionCode cond;
+
+    FpRegRegRegCondOp(const char *mnem, ExtMachInst _machInst,
+                      OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
+                      IntRegIndex _op2, ConditionCode _cond,
+                      VfpMicroMode mode = VfpNotAMicroop) :
+        FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2),
+        cond(_cond)
+    {
+        setVfpMicroFlags(mode, flags);
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
 class FpRegRegRegRegOp : public FpOp
 {
   protected:
diff -r 6ce719503eae -r 520509f3e66c src/arch/arm/isa/formats/fp.isa
--- a/src/arch/arm/isa/formats/fp.isa   Thu Oct 13 03:17:19 2016 -0400
+++ b/src/arch/arm/isa/formats/fp.isa   Thu Oct 13 19:22:10 2016 +0100
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2010-2011 ARM Limited
+// Copyright (c) 2010-2011,2016 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -1950,7 +1950,101 @@
         const uint32_t b = bits(machInst, 6, 5);
         if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
             (machInst.thumb == 0 && machInst.condCode == 0xf)) {
-            return new Unknown(machInst);
+            // Determine if this is backported aarch64 FP instruction
+            const bool b31_b24 = bits(machInst, 31, 24) == 0xFE;
+            const bool b23 = bits(machInst, 23);
+            const bool b21_b18 = bits(machInst, 21, 18) == 0xE;
+            const bool b11_b9  = bits(machInst, 11, 9) == 0x5;
+            const bool sz = bits(machInst, 8);
+            const bool b7_b6   = bits(machInst, 7, 6) == 0x1;
+            const bool b6 = bits(machInst, 6) == 0x0;
+            const bool b4 = bits(machInst, 4) == 0x0;
+            if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) {
+                  // VINT* Integer Rounding Instructon
+                  const uint32_t rm = bits(machInst, 17, 16);
+
+                  if (sz) {
+                      const IntRegIndex vd =
+                          (IntRegIndex)((bits(machInst, 22) << 5) |
+                                        (bits(machInst, 15, 12) << 1));
+                      const IntRegIndex vm =
+                          (IntRegIndex)((bits(machInst, 5) << 5) |
+                                        (bits(machInst, 3, 0) << 1));
+                      switch(rm) {
+                        case 0x0:
+                          return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
+                                                            true);
+                        case 0x1:
+                          return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
+                                                            true);
+                        case 0x2:
+                          return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm,
+                                                            true);
+                        case 0x3:
+                          return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm,
+                                                            true);
+                        default: return new Unknown(machInst);
+                      }
+                  } else {
+                      const IntRegIndex vd =
+                          (IntRegIndex)(bits(machInst, 22) |
+                                       (bits(machInst, 15, 12) << 1));
+                      const IntRegIndex vm =
+                          (IntRegIndex)(bits(machInst, 5) |
+                                        (bits(machInst, 3, 0) << 1));
+                      switch(rm) {
+                        case 0x0:
+                          return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm,
+                                                            false);
+                        case 0x1:
+                          return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm,
+                                                            false);
+                        case 0x2:
+                          return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm,
+                                                            false);
+                        case 0x3:
+                          return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
+                                                            false);
+                        default: return new Unknown(machInst);
+                      }
+                  }
+            } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){
+                // VSEL* floating point conditional select
+
+                ConditionCode cond;
+                switch(bits(machInst, 21, 20)) {
+                  case 0x0: cond = COND_EQ; break;
+                  case 0x1: cond = COND_VS; break;
+                  case 0x2: cond = COND_GE; break;
+                  case 0x3: cond = COND_GT; break;
+                }
+
+                if (sz) {
+                      const IntRegIndex vd =
+                          (IntRegIndex)((bits(machInst, 22) << 5) |
+                                        (bits(machInst, 15, 12) << 1));
+                      const IntRegIndex vm =
+                          (IntRegIndex)((bits(machInst, 5) << 5) |
+                                        (bits(machInst, 3, 0) << 1));
+                      const IntRegIndex vn =
+                          (IntRegIndex)((bits(machInst, 7) << 5) |
+                                       (bits(machInst, 19, 16) << 1));
+                    return new VselD(machInst, vd, vn, vm, cond);
+                } else {
+                      const IntRegIndex vd =
+                          (IntRegIndex)(bits(machInst, 22) |
+                                       (bits(machInst, 15, 12) << 1));
+                      const IntRegIndex vm =
+                          (IntRegIndex)(bits(machInst, 5) |
+                                        (bits(machInst, 3, 0) << 1));
+                      const IntRegIndex vn =
+                          (IntRegIndex)((bits(machInst, 19, 16) << 1) |
+                                        bits(machInst, 7));
+                      return new VselS(machInst, vd, vn, vm, cond);
+                }
+            } else {
+                return new Unknown(machInst);
+            }
         }
         if (l == 0 && c == 0) {
             if (a == 0) {
diff -r 6ce719503eae -r 520509f3e66c src/arch/arm/isa/insts/fp.isa
--- a/src/arch/arm/isa/insts/fp.isa     Thu Oct 13 03:17:19 2016 -0400
+++ b/src/arch/arm/isa/insts/fp.isa     Thu Oct 13 19:22:10 2016 +0100
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2010-2013 ARM Limited
+// Copyright (c) 2010-2013,2016 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -642,6 +642,26 @@
                          "-FpOp1", "-dbl(FpOp1P0_uw, FpOp1P1_uw)")
     buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp",
                          "fabsf(FpOp1)", "fabs(dbl(FpOp1P0_uw, FpOp1P1_uw))")
+    buildSimpleUnaryFpOp("vrintp", "VRIntP", "FpRegRegOp", "SimdFloatMiscOp",
+        "fplibRoundInt<uint32_t>(FpOp1, FPRounding_POSINF, false, fpscr)",
+        "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
+        "FPRounding_POSINF, false, fpscr)"
+        )
+    buildSimpleUnaryFpOp("vrintm", "VRIntM", "FpRegRegOp", "SimdFloatMiscOp",
+        "fplibRoundInt<uint32_t>(FpOp1, FPRounding_NEGINF, false, fpscr)",
+        "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
+        "FPRounding_NEGINF, false, fpscr)"
+        )
+    buildSimpleUnaryFpOp("vrinta", "VRIntA", "FpRegRegOp", "SimdFloatMiscOp",
+        "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEAWAY, false, fpscr)",
+        "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
+        "FPRounding_TIEAWAY, false, fpscr)"
+        )
+    buildSimpleUnaryFpOp("vrintn", "VRIntN", "FpRegRegOp", "SimdFloatMiscOp",
+        "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEEVEN, false, fpscr)",
+        "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
+        "FPRounding_TIEEVEN, false, fpscr)"
+        )
 }};
 
 let {{
@@ -1408,6 +1428,46 @@
     decoder_output = ""
     exec_output = ""
 
+    vselSCode = vfpEnabledCheckCode + '''
+        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
+            FpDest = FpOp1;
+        } else {
+            FpDest = FpOp2;
+        } '''
+
+    vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
+                             { "code" : vselSCode,
+                               "predicate_test" : predicateTest,
+                               "op_class" : "SimdFloatCmpOp" }, [] )
+    header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
+    decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
+    exec_output +=  PredOpExecute.subst(vselSIop);
+
+    vselDCode = vfpEnabledCheckCode + '''
+        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
+            FpDestP0_uw = FpOp1P0_uw;
+            FpDestP1_uw = FpOp1P1_uw;
+        } else {
+            FpDestP0_uw = FpOp2P0_uw;
+            FpDestP1_uw = FpOp2P1_uw;
+        } '''
+
+    vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
+                             { "code" : vselDCode,
+                               "predicate_test" : predicateTest,
+                               "op_class" : "SimdFloatCmpOp" }, [] )
+    header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
+    decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
+    exec_output +=  PredOpExecute.subst(vselDIop);
+}};
+
+
+let {{
+
+    header_output = ""
+    decoder_output = ""
+    exec_output = ""
+
     vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
         FPSCR fpscr = (FPSCR) FpscrExc;
         vfpFlushToZero(fpscr, FpOp1);
diff -r 6ce719503eae -r 520509f3e66c src/arch/arm/isa/templates/vfp.isa
--- a/src/arch/arm/isa/templates/vfp.isa        Thu Oct 13 03:17:19 2016 -0400
+++ b/src/arch/arm/isa/templates/vfp.isa        Thu Oct 13 19:22:10 2016 +0100
@@ -210,3 +210,30 @@
         }
     }
 }};
+
+def template FpRegRegRegCondOpDeclare {{
+class %(class_name)s : public %(base_class)s
+{
+  public:
+    // Constructor
+    %(class_name)s(ExtMachInst machInst,
+                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
+                  ConditionCode _cond,
+                   VfpMicroMode mode = VfpNotAMicroop);
+    %(BasicExecDeclare)s
+};
+}};
+
+def template FpRegRegRegCondOpConstructor {{
+    %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                          IntRegIndex _dest,
+                                          IntRegIndex _op1,
+                                          IntRegIndex _op2,
+                                          ConditionCode _cond,
+                                          VfpMicroMode mode)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                         _dest, _op1, _op2, _cond, mode)
+    {
+        %(constructor)s;
+    }
+}};
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to