The BLX instruction is encoded differently than the BL, because why not? In
[oota-llvm.git] / lib / Target / SystemZ / SystemZInstrFP.td
index 9e367fe43a583bb64b9ab57f82bcfca9de186ce4..a65828061d3bc02066e8671c184c45af56580069 100644 (file)
@@ -25,15 +25,15 @@ def fpimmneg0 : PatLeaf<(fpimm), [{
   return N->isExactlyValue(-0.0);
 }]>;
 
-let usesCustomDAGSchedInserter = 1 in {
+let Uses = [PSW], usesCustomInserter = 1 in {
   def SelectF32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, i8imm:$cc),
                         "# SelectF32 PSEUDO",
                         [(set FP32:$dst,
-                              (SystemZselect FP32:$src1, FP32:$src2, imm:$cc))]>;
+                              (SystemZselect FP32:$src1, FP32:$src2, imm:$cc, PSW))]>;
   def SelectF64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, i8imm:$cc),
                         "# SelectF64 PSEUDO",
                         [(set FP64:$dst,
-                              (SystemZselect FP64:$src1, FP64:$src2, imm:$cc))]>;
+                              (SystemZselect FP64:$src1, FP64:$src2, imm:$cc, PSW))]>;
 }
 
 //===----------------------------------------------------------------------===//
@@ -58,7 +58,7 @@ def FMOV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
                       []>;
 }
 
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
+let canFoldAsLoad = 1, isReMaterializable = 1 in {
 def FMOV32rm  : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src),
                       "le\t{$dst, $src}",
                       [(set FP32:$dst, (load rriaddr12:$src))]>;
@@ -86,6 +86,13 @@ def FMOV64mry : Pseudo<(outs), (ins rriaddr:$dst, FP64:$src),
                        "stdy\t{$src, $dst}",
                        [(store FP64:$src, rriaddr:$dst)]>;
 
+def FCOPYSIGN32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
+                         "cpsdr\t{$dst, $src2, $src1}",
+                         [(set FP32:$dst, (fcopysign FP32:$src1, FP32:$src2))]>;
+def FCOPYSIGN64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
+                         "cpsdr\t{$dst, $src2, $src1}",
+                         [(set FP64:$dst, (fcopysign FP64:$src1, FP64:$src2))]>;
+
 //===----------------------------------------------------------------------===//
 // Arithmetic Instructions
 
@@ -119,7 +126,7 @@ def FNABS64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
                         (implicit PSW)]>;
 }
 
-let isTwoAddress = 1 in {
+let Constraints = "$src1 = $dst" in {
 let Defs = [PSW] in {
 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
 def FADD32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
@@ -132,13 +139,13 @@ def FADD64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
                         (implicit PSW)]>;
 }
 
-def FADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2),
+def FADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
                        "aeb\t{$dst, $src2}",
-                       [(set FP32:$dst, (fadd FP32:$src1, (load rriaddr:$src2))),
+                       [(set FP32:$dst, (fadd FP32:$src1, (load rriaddr12:$src2))),
                         (implicit PSW)]>;
-def FADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2),
+def FADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
                        "adb\t{$dst, $src2}",
-                       [(set FP64:$dst, (fadd FP64:$src1, (load rriaddr:$src2))),
+                       [(set FP64:$dst, (fadd FP64:$src1, (load rriaddr12:$src2))),
                         (implicit PSW)]>;
 
 def FSUB32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
@@ -150,13 +157,13 @@ def FSUB64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
                        [(set FP64:$dst, (fsub FP64:$src1, FP64:$src2)),
                         (implicit PSW)]>;
 
-def FSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2),
+def FSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
                        "seb\t{$dst, $src2}",
-                       [(set FP32:$dst, (fsub FP32:$src1, (load rriaddr:$src2))),
+                       [(set FP32:$dst, (fsub FP32:$src1, (load rriaddr12:$src2))),
                         (implicit PSW)]>;
-def FSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2),
+def FSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
                        "sdb\t{$dst, $src2}",
-                       [(set FP64:$dst, (fsub FP64:$src1, (load rriaddr:$src2))),
+                       [(set FP64:$dst, (fsub FP64:$src1, (load rriaddr12:$src2))),
                         (implicit PSW)]>;
 } // Defs = [PSW]
 
@@ -169,20 +176,20 @@ def FMUL64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
                        [(set FP64:$dst, (fmul FP64:$src1, FP64:$src2))]>;
 }
 
-def FMUL32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2),
+def FMUL32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
                        "meeb\t{$dst, $src2}",
-                       [(set FP32:$dst, (fmul FP32:$src1, (load rriaddr:$src2)))]>;
-def FMUL64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2),
+                       [(set FP32:$dst, (fmul FP32:$src1, (load rriaddr12:$src2)))]>;
+def FMUL64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
                        "mdb\t{$dst, $src2}",
-                       [(set FP64:$dst, (fmul FP64:$src1, (load rriaddr:$src2)))]>;
+                       [(set FP64:$dst, (fmul FP64:$src1, (load rriaddr12:$src2)))]>;
 
 def FMADD32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, FP32:$src3),
                        "maebr\t{$dst, $src3, $src2}",
                        [(set FP32:$dst, (fadd (fmul FP32:$src2, FP32:$src3),
                                               FP32:$src1))]>;
-def FMADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2, FP32:$src3),
+def FMADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2, FP32:$src3),
                        "maeb\t{$dst, $src3, $src2}",
-                       [(set FP32:$dst, (fadd (fmul (load rriaddr:$src2),
+                       [(set FP32:$dst, (fadd (fmul (load rriaddr12:$src2),
                                                      FP32:$src3),
                                               FP32:$src1))]>;
 
@@ -190,9 +197,9 @@ def FMADD64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, FP64:$src3
                        "madbr\t{$dst, $src3, $src2}",
                        [(set FP64:$dst, (fadd (fmul FP64:$src2, FP64:$src3),
                                               FP64:$src1))]>;
-def FMADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2, FP64:$src3),
+def FMADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2, FP64:$src3),
                        "madb\t{$dst, $src3, $src2}",
-                       [(set FP64:$dst, (fadd (fmul (load rriaddr:$src2),
+                       [(set FP64:$dst, (fadd (fmul (load rriaddr12:$src2),
                                                      FP64:$src3),
                                               FP64:$src1))]>;
 
@@ -200,9 +207,9 @@ def FMSUB32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, FP32:$src3
                        "msebr\t{$dst, $src3, $src2}",
                        [(set FP32:$dst, (fsub (fmul FP32:$src2, FP32:$src3),
                                               FP32:$src1))]>;
-def FMSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2, FP32:$src3),
+def FMSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2, FP32:$src3),
                        "mseb\t{$dst, $src3, $src2}",
-                       [(set FP32:$dst, (fsub (fmul (load rriaddr:$src2),
+                       [(set FP32:$dst, (fsub (fmul (load rriaddr12:$src2),
                                                      FP32:$src3),
                                               FP32:$src1))]>;
 
@@ -210,9 +217,9 @@ def FMSUB64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, FP64:$src3
                        "msdbr\t{$dst, $src3, $src2}",
                        [(set FP64:$dst, (fsub (fmul FP64:$src2, FP64:$src3),
                                               FP64:$src1))]>;
-def FMSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2, FP64:$src3),
+def FMSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2, FP64:$src3),
                        "msdb\t{$dst, $src3, $src2}",
-                       [(set FP64:$dst, (fsub (fmul (load rriaddr:$src2),
+                       [(set FP64:$dst, (fsub (fmul (load rriaddr12:$src2),
                                                      FP64:$src3),
                                               FP64:$src1))]>;
 
@@ -223,14 +230,14 @@ def FDIV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
                        "ddbr\t{$dst, $src2}",
                        [(set FP64:$dst, (fdiv FP64:$src1, FP64:$src2))]>;
 
-def FDIV32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2),
+def FDIV32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
                        "deb\t{$dst, $src2}",
-                       [(set FP32:$dst, (fdiv FP32:$src1, (load rriaddr:$src2)))]>;
-def FDIV64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2),
+                       [(set FP32:$dst, (fdiv FP32:$src1, (load rriaddr12:$src2)))]>;
+def FDIV64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
                        "ddb\t{$dst, $src2}",
-                       [(set FP64:$dst, (fdiv FP64:$src1, (load rriaddr:$src2)))]>;
+                       [(set FP64:$dst, (fdiv FP64:$src1, (load rriaddr12:$src2)))]>;
 
-} // isTwoAddress = 1
+} // Constraints = "$src1 = $dst"
 
 def FSQRT32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
                        "sqebr\t{$dst, $src}",
@@ -239,12 +246,12 @@ def FSQRT64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
                        "sqdbr\t{$dst, $src}",
                        [(set FP64:$dst, (fsqrt FP64:$src))]>;
 
-def FSQRT32rm : Pseudo<(outs FP32:$dst), (ins rriaddr:$src),
+def FSQRT32rm : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src),
                        "sqeb\t{$dst, $src}",
-                       [(set FP32:$dst, (fsqrt (load rriaddr:$src)))]>;
-def FSQRT64rm : Pseudo<(outs FP64:$dst), (ins rriaddr:$src),
+                       [(set FP32:$dst, (fsqrt (load rriaddr12:$src)))]>;
+def FSQRT64rm : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src),
                        "sqdb\t{$dst, $src}",
-                       [(set FP64:$dst, (fsqrt (load rriaddr:$src)))]>;
+                       [(set FP64:$dst, (fsqrt (load rriaddr12:$src)))]>;
 
 def FROUND64r32 : Pseudo<(outs FP32:$dst), (ins FP64:$src),
                          "ledbr\t{$dst, $src}",
@@ -253,9 +260,9 @@ def FROUND64r32 : Pseudo<(outs FP32:$dst), (ins FP64:$src),
 def FEXT32r64   : Pseudo<(outs FP64:$dst), (ins FP32:$src),
                          "ldebr\t{$dst, $src}",
                          [(set FP64:$dst, (fextend FP32:$src))]>;
-def FEXT32m64   : Pseudo<(outs FP64:$dst), (ins rriaddr:$src),
+def FEXT32m64   : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src),
                          "ldeb\t{$dst, $src}",
-                         [(set FP64:$dst, (fextend (load rriaddr:$src)))]>;
+                         [(set FP64:$dst, (fextend (load rriaddr12:$src)))]>;
 
 let Defs = [PSW] in {
 def FCONVFP32   : Pseudo<(outs FP32:$dst), (ins GR32:$src),
@@ -281,12 +288,12 @@ def FCONVGR32   : Pseudo<(outs GR32:$dst), (ins FP32:$src),
                          [(set GR32:$dst, (fp_to_sint FP32:$src)),
                           (implicit PSW)]>;
 def FCONVGR32r64: Pseudo<(outs GR32:$dst), (ins FP64:$src),
-                         "cgebr\t{$dst, 5, $src}",
+                         "cfdbr\t{$dst, 5, $src}",
                          [(set GR32:$dst, (fp_to_sint FP64:$src)),
                           (implicit PSW)]>;
 
 def FCONVGR64r32: Pseudo<(outs GR64:$dst), (ins FP32:$src),
-                         "cfdbr\t{$dst, 5, $src}",
+                         "cgebr\t{$dst, 5, $src}",
                          [(set GR64:$dst, (fp_to_sint FP32:$src)),
                           (implicit PSW)]>;
 def FCONVGR64   : Pseudo<(outs GR64:$dst), (ins FP64:$src),
@@ -295,6 +302,13 @@ def FCONVGR64   : Pseudo<(outs GR64:$dst), (ins FP64:$src),
                           (implicit PSW)]>;
 } // Defs = [PSW]
 
+def FBCONVG64   : Pseudo<(outs GR64:$dst), (ins FP64:$src),
+                         "lgdr\t{$dst, $src}",
+                         [(set GR64:$dst, (bitconvert FP64:$src))]>;
+def FBCONVF64   : Pseudo<(outs FP64:$dst), (ins GR64:$src),
+                         "ldgr\t{$dst, $src}",
+                         [(set FP64:$dst, (bitconvert GR64:$src))]>;
+
 //===----------------------------------------------------------------------===//
 // Test instructions (like AND but do not produce any result)
 
@@ -302,19 +316,19 @@ def FCONVGR64   : Pseudo<(outs GR64:$dst), (ins FP64:$src),
 let Defs = [PSW] in {
 def FCMP32rr : Pseudo<(outs), (ins FP32:$src1, FP32:$src2),
                       "cebr\t$src1, $src2",
-                      [(SystemZcmp FP32:$src1, FP32:$src2), (implicit PSW)]>;
+                      [(set PSW, (SystemZcmp FP32:$src1, FP32:$src2))]>;
 def FCMP64rr : Pseudo<(outs), (ins FP64:$src1, FP64:$src2),
                       "cdbr\t$src1, $src2",
-                      [(SystemZcmp FP64:$src1, FP64:$src2), (implicit PSW)]>;
+                      [(set PSW, (SystemZcmp FP64:$src1, FP64:$src2))]>;
 
-def FCMP32rm : Pseudo<(outs), (ins FP32:$src1, rriaddr:$src2),
+def FCMP32rm : Pseudo<(outs), (ins FP32:$src1, rriaddr12:$src2),
                       "ceb\t$src1, $src2",
-                      [(SystemZcmp FP32:$src1, (load rriaddr:$src2)),
-                       (implicit PSW)]>;
-def FCMP64rm : Pseudo<(outs), (ins FP64:$src1, rriaddr:$src2),
+                      [(set PSW, (SystemZcmp FP32:$src1,
+                                             (load rriaddr12:$src2)))]>;
+def FCMP64rm : Pseudo<(outs), (ins FP64:$src1, rriaddr12:$src2),
                       "cdb\t$src1, $src2",
-                      [(SystemZcmp FP64:$src1, (load rriaddr:$src2)),
-                       (implicit PSW)]>;
+                      [(set PSW, (SystemZcmp FP64:$src1,
+                                             (load rriaddr12:$src2)))]>;
 } // Defs = [PSW]
 
 //===----------------------------------------------------------------------===//