Home | History | Annotate | Line # | Download | only in rs6000
dfp.md revision 1.5
      1 ;; Decimal Floating Point (DFP) patterns.
      2 ;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
      3 ;; Contributed by Ben Elliston (bje (a] au.ibm.com) and Peter Bergner
      4 ;; (bergner (a] vnet.ibm.com).
      5 
      6 ;; This file is part of GCC.
      7 
      8 ;; GCC is free software; you can redistribute it and/or modify it
      9 ;; under the terms of the GNU General Public License as published
     10 ;; by the Free Software Foundation; either version 3, or (at your
     11 ;; option) any later version.
     12 
     13 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
     14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     16 ;; License for more details.
     17 
     18 ;; You should have received a copy of the GNU General Public License
     19 ;; along with GCC; see the file COPYING3.  If not see
     20 ;; <http://www.gnu.org/licenses/>.
     21 
     22 ;;
     23 ;; UNSPEC usage
     24 ;;
     25 
     26 (define_c_enum "unspec"
     27   [UNSPEC_MOVSD_LOAD
     28    UNSPEC_MOVSD_STORE
     29   ])
     30 
     31 
     32 (define_insn "movsd_store"
     33   [(set (match_operand:DD 0 "nonimmediate_operand" "=m")
     34 	(unspec:DD [(match_operand:SD 1 "input_operand" "d")]
     35 		   UNSPEC_MOVSD_STORE))]
     36   "(gpc_reg_operand (operands[0], DDmode)
     37    || gpc_reg_operand (operands[1], SDmode))
     38    && TARGET_HARD_FLOAT && TARGET_FPRS"
     39   "stfd%U0%X0 %1,%0"
     40   [(set_attr "type" "fpstore")
     41    (set_attr "length" "4")])
     42 
     43 (define_insn "movsd_load"
     44   [(set (match_operand:SD 0 "nonimmediate_operand" "=f")
     45 	(unspec:SD [(match_operand:DD 1 "input_operand" "m")]
     46 		   UNSPEC_MOVSD_LOAD))]
     47   "(gpc_reg_operand (operands[0], SDmode)
     48    || gpc_reg_operand (operands[1], DDmode))
     49    && TARGET_HARD_FLOAT && TARGET_FPRS"
     50   "lfd%U1%X1 %0,%1"
     51   [(set_attr "type" "fpload")
     52    (set_attr "length" "4")])
     53 
     54 ;; Hardware support for decimal floating point operations.
     55 
     56 (define_insn "extendsddd2"
     57   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
     58 	(float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
     59   "TARGET_DFP"
     60   "dctdp %0,%1"
     61   [(set_attr "type" "fp")])
     62 
     63 (define_expand "extendsdtd2"
     64   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
     65 	(float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))]
     66   "TARGET_DFP"
     67 {
     68   rtx tmp = gen_reg_rtx (DDmode);
     69   emit_insn (gen_extendsddd2 (tmp, operands[1]));
     70   emit_insn (gen_extendddtd2 (operands[0], tmp));
     71   DONE;
     72 })
     73 
     74 (define_insn "truncddsd2"
     75   [(set (match_operand:SD 0 "gpc_reg_operand" "=f")
     76 	(float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
     77   "TARGET_DFP"
     78   "drsp %0,%1"
     79   [(set_attr "type" "fp")])
     80 
     81 (define_expand "negdd2"
     82   [(set (match_operand:DD 0 "gpc_reg_operand" "")
     83 	(neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
     84   "TARGET_HARD_FLOAT && TARGET_FPRS"
     85   "")
     86 
     87 (define_insn "*negdd2_fpr"
     88   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
     89 	(neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
     90   "TARGET_HARD_FLOAT && TARGET_FPRS"
     91   "fneg %0,%1"
     92   [(set_attr "type" "fp")])
     93 
     94 (define_expand "absdd2"
     95   [(set (match_operand:DD 0 "gpc_reg_operand" "")
     96 	(abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
     97   "TARGET_HARD_FLOAT && TARGET_FPRS"
     98   "")
     99 
    100 (define_insn "*absdd2_fpr"
    101   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    102 	(abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
    103   "TARGET_HARD_FLOAT && TARGET_FPRS"
    104   "fabs %0,%1"
    105   [(set_attr "type" "fp")])
    106 
    107 (define_insn "*nabsdd2_fpr"
    108   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    109 	(neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))]
    110   "TARGET_HARD_FLOAT && TARGET_FPRS"
    111   "fnabs %0,%1"
    112   [(set_attr "type" "fp")])
    113 
    114 (define_expand "negtd2"
    115   [(set (match_operand:TD 0 "gpc_reg_operand" "")
    116 	(neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
    117   "TARGET_HARD_FLOAT && TARGET_FPRS"
    118   "")
    119 
    120 (define_insn "*negtd2_fpr"
    121   [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
    122 	(neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
    123   "TARGET_HARD_FLOAT && TARGET_FPRS"
    124   "@
    125    fneg %0,%1
    126    fneg %0,%1\;fmr %L0,%L1"
    127   [(set_attr "type" "fp")
    128    (set_attr "length" "4,8")])
    129 
    130 (define_expand "abstd2"
    131   [(set (match_operand:TD 0 "gpc_reg_operand" "")
    132 	(abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
    133   "TARGET_HARD_FLOAT && TARGET_FPRS"
    134   "")
    135 
    136 (define_insn "*abstd2_fpr"
    137   [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
    138 	(abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
    139   "TARGET_HARD_FLOAT && TARGET_FPRS"
    140   "@
    141    fabs %0,%1
    142    fabs %0,%1\;fmr %L0,%L1"
    143   [(set_attr "type" "fp")
    144    (set_attr "length" "4,8")])
    145 
    146 (define_insn "*nabstd2_fpr"
    147   [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
    148 	(neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))]
    149   "TARGET_HARD_FLOAT && TARGET_FPRS"
    150   "@
    151    fnabs %0,%1
    152    fnabs %0,%1\;fmr %L0,%L1"
    153   [(set_attr "type" "fp")
    154    (set_attr "length" "4,8")])
    155 
    156 ;; Hardware support for decimal floating point operations.
    157 
    158 (define_insn "extendddtd2"
    159   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    160 	(float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
    161   "TARGET_DFP"
    162   "dctqpq %0,%1"
    163   [(set_attr "type" "fp")])
    164 
    165 ;; The result of drdpq is an even/odd register pair with the converted
    166 ;; value in the even register and zero in the odd register.
    167 ;; FIXME: Avoid the register move by using a reload constraint to ensure
    168 ;; that the result is the first of the pair receiving the result of drdpq.
    169 
    170 (define_insn "trunctddd2"
    171   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    172 	(float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d")))
    173    (clobber (match_scratch:TD 2 "=d"))]
    174   "TARGET_DFP"
    175   "drdpq %2,%1\;fmr %0,%2"
    176   [(set_attr "type" "fp")])
    177 
    178 (define_insn "adddd3"
    179   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    180 	(plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
    181 		 (match_operand:DD 2 "gpc_reg_operand" "d")))]
    182   "TARGET_DFP"
    183   "dadd %0,%1,%2"
    184   [(set_attr "type" "fp")])
    185 
    186 (define_insn "addtd3"
    187   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    188 	(plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
    189 		 (match_operand:TD 2 "gpc_reg_operand" "d")))]
    190   "TARGET_DFP"
    191   "daddq %0,%1,%2"
    192   [(set_attr "type" "fp")])
    193 
    194 (define_insn "subdd3"
    195   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    196 	(minus:DD (match_operand:DD 1 "gpc_reg_operand" "d")
    197 		  (match_operand:DD 2 "gpc_reg_operand" "d")))]
    198   "TARGET_DFP"
    199   "dsub %0,%1,%2"
    200   [(set_attr "type" "fp")])
    201 
    202 (define_insn "subtd3"
    203   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    204 	(minus:TD (match_operand:TD 1 "gpc_reg_operand" "d")
    205 		  (match_operand:TD 2 "gpc_reg_operand" "d")))]
    206   "TARGET_DFP"
    207   "dsubq %0,%1,%2"
    208   [(set_attr "type" "fp")])
    209 
    210 (define_insn "muldd3"
    211   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    212 	(mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
    213 		 (match_operand:DD 2 "gpc_reg_operand" "d")))]
    214   "TARGET_DFP"
    215   "dmul %0,%1,%2"
    216   [(set_attr "type" "fp")])
    217 
    218 (define_insn "multd3"
    219   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    220 	(mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
    221 		 (match_operand:TD 2 "gpc_reg_operand" "d")))]
    222   "TARGET_DFP"
    223   "dmulq %0,%1,%2"
    224   [(set_attr "type" "fp")])
    225 
    226 (define_insn "divdd3"
    227   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    228 	(div:DD (match_operand:DD 1 "gpc_reg_operand" "d")
    229 		(match_operand:DD 2 "gpc_reg_operand" "d")))]
    230   "TARGET_DFP"
    231   "ddiv %0,%1,%2"
    232   [(set_attr "type" "fp")])
    233 
    234 (define_insn "divtd3"
    235   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    236 	(div:TD (match_operand:TD 1 "gpc_reg_operand" "d")
    237 		(match_operand:TD 2 "gpc_reg_operand" "d")))]
    238   "TARGET_DFP"
    239   "ddivq %0,%1,%2"
    240   [(set_attr "type" "fp")])
    241 
    242 (define_insn "*cmpdd_internal1"
    243   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
    244 	(compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d")
    245 		      (match_operand:DD 2 "gpc_reg_operand" "d")))]
    246   "TARGET_DFP"
    247   "dcmpu %0,%1,%2"
    248   [(set_attr "type" "fpcompare")])
    249 
    250 (define_insn "*cmptd_internal1"
    251   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
    252 	(compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d")
    253 		      (match_operand:TD 2 "gpc_reg_operand" "d")))]
    254   "TARGET_DFP"
    255   "dcmpuq %0,%1,%2"
    256   [(set_attr "type" "fpcompare")])
    257 
    258 (define_insn "floatdidd2"
    259   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    260 	(float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))]
    261   "TARGET_DFP && TARGET_POPCNTD"
    262   "dcffix %0,%1"
    263   [(set_attr "type" "fp")])
    264 
    265 (define_insn "floatditd2"
    266   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    267 	(float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
    268   "TARGET_DFP"
    269   "dcffixq %0,%1"
    270   [(set_attr "type" "fp")])
    271 
    272 ;; Convert a decimal64 to a decimal64 whose value is an integer.
    273 ;; This is the first stage of converting it to an integer type.
    274 
    275 (define_insn "ftruncdd2"
    276   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    277 	(fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
    278   "TARGET_DFP"
    279   "drintn. 0,%0,%1,1"
    280   [(set_attr "type" "fp")])
    281 
    282 ;; Convert a decimal64 whose value is an integer to an actual integer.
    283 ;; This is the second stage of converting decimal float to integer type.
    284 
    285 (define_insn "fixdddi2"
    286   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
    287 	(fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
    288   "TARGET_DFP"
    289   "dctfix %0,%1"
    290   [(set_attr "type" "fp")])
    291 
    292 ;; Convert a decimal128 to a decimal128 whose value is an integer.
    293 ;; This is the first stage of converting it to an integer type.
    294 
    295 (define_insn "ftrunctd2"
    296   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    297 	(fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
    298   "TARGET_DFP"
    299   "drintnq. 0,%0,%1,1"
    300   [(set_attr "type" "fp")])
    301 
    302 ;; Convert a decimal128 whose value is an integer to an actual integer.
    303 ;; This is the second stage of converting decimal float to integer type.
    304 
    305 (define_insn "fixtddi2"
    306   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
    307 	(fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
    308   "TARGET_DFP"
    309   "dctfixq %0,%1"
    310   [(set_attr "type" "fp")])
    311 
    312 
    314 ;; Decimal builtin support
    315 
    316 (define_c_enum "unspec"
    317   [UNSPEC_DDEDPD
    318    UNSPEC_DENBCD
    319    UNSPEC_DXEX
    320    UNSPEC_DIEX
    321    UNSPEC_DSCLI
    322    UNSPEC_DSCRI])
    323 
    324 (define_mode_iterator D64_D128 [DD TD])
    325 
    326 (define_mode_attr dfp_suffix [(DD "")
    327 			      (TD "q")])
    328 
    329 (define_insn "dfp_ddedpd_<mode>"
    330   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    331 	(unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i")
    332 			  (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
    333 			 UNSPEC_DDEDPD))]
    334   "TARGET_DFP"
    335   "ddedpd<dfp_suffix> %1,%0,%2"
    336   [(set_attr "type" "fp")])
    337 
    338 (define_insn "dfp_denbcd_<mode>"
    339   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    340 	(unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i")
    341 			  (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
    342 			 UNSPEC_DENBCD))]
    343   "TARGET_DFP"
    344   "denbcd<dfp_suffix> %1,%0,%2"
    345   [(set_attr "type" "fp")])
    346 
    347 (define_insn "dfp_dxex_<mode>"
    348   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    349 	(unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
    350 			 UNSPEC_DXEX))]
    351   "TARGET_DFP"
    352   "dxex<dfp_suffix> %0,%1"
    353   [(set_attr "type" "fp")])
    354 
    355 (define_insn "dfp_diex_<mode>"
    356   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    357 	(unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
    358 			  (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
    359 			 UNSPEC_DXEX))]
    360   "TARGET_DFP"
    361   "diex<dfp_suffix> %0,%1,%2"
    362   [(set_attr "type" "fp")])
    363 
    364 (define_insn "dfp_dscli_<mode>"
    365   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    366 	(unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
    367 			  (match_operand:QI 2 "immediate_operand" "i")]
    368 			 UNSPEC_DSCLI))]
    369   "TARGET_DFP"
    370   "dscli<dfp_suffix> %0,%1,%2"
    371   [(set_attr "type" "fp")])
    372 
    373 (define_insn "dfp_dscri_<mode>"
    374   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    375 	(unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
    376 			  (match_operand:QI 2 "immediate_operand" "i")]
    377 			 UNSPEC_DSCRI))]
    378   "TARGET_DFP"
    379   "dscri<dfp_suffix> %0,%1,%2"
    380   [(set_attr "type" "fp")])
    381