Add preliminary v2f32 support for SPU. Like with v2i32, we just
authorKalle Raiskila <kalle.raiskila@nokia.com>
Mon, 2 Aug 2010 10:25:47 +0000 (10:25 +0000)
committerKalle Raiskila <kalle.raiskila@nokia.com>
Mon, 2 Aug 2010 10:25:47 +0000 (10:25 +0000)
duplicate the instructions and operate on half vectors.

Also reorder code in SPUInstrInfo.td for better coherency.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110037 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/CellSPU/SPUCallingConv.td
lib/Target/CellSPU/SPUISelLowering.cpp
lib/Target/CellSPU/SPUInstrInfo.td
lib/Target/CellSPU/SPURegisterInfo.td
test/CodeGen/CellSPU/v2f32.ll [new file with mode: 0644]

index 047eeb4f1b72284aa8761fb7cb95b983095865c2..1c9e5184c6422f00f70c49b4cb05ccec0b40955a 100644 (file)
@@ -28,7 +28,7 @@ def RetCC_SPU : CallingConv<[
   CCIfType<[i128],     CCAssignToReg<[R3]>>,
   CCIfType<[f32, f64], CCAssignToReg<[R3]>>,
   CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[R3]>>,
-  CCIfType<[v2i32],                                    CCAssignToReg<[R3]>>
+  CCIfType<[v2i32, v2f32],                             CCAssignToReg<[R3]>>
 ]>;
 
 
@@ -37,7 +37,7 @@ def RetCC_SPU : CallingConv<[
 //===----------------------------------------------------------------------===//
 def CCC_SPU : CallingConv<[
   CCIfType<[i8, i16, i32, i64, i128, f32, f64, 
-            v16i8, v8i16, v4i32, v4f32, v2i64, v2f64, v2i32],
+            v16i8, v8i16, v4i32, v4f32, v2i64, v2f64, v2i32, v2f32],
             CCAssignToReg<[R3,   R4,  R5,  R6,  R7,  R8,  R9, R10, R11,
                            R12, R13, R14, R15, R16, R17, R18, R19, R20,
                            R21, R22, R23, R24, R25, R26, R27, R28, R29,
index bcde5794af85a392bd84761c580576d97873561e..83726f2ea540e2cd8406cce41c6904d18f4eaf90 100644 (file)
@@ -428,6 +428,7 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
 
   // "Odd size" vector classes that we're willing to support:
   addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
+  addRegisterClass(MVT::v2f32, SPU::VECREGRegisterClass);
 
   for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
        i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
@@ -1068,6 +1069,7 @@ SPUTargetLowering::LowerFormalArguments(SDValue Chain,
       case MVT::v8i16:
       case MVT::v16i8:
       case MVT::v2i32:
+      case MVT::v2f32:
         ArgRegClass = &SPU::VECREGRegClass;
         break;
       }
index bc9668a8097e457b7797539f996074e9803cb4fc..96b0d5070b0c19e8f0ded4ea123c221b7408107a 100644 (file)
@@ -3892,6 +3892,7 @@ class FAVecInst<ValueType vectype>:
 multiclass SFPAdd
 {
   def v4f32: FAVecInst<v4f32>;
+  def v2f32: FAVecInst<v2f32>;
   def f32:   FAInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
                     [(set R32FP:$rT, (fadd R32FP:$rA, R32FP:$rB))]>;
 }
@@ -3910,12 +3911,87 @@ class FSVecInst<ValueType vectype>:
 multiclass SFPSub
 {
   def v4f32: FSVecInst<v4f32>;
+  def v2f32: FSVecInst<v2f32>;
   def f32:   FSInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
                     [(set R32FP:$rT, (fsub R32FP:$rA, R32FP:$rB))]>;
 }
 
 defm FS : SFPSub;
 
+class FMInst<dag OOL, dag IOL, list<dag> pattern>:
+    RRForm<0b01100011010, OOL, IOL,
+      "fm\t$rT, $rA, $rB", SPrecFP,
+      pattern>;
+
+class FMVecInst<ValueType type>:
+    FMInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
+           [(set (type VECREG:$rT),
+                 (fmul (type VECREG:$rA), (type VECREG:$rB)))]>;
+
+multiclass SFPMul
+{
+  def v4f32: FMVecInst<v4f32>;
+  def v2f32: FMVecInst<v2f32>;
+  def f32:   FMInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
+                     [(set R32FP:$rT, (fmul R32FP:$rA, R32FP:$rB))]>; 
+}
+
+defm FM : SFPMul;
+
+// Floating point multiply and add
+// e.g. d = c + (a * b)
+def FMAv4f32:
+    RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
+      "fma\t$rT, $rA, $rB, $rC", SPrecFP,
+      [(set (v4f32 VECREG:$rT),
+            (fadd (v4f32 VECREG:$rC),
+                  (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB))))]>;
+
+def FMAf32:
+    RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
+      "fma\t$rT, $rA, $rB, $rC", SPrecFP,
+      [(set R32FP:$rT, (fadd R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>;
+
+// FP multiply and subtract
+// Subtracts value in rC from product
+// res = a * b - c
+def FMSv4f32 :
+    RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
+      "fms\t$rT, $rA, $rB, $rC", SPrecFP,
+      [(set (v4f32 VECREG:$rT),
+            (fsub (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)),
+                  (v4f32 VECREG:$rC)))]>;
+
+def FMSf32 :
+    RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
+      "fms\t$rT, $rA, $rB, $rC", SPrecFP,
+      [(set R32FP:$rT,
+            (fsub (fmul R32FP:$rA, R32FP:$rB), R32FP:$rC))]>;
+
+// Floating Negative Mulitply and Subtract
+// Subtracts product from value in rC
+// res = fneg(fms a b c)
+//     = - (a * b - c)
+//     = c - a * b
+// NOTE: subtraction order
+// fsub a b = a - b
+// fs a b = b - a?
+def FNMSf32 :
+    RRRForm<0b1101, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
+      "fnms\t$rT, $rA, $rB, $rC", SPrecFP,
+      [(set R32FP:$rT, (fsub R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>;
+
+def FNMSv4f32 :
+    RRRForm<0b1101, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
+      "fnms\t$rT, $rA, $rB, $rC", SPrecFP,
+      [(set (v4f32 VECREG:$rT),
+            (fsub (v4f32 VECREG:$rC),
+                  (fmul (v4f32 VECREG:$rA),
+                        (v4f32 VECREG:$rB))))]>;
+
+
+
+
 // Floating point reciprocal estimate
 
 class FRESTInst<dag OOL, dag IOL>:
@@ -4040,72 +4116,6 @@ def FSCRRf32 :
 // status and control register write
 // status and control register read
 
-//--------------------------------------
-// Floating point multiply instructions
-//--------------------------------------
-
-def FMv4f32:
-    RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
-      "fm\t$rT, $rA, $rB", SPrecFP,
-      [(set (v4f32 VECREG:$rT), (fmul (v4f32 VECREG:$rA),
-                                      (v4f32 VECREG:$rB)))]>;
-
-def FMf32 :
-    RRForm<0b01100011010, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
-      "fm\t$rT, $rA, $rB", SPrecFP,
-      [(set R32FP:$rT, (fmul R32FP:$rA, R32FP:$rB))]>;
-
-// Floating point multiply and add
-// e.g. d = c + (a * b)
-def FMAv4f32:
-    RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
-      "fma\t$rT, $rA, $rB, $rC", SPrecFP,
-      [(set (v4f32 VECREG:$rT),
-            (fadd (v4f32 VECREG:$rC),
-                  (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB))))]>;
-
-def FMAf32:
-    RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
-      "fma\t$rT, $rA, $rB, $rC", SPrecFP,
-      [(set R32FP:$rT, (fadd R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>;
-
-// FP multiply and subtract
-// Subtracts value in rC from product
-// res = a * b - c
-def FMSv4f32 :
-    RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
-      "fms\t$rT, $rA, $rB, $rC", SPrecFP,
-      [(set (v4f32 VECREG:$rT),
-            (fsub (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)),
-                  (v4f32 VECREG:$rC)))]>;
-
-def FMSf32 :
-    RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
-      "fms\t$rT, $rA, $rB, $rC", SPrecFP,
-      [(set R32FP:$rT,
-            (fsub (fmul R32FP:$rA, R32FP:$rB), R32FP:$rC))]>;
-
-// Floating Negative Mulitply and Subtract
-// Subtracts product from value in rC
-// res = fneg(fms a b c)
-//     = - (a * b - c)
-//     = c - a * b
-// NOTE: subtraction order
-// fsub a b = a - b
-// fs a b = b - a?
-def FNMSf32 :
-    RRRForm<0b1101, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
-      "fnms\t$rT, $rA, $rB, $rC", SPrecFP,
-      [(set R32FP:$rT, (fsub R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>;
-
-def FNMSv4f32 :
-    RRRForm<0b1101, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
-      "fnms\t$rT, $rA, $rB, $rC", SPrecFP,
-      [(set (v4f32 VECREG:$rT),
-            (fsub (v4f32 VECREG:$rC),
-                  (fmul (v4f32 VECREG:$rA),
-                        (v4f32 VECREG:$rB))))]>;
-
 //--------------------------------------
 // Floating Point Conversions
 // Signed conversions:
index bb88f2bf9a2986b1a7168778d4db585bd76e12fb..dd09d50412e867719c8ae8d94c72cd1da5c8e49f 100644 (file)
@@ -394,7 +394,7 @@ def R8C : RegisterClass<"SPU", [i8], 128,
 
 // The SPU's registers as vector registers:
 def VECREG : RegisterClass<"SPU",
-                           [v16i8,v8i16,v2i32,v4i32,v4f32,v2i64,v2f64],
+                           [v16i8,v8i16,v2i32,v2f32,v4i32,v4f32,v2i64,v2f64],
                            128,
  [
    /* volatile register */
diff --git a/test/CodeGen/CellSPU/v2f32.ll b/test/CodeGen/CellSPU/v2f32.ll
new file mode 100644 (file)
index 0000000..2631777
--- /dev/null
@@ -0,0 +1,35 @@
+;RUN: llc --march=cellspu %s -o - | FileCheck %s
+%vec = type <2 x float>
+
+define %vec @test_ret(%vec %param)
+{
+;CHECK: bi $lr
+ ret %vec %param
+}
+
+define %vec @test_add(%vec %param)
+{
+;CHECK: fa $3, $3, $3
+ %1 = fadd %vec %param, %param
+;CHECK: bi $lr
+ ret %vec %1
+}
+
+define %vec @test_sub(%vec %param)
+{
+;CHECK: fs $3, $3, $3
+ %1 = fsub %vec %param, %param
+
+;CHECK: bi $lr
+ ret %vec %1
+}
+
+define %vec @test_mul(%vec %param)
+{
+;CHECK: fm $3, $3, $3
+ %1 = fmul %vec %param, %param
+
+;CHECK: bi $lr
+ ret %vec %1
+}
+