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