This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] S/390: Add support for the "load fp integer" instructions


Hi,

the attached patch implements pattern definitions for the nearest
integer functions for binary and decimal floating point.  Since z196
we have "load fp integer" instructions which allow suppression of the
inexact exception.  These provide a 1:1 mapping to several of the
standard math.h functions.

The DFP variants are not yet expanded for the standard math function
since the necessary GCC builtins are missing so far.

I'll commit the patch after waiting for comments and regression test.

Bye,

-Andreas-

2013-09-03  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* config/s390/s390.md (UNSPEC_FPINT_FLOOR, UNSPEC_FPINT_BTRUNC)
	(UNSPEC_FPINT_ROUND, UNSPEC_FPINT_CEIL, UNSPEC_FPINT_NEARBYINT)
	(UNSPEC_FPINT_RINT): New constant definitions.
	(FPINT, fpint_name, fpint_roundingmode): New integer iterator
	definition with 2 attributes.
	("<FPINT:fpint_name><BFP:mode>2", "rint<BFP:mode>2")
	("<FPINT:fpint_name><DFP:mode>2", "rint<DFP:mode>2"): New pattern
	definitions.

2013-09-03  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* gcc.target/s390/nearestint-1.c: New testcase.


---
 gcc/config/s390/2827.md                      |   21 ++++++!
 gcc/config/s390/s390.md                      |   78 ++++++++++++++++++++++++++!
 gcc/testsuite/gcc.target/s390/nearestint-1.c |   48 ++++++++++++++++
 3 files changed, 143 insertions(+), 4 modifications(!)

Index: gcc/config/s390/2827.md
===================================================================
*** gcc/config/s390/2827.md.orig
--- gcc/config/s390/2827.md
***************
*** 37,43 ****
  
  (define_insn_reservation "zEC12_simple" 1
    (and (eq_attr "cpu" "zEC12")
!        (eq_attr "mnemonic" "ltg,ogrk,lr,lnebr,lghrl,sdbr,x,asi,lhr,sebr,madb,ar,lhrl,clfxtr,llgfr,clghrl,cgr,cli,agrk,ic,adbr,aebr,lrv,clg,cy,cghi,sy,celfbr,seb,clgfr,al,tm,lang,clfebr,lghr,cdb,lpebr,laa,ark,lh,or,icy,xi,msebr,n,llihl,afi,cs,nrk,sth,lgr,l,lcr,stey,xg,crt,slgfr,ny,ld,j,llihh,slgr,clfhsi,slg,lb,lgrl,lrl,llihf,lndbr,llcr,laxg,mvghi,rllg,sdb,xrk,laag,alhsik,algfi,algr,aly,agfi,lrvr,d,crl,llgc,tmhl,algsi,lgh,icmh,clhrl,xgrk,icm,iilf,ork,lbr,cg,ldgr,lgf,iihf,llghr,sg,clfdbr,llgtr,stam,cebr,tmhh,tceb,slgf,basr,lgbr,maebr,lgb,cgfi,aeb,ltebr,lax,clfit,lrvgr,nihl,ni,clfdtr,srdl,mdb,srk,xihf,stgrl,sthrl,algf,ltr,cdlgbr,cgit,ng,lat,llghrl,ltgr,nihh,clgfrl,srlk,maeb,agr,cxlftr,ler,bcr_flush,stcy,cds,clfi,nihf,ly,clt,lgat,alg,lhy,lgfrl,clghsi,clrt,tmll,srlg,tcdb,ay,sty,clr,lgfi,lan,lpdbr,clgt,adb,ahik,sra,algrk,cdfbr,lcebr,clfxbr,msdbr,ceb,clgr,tmy,tmlh,alghsik,lcgr,mvi,cdbr,ltgf,xr,larl,ldr,llgcr,clgrt,clrl,cghsi,cliy,madbr,oy,ogr,llgt,meebr,slr,clgxbr,chi,s,icmy,llc,ngr,clhhsi,ltgfr,llill,lhi,o,meeb,clgdtr,sll,clgrl,clgf,ledbr,cegbr,mviy,algfr,rll,cdlftr,sldl,cdlgtr,lg,niy,st,sgr,ag,le,xgr,cr,stg,llilh,sr,lzer,cdsg,sllk,mdbr,stoc,csg,clgit,chhsi,strl,llilf,lndfr,ngrk,clgebr,clgfi,llgh,mseb,ltdbr,oill,la,llhrl,stc,lghi,oihl,xiy,sllg,llgf,cgrt,ldeb,cl,sl,cdlfbr,oi,oilh,nr,srak,oihh,ear,slgrk,og,c,slgfi,sthy,oilf,oiy,msdb,oihf,a,cfi,lzxr,lzdr,srag,cdgbr,brasl,alr,cgrl,llgfrl,cit,clgxtr,ley,exrl,lcdfr,lay,xilf,lcdbr,alsi,mvhhi,srl,chsi,lgfr,lrvg,cly,sgrk,ahi,celgbr,nill,clgdbr,jg,slrk,lxr,sar,slfi,cpsdr,lcgfr,aghik,nilh,mvhi,lpdfr,xy,alrk,lao,agsi,ldy,nilf,llhr,alfi,laog,sly,aghi,ldebr,bras,srda,cefbr,lt")) "nothing")
  
  (define_insn_reservation "zEC12_cgdbr" 2
    (and (eq_attr "cpu" "zEC12")
--- 37,43 ----
  
  (define_insn_reservation "zEC12_simple" 1
    (and (eq_attr "cpu" "zEC12")
!        (eq_attr "mnemonic" "ltg,ogrk,lr,lnebr,lghrl,sdbr,x,asi,lhr,sebr,madb,ar,lhrl,clfxtr,llgfr,clghrl,cgr,cli,agrk,ic,adbr,aebr,lrv,clg,cy,cghi,sy,celfbr,seb,clgfr,al,tm,lang,clfebr,lghr,cdb,lpebr,laa,ark,lh,or,icy,xi,msebr,n,llihl,afi,cs,nrk,sth,lgr,l,lcr,stey,xg,crt,slgfr,ny,ld,j,llihh,slgr,clfhsi,slg,lb,lgrl,lrl,llihf,lndbr,llcr,laxg,mvghi,rllg,sdb,xrk,laag,alhsik,algfi,algr,aly,agfi,lrvr,d,crl,llgc,tmhl,algsi,lgh,icmh,clhrl,xgrk,icm,iilf,ork,lbr,cg,ldgr,lgf,iihf,llghr,sg,clfdbr,llgtr,stam,cebr,tmhh,tceb,slgf,basr,lgbr,maebr,lgb,cgfi,aeb,ltebr,lax,clfit,lrvgr,nihl,ni,clfdtr,srdl,mdb,srk,xihf,stgrl,sthrl,algf,ltr,cdlgbr,cgit,ng,lat,llghrl,ltgr,nihh,clgfrl,srlk,maeb,agr,cxlftr,ler,bcr_flush,stcy,cds,clfi,nihf,ly,clt,lgat,alg,lhy,lgfrl,clghsi,clrt,tmll,srlg,tcdb,ay,sty,clr,lgfi,lan,lpdbr,clgt,adb,ahik,sra,algrk,cdfbr,lcebr,clfxbr,msdbr,ceb,clgr,tmy,tmlh,alghsik,lcgr,mvi,cdbr,ltgf,xr,larl,ldr,llgcr,clgrt,clrl,cghsi,cliy,madbr,oy,ogr,llgt,meebr,slr,clgxbr,chi,s,icmy,llc,ngr,clhhsi,ltgfr,llill,lhi,o,meeb,clgdtr,sll,clgrl,clgf,ledbr,cegbr,mviy,algfr,rll,cdlftr,sldl,cdlgtr,lg,niy,st,sgr,ag,le,xgr,cr,stg,llilh,sr,lzer,cdsg,sllk,mdbr,stoc,csg,clgit,chhsi,strl,llilf,lndfr,ngrk,clgebr,clgfi,llgh,mseb,ltdbr,oill,la,llhrl,stc,lghi,oihl,xiy,sllg,llgf,cgrt,ldeb,cl,sl,cdlfbr,oi,oilh,nr,srak,oihh,ear,slgrk,og,c,slgfi,sthy,oilf,oiy,msdb,oihf,a,cfi,lzxr,lzdr,srag,cdgbr,brasl,alr,cgrl,llgfrl,cit,clgxtr,ley,exrl,lcdfr,lay,xilf,lcdbr,alsi,mvhhi,srl,chsi,lgfr,lrvg,cly,sgrk,ahi,celgbr,nill,clgdbr,jg,slrk,lxr,sar,slfi,cpsdr,lcgfr,aghik,nilh,mvhi,lpdfr,xy,alrk,lao,agsi,ldy,nilf,llhr,alfi,laog,sly,aghi,ldebr,bras,srda,cefbr,lt,fiebra,fidbra,fixbra,fidtr,fixtr")) "nothing")
  
  (define_insn_reservation "zEC12_cgdbr" 2
    (and (eq_attr "cpu" "zEC12")
***************
*** 603,605 ****
--- 603,624 ----
    (and (eq_attr "cpu" "zEC12")
         (eq_attr "mnemonic" "mh")) "nothing")
  
+ (define_insn_reservation "zEC12_fiebra" 6
+   (and (eq_attr "cpu" "zEC12")
+        (eq_attr "mnemonic" "fiebra")) "nothing")
+ 
+ (define_insn_reservation "zEC12_fidbra" 6
+   (and (eq_attr "cpu" "zEC12")
+        (eq_attr "mnemonic" "fidbra")) "nothing")
+ 
+ (define_insn_reservation "zEC12_fixbra" 10
+   (and (eq_attr "cpu" "zEC12")
+        (eq_attr "mnemonic" "fixbra")) "nothing")
+ 
+ (define_insn_reservation "zEC12_fidtr" 6
+   (and (eq_attr "cpu" "zEC12")
+        (eq_attr "mnemonic" "fidtr")) "nothing")
+ 
+ (define_insn_reservation "zEC12_fixtr" 10
+   (and (eq_attr "cpu" "zEC12")
+        (eq_attr "mnemonic" "fixtr")) "nothing")
Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig
--- gcc/config/s390/s390.md
***************
*** 117,122 ****
--- 117,130 ----
     ; Population Count
     UNSPEC_POPCNT
     UNSPEC_COPYSIGN
+ 
+    ; Load FP Integer
+    UNSPEC_FPINT_FLOOR
+    UNSPEC_FPINT_BTRUNC
+    UNSPEC_FPINT_ROUND
+    UNSPEC_FPINT_CEIL
+    UNSPEC_FPINT_NEARBYINT
+    UNSPEC_FPINT_RINT
   ])
  
  ;;
***************
*** 429,437 ****
  ;; the same template.
  (define_code_iterator SHIFT [ashift lshiftrt])
  
! ;; This iterator allow r[ox]sbg to be defined with the same template
  (define_code_iterator IXOR [ior xor])
  
  ;; This iterator and attribute allow to combine most atomic operations.
  (define_code_iterator ATOMIC [and ior xor plus minus mult])
  (define_code_iterator ATOMIC_Z196 [and ior xor plus])
--- 437,461 ----
  ;; the same template.
  (define_code_iterator SHIFT [ashift lshiftrt])
  
! ;; This iterator allows r[ox]sbg to be defined with the same template
  (define_code_iterator IXOR [ior xor])
  
+ ;; This iterator is used to expand the patterns for the nearest
+ ;; integer functions.
+ (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
+ 			    UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
+ 			    UNSPEC_FPINT_NEARBYINT])
+ (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
+ 			     (UNSPEC_FPINT_BTRUNC "btrunc")
+ 			     (UNSPEC_FPINT_ROUND "round")
+ 			     (UNSPEC_FPINT_CEIL "ceil")
+ 			     (UNSPEC_FPINT_NEARBYINT "nearbyint")])
+ (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
+ 				     (UNSPEC_FPINT_BTRUNC "5")
+ 				     (UNSPEC_FPINT_ROUND "1")
+ 				     (UNSPEC_FPINT_CEIL "6")
+ 				     (UNSPEC_FPINT_NEARBYINT "0")])
+ 
  ;; This iterator and attribute allow to combine most atomic operations.
  (define_code_iterator ATOMIC [and ior xor plus minus mult])
  (define_code_iterator ATOMIC_Z196 [and ior xor plus])
***************
*** 4414,4419 ****
--- 4438,4495 ----
    [(set_attr "op_type" "RRF")
     (set_attr "type"    "fsimptf")])
  
+ ; Binary Floating Point - load fp integer
+ 
+ ; Expanders for: floor, btrunc, round, ceil, and nearbyint
+ ; For all of them the inexact exceptions are suppressed.
+ 
+ ; fiebra, fidbra, fixbra
+ (define_insn "<FPINT:fpint_name><BFP:mode>2"
+   [(set (match_operand:BFP 0 "register_operand" "=f")
+ 	(unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
+ 		    FPINT))]
+   "TARGET_Z196"
+   "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
+   [(set_attr "op_type"   "RRF")
+    (set_attr "type"      "fsimp<BFP:mode>")])
+ 
+ ; rint is supposed to raise an inexact exception so we can use the
+ ; older instructions.
+ 
+ ; fiebr, fidbr, fixbr
+ (define_insn "rint<BFP:mode>2"
+   [(set (match_operand:BFP 0 "register_operand" "=f")
+ 	(unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
+ 		    UNSPEC_FPINT_RINT))]
+   ""
+   "fi<BFP:xde>br\t%0,0,%1"
+   [(set_attr "op_type"   "RRF")
+    (set_attr "type"      "fsimp<BFP:mode>")])
+ 
+ 
+ ; Decimal Floating Point - load fp integer
+ 
+ ; fidtr, fixtr
+ (define_insn "<FPINT:fpint_name><DFP:mode>2"
+   [(set (match_operand:DFP 0 "register_operand" "=f")
+ 	(unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
+ 		    FPINT))]
+   "TARGET_HARD_DFP"
+   "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
+   [(set_attr "op_type"   "RRF")
+    (set_attr "type"      "fsimp<DFP:mode>")])
+ 
+ ; fidtr, fixtr
+ (define_insn "rint<DFP:mode>2"
+   [(set (match_operand:DFP 0 "register_operand" "=f")
+ 	(unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
+ 		    UNSPEC_FPINT_RINT))]
+   "TARGET_HARD_DFP"
+   "fi<DFP:xde>tr\t%0,0,%1,0"
+   [(set_attr "op_type"   "RRF")
+    (set_attr "type"      "fsimp<DFP:mode>")])
+ 
+ ;
  ; Binary <-> Decimal floating point trunc patterns
  ;
  
Index: gcc/testsuite/gcc.target/s390/nearestint-1.c
===================================================================
*** /dev/null
--- gcc/testsuite/gcc.target/s390/nearestint-1.c
***************
*** 0 ****
--- 1,48 ----
+ /* Since z196 the nearest integer functions can be expanded to single
+    instructions.  */
+ 
+ /* { dg-do compile } */
+ /* { dg-options "-O3 -march=z196 -mzarch" } */
+ 
+ extern float ceilf (float x);
+ extern double ceil (double x);
+ extern long double ceill (long double x);
+ extern float floorf (float x);
+ extern double floor (double x);
+ extern long double floorl (long double x);
+ extern float truncf (float x);
+ extern double trunc (double x);
+ extern long double truncl (long double x);
+ extern float nearbyintf (float x);
+ extern double nearbyint (double x);
+ extern long double nearbyintl (long double x);
+ extern float rintf (float x);
+ extern double rint (double x);
+ extern long double rintl (long double x);
+ 
+ float my_ceilf (float x) { return ceilf (x); }
+ double my_ceil (double x) { return ceil (x); }
+ long double my_ceill (long double x) { return ceill (x); }
+ 
+ float my_floorf (float x) { return floorf (x); }
+ double my_floor (double x) { return floor (x); }
+ long double my_floorl (long double x) { return floorl (x); }
+ 
+ float my_truncf (float x) { return truncf (x); }
+ double my_trunc (double x) { return trunc (x); }
+ long double my_truncl (long double x) { return truncl (x); }
+ 
+ float my_nearbyintf (float x) { return nearbyintf (x); }
+ double my_nearbyint (double x) { return nearbyint (x); }
+ long double my_nearbyintl (long double x) { return nearbyintl (x); }
+ 
+ float my_rintf (float x) { return rintf (x); }
+ double my_rint (double x) { return rint (x); }
+ long double my_rintl (long double x) { return rintl (x); }
+ 
+ /* { dg-final { scan-assembler-times "fiebr\t" 1 } } */
+ /* { dg-final { scan-assembler-times "fidbr\t" 1 } } */
+ /* { dg-final { scan-assembler-times "fixbr\t" 1 } } */
+ /* { dg-final { scan-assembler-times "fiebra\t" 4 } } */
+ /* { dg-final { scan-assembler-times "fidbra\t" 4 } } */
+ /* { dg-final { scan-assembler-times "fixbra\t" 4 } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]