improve encoding information for branches. We now know they have
[oota-llvm.git] / lib / Target / CellSPU / SPUInstrInfo.td
index e1d9228ef93b18e30905c481183606b70638cb2e..f24ffd2f8d4d30d5e23c7ec42b830afddaf9c977 100644 (file)
@@ -30,14 +30,6 @@ let hasCtrlDep = 1, Defs = [R1], Uses = [R1] in {
                                 [(callseq_end timm:$amt)]>;
 }
 
-//===----------------------------------------------------------------------===//
-// DWARF debugging Pseudo Instructions
-//===----------------------------------------------------------------------===//
-
-def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
-           ".loc $file, $line, $col",
-           [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
-
 //===----------------------------------------------------------------------===//
 // Loads:
 // NB: The ordering is actually important, since the instruction selection
@@ -1258,10 +1250,9 @@ multiclass BitwiseAnd
   def fabs32: ANDInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB),
                       [/* Intentionally does not match a pattern */]>;
 
-  def fabs64: ANDInst<(outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB),
+  def fabs64: ANDInst<(outs R64FP:$rT), (ins R64FP:$rA, R64C:$rB),
                       [/* Intentionally does not match a pattern */]>;
 
-  // Could use v4i32, but won't for clarity
   def fabsvec: ANDInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
                        [/* Intentionally does not match a pattern */]>;
 
@@ -1288,10 +1279,11 @@ class ANDCInst<dag OOL, dag IOL, list<dag> pattern>:
     RRForm<0b10000011010, OOL, IOL, "andc\t$rT, $rA, $rB",
            IntegerOp, pattern>;
 
-class ANDCVecInst<ValueType vectype>:
+class ANDCVecInst<ValueType vectype, PatFrag vnot_frag = vnot>:
     ANDCInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
-             [(set (vectype VECREG:$rT), (and (vectype VECREG:$rA),
-                                              (vnot (vectype VECREG:$rB))))]>;
+             [(set (vectype VECREG:$rT),
+                   (and (vectype VECREG:$rA),
+                        (vnot_frag (vectype VECREG:$rB))))]>;
 
 class ANDCRegInst<RegisterClass rclass>:
     ANDCInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB),
@@ -1309,6 +1301,9 @@ multiclass AndComplement
   def r32:  ANDCRegInst<R32C>;
   def r16:  ANDCRegInst<R16C>;
   def r8:   ANDCRegInst<R8C>;
+
+  // Sometimes, the xor pattern has a bitcast constant:
+  def v16i8_conv: ANDCVecInst<v16i8, vnot_conv>;
 }
 
 defm ANDC : AndComplement;
@@ -1784,17 +1779,16 @@ multiclass BitwiseExclusiveOr
   def r16:   XORRegInst<R16C>;
   def r8:    XORRegInst<R8C>;
 
-  // Special forms for floating point instructions.
-  // fneg and fabs require bitwise logical ops to manipulate the sign bit.
+  // XOR instructions used to negate f32 and f64 quantities.
 
   def fneg32: XORInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB),
-                      [/* no pattern */]>;
+                     [/* no pattern */]>;
 
-  def fneg64: XORInst<(outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB),
-                      [/* no pattern */]>;
+  def fneg64: XORInst<(outs R64FP:$rT), (ins R64FP:$rA, R64C:$rB),
+                     [/* no pattern */]>;
 
   def fnegvec: XORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
-                       [/* no pattern, see fneg{32,64} */]>;
+                      [/* no pattern, see fneg{32,64} */]>;
 }
 
 defm XOR : BitwiseExclusiveOr;
@@ -3599,21 +3593,23 @@ def : Pat<(SPUcall (SPUaform texternalsym:$func, 0)),
           (BRASL texternalsym:$func)>;
 
 // Unconditional branches:
-let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
-  def BR :
-    UncondBranch<0b001001100, (outs), (ins brtarget:$dest),
-      "br\t$dest",
-      [(br bb:$dest)]>;
-
-  // Unconditional, absolute address branch
-  def BRA:
-    UncondBranch<0b001100000, (outs), (ins brtarget:$dest),
-      "bra\t$dest",
-      [/* no pattern */]>;
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
+  let isBarrier = 1 in {
+    def BR :
+      UncondBranch<0b001001100, (outs), (ins brtarget:$dest),
+        "br\t$dest",
+        [(br bb:$dest)]>;
+
+    // Unconditional, absolute address branch
+    def BRA:
+      UncondBranch<0b001100000, (outs), (ins brtarget:$dest),
+        "bra\t$dest",
+        [/* no pattern */]>;
 
-  // Indirect branch
-  def BI:
-    BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>;
+    // Indirect branch
+    def BI:
+      BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>;
+  }
 
   // Conditional branches:
   class BRNZInst<dag IOL, list<dag> pattern>:
@@ -4239,33 +4235,36 @@ def FMSv2f64 :
             (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)),
                   (v2f64 VECREG:$rC)))]>;
 
-// FNMS: - (a * b - c)
+// DFNMS: - (a * b - c)
 // - (a * b) + c => c - (a * b)
-def FNMSf64 :
-    RRForm<0b01111010110, (outs R64FP:$rT),
-                          (ins R64FP:$rA, R64FP:$rB, R64FP:$rC),
-      "dfnms\t$rT, $rA, $rB", DPrecFP,
-      [(set R64FP:$rT, (fsub R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB)))]>,
+
+class DFNMSInst<dag OOL, dag IOL, list<dag> pattern>:
+    RRForm<0b01111010110, OOL, IOL, "dfnms\t$rT, $rA, $rB",
+           DPrecFP, pattern>,
     RegConstraint<"$rC = $rT">,
     NoEncode<"$rC">;
 
-def : Pat<(fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)),
-          (FNMSf64 R64FP:$rA, R64FP:$rB, R64FP:$rC)>;
+class DFNMSVecInst<list<dag> pattern>:
+    DFNMSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
+              pattern>;
 
-def FNMSv2f64 :
-    RRForm<0b01111010110, (outs VECREG:$rT),
-                          (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
-      "dfnms\t$rT, $rA, $rB", DPrecFP,
-      [(set (v2f64 VECREG:$rT),
-            (fsub (v2f64 VECREG:$rC),
-                  (fmul (v2f64 VECREG:$rA),
-                        (v2f64 VECREG:$rB))))]>,
-    RegConstraint<"$rC = $rT">,
-    NoEncode<"$rC">;
+class DFNMSRegInst<list<dag> pattern>:
+    DFNMSInst<(outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB, R64FP:$rC),
+             pattern>;
+
+multiclass DFMultiplySubtract
+{
+  def v2f64 : DFNMSVecInst<[(set (v2f64 VECREG:$rT), 
+                                 (fsub (v2f64 VECREG:$rC),
+                                       (fmul (v2f64 VECREG:$rA),
+                                             (v2f64 VECREG:$rB))))]>;
+
+  def f64 : DFNMSRegInst<[(set R64FP:$rT,
+                               (fsub R64FP:$rC,
+                                     (fmul R64FP:$rA, R64FP:$rB)))]>;
+}
 
-def : Pat<(fneg (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)),
-                (v2f64 VECREG:$rC))),
-          (FNMSv2f64 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
+defm DFNMS : DFMultiplySubtract;
 
 // - (a * b + c)
 // - (a * b) - c
@@ -4299,29 +4298,15 @@ def : Pat<(fneg (v4f32 VECREG:$rA)),
 def : Pat<(fneg R32FP:$rA),
           (XORfneg32 R32FP:$rA, (ILHUr32 0x8000))>;
 
-def : Pat<(fneg (v2f64 VECREG:$rA)),
-          (XORfnegvec (v2f64 VECREG:$rA),
-                      (v2f64 (ANDBIv16i8 (FSMBIv16i8 0x8080), 0x80)))>;
-
-def : Pat<(fneg R64FP:$rA),
-          (XORfneg64 R64FP:$rA,
-                     (ANDBIv16i8 (FSMBIv16i8 0x8080), 0x80))>;
-
 // Floating point absolute value
+// Note: f64 fabs is custom-selected.
 
 def : Pat<(fabs R32FP:$rA),
           (ANDfabs32 R32FP:$rA, (IOHLr32 (ILHUr32 0x7fff), 0xffff))>;
 
 def : Pat<(fabs (v4f32 VECREG:$rA)),
           (ANDfabsvec (v4f32 VECREG:$rA),
-                      (v4f32 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>;
-
-def : Pat<(fabs R64FP:$rA),
-          (ANDfabs64 R64FP:$rA, (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f))>;
-
-def : Pat<(fabs (v2f64 VECREG:$rA)),
-          (ANDfabsvec (v2f64 VECREG:$rA),
-                      (v2f64 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>;
+                      (IOHLv4i32 (ILHUv4i32 0x7fff), 0xffff))>;
 
 //===----------------------------------------------------------------------===//
 // Hint for branch instructions:
@@ -4439,13 +4424,6 @@ def : Pat<(v4i32 v4i32Imm:$imm),
 def : Pat<(i8 imm:$imm),
           (ILHr8 imm:$imm)>;
 
-//===----------------------------------------------------------------------===//
-// Call instruction patterns:
-//===----------------------------------------------------------------------===//
-// Return void
-def : Pat<(ret),
-          (RET)>;
-
 //===----------------------------------------------------------------------===//
 // Zero/Any/Sign extensions
 //===----------------------------------------------------------------------===//