public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH/AARCH64] Decimal floating point support for AARCH64
@ 2017-07-14  0:21 Andrew Pinski
  2017-07-15  6:20 ` Andrew Pinski
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Andrew Pinski @ 2017-07-14  0:21 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1835 bytes --]

Hi,
  This patch adds Decimal floating point support to aarch64.  It is
the base support in that since there is no hardware support for DFP,
it just defines the ABI.  The ABI I chose is that _Decimal32 is
treated like float, _Decimal64 is treated like double and _Decimal128
is treated like long double.  In that they are passed via the floating
registers (sN, dN, qN).
Is this ok an ABI?

Is the patch ok?  Bootstrapped and tested on aarch64-linux-gnu with
--enable-decimal-float with no regressions and all of the dfp
testcases pass.

Thanks,
Andrew Pinski

gcc/ChangeLog:
* config/aarch64/aarch64.c (aarch64_split_128bit_move): Handle TDmode.
(aarch64_classify_address): Likewise.
(aarch64_legitimize_address_displacement): Likewise.
(aarch64_legitimize_address): Likewise.
(aarch64_constant_pool_reload_icode): Handle SD, DD, and TD modes.
(aarch64_secondary_reload): Handle TDmode.
(aarch64_valid_floating_const): For decimal floating point return false.
(aarch64_gimplify_va_arg_expr): Handle SD, DD, and TD modes.
(aapcs_vfp_sub_candidate): Likewise.
(aarch64_vfp_is_call_or_return_candidate): Handle MODE_DECIMAL_FLOAT.
(aarch64_scalar_mode_supported_p): For DECIMAL_FLOAT_MODE_P, return
default_decimal_float_supported_p.
* config/aarch64/iterators.md (GPF_TF_F16): Add SD, DD, and TD modes.
(SFD): New iterator.
(DFD): New iterator.
(TFD): New iterator.
(GPF_TF): Add SD, DD, and TD modes.
(TX): Add TD mode.
* config/aarch64/aarch64.md (*movsf_aarch64): Use SFD iterator.
(*movdf_aarch64): Use DFD iterator.
(*movtf_aarch64): Use TFD iterator.
(define_split for TF): Use TFD iterator.


gcc/testsuite/ChangeLog:
* c-c++-common/dfp/pr39986.c: Allow for word instead of just long.

libgcc/ChangeLog:
* config.host (aarch64*-*-elf): Add t-dfprules to tmake_file.
(aarch64*-*-freebsd*): Likewise.
(aarch64*-*-linux*): Likewise.

[-- Attachment #2: current-dfp.diff.txt --]
[-- Type: text/plain, Size: 14721 bytes --]

Index: config/aarch64/aarch64.c
===================================================================
--- config/aarch64/aarch64.c	(revision 250186)
+++ config/aarch64/aarch64.c	(working copy)
@@ -1653,7 +1653,7 @@ aarch64_split_128bit_move (rtx dst, rtx
 
   machine_mode mode = GET_MODE (dst);
 
-  gcc_assert (mode == TImode || mode == TFmode);
+  gcc_assert (mode == TImode || mode == TFmode || mode == TDmode);
   gcc_assert (!(side_effects_p (src) || side_effects_p (dst)));
   gcc_assert (mode == GET_MODE (src) || GET_MODE (src) == VOIDmode);
 
@@ -1673,11 +1673,16 @@ aarch64_split_128bit_move (rtx dst, rtx
 	      emit_insn (gen_aarch64_movtilow_di (dst, src_lo));
 	      emit_insn (gen_aarch64_movtihigh_di (dst, src_hi));
 	    }
-	  else
+	  else if (mode == TFmode)
 	    {
 	      emit_insn (gen_aarch64_movtflow_di (dst, src_lo));
 	      emit_insn (gen_aarch64_movtfhigh_di (dst, src_hi));
 	    }
+	  else
+	    {
+	      emit_insn (gen_aarch64_movtdlow_di (dst, src_lo));
+	      emit_insn (gen_aarch64_movtdhigh_di (dst, src_hi));
+	    }
 	  return;
 	}
       else if (GP_REGNUM_P (dst_regno) && FP_REGNUM_P (src_regno))
@@ -1690,11 +1695,16 @@ aarch64_split_128bit_move (rtx dst, rtx
 	      emit_insn (gen_aarch64_movdi_tilow (dst_lo, src));
 	      emit_insn (gen_aarch64_movdi_tihigh (dst_hi, src));
 	    }
-	  else
+	  else if (mode == TFmode)
 	    {
 	      emit_insn (gen_aarch64_movdi_tflow (dst_lo, src));
 	      emit_insn (gen_aarch64_movdi_tfhigh (dst_hi, src));
 	    }
+	  else if (mode == TDmode)
+	    {
+	      emit_insn (gen_aarch64_movdi_tdlow (dst_lo, src));
+	      emit_insn (gen_aarch64_movdi_tdhigh (dst_hi, src));
+	    }
 	  return;
 	}
     }
@@ -4420,10 +4430,11 @@ aarch64_classify_address (struct aarch64
   rtx op0, op1;
 
   /* On BE, we use load/store pair for all large int mode load/stores.
-     TI/TFmode may also use a load/store pair.  */
+     TI/TF/TDmode may also use a load/store pair.  */
   bool load_store_pair_p = (outer_code == PARALLEL
 			    || mode == TImode
 			    || mode == TFmode
+			    || mode == TDmode
 			    || (BYTES_BIG_ENDIAN
 				&& aarch64_vect_struct_mode_p (mode)));
 
@@ -4473,7 +4484,7 @@ aarch64_classify_address (struct aarch64
 	  info->base = op0;
 	  info->offset = op1;
 
-	  /* TImode and TFmode values are allowed in both pairs of X
+	  /* TImode and TFmode and TDmode values are allowed in both pairs of X
 	     registers and individual Q registers.  The available
 	     address modes are:
 	     X,X: 7-bit signed scaled offset
@@ -4482,7 +4493,7 @@ aarch64_classify_address (struct aarch64
 	     When performing the check for pairs of X registers i.e.  LDP/STP
 	     pass down DImode since that is the natural size of the LDP/STP
 	     instruction memory accesses.  */
-	  if (mode == TImode || mode == TFmode)
+	  if (mode == TImode || mode == TFmode || mode == TDmode)
 	    return (aarch64_offset_7bit_signed_scaled_p (DImode, offset)
 		    && (offset_9bit_signed_unscaled_p (mode, offset)
 			|| offset_12bit_unsigned_scaled_p (mode, offset)));
@@ -4558,14 +4569,14 @@ aarch64_classify_address (struct aarch64
 	  info->offset = XEXP (XEXP (x, 1), 1);
 	  offset = INTVAL (info->offset);
 
-	  /* TImode and TFmode values are allowed in both pairs of X
+	  /* TImode and TFmode and TDmode values are allowed in both pairs of X
 	     registers and individual Q registers.  The available
 	     address modes are:
 	     X,X: 7-bit signed scaled offset
 	     Q:   9-bit signed offset
 	     We conservatively require an offset representable in either mode.
 	   */
-	  if (mode == TImode || mode == TFmode)
+	  if (mode == TImode || mode == TFmode || mode == TDmode)
 	    return (aarch64_offset_7bit_signed_scaled_p (mode, offset)
 		    && offset_9bit_signed_unscaled_p (mode, offset));
 
@@ -4714,7 +4725,7 @@ aarch64_legitimize_address_displacement
   HOST_WIDE_INT offset = INTVAL (*disp);
   HOST_WIDE_INT base = offset & ~(GET_MODE_SIZE (mode) < 4 ? 0xfff : 0x3ffc);
 
-  if (mode == TImode || mode == TFmode
+  if (mode == TImode || mode == TFmode || mode == TDmode
       || (offset & (GET_MODE_SIZE (mode) - 1)) != 0)
     base = (offset + 0x100) & ~0x1ff;
 
@@ -5649,7 +5660,7 @@ aarch64_legitimize_address (rtx x, rtx /
       /* Small negative offsets are supported.  */
       else if (IN_RANGE (offset, -256, 0))
 	base_offset = 0;
-      else if (mode == TImode || mode == TFmode)
+      else if (mode == TImode || mode == TFmode || mode == TDmode)
 	base_offset = (offset + 0x100) & ~0x1ff;
       /* Use 12-bit offset by access size.  */
       else
@@ -5681,6 +5692,15 @@ aarch64_constant_pool_reload_icode (mach
     case TFmode:
       return CODE_FOR_aarch64_reload_movcptfdi;
 
+    case SDmode:
+      return CODE_FOR_aarch64_reload_movcpsddi;
+
+    case DDmode:
+      return CODE_FOR_aarch64_reload_movcpdddi;
+
+    case TDmode:
+      return CODE_FOR_aarch64_reload_movcptddi;
+
     case V8QImode:
       return CODE_FOR_aarch64_reload_movcpv8qidi;
 
@@ -5731,25 +5751,27 @@ aarch64_secondary_reload (bool in_p ATTR
 
   /* Without the TARGET_SIMD instructions we cannot move a Q register
      to a Q register directly.  We need a scratch.  */
-  if (REG_P (x) && (mode == TFmode || mode == TImode) && mode == GET_MODE (x)
+  if (REG_P (x) && (mode == TFmode || mode == TDmode || mode == TImode) && mode == GET_MODE (x)
       && FP_REGNUM_P (REGNO (x)) && !TARGET_SIMD
       && reg_class_subset_p (rclass, FP_REGS))
     {
       if (mode == TFmode)
         sri->icode = CODE_FOR_aarch64_reload_movtf;
+      else if (mode == TDmode)
+        sri->icode = CODE_FOR_aarch64_reload_movtd;
       else if (mode == TImode)
         sri->icode = CODE_FOR_aarch64_reload_movti;
       return NO_REGS;
     }
 
-  /* A TFmode or TImode memory access should be handled via an FP_REGS
+  /* A TFmode or TImode or TDmode memory access should be handled via an FP_REGS
      because AArch64 has richer addressing modes for LDR/STR instructions
      than LDP/STP instructions.  */
   if (TARGET_FLOAT && rclass == GENERAL_REGS
       && GET_MODE_SIZE (mode) == 16 && MEM_P (x))
     return FP_REGS;
 
-  if (rclass == FP_REGS && (mode == TImode || mode == TFmode) && CONSTANT_P(x))
+  if (rclass == FP_REGS && (mode == TImode || mode == TFmode || mode == TDmode) && CONSTANT_P(x))
       return GENERAL_REGS;
 
   return NO_REGS;
@@ -10215,6 +10237,10 @@ aarch64_legitimate_pic_operand_p (rtx x)
 static bool
 aarch64_valid_floating_const (machine_mode mode, rtx x)
 {
+  /* FIXME: Handle decimal floating point constants. */
+  if (GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT)
+    return false;
+
   if (!CONST_DOUBLE_P (x))
     return false;
 
@@ -10636,6 +10662,18 @@ aarch64_gimplify_va_arg_expr (tree valis
 	  field_t = long_double_type_node;
 	  field_ptr_t = long_double_ptr_type_node;
 	  break;
+	case SDmode:
+	  field_t = dfloat32_type_node;
+	  field_ptr_t = dfloat32_ptr_type_node;
+	  break;
+	case DDmode:
+	  field_t = dfloat64_type_node;
+	  field_ptr_t = dfloat64_ptr_type_node;
+	  break;
+	case TDmode:
+	  field_t = dfloat128_type_node;
+	  field_ptr_t = dfloat128_ptr_type_node;
+	  break;
 	case HFmode:
 	  field_t = aarch64_fp16_type_node;
 	  field_ptr_t = aarch64_fp16_ptr_type_node;
@@ -10802,7 +10840,9 @@ aapcs_vfp_sub_candidate (const_tree type
     case REAL_TYPE:
       mode = TYPE_MODE (type);
       if (mode != DFmode && mode != SFmode
-	  && mode != TFmode && mode != HFmode)
+	  && mode != TFmode && mode != HFmode
+	  && mode != DDmode && mode != SDmode
+	  && mode != TDmode)
 	return -1;
 
       if (*modep == VOIDmode)
@@ -11030,7 +11070,9 @@ aarch64_vfp_is_call_or_return_candidate
 
   if (is_ha != NULL) *is_ha = false;
 
-  if ((!composite_p && GET_MODE_CLASS (mode) == MODE_FLOAT)
+  if ((!composite_p
+       && (GET_MODE_CLASS (mode) == MODE_FLOAT
+	   || GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT))
       || aarch64_short_vector_p (type, mode))
     {
       *count = 1;
@@ -15028,6 +15070,9 @@ aarch64_libgcc_floating_mode_supported_p
 static bool
 aarch64_scalar_mode_supported_p (machine_mode mode)
 {
+  if (DECIMAL_FLOAT_MODE_P (mode))
+    return default_decimal_float_supported_p ();
+
   return (mode == HFmode
 	  ? true
 	  : default_scalar_mode_supported_p (mode));
Index: config/aarch64/aarch64.md
===================================================================
--- config/aarch64/aarch64.md	(revision 250186)
+++ config/aarch64/aarch64.md	(working copy)
@@ -1081,11 +1081,11 @@ (define_insn "*movhf_aarch64"
    (set_attr "simd" "yes,yes,yes,yes,*,*,*,*,*")]
 )
 
-(define_insn "*movsf_aarch64"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=w,w  ,?r,w,w  ,w,m,r,m ,r")
-	(match_operand:SF 1 "general_operand"      "Y ,?rY, w,w,Ufc,m,w,m,rY,r"))]
-  "TARGET_FLOAT && (register_operand (operands[0], SFmode)
-    || aarch64_reg_or_fp_zero (operands[1], SFmode))"
+(define_insn "*mov<mode>_aarch64"
+  [(set (match_operand:SFD 0 "nonimmediate_operand" "=w,w  ,?r,w,w  ,w,m,r,m ,r")
+	(match_operand:SFD 1 "general_operand"      "Y ,?rY, w,w,Ufc,m,w,m,rY,r"))]
+  "TARGET_FLOAT && (register_operand (operands[0], <MODE>mode)
+    || aarch64_reg_or_fp_zero (operands[1], <MODE>mode))"
   "@
    movi\\t%0.2s, #0
    fmov\\t%s0, %w1
@@ -1102,11 +1102,11 @@ (define_insn "*movsf_aarch64"
    (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")]
 )
 
-(define_insn "*movdf_aarch64"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=w,w  ,?r,w,w  ,w,m,r,m ,r")
-	(match_operand:DF 1 "general_operand"      "Y ,?rY, w,w,Ufc,m,w,m,rY,r"))]
-  "TARGET_FLOAT && (register_operand (operands[0], DFmode)
-    || aarch64_reg_or_fp_zero (operands[1], DFmode))"
+(define_insn "*mov<mode>_aarch64"
+  [(set (match_operand:DFD 0 "nonimmediate_operand" "=w,w  ,?r,w,w  ,w,m,r,m ,r")
+	(match_operand:DFD 1 "general_operand"      "Y ,?rY, w,w,Ufc,m,w,m,rY,r"))]
+  "TARGET_FLOAT && (register_operand (operands[0], <MODE>mode)
+    || aarch64_reg_or_fp_zero (operands[1], <MODE>mode))"
   "@
    movi\\t%d0, #0
    fmov\\t%d0, %x1
@@ -1123,13 +1123,13 @@ (define_insn "*movdf_aarch64"
    (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")]
 )
 
-(define_insn "*movtf_aarch64"
-  [(set (match_operand:TF 0
+(define_insn "*mov<mode>_aarch64"
+  [(set (match_operand:TFD 0
 	 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r,m ,m")
-	(match_operand:TF 1
+	(match_operand:TFD 1
 	 "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,m ,?r,Y"))]
-  "TARGET_FLOAT && (register_operand (operands[0], TFmode)
-    || aarch64_reg_or_fp_zero (operands[1], TFmode))"
+  "TARGET_FLOAT && (register_operand (operands[0], <MODE>mode)
+    || aarch64_reg_or_fp_zero (operands[1], <MODE>mode))"
   "@
    mov\\t%0.16b, %1.16b
    #
@@ -1149,8 +1149,8 @@ (define_insn "*movtf_aarch64"
 )
 
 (define_split
-   [(set (match_operand:TF 0 "register_operand" "")
-	 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
+   [(set (match_operand:TFD 0 "register_operand" "")
+	 (match_operand:TFD 1 "aarch64_reg_or_imm" ""))]
   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
   [(const_int 0)]
   {
Index: config/aarch64/iterators.md
===================================================================
--- config/aarch64/iterators.md	(revision 250186)
+++ config/aarch64/iterators.md	(working copy)
@@ -44,14 +44,23 @@ (define_mode_iterator GPF [SF DF])
 ;; Iterator for all scalar floating point modes (HF, SF, DF)
 (define_mode_iterator GPF_F16 [(HF "AARCH64_ISA_F16") SF DF])
 
-;; Iterator for all scalar floating point modes (HF, SF, DF and TF)
-(define_mode_iterator GPF_TF_F16 [HF SF DF TF])
+;; Iterator for all scalar floating point modes (HF, SF, DF and TF [SD, DD, and TD])
+(define_mode_iterator GPF_TF_F16 [HF SF DF TF SD DD TD])
+
+;; Iterator for scalar 32bit fp modes (SF, SD)
+(define_mode_iterator SFD [SD SF])
+
+;; Iterator for scalar 64bit fp modes (DF, DD)
+(define_mode_iterator DFD [DD DF])
+
+;; Iterator for scalar 128bit fp modes (TF, TD)
+(define_mode_iterator TFD [TD TF])
 
 ;; Double vector modes.
 (define_mode_iterator VDF [V2SF V4HF])
 
-;; Iterator for all scalar floating point modes (SF, DF and TF)
-(define_mode_iterator GPF_TF [SF DF TF])
+;; Iterator for all scalar floating point modes (SF, DF and TF [SD, DD, and TD])
+(define_mode_iterator GPF_TF [SF DF TF SD DD TD])
 
 ;; Integer vector modes.
 (define_mode_iterator VDQ_I [V8QI V16QI V4HI V8HI V2SI V4SI V2DI])
@@ -224,7 +233,7 @@ (define_mode_iterator VB [V8QI V16QI])
 ;; 2 and 4 lane SI modes.
 (define_mode_iterator VS [V2SI V4SI])
 
-(define_mode_iterator TX [TI TF])
+(define_mode_iterator TX [TI TF TD])
 
 ;; Opaque structure modes.
 (define_mode_iterator VSTRUCT [OI CI XI])
Index: testsuite/c-c++-common/dfp/pr39986.c
===================================================================
--- testsuite/c-c++-common/dfp/pr39986.c	(revision 250186)
+++ testsuite/c-c++-common/dfp/pr39986.c	(working copy)
@@ -14,19 +14,19 @@ _Decimal128 f = -678901.234e-6dl;
 /* The first value is DPD, the second is BID.  The order differs depending
    on whether the target is big-endian or little-endian.  */
 
-/* { dg-final { scan-assembler ".long\t(572653859|822183807)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(572653859|822183807)\n" } } */
 
-/* { dg-final { scan-assembler ".long\t(-1572863965|-1308622825)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(-1572863965|-1308622825)\n" } } */
 
-/* { dg-final { scan-assembler ".long\t(52|34)\n" } } */
-/* { dg-final { scan-assembler ".long\t(572784640|824180736)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(52|34)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(572784640|824180736)\n" } } */
 
-/* { dg-final { scan-assembler ".long\t(4736|4500)\n" } } */
-/* { dg-final { scan-assembler ".long\t(-1574174720|-1319108608)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(4736|4500)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(-1574174720|-1319108608)\n" } } */
 
-/* { dg-final { scan-assembler ".long\t(-1975952433|957645077)\n" } } */
-/* { dg-final { scan-assembler ".long\t(190215|132222)\n" } } */
-/* { dg-final { scan-assembler ".long\t(574193664|835452928)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(-1975952433|957645077)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(190215|132222)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(574193664|835452928)\n" } } */
 
-/* { dg-final { scan-assembler ".long\t(931280180|678901234)\n" } } */
-/* { dg-final { scan-assembler ".long\t(-1576681472|-1339162624)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(931280180|678901234)\n" } } */
+/* { dg-final { scan-assembler ".(word|long)\t(-1576681472|-1339162624)\n" } } */

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-07-28 18:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-14  0:21 [PATCH/AARCH64] Decimal floating point support for AARCH64 Andrew Pinski
2017-07-15  6:20 ` Andrew Pinski
2017-07-21 21:45 ` Peter Bergner
2017-07-21 21:51   ` Andrew Pinski
2017-07-21 21:54     ` Peter Bergner
2017-07-28 18:03 ` Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).