[ARC] Add support for QuarkSE processor.
authorClaudiu Zissulescu <claziss@synopsys.com>
Thu, 17 Nov 2016 13:43:32 +0000 (14:43 +0100)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Thu, 17 Nov 2016 13:43:32 +0000 (14:43 +0100)
gcc/
2016-11-17  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc-arches.def: Add FPX quarkse instruction as valid
for arcem.
* config/arc/arc-c.def (__ARC_FPX_QUARK__): Define.
* config/arc/arc-cpus.def (quarkse_em): Add.
* config/arc/arc-options.def (FL_FPX_QUARK, FL_QUARK): Likewise.
* config/arc/arc-opts.h (FPX_QK): Define.
* config/arc/arc-tables.opt: Regenerate.
* config/arc/arc.c (gen_compare_reg): Change.
(arc_register_move_cost): Avoid Dy,Dx moves.
* config/arc/arc.h (TARGET_HARD_FLOAT): Change.
(TARGET_FPX_QUARK, TARGET_FP_ASSIST): Define.
* config/arc/arc.md (divsf3, sqrtsf2, fix_truncsfsi2, floatsisf2):
New expands.
* config/arc/fpu.md (divsf3_fpu, sqrtsf2_fpu, floatsisf2_fpu)
(fix_truncsfsi2_fpu): Rename.
* config/arc/fpx.md (cmp_quark, cmpsf_quark_, cmpsf_quark_ord)
(cmpsf_quark_uneq, cmpsf_quark_eq, divsf3_quark, sqrtsf2_quark)
(fix_truncsfsi2_quark, floatsisf2_quark): New patterns.
* config/arc/t-multilib: Regenerate.

From-SVN: r242546

13 files changed:
gcc/ChangeLog
gcc/config/arc/arc-arches.def
gcc/config/arc/arc-c.def
gcc/config/arc/arc-cpus.def
gcc/config/arc/arc-options.def
gcc/config/arc/arc-opts.h
gcc/config/arc/arc-tables.opt
gcc/config/arc/arc.c
gcc/config/arc/arc.h
gcc/config/arc/arc.md
gcc/config/arc/fpu.md
gcc/config/arc/fpx.md
gcc/config/arc/t-multilib

index 0efea0beb7ba973e630e1c11414e48a4214a28d5..d69226644caa6887513793b216df33a514bbc24b 100644 (file)
@@ -1,3 +1,25 @@
+2016-11-17  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc-arches.def: Add FPX quarkse instruction as valid
+       for arcem.
+       * config/arc/arc-c.def (__ARC_FPX_QUARK__): Define.
+       * config/arc/arc-cpus.def (quarkse_em): Add.
+       * config/arc/arc-options.def (FL_FPX_QUARK, FL_QUARK): Likewise.
+       * config/arc/arc-opts.h (FPX_QK): Define.
+       * config/arc/arc-tables.opt: Regenerate.
+       * config/arc/arc.c (gen_compare_reg): Change.
+       (arc_register_move_cost): Avoid Dy,Dx moves.
+       * config/arc/arc.h (TARGET_HARD_FLOAT): Change.
+       (TARGET_FPX_QUARK, TARGET_FP_ASSIST): Define.
+       * config/arc/arc.md (divsf3, sqrtsf2, fix_truncsfsi2, floatsisf2):
+       New expands.
+       * config/arc/fpu.md (divsf3_fpu, sqrtsf2_fpu, floatsisf2_fpu)
+       (fix_truncsfsi2_fpu): Rename.
+       * config/arc/fpx.md (cmp_quark, cmpsf_quark_, cmpsf_quark_ord)
+       (cmpsf_quark_uneq, cmpsf_quark_eq, divsf3_quark, sqrtsf2_quark)
+       (fix_truncsfsi2_quark, floatsisf2_quark): New patterns.
+       * config/arc/t-multilib: Regenerate.
+
 2016-11-17  Georg-Johann Lay  <avr@gjlay.de>
 
        * config/avr/avr.c (avr_print_operand_address): Use CONST_INT_P if
index f24babb4d5325d18ad0f8c8ae2aaa1451da554af..5fd45cda25c4dd96d7b549b95750e5fca6fd2e69 100644 (file)
@@ -40,7 +40,7 @@
 
 ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM     \
          | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP               \
-         | FL_SIMD | FL_FPUDA, 0)
+         | FL_SIMD | FL_FPUDA | FL_QUARK, 0)
 ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD     \
          | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP                       \
          | FL_FPUS | FL_FPUD,                                          \
index 4cfd7b6e35fd55273e68f54bf26f2d1db302f57f..fd643760d88efb69426171b4c13dc156b8f073da 100644 (file)
@@ -58,6 +58,7 @@ ARC_C_DEF ("__ARC_FPU_DP_DIV__", TARGET_FP_DP_SQRT)
 ARC_C_DEF ("__ARC_FPU_SP_FMA__", TARGET_FP_SP_FUSED)
 ARC_C_DEF ("__ARC_FPU_DP_FMA__", TARGET_FP_DP_FUSED)
 ARC_C_DEF ("__ARC_FPU_ASSIST__", TARGET_FP_DP_AX)
+ARC_C_DEF ("__ARC_FPX_QUARK__",  TARGET_FPX_QUARK)
 
 /* To be deprecated.  */
 ARC_C_DEF ("__A6__",     TARGET_ARC600)
index 0ceb7344a8397dff3eedc276f601c993ea690962..720048559c8a26aab609899acf22c906d32b0f11 100644 (file)
@@ -51,6 +51,7 @@ ARC_CPU (em4,     em, FL_CD, NONE)
 ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
 ARC_CPU (em4_fpus,  em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE)
 ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE)
+ARC_CPU (quarkse_em, em, FL_MPYOPT_3|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPX_QUARK|FL_SPFP|FL_DPFP, NONE)
 
 ARC_CPU (hs,        hs, 0, NONE)
 ARC_CPU (archs,             hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE)
index 0f9d36ccc84df0fee23d625044516042ebef7aac..a16637e9cbe21bcc1e56350cf4e31e8a0dfaaea9 100644 (file)
@@ -99,10 +99,12 @@ ARC_OPTX (FL_FPU_FPUD,          (1ULL << 34), arc_fpu_build, FPU_FPUD,      "mfpu=fpud")
 ARC_OPTX (FL_FPU_FPUD_DIV,  (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV, "mfpu=fpud_div")
 ARC_OPTX (FL_FPU_FPUD_FMA,  (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA, "mfpu=fpud_fma")
 ARC_OPTX (FL_FPU_FPUD_ALL,  (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL, "mfpu=fpud_all")
+ARC_OPTX (FL_FPX_QUARK,            (1ULL << 38), arc_fpu_build, FPX_QK,        "quarkse fp")
 
 ARC_OPT (FL_FPUS,  (0xFULL << 26), 0, "single precission floating point")
 ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist")
 ARC_OPT (FL_FPUD,  (0xF0FULL << 26), 0, "double precission floating point")
+ARC_OPT (FL_QUARK, (1ULL << 38), 0, "Quark SE fp extension")
 
 /* Local Variables: */
 /* mode: c */
index e5bca8494f1b10e1f7dce713d3ca7a7988725817..2fd3c348f9ca05fb422f7c1792cba39a5d9e2c3a 100644 (file)
@@ -48,6 +48,8 @@ enum processor_type
 #define FPU_DD    0x0080
 /* Double precision floating point assist operations.  */
 #define FPX_DP    0x0100
+/* Quark SE floating point instructions.  */
+#define FPX_QK    0x0200
 
 /* fpus option combi.  */
 #define FPU_FPUS  (FPU_SP | FPU_SC)
index 0e7c50c7be78553956fb4b35ab0f2ce698e21312..41e325c91d57859ec03e997986e6b798d7199bc3 100644 (file)
@@ -42,6 +42,9 @@ Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus)
 EnumValue
 Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda)
 
+EnumValue
+Enum(processor_type) String(quarkse_em) Value(PROCESSOR_quarkse_em)
+
 EnumValue
 Enum(processor_type) String(hs) Value(PROCESSOR_hs)
 
index 98c7298cf0c8761d01585fcfc6852ba6949ee5f1..92ae42159a684da112adde661d9dbde5936810f3 100644 (file)
@@ -1726,6 +1726,26 @@ gen_compare_reg (rtx comparison, machine_mode omode)
                                                 gen_rtx_REG (CC_FPXmode, 61),
                                                 const0_rtx)));
     }
+  else if (TARGET_FPX_QUARK && (cmode == SFmode))
+    {
+      switch (code)
+       {
+       case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
+       case UNEQ: case LTGT: case ORDERED: case UNORDERED:
+         break;
+       case LT: case UNGE: case LE: case UNGT:
+         code = swap_condition (code);
+         tmp = x;
+         x = y;
+         y = tmp;
+         break;
+       default:
+         gcc_unreachable ();
+       }
+
+      emit_insn (gen_cmp_quark (cc_reg,
+                               gen_rtx_COMPARE (mode, x, y)));
+    }
   else if (TARGET_HARD_FLOAT
           && ((cmode == SFmode && TARGET_FP_SP_BASE)
               || (cmode == DFmode && TARGET_FP_DP_BASE)))
@@ -7281,7 +7301,7 @@ arc_register_move_cost (machine_mode,
     return 8;
 
   /* Force an attempt to 'mov Dy,Dx' to spill.  */
-  if (TARGET_ARC700 && TARGET_DPFP
+  if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
       && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
     return 100;
 
index 6188a4f81ad4447b71b815661fa5b5a3513809cc..611ef54df229f82f72653fbf771f90392d7f6865 100644 (file)
@@ -197,12 +197,7 @@ extern const char *arc_cpu_to_as (int argc, const char **argv);
    default for A7, and only for pre A7 cores when -mnorm is given.  */
 #define TARGET_NORM (TARGET_ARC700 || TARGET_NORM_SET || TARGET_HS)
 /* Indicate if an optimized floating point emulation library is available.  */
-#define TARGET_OPTFPE                          \
-   (TARGET_ARC700                              \
-    /* We need a barrel shifter and NORM.  */  \
-    || (TARGET_ARC600 && TARGET_NORM_SET)      \
-    || TARGET_HS                               \
-    || (TARGET_EM && TARGET_NORM_SET && TARGET_BARREL_SHIFTER))
+#define TARGET_OPTFPE (TARGET_ARC700 || TARGET_FPX_QUARK)
 
 /* Non-zero means the cpu supports swap instruction.  This flag is set by
    default for A7, and only for pre A7 cores when -mswap is given.  */
@@ -1702,7 +1697,7 @@ enum
 
 /* FPU defines.  */
 /* Any FPU support.  */
-#define TARGET_HARD_FLOAT (arc_fpu_build != 0)
+#define TARGET_HARD_FLOAT   ((arc_fpu_build & (FPU_SP | FPU_DP)) != 0)
 /* Single precision floating point support.  */
 #define TARGET_FP_SP_BASE   ((arc_fpu_build & FPU_SP) != 0)
 /* Double precision floating point support.  */
@@ -1721,5 +1716,8 @@ enum
 #define TARGET_FP_DP_SQRT   ((arc_fpu_build & FPU_DD) != 0)
 /* Double precision floating point assist instruction support.  */
 #define TARGET_FP_DP_AX     ((arc_fpu_build & FPX_DP) != 0)
+/* Custom FP instructions used by QuarkSE EM cpu.  */
+#define TARGET_FPX_QUARK    (TARGET_EM && TARGET_SPFP          \
+                            && (arc_fpu_build == FPX_QK))
 
 #endif /* GCC_ARC_H */
index c494ca5dc604f62b5172f7469cf2cbb3ef984a4d..c16bf67816def8c028b29d2768e55e60e1fac71e 100644 (file)
    gcc_unreachable ();
  ")
 
+;;div
+(define_expand "divsf3"
+  [(set (match_operand:SF 0 "register_operand"        "")
+       (div:SF (match_operand:SF 1 "nonmemory_operand" "")
+               (match_operand:SF 2 "nonmemory_operand" "")))]
+  "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
+  "
+  if (TARGET_FPX_QUARK)
+   {
+     operands[1] = force_reg (SFmode, operands[1]);
+     operands[2] = force_reg (SFmode, operands[2]);
+   }
+  else
+   {
+     if (!register_operand (operands[1], SFmode)
+        && !register_operand (operands[2], SFmode))
+       operands[1] = force_reg (SFmode, operands[1]);
+   }
+  ")
+
+;; Square root
+(define_expand "sqrtsf2"
+  [(set (match_operand:SF 0 "register_operand"           "")
+       (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
+  "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
+  "
+  if (TARGET_FPX_QUARK)
+   {
+     operands[1] = force_reg (SFmode, operands[1]);
+   }
+")
+
+;; SF->SI (using rounding towards zero)
+(define_expand "fix_truncsfsi2"
+  [(set (match_operand:SI 0 "register_operand"                "")
+       (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
+  "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
+  "")
+
+;; SI->SF
+(define_expand "floatsisf2"
+  [(set (match_operand:SF 0 "register_operand"            "")
+       (float:SF (match_operand:SI 1 "register_operand" "")))]
+  "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
+  "")
+
 (define_expand "extzv"
   [(set (match_operand:SI 0 "register_operand" "")
        (zero_extract:SI (match_operand:SI 1 "register_operand" "")
index e43047ce1d6bc9e974b9863a2cd0d12277cca024..5c56f76c67996ac542974fc2347b4d46bda2025c 100644 (file)
 ;; see pattern in arc.md
 
 ;; Square root
-(define_insn "sqrtsf2"
+(define_insn "sqrtsf2_fpu"
   [(set (match_operand:SF 0 "register_operand"           "=r,r")
        (sqrt:SF (match_operand:SF 1 "nonmemory_operand"  "r,F")))]
   "TARGET_FP_SP_SQRT"
 )
 
 ;; SI->SF
-(define_insn "floatsisf2"
+(define_insn "floatsisf2_fpu"
   [(set (match_operand:SF 0 "register_operand"           "=r,r")
        (float:SF (match_operand:SI 1 "register_operand"  "0,r")))]
   "TARGET_FP_SP_CONV"
 )
 
 ;; SF->SI (using rounding towards zero)
-(define_insn "fix_truncsfsi2"
+(define_insn "fix_truncsfsi2_fpu"
   [(set (match_operand:SI 0 "register_operand"                "=r,r")
        (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))]
   "TARGET_FP_SP_CONV"
index 9ed2b7c683ab0a1f9725a4defcf21bd31882cd5b..094319e1ce4f04feeab4281f5721cc6b50a4d201 100644 (file)
  [(set_attr "type" "dpfp_addsub")
   (set_attr "length" "4,8,4,8")
   (set_attr "cpu_facility" "*,*,fpx,fpx")])
+
+;; Intel QUARK SE extensions
+(define_mode_iterator QUARK_CMP [CC_FP_GT CC_FP_GE])
+(define_mode_attr quark_cmp [(CC_FP_GT "gt") (CC_FP_GE "ge")])
+
+(define_expand "cmp_quark"
+  [(parallel [(set (match_operand 0 "")
+                  (match_operand 1 ""))
+             (clobber (match_scratch:SI 2 ""))])]
+  ""
+  "")
+
+(define_insn "*cmpsf_quark_<quark_cmp>"
+  [(set (reg:QUARK_CMP CC_REG)
+       (compare:QUARK_CMP (match_operand:SF 0 "register_operand" "r")
+                          (match_operand:SF 1 "register_operand" "r")))
+   (clobber (match_scratch:SI 2 "=&r"))]
+  "TARGET_FPX_QUARK"
+  "dsp_fp_cmp\\t%2,%0,%1\\n\\trsub.f\\t0,%2,7\\n\\tcmp.nc\\t%2,1\\n\\tcmp.hi\\t%2,3"
+  [(set_attr "length" "16")
+   (set_attr "cond" "set")
+   (set_attr "predicable" "no")
+   (set_attr "cond" "nocond")])
+
+(define_insn "*cmpsf_quark_ord"
+  [(set (reg:CC_FP_ORD CC_REG)
+       (compare:CC_FP_ORD (match_operand:SF 0 "register_operand" "r")
+                          (match_operand:SF 1 "register_operand" "r")))
+   (clobber (match_scratch:SI 2 "=&r"))]
+  "TARGET_FPX_QUARK"
+  "dsp_fp_cmp\\t%2,%0,%1\\n\\tadd.f\\t%2,%2,-8"
+  [(set_attr "length" "8")
+   (set_attr "cond" "set")
+   (set_attr "predicable" "no")
+   (set_attr "cond" "nocond")])
+
+(define_insn "*cmpsf_quark_uneq"
+  [(set (reg:CC_FP_UNEQ CC_REG)
+       (compare:CC_FP_UNEQ (match_operand:SF 0 "register_operand" "r")
+                           (match_operand:SF 1 "register_operand" "r")))
+   (clobber (match_scratch:SI 2 "=&r"))]
+  "TARGET_FPX_QUARK"
+  "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,6"
+  [(set_attr "length" "8")
+   (set_attr "cond" "set")
+   (set_attr "predicable" "no")
+   (set_attr "cond" "nocond")])
+
+(define_insn "*cmpsf_quark_eq"
+  [(set (reg:CC_Z CC_REG)
+       (compare:CC_Z (match_operand:SF 0 "register_operand" "r")
+                     (match_operand:SF 1 "register_operand" "r")))
+   (clobber (match_scratch:SI 2 "=&r"))]
+  "TARGET_FPX_QUARK"
+  "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,0x0E"
+  [(set_attr "length" "8")
+   (set_attr "cond" "set")
+   (set_attr "predicable" "no")
+   (set_attr "cond" "nocond")])
+
+(define_insn "*divsf3_quark"
+  [(set (match_operand:SF 0 "register_operand"        "=r")
+       (div:SF (match_operand:SF 1 "register_operand" "r")
+               (match_operand:SF 2 "register_operand" "r")))]
+  "TARGET_FPX_QUARK"
+  "dsp_fp_div\\t%0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "predicable" "no")
+   (set_attr "cond" "nocond")])
+
+(define_insn "*sqrtsf2_quark"
+  [(set (match_operand:SF 0 "register_operand"          "=r")
+       (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
+  "TARGET_FPX_QUARK"
+  "dsp_fp_sqrt\\t%0,%1"
+  [(set_attr "length" "4")
+   (set_attr "predicable" "no")
+   (set_attr "cond" "nocond")])
+
+;; SF->SI (using rounding towards zero)
+(define_insn "*fix_truncsfsi2_quark"
+  [(set (match_operand:SI 0 "register_operand"                "=r")
+       (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "r"))))]
+  "TARGET_FPX_QUARK"
+  "dsp_fp_flt2i\\t%0,%1"
+  [(set_attr "length" "4")
+   (set_attr "predicable" "no")
+   (set_attr "cond" "nocond")])
+
+;; SI->SF
+(define_insn "*floatsisf2_quark"
+  [(set (match_operand:SF 0 "register_operand"          "=r")
+       (float:SF (match_operand:SI 1 "register_operand" "r")))]
+  "TARGET_FPX_QUARK"
+  "dsp_fp_i2flt\\t%0,%1"
+  [(set_attr "length" "4")
+   (set_attr "predicable" "no")
+   (set_attr "cond" "nocond")])
+
index 5a36af6571e48dd109dd5650f20020fe432f3714..a96433086d9a5621d7310f8027d934807aa398f0 100644 (file)
@@ -21,9 +21,9 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
+MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=quarkse_em/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
 
-MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
+MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda quarkse_em hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
 
 # Aliases:
 MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600