Patchwork [ARM,1/2] ARMv8 aarch32 round to integral instructions

login
register
mail settings
Submitter Kyrylo Tkachov
Date Nov. 14, 2012, 1:51 p.m.
Message ID <003901cdc26f$36b432f0$a41c98d0$@tkachov@arm.com>
Download mbox | patch
Permalink /patch/198914/
State New
Headers show

Comments

Kyrylo Tkachov - Nov. 14, 2012, 1:51 p.m.
Hi all,

This patch adds support for the vrint family of instructions in aarch32 (the
32-bit execution state in ARMv8).
These are rounding instructions that can be used to implement round to
integral functions from the math library such as:
trunc, ceil, round, floor, nearbyint, rint. This patch implements the single
and double precision variants of these functions.
There is only one pattern for them in the machine description because it
uses some new iterators to generate the correct variant for each function.

The tests for this are coming in a second patch soon.

These changes have been tested using AEM for the new functionality.
Also, no regressions when testing for ARMv7-a (for which these changes
should not have any effect) on qemu.

Ok for trunk?

Thanks,
Kyrill

gcc/ChangeLog

2012-11-14  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

	* config/arm/arm.h (TARGET_FPU_ARMV8): New macro.
	* config/arm/arm.md (UNSPEC_VRINTZ, UNSPEC_VRINTP, UNSPEC_VRINTM,
	 UNSPEC_VRINTR, UNSPEC_VRINTX, UNSPEC_VRINTA): New unspecs.
	 (f_rints, f_rintd): New types.
	* config/arm/iterators.md (VRINT): New int iterator.
	 (F_fma_type): Remove.
	 (vfp_type): New mode attribute.
	 (vfp_double_cond): Likewise.
	 (vrint_pattern, vrint_variant, vrint_predicable): New int
attribute.
	* config/arm/vfp.md (fma<SDF:mode>4, *fmsub<SDF:mode>4,
	 *fnmsub<SDF:mode>4, *fnmadd<SDF:mode>4): Use vfp_type iterator
	 instead of F_fma_type.
	 (<VRINT:pattern><SDF:mode>2): New pattern.
Kyrylo Tkachov - Nov. 14, 2012, 1:59 p.m.
Sorry, the ChangeLog entry for vfp.md in the end should say:

(<vrint_pattern><SDF:mode>2): New pattern.

Instead of

(<VRINT:pattern><SDF:mode>2): New pattern.

-----Original Message-----
From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-owner@gcc.gnu.org] On Behalf Of Kyrylo Tkachov
Sent: 14 November 2012 13:52
To: gcc-patches@gcc.gnu.org
Cc: Richard Earnshaw; Ramana Radhakrishnan
Subject: [PATCH][ARM][1/2] ARMv8 aarch32 round to integral instructions

Hi all,

This patch adds support for the vrint family of instructions in aarch32 (the
32-bit execution state in ARMv8).
These are rounding instructions that can be used to implement round to
integral functions from the math library such as:
trunc, ceil, round, floor, nearbyint, rint. This patch implements the single
and double precision variants of these functions.
There is only one pattern for them in the machine description because it
uses some new iterators to generate the correct variant for each function.

The tests for this are coming in a second patch soon.

These changes have been tested using AEM for the new functionality.
Also, no regressions when testing for ARMv7-a (for which these changes
should not have any effect) on qemu.

Ok for trunk?

Thanks,
Kyrill

gcc/ChangeLog

2012-11-14  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

	* config/arm/arm.h (TARGET_FPU_ARMV8): New macro.
	* config/arm/arm.md (UNSPEC_VRINTZ, UNSPEC_VRINTP, UNSPEC_VRINTM,
	 UNSPEC_VRINTR, UNSPEC_VRINTX, UNSPEC_VRINTA): New unspecs.
	 (f_rints, f_rintd): New types.
	* config/arm/iterators.md (VRINT): New int iterator.
	 (F_fma_type): Remove.
	 (vfp_type): New mode attribute.
	 (vfp_double_cond): Likewise.
	 (vrint_pattern, vrint_variant, vrint_predicable): New int
attribute.
	* config/arm/vfp.md (fma<SDF:mode>4, *fmsub<SDF:mode>4,
	 *fnmsub<SDF:mode>4, *fnmadd<SDF:mode>4): Use vfp_type iterator
	 instead of F_fma_type.
	 (<VRINT:pattern><SDF:mode>2): New pattern.
Kyrylo Tkachov - Nov. 21, 2012, 11:29 a.m.
Ping?

Thanks,
Kyrill

-----Original Message-----
From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-owner@gcc.gnu.org]
On Behalf Of Kyrylo Tkachov
Sent: 14 November 2012 13:52
To: gcc-patches@gcc.gnu.org
Cc: Richard Earnshaw; Ramana Radhakrishnan
Subject: [PATCH][ARM][1/2] ARMv8 aarch32 round to integral instructions

Hi all,

This patch adds support for the vrint family of instructions in aarch32 (the
32-bit execution state in ARMv8).
These are rounding instructions that can be used to implement round to
integral functions from the math library such as:
trunc, ceil, round, floor, nearbyint, rint. This patch implements the single
and double precision variants of these functions.
There is only one pattern for them in the machine description because it
uses some new iterators to generate the correct variant for each function.

The tests for this are coming in a second patch soon.

These changes have been tested using AEM for the new functionality.
Also, no regressions when testing for ARMv7-a (for which these changes
should not have any effect) on qemu.

Ok for trunk?

Thanks,
Kyrill

gcc/ChangeLog

2012-11-14  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

	* config/arm/arm.h (TARGET_FPU_ARMV8): New macro.
	* config/arm/arm.md (UNSPEC_VRINTZ, UNSPEC_VRINTP, UNSPEC_VRINTM,
	 UNSPEC_VRINTR, UNSPEC_VRINTX, UNSPEC_VRINTA): New unspecs.
	 (f_rints, f_rintd): New types.
	* config/arm/iterators.md (VRINT): New int iterator.
	 (F_fma_type): Remove.
	 (vfp_type): New mode attribute.
	 (vfp_double_cond): Likewise.
	 (vrint_pattern, vrint_variant, vrint_predicable): New int
	attribute.
	* config/arm/vfp.md (fma<SDF:mode>4, *fmsub<SDF:mode>4,
	 *fnmsub<SDF:mode>4, *fnmadd<SDF:mode>4): Use vfp_type iterator
	 instead of F_fma_type.
	 (<vrint_pattern><SDF:mode>2): New pattern.

Patch

--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -296,6 +296,9 @@  extern void (*arm_lang_output_object_att
 /* FPU supports fused-multiply-add operations.  */
 #define TARGET_FMA (TARGET_VFP && arm_fpu_desc->rev >= 4)
 
+/* FPU is ARMv8 compatible.  */
+#define TARGET_FPU_ARMV8 (TARGET_VFP && arm_fpu_desc->rev >= 8)
+
 /* FPU supports Crypto extensions.  */
 #define TARGET_CRYPTO (TARGET_VFP && arm_fpu_desc->crypto)
 
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 7e92b69ad861fe90ed409494d451854f30888462..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -111,6 +111,18 @@  (define_c_enum "unspec" [
   UNSPEC_UNALIGNED_STORE ; Same for str/strh.
   UNSPEC_PIC_UNIFIED    ; Create a common pic addressing form.
   UNSPEC_LL		; Represent an unpaired load-register-exclusive.
+  UNSPEC_VRINTZ         ; Represent a float to integral float rounding
+                        ; towards zero.
+  UNSPEC_VRINTP         ; Represent a float to integral float rounding
+                        ; towards +Inf.
+  UNSPEC_VRINTM         ; Represent a float to integral float rounding
+                        ; towards -Inf.
+  UNSPEC_VRINTR         ; Represent a float to integral float rounding
+                        ; FPSCR rounding mode.
+  UNSPEC_VRINTX         ; Represent a float to integral float rounding
+                        ; FPSCR rounding mode and signal inexactness.
+  UNSPEC_VRINTA         ; Represent a float to integral float rounding
+                        ; towards nearest, ties away from zero.
 ])
 
 ;; UNSPEC_VOLATILE Usage:
@@ -366,6 +378,8 @@  (define_attr "type"
   fmuld,\
   fmacs,\
   fmacd,\
+  f_rints,\
+  f_rintd,\
   f_flag,\
   f_loads,\
   f_loadd,\
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 0a34c82974a4b3f65bbd40032c5d33cc862be095..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -192,6 +192,13 @@  (define_code_iterator SE [sign_extend ze
 (define_code_iterator rshifts [ashiftrt lshiftrt])
 
 ;;----------------------------------------------------------------------------
+;; Int iterators
+;;----------------------------------------------------------------------------
+
+(define_int_iterator VRINT [UNSPEC_VRINTZ UNSPEC_VRINTP UNSPEC_VRINTM
+                            UNSPEC_VRINTR UNSPEC_VRINTX UNSPEC_VRINTA])
+
+;;----------------------------------------------------------------------------
 ;; Mode attributes
 ;;----------------------------------------------------------------------------
 
@@ -431,9 +438,10 @@  (define_mode_attr qaddsub_suf [(V4UQQ "8
 ;; Mode attribute for vshll.
 (define_mode_attr V_innermode [(V8QI "QI") (V4HI "HI") (V2SI "SI")])
 
-;; Mode attributes used for fused-multiply-accumulate VFP support
+;; Mode attributes used for VFP support.
 (define_mode_attr F_constraint [(SF "t") (DF "w")])
-(define_mode_attr F_fma_type [(SF "fmacs") (DF "fmacd")])
+(define_mode_attr vfp_type [(SF "s") (DF "d")])
+(define_mode_attr vfp_double_cond [(SF "") (DF "&& TARGET_VFP_DOUBLE")])
 
 ;;----------------------------------------------------------------------------
 ;; Code attributes
@@ -457,3 +465,21 @@  (define_code_attr US [(sign_extend "s") 
 (define_code_attr shift [(ashiftrt "ashr") (lshiftrt "lshr")])
 (define_code_attr shifttype [(ashiftrt "signed") (lshiftrt "unsigned")])
 
+;;----------------------------------------------------------------------------
+;; Int attributes
+;;----------------------------------------------------------------------------
+
+;; Standard names for floating point to integral rounding instructions.
+(define_int_attr vrint_pattern [(UNSPEC_VRINTZ "btrunc") (UNSPEC_VRINTP "ceil")
+                         (UNSPEC_VRINTA "round") (UNSPEC_VRINTM "floor")
+                         (UNSPEC_VRINTR "nearbyint") (UNSPEC_VRINTX "rint")])
+
+;; Suffixes for vrint instructions specifying rounding modes.
+(define_int_attr vrint_variant [(UNSPEC_VRINTZ "z") (UNSPEC_VRINTP "p")
+                               (UNSPEC_VRINTA "a") (UNSPEC_VRINTM "m")
+                               (UNSPEC_VRINTR "r") (UNSPEC_VRINTX "x")])
+
+;; Some of the vrint instuctions are predicable.
+(define_int_attr vrint_predicable [(UNSPEC_VRINTZ "yes") (UNSPEC_VRINTP "no")
+                                  (UNSPEC_VRINTA "no") (UNSPEC_VRINTM "no")
+                                  (UNSPEC_VRINTR "yes") (UNSPEC_VRINTX "yes")])
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index d48d4e66a6c827ec6d471a218a175537f038d798..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -908,7 +908,7 @@  (define_insn "fma<SDF:mode>4"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
   "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
   [(set_attr "predicable" "yes")
-   (set_attr "type" "<F_fma_type>")]
+   (set_attr "type" "fmac<vfp_type>")]
 )
 
 (define_insn "*fmsub<SDF:mode>4"
@@ -920,7 +920,7 @@  (define_insn "*fmsub<SDF:mode>4"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
   "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
   [(set_attr "predicable" "yes")
-   (set_attr "type" "<F_fma_type>")]
+   (set_attr "type" "fmac<vfp_type>")]
 )
 
 (define_insn "*fnmsub<SDF:mode>4"
@@ -931,7 +931,7 @@  (define_insn "*fnmsub<SDF:mode>4"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
   "vfnms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
   [(set_attr "predicable" "yes")
-   (set_attr "type" "<F_fma_type>")]
+   (set_attr "type" "fmac<vfp_type>")]
 )
 
 (define_insn "*fnmadd<SDF:mode>4"
@@ -943,7 +943,7 @@  (define_insn "*fnmadd<SDF:mode>4"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
   "vfnma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
   [(set_attr "predicable" "yes")
-   (set_attr "type" "<F_fma_type>")]
+   (set_attr "type" "fmac<vfp_type>")]
 )
 
 
@@ -1248,6 +1248,20 @@  (define_insn "*push_multi_vfp"
   [(set_attr "type" "f_stored")]
 )
 
+;; VRINT round to integral instructions.
+;; Invoked for the patterns: btruncsf2, btruncdf2, ceilsf2, ceildf2,
+;; roundsf2, rounddf2, floorsf2, floordf2, nearbyintsf2, nearbyintdf2,
+;; rintsf2, rintdf2.
+(define_insn "<vrint_pattern><SDF:mode>2"
+  [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
+        (unspec:SDF [(match_operand:SDF 1
+		         "register_operand" "<F_constraint>")]
+         VRINT))]
+  "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
+  "vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1"
+  [(set_attr "predicable" "<vrint_predicable>")
+   (set_attr "type" "f_rint<vfp_type>")]
+)
 
 ;; Unimplemented insns:
 ;; fldm*