Home | History | Annotate | Download | only in SystemZ
      1 //===- SystemZInstrFP.td - SystemZ FP Instruction defs --------*- tblgen-*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source 
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file describes the SystemZ (binary) floating point instructions in 
     11 // TableGen format.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 // FIXME: multiclassify!
     16 
     17 //===----------------------------------------------------------------------===//
     18 // FP Pattern fragments
     19 
     20 def fpimm0 : PatLeaf<(fpimm), [{
     21   return N->isExactlyValue(+0.0);
     22 }]>;
     23 
     24 def fpimmneg0 : PatLeaf<(fpimm), [{
     25   return N->isExactlyValue(-0.0);
     26 }]>;
     27 
     28 let Uses = [PSW], usesCustomInserter = 1 in {
     29   def SelectF32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, i8imm:$cc),
     30                         "# SelectF32 PSEUDO",
     31                         [(set FP32:$dst,
     32                               (SystemZselect FP32:$src1, FP32:$src2, imm:$cc, PSW))]>;
     33   def SelectF64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, i8imm:$cc),
     34                         "# SelectF64 PSEUDO",
     35                         [(set FP64:$dst,
     36                               (SystemZselect FP64:$src1, FP64:$src2, imm:$cc, PSW))]>;
     37 }
     38 
     39 //===----------------------------------------------------------------------===//
     40 // Move Instructions
     41 
     42 // Floating point constant loads.
     43 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
     44 def LD_Fp032 : Pseudo<(outs FP32:$dst), (ins),
     45                       "lzer\t{$dst}",
     46                       [(set FP32:$dst, fpimm0)]>;
     47 def LD_Fp064 : Pseudo<(outs FP64:$dst), (ins),
     48                       "lzdr\t{$dst}",
     49                       [(set FP64:$dst, fpimm0)]>;
     50 }
     51 
     52 let neverHasSideEffects = 1 in {
     53 def FMOV32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
     54                       "ler\t{$dst, $src}",
     55                       []>;
     56 def FMOV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
     57                       "ldr\t{$dst, $src}",
     58                       []>;
     59 }
     60 
     61 let canFoldAsLoad = 1, isReMaterializable = 1 in {
     62 def FMOV32rm  : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src),
     63                       "le\t{$dst, $src}",
     64                       [(set FP32:$dst, (load rriaddr12:$src))]>;
     65 def FMOV32rmy : Pseudo<(outs FP32:$dst), (ins rriaddr:$src),
     66                       "ley\t{$dst, $src}",
     67                       [(set FP32:$dst, (load rriaddr:$src))]>;
     68 def FMOV64rm  : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src),
     69                       "ld\t{$dst, $src}",
     70                       [(set FP64:$dst, (load rriaddr12:$src))]>;
     71 def FMOV64rmy : Pseudo<(outs FP64:$dst), (ins rriaddr:$src),
     72                       "ldy\t{$dst, $src}",
     73                       [(set FP64:$dst, (load rriaddr:$src))]>;
     74 }
     75 
     76 def FMOV32mr  : Pseudo<(outs), (ins rriaddr12:$dst, FP32:$src),
     77                        "ste\t{$src, $dst}",
     78                        [(store FP32:$src, rriaddr12:$dst)]>;
     79 def FMOV32mry : Pseudo<(outs), (ins rriaddr:$dst, FP32:$src),
     80                        "stey\t{$src, $dst}",
     81                        [(store FP32:$src, rriaddr:$dst)]>;
     82 def FMOV64mr  : Pseudo<(outs), (ins rriaddr12:$dst, FP64:$src),
     83                        "std\t{$src, $dst}",
     84                        [(store FP64:$src, rriaddr12:$dst)]>;
     85 def FMOV64mry : Pseudo<(outs), (ins rriaddr:$dst, FP64:$src),
     86                        "stdy\t{$src, $dst}",
     87                        [(store FP64:$src, rriaddr:$dst)]>;
     88 
     89 def FCOPYSIGN32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
     90                          "cpsdr\t{$dst, $src2, $src1}",
     91                          [(set FP32:$dst, (fcopysign FP32:$src1, FP32:$src2))]>;
     92 def FCOPYSIGN64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
     93                          "cpsdr\t{$dst, $src2, $src1}",
     94                          [(set FP64:$dst, (fcopysign FP64:$src1, FP64:$src2))]>;
     95 
     96 //===----------------------------------------------------------------------===//
     97 // Arithmetic Instructions
     98 
     99 
    100 let Defs = [PSW] in {
    101 def FNEG32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
    102                        "lcebr\t{$dst, $src}",
    103                        [(set FP32:$dst, (fneg FP32:$src)),
    104                         (implicit PSW)]>;
    105 def FNEG64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
    106                        "lcdbr\t{$dst, $src}",
    107                        [(set FP64:$dst, (fneg FP64:$src)),
    108                         (implicit PSW)]>;
    109 
    110 def FABS32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
    111                        "lpebr\t{$dst, $src}",
    112                        [(set FP32:$dst, (fabs FP32:$src)),
    113                         (implicit PSW)]>;
    114 def FABS64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
    115                        "lpdbr\t{$dst, $src}",
    116                        [(set FP64:$dst, (fabs FP64:$src)),
    117                         (implicit PSW)]>;
    118 
    119 def FNABS32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
    120                        "lnebr\t{$dst, $src}",
    121                        [(set FP32:$dst, (fneg(fabs FP32:$src))),
    122                         (implicit PSW)]>;
    123 def FNABS64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
    124                        "lndbr\t{$dst, $src}",
    125                        [(set FP64:$dst, (fneg(fabs FP64:$src))),
    126                         (implicit PSW)]>;
    127 }
    128 
    129 let Constraints = "$src1 = $dst" in {
    130 let Defs = [PSW] in {
    131 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
    132 def FADD32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
    133                        "aebr\t{$dst, $src2}",
    134                        [(set FP32:$dst, (fadd FP32:$src1, FP32:$src2)),
    135                         (implicit PSW)]>;
    136 def FADD64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
    137                        "adbr\t{$dst, $src2}",
    138                        [(set FP64:$dst, (fadd FP64:$src1, FP64:$src2)),
    139                         (implicit PSW)]>;
    140 }
    141 
    142 def FADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
    143                        "aeb\t{$dst, $src2}",
    144                        [(set FP32:$dst, (fadd FP32:$src1, (load rriaddr12:$src2))),
    145                         (implicit PSW)]>;
    146 def FADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
    147                        "adb\t{$dst, $src2}",
    148                        [(set FP64:$dst, (fadd FP64:$src1, (load rriaddr12:$src2))),
    149                         (implicit PSW)]>;
    150 
    151 def FSUB32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
    152                        "sebr\t{$dst, $src2}",
    153                        [(set FP32:$dst, (fsub FP32:$src1, FP32:$src2)),
    154                         (implicit PSW)]>;
    155 def FSUB64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
    156                        "sdbr\t{$dst, $src2}",
    157                        [(set FP64:$dst, (fsub FP64:$src1, FP64:$src2)),
    158                         (implicit PSW)]>;
    159 
    160 def FSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
    161                        "seb\t{$dst, $src2}",
    162                        [(set FP32:$dst, (fsub FP32:$src1, (load rriaddr12:$src2))),
    163                         (implicit PSW)]>;
    164 def FSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
    165                        "sdb\t{$dst, $src2}",
    166                        [(set FP64:$dst, (fsub FP64:$src1, (load rriaddr12:$src2))),
    167                         (implicit PSW)]>;
    168 } // Defs = [PSW]
    169 
    170 let isCommutable = 1 in { // X = MUL Y, Z  == X = MUL Z, Y
    171 def FMUL32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
    172                        "meebr\t{$dst, $src2}",
    173                        [(set FP32:$dst, (fmul FP32:$src1, FP32:$src2))]>;
    174 def FMUL64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
    175                        "mdbr\t{$dst, $src2}",
    176                        [(set FP64:$dst, (fmul FP64:$src1, FP64:$src2))]>;
    177 }
    178 
    179 def FMUL32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
    180                        "meeb\t{$dst, $src2}",
    181                        [(set FP32:$dst, (fmul FP32:$src1, (load rriaddr12:$src2)))]>;
    182 def FMUL64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
    183                        "mdb\t{$dst, $src2}",
    184                        [(set FP64:$dst, (fmul FP64:$src1, (load rriaddr12:$src2)))]>;
    185 
    186 def FMADD32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, FP32:$src3),
    187                        "maebr\t{$dst, $src3, $src2}",
    188                        [(set FP32:$dst, (fadd (fmul FP32:$src2, FP32:$src3),
    189                                               FP32:$src1))]>;
    190 def FMADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2, FP32:$src3),
    191                        "maeb\t{$dst, $src3, $src2}",
    192                        [(set FP32:$dst, (fadd (fmul (load rriaddr12:$src2),
    193                                                      FP32:$src3),
    194                                               FP32:$src1))]>;
    195 
    196 def FMADD64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, FP64:$src3),
    197                        "madbr\t{$dst, $src3, $src2}",
    198                        [(set FP64:$dst, (fadd (fmul FP64:$src2, FP64:$src3),
    199                                               FP64:$src1))]>;
    200 def FMADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2, FP64:$src3),
    201                        "madb\t{$dst, $src3, $src2}",
    202                        [(set FP64:$dst, (fadd (fmul (load rriaddr12:$src2),
    203                                                      FP64:$src3),
    204                                               FP64:$src1))]>;
    205 
    206 def FMSUB32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, FP32:$src3),
    207                        "msebr\t{$dst, $src3, $src2}",
    208                        [(set FP32:$dst, (fsub (fmul FP32:$src2, FP32:$src3),
    209                                               FP32:$src1))]>;
    210 def FMSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2, FP32:$src3),
    211                        "mseb\t{$dst, $src3, $src2}",
    212                        [(set FP32:$dst, (fsub (fmul (load rriaddr12:$src2),
    213                                                      FP32:$src3),
    214                                               FP32:$src1))]>;
    215 
    216 def FMSUB64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, FP64:$src3),
    217                        "msdbr\t{$dst, $src3, $src2}",
    218                        [(set FP64:$dst, (fsub (fmul FP64:$src2, FP64:$src3),
    219                                               FP64:$src1))]>;
    220 def FMSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2, FP64:$src3),
    221                        "msdb\t{$dst, $src3, $src2}",
    222                        [(set FP64:$dst, (fsub (fmul (load rriaddr12:$src2),
    223                                                      FP64:$src3),
    224                                               FP64:$src1))]>;
    225 
    226 def FDIV32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
    227                        "debr\t{$dst, $src2}",
    228                        [(set FP32:$dst, (fdiv FP32:$src1, FP32:$src2))]>;
    229 def FDIV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
    230                        "ddbr\t{$dst, $src2}",
    231                        [(set FP64:$dst, (fdiv FP64:$src1, FP64:$src2))]>;
    232 
    233 def FDIV32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
    234                        "deb\t{$dst, $src2}",
    235                        [(set FP32:$dst, (fdiv FP32:$src1, (load rriaddr12:$src2)))]>;
    236 def FDIV64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
    237                        "ddb\t{$dst, $src2}",
    238                        [(set FP64:$dst, (fdiv FP64:$src1, (load rriaddr12:$src2)))]>;
    239 
    240 } // Constraints = "$src1 = $dst"
    241 
    242 def FSQRT32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
    243                        "sqebr\t{$dst, $src}",
    244                        [(set FP32:$dst, (fsqrt FP32:$src))]>;
    245 def FSQRT64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
    246                        "sqdbr\t{$dst, $src}",
    247                        [(set FP64:$dst, (fsqrt FP64:$src))]>;
    248 
    249 def FSQRT32rm : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src),
    250                        "sqeb\t{$dst, $src}",
    251                        [(set FP32:$dst, (fsqrt (load rriaddr12:$src)))]>;
    252 def FSQRT64rm : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src),
    253                        "sqdb\t{$dst, $src}",
    254                        [(set FP64:$dst, (fsqrt (load rriaddr12:$src)))]>;
    255 
    256 def FROUND64r32 : Pseudo<(outs FP32:$dst), (ins FP64:$src),
    257                          "ledbr\t{$dst, $src}",
    258                          [(set FP32:$dst, (fround FP64:$src))]>;
    259 
    260 def FEXT32r64   : Pseudo<(outs FP64:$dst), (ins FP32:$src),
    261                          "ldebr\t{$dst, $src}",
    262                          [(set FP64:$dst, (fextend FP32:$src))]>;
    263 def FEXT32m64   : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src),
    264                          "ldeb\t{$dst, $src}",
    265                          [(set FP64:$dst, (fextend (load rriaddr12:$src)))]>;
    266 
    267 let Defs = [PSW] in {
    268 def FCONVFP32   : Pseudo<(outs FP32:$dst), (ins GR32:$src),
    269                          "cefbr\t{$dst, $src}",
    270                          [(set FP32:$dst, (sint_to_fp GR32:$src)),
    271                           (implicit PSW)]>;
    272 def FCONVFP32r64: Pseudo<(outs FP32:$dst), (ins GR64:$src),
    273                          "cegbr\t{$dst, $src}",
    274                          [(set FP32:$dst, (sint_to_fp GR64:$src)),
    275                           (implicit PSW)]>;
    276 
    277 def FCONVFP64r32: Pseudo<(outs FP64:$dst), (ins GR32:$src),
    278                          "cdfbr\t{$dst, $src}",
    279                          [(set FP64:$dst, (sint_to_fp GR32:$src)),
    280                           (implicit PSW)]>;
    281 def FCONVFP64   : Pseudo<(outs FP64:$dst), (ins GR64:$src),
    282                          "cdgbr\t{$dst, $src}",
    283                          [(set FP64:$dst, (sint_to_fp GR64:$src)),
    284                           (implicit PSW)]>;
    285 
    286 def FCONVGR32   : Pseudo<(outs GR32:$dst), (ins FP32:$src),
    287                          "cfebr\t{$dst, 5, $src}",
    288                          [(set GR32:$dst, (fp_to_sint FP32:$src)),
    289                           (implicit PSW)]>;
    290 def FCONVGR32r64: Pseudo<(outs GR32:$dst), (ins FP64:$src),
    291                          "cfdbr\t{$dst, 5, $src}",
    292                          [(set GR32:$dst, (fp_to_sint FP64:$src)),
    293                           (implicit PSW)]>;
    294 
    295 def FCONVGR64r32: Pseudo<(outs GR64:$dst), (ins FP32:$src),
    296                          "cgebr\t{$dst, 5, $src}",
    297                          [(set GR64:$dst, (fp_to_sint FP32:$src)),
    298                           (implicit PSW)]>;
    299 def FCONVGR64   : Pseudo<(outs GR64:$dst), (ins FP64:$src),
    300                          "cgdbr\t{$dst, 5, $src}",
    301                          [(set GR64:$dst, (fp_to_sint FP64:$src)),
    302                           (implicit PSW)]>;
    303 } // Defs = [PSW]
    304 
    305 def FBCONVG64   : Pseudo<(outs GR64:$dst), (ins FP64:$src),
    306                          "lgdr\t{$dst, $src}",
    307                          [(set GR64:$dst, (bitconvert FP64:$src))]>;
    308 def FBCONVF64   : Pseudo<(outs FP64:$dst), (ins GR64:$src),
    309                          "ldgr\t{$dst, $src}",
    310                          [(set FP64:$dst, (bitconvert GR64:$src))]>;
    311 
    312 //===----------------------------------------------------------------------===//
    313 // Test instructions (like AND but do not produce any result)
    314 
    315 // Integer comparisons
    316 let Defs = [PSW] in {
    317 def FCMP32rr : Pseudo<(outs), (ins FP32:$src1, FP32:$src2),
    318                       "cebr\t$src1, $src2",
    319                       [(set PSW, (SystemZcmp FP32:$src1, FP32:$src2))]>;
    320 def FCMP64rr : Pseudo<(outs), (ins FP64:$src1, FP64:$src2),
    321                       "cdbr\t$src1, $src2",
    322                       [(set PSW, (SystemZcmp FP64:$src1, FP64:$src2))]>;
    323 
    324 def FCMP32rm : Pseudo<(outs), (ins FP32:$src1, rriaddr12:$src2),
    325                       "ceb\t$src1, $src2",
    326                       [(set PSW, (SystemZcmp FP32:$src1,
    327                                              (load rriaddr12:$src2)))]>;
    328 def FCMP64rm : Pseudo<(outs), (ins FP64:$src1, rriaddr12:$src2),
    329                       "cdb\t$src1, $src2",
    330                       [(set PSW, (SystemZcmp FP64:$src1,
    331                                              (load rriaddr12:$src2)))]>;
    332 } // Defs = [PSW]
    333 
    334 //===----------------------------------------------------------------------===//
    335 // Non-Instruction Patterns
    336 //===----------------------------------------------------------------------===//
    337 
    338 // Floating point constant -0.0
    339 def : Pat<(f32 fpimmneg0), (FNEG32rr (LD_Fp032))>;
    340 def : Pat<(f64 fpimmneg0), (FNEG64rr (LD_Fp064))>;
    341