Home | History | Annotate | Line # | Download | only in rs6000
dfp.md revision 1.1.1.2
      1 ;; Decimal Floating Point (DFP) patterns.
      2 ;; Copyright (C) 2007-2013 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")
     41       (if_then_else
     42 	(match_test "update_indexed_address_mem (operands[0], VOIDmode)")
     43 	(const_string "fpstore_ux")
     44 	(if_then_else
     45 	  (match_test "update_address_mem (operands[0], VOIDmode)")
     46 	  (const_string "fpstore_u")
     47 	  (const_string "fpstore"))))
     48    (set_attr "length" "4")])
     49 
     50 (define_insn "movsd_load"
     51   [(set (match_operand:SD 0 "nonimmediate_operand" "=f")
     52 	(unspec:SD [(match_operand:DD 1 "input_operand" "m")]
     53 		   UNSPEC_MOVSD_LOAD))]
     54   "(gpc_reg_operand (operands[0], SDmode)
     55    || gpc_reg_operand (operands[1], DDmode))
     56    && TARGET_HARD_FLOAT && TARGET_FPRS"
     57   "lfd%U1%X1 %0,%1"
     58   [(set (attr "type")
     59       (if_then_else
     60 	(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
     61 	(const_string "fpload_ux")
     62 	(if_then_else
     63 	  (match_test "update_address_mem (operands[1], VOIDmode)")
     64 	  (const_string "fpload_u")
     65 	  (const_string "fpload"))))
     66    (set_attr "length" "4")])
     67 
     68 ;; Hardware support for decimal floating point operations.
     69 
     70 (define_insn "extendsddd2"
     71   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
     72 	(float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
     73   "TARGET_DFP"
     74   "dctdp %0,%1"
     75   [(set_attr "type" "fp")])
     76 
     77 (define_expand "extendsdtd2"
     78   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
     79 	(float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))]
     80   "TARGET_DFP"
     81 {
     82   rtx tmp = gen_reg_rtx (DDmode);
     83   emit_insn (gen_extendsddd2 (tmp, operands[1]));
     84   emit_insn (gen_extendddtd2 (operands[0], tmp));
     85   DONE;
     86 })
     87 
     88 (define_insn "truncddsd2"
     89   [(set (match_operand:SD 0 "gpc_reg_operand" "=f")
     90 	(float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
     91   "TARGET_DFP"
     92   "drsp %0,%1"
     93   [(set_attr "type" "fp")])
     94 
     95 (define_expand "negdd2"
     96   [(set (match_operand:DD 0 "gpc_reg_operand" "")
     97 	(neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
     98   "TARGET_HARD_FLOAT && TARGET_FPRS"
     99   "")
    100 
    101 (define_insn "*negdd2_fpr"
    102   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    103 	(neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
    104   "TARGET_HARD_FLOAT && TARGET_FPRS"
    105   "fneg %0,%1"
    106   [(set_attr "type" "fp")])
    107 
    108 (define_expand "absdd2"
    109   [(set (match_operand:DD 0 "gpc_reg_operand" "")
    110 	(abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
    111   "TARGET_HARD_FLOAT && TARGET_FPRS"
    112   "")
    113 
    114 (define_insn "*absdd2_fpr"
    115   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    116 	(abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
    117   "TARGET_HARD_FLOAT && TARGET_FPRS"
    118   "fabs %0,%1"
    119   [(set_attr "type" "fp")])
    120 
    121 (define_insn "*nabsdd2_fpr"
    122   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    123 	(neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))]
    124   "TARGET_HARD_FLOAT && TARGET_FPRS"
    125   "fnabs %0,%1"
    126   [(set_attr "type" "fp")])
    127 
    128 (define_expand "negtd2"
    129   [(set (match_operand:TD 0 "gpc_reg_operand" "")
    130 	(neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
    131   "TARGET_HARD_FLOAT && TARGET_FPRS"
    132   "")
    133 
    134 (define_insn "*negtd2_fpr"
    135   [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
    136 	(neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
    137   "TARGET_HARD_FLOAT && TARGET_FPRS"
    138   "@
    139    fneg %0,%1
    140    fneg %0,%1\;fmr %L0,%L1"
    141   [(set_attr "type" "fp")
    142    (set_attr "length" "4,8")])
    143 
    144 (define_expand "abstd2"
    145   [(set (match_operand:TD 0 "gpc_reg_operand" "")
    146 	(abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
    147   "TARGET_HARD_FLOAT && TARGET_FPRS"
    148   "")
    149 
    150 (define_insn "*abstd2_fpr"
    151   [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
    152 	(abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
    153   "TARGET_HARD_FLOAT && TARGET_FPRS"
    154   "@
    155    fabs %0,%1
    156    fabs %0,%1\;fmr %L0,%L1"
    157   [(set_attr "type" "fp")
    158    (set_attr "length" "4,8")])
    159 
    160 (define_insn "*nabstd2_fpr"
    161   [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
    162 	(neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))]
    163   "TARGET_HARD_FLOAT && TARGET_FPRS"
    164   "@
    165    fnabs %0,%1
    166    fnabs %0,%1\;fmr %L0,%L1"
    167   [(set_attr "type" "fp")
    168    (set_attr "length" "4,8")])
    169 
    170 ;; Hardware support for decimal floating point operations.
    171 
    172 (define_insn "extendddtd2"
    173   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    174 	(float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
    175   "TARGET_DFP"
    176   "dctqpq %0,%1"
    177   [(set_attr "type" "fp")])
    178 
    179 ;; The result of drdpq is an even/odd register pair with the converted
    180 ;; value in the even register and zero in the odd register.
    181 ;; FIXME: Avoid the register move by using a reload constraint to ensure
    182 ;; that the result is the first of the pair receiving the result of drdpq.
    183 
    184 (define_insn "trunctddd2"
    185   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    186 	(float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d")))
    187    (clobber (match_scratch:TD 2 "=d"))]
    188   "TARGET_DFP"
    189   "drdpq %2,%1\;fmr %0,%2"
    190   [(set_attr "type" "fp")])
    191 
    192 (define_insn "adddd3"
    193   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    194 	(plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
    195 		 (match_operand:DD 2 "gpc_reg_operand" "d")))]
    196   "TARGET_DFP"
    197   "dadd %0,%1,%2"
    198   [(set_attr "type" "fp")])
    199 
    200 (define_insn "addtd3"
    201   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    202 	(plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
    203 		 (match_operand:TD 2 "gpc_reg_operand" "d")))]
    204   "TARGET_DFP"
    205   "daddq %0,%1,%2"
    206   [(set_attr "type" "fp")])
    207 
    208 (define_insn "subdd3"
    209   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    210 	(minus:DD (match_operand:DD 1 "gpc_reg_operand" "d")
    211 		  (match_operand:DD 2 "gpc_reg_operand" "d")))]
    212   "TARGET_DFP"
    213   "dsub %0,%1,%2"
    214   [(set_attr "type" "fp")])
    215 
    216 (define_insn "subtd3"
    217   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    218 	(minus:TD (match_operand:TD 1 "gpc_reg_operand" "d")
    219 		  (match_operand:TD 2 "gpc_reg_operand" "d")))]
    220   "TARGET_DFP"
    221   "dsubq %0,%1,%2"
    222   [(set_attr "type" "fp")])
    223 
    224 (define_insn "muldd3"
    225   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    226 	(mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
    227 		 (match_operand:DD 2 "gpc_reg_operand" "d")))]
    228   "TARGET_DFP"
    229   "dmul %0,%1,%2"
    230   [(set_attr "type" "fp")])
    231 
    232 (define_insn "multd3"
    233   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    234 	(mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
    235 		 (match_operand:TD 2 "gpc_reg_operand" "d")))]
    236   "TARGET_DFP"
    237   "dmulq %0,%1,%2"
    238   [(set_attr "type" "fp")])
    239 
    240 (define_insn "divdd3"
    241   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    242 	(div:DD (match_operand:DD 1 "gpc_reg_operand" "d")
    243 		(match_operand:DD 2 "gpc_reg_operand" "d")))]
    244   "TARGET_DFP"
    245   "ddiv %0,%1,%2"
    246   [(set_attr "type" "fp")])
    247 
    248 (define_insn "divtd3"
    249   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    250 	(div:TD (match_operand:TD 1 "gpc_reg_operand" "d")
    251 		(match_operand:TD 2 "gpc_reg_operand" "d")))]
    252   "TARGET_DFP"
    253   "ddivq %0,%1,%2"
    254   [(set_attr "type" "fp")])
    255 
    256 (define_insn "*cmpdd_internal1"
    257   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
    258 	(compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d")
    259 		      (match_operand:DD 2 "gpc_reg_operand" "d")))]
    260   "TARGET_DFP"
    261   "dcmpu %0,%1,%2"
    262   [(set_attr "type" "fpcompare")])
    263 
    264 (define_insn "*cmptd_internal1"
    265   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
    266 	(compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d")
    267 		      (match_operand:TD 2 "gpc_reg_operand" "d")))]
    268   "TARGET_DFP"
    269   "dcmpuq %0,%1,%2"
    270   [(set_attr "type" "fpcompare")])
    271 
    272 (define_insn "floatdidd2"
    273   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    274 	(float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))]
    275   "TARGET_DFP && TARGET_POPCNTD"
    276   "dcffix %0,%1"
    277   [(set_attr "type" "fp")])
    278 
    279 (define_insn "floatditd2"
    280   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    281 	(float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
    282   "TARGET_DFP"
    283   "dcffixq %0,%1"
    284   [(set_attr "type" "fp")])
    285 
    286 ;; Convert a decimal64 to a decimal64 whose value is an integer.
    287 ;; This is the first stage of converting it to an integer type.
    288 
    289 (define_insn "ftruncdd2"
    290   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
    291 	(fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
    292   "TARGET_DFP"
    293   "drintn. 0,%0,%1,1"
    294   [(set_attr "type" "fp")])
    295 
    296 ;; Convert a decimal64 whose value is an integer to an actual integer.
    297 ;; This is the second stage of converting decimal float to integer type.
    298 
    299 (define_insn "fixdddi2"
    300   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
    301 	(fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
    302   "TARGET_DFP"
    303   "dctfix %0,%1"
    304   [(set_attr "type" "fp")])
    305 
    306 ;; Convert a decimal128 to a decimal128 whose value is an integer.
    307 ;; This is the first stage of converting it to an integer type.
    308 
    309 (define_insn "ftrunctd2"
    310   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
    311 	(fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
    312   "TARGET_DFP"
    313   "drintnq. 0,%0,%1,1"
    314   [(set_attr "type" "fp")])
    315 
    316 ;; Convert a decimal128 whose value is an integer to an actual integer.
    317 ;; This is the second stage of converting decimal float to integer type.
    318 
    319 (define_insn "fixtddi2"
    320   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
    321 	(fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
    322   "TARGET_DFP"
    323   "dctfixq %0,%1"
    324   [(set_attr "type" "fp")])
    325 
    326 
    328 ;; Decimal builtin support
    329 
    330 (define_c_enum "unspec"
    331   [UNSPEC_DDEDPD
    332    UNSPEC_DENBCD
    333    UNSPEC_DXEX
    334    UNSPEC_DIEX
    335    UNSPEC_DSCLI
    336    UNSPEC_DSCRI])
    337 
    338 (define_mode_iterator D64_D128 [DD TD])
    339 
    340 (define_mode_attr dfp_suffix [(DD "")
    341 			      (TD "q")])
    342 
    343 (define_insn "dfp_ddedpd_<mode>"
    344   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    345 	(unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i")
    346 			  (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
    347 			 UNSPEC_DDEDPD))]
    348   "TARGET_DFP"
    349   "ddedpd<dfp_suffix> %1,%0,%2"
    350   [(set_attr "type" "fp")])
    351 
    352 (define_insn "dfp_denbcd_<mode>"
    353   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    354 	(unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i")
    355 			  (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
    356 			 UNSPEC_DENBCD))]
    357   "TARGET_DFP"
    358   "denbcd<dfp_suffix> %1,%0,%2"
    359   [(set_attr "type" "fp")])
    360 
    361 (define_insn "dfp_dxex_<mode>"
    362   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    363 	(unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
    364 			 UNSPEC_DXEX))]
    365   "TARGET_DFP"
    366   "dxex<dfp_suffix> %0,%1"
    367   [(set_attr "type" "fp")])
    368 
    369 (define_insn "dfp_diex_<mode>"
    370   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    371 	(unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
    372 			  (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
    373 			 UNSPEC_DXEX))]
    374   "TARGET_DFP"
    375   "diex<dfp_suffix> %0,%1,%2"
    376   [(set_attr "type" "fp")])
    377 
    378 (define_insn "dfp_dscli_<mode>"
    379   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    380 	(unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
    381 			  (match_operand:QI 2 "immediate_operand" "i")]
    382 			 UNSPEC_DSCLI))]
    383   "TARGET_DFP"
    384   "dscli<dfp_suffix> %0,%1,%2"
    385   [(set_attr "type" "fp")])
    386 
    387 (define_insn "dfp_dscri_<mode>"
    388   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
    389 	(unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
    390 			  (match_operand:QI 2 "immediate_operand" "i")]
    391 			 UNSPEC_DSCRI))]
    392   "TARGET_DFP"
    393   "dscri<dfp_suffix> %0,%1,%2"
    394   [(set_attr "type" "fp")])
    395