Implement Calls for V8.  This would be completely autogenerated except for
a small bug in tblgen.  When that is fixed, we can remove the ISD::Call case
in Select.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24830 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td
index 46d1d3a..c9777b9 100644
--- a/lib/Target/Sparc/SparcInstrInfo.td
+++ b/lib/Target/Sparc/SparcInstrInfo.td
@@ -57,6 +57,7 @@
 
 // Branch targets have OtherVT type.
 def brtarget : Operand<OtherVT>;
+def calltarget : Operand<i32>;
 
 def SDTV8cmpicc : 
 SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
@@ -83,6 +84,15 @@
 def V8selecticc : SDNode<"V8ISD::SELECT_ICC", SDTV8selectcc>;
 def V8selectfcc : SDNode<"V8ISD::SELECT_FCC", SDTV8selectcc>;
 
+// These are target-independent nodes, but have target-specific formats.
+def SDT_V8CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
+def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>;
+def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_V8CallSeq, [SDNPHasChain]>;
+
+def SDT_V8Call    : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisVT<1, i32>,
+                                         SDTCisVT<2, FlagVT>]>;
+def call          : SDNode<"ISD::CALL", SDT_V8Call, [SDNPHasChain]>;
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -92,8 +102,12 @@
    : InstV8<ops, asmstr, pattern>;
 
 def PHI : Pseudo<(ops variable_ops), "PHI", []>;
-def ADJCALLSTACKDOWN : Pseudo<(ops i32imm:$amt), "!ADJCALLSTACKDOWN $amt",[]>;
-def ADJCALLSTACKUP : Pseudo<(ops i32imm:$amt), "!ADJCALLSTACKUP $amt", []>;
+def ADJCALLSTACKDOWN : Pseudo<(ops i32imm:$amt),
+                               "!ADJCALLSTACKDOWN $amt",
+                               [(callseq_start imm:$amt)]>;
+def ADJCALLSTACKUP : Pseudo<(ops i32imm:$amt),
+                            "!ADJCALLSTACKUP $amt",
+                            [(callseq_end imm:$amt)]>;
 def IMPLICIT_DEF : Pseudo<(ops IntRegs:$dst), "!IMPLICIT_DEF $dst", []>;
 def FpMOVD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
                     "!FpMOVD", []>;      // pseudo 64-bit double move
@@ -523,23 +537,27 @@
 
 // Section B.24 - Call and Link Instruction, p. 125
 // This is the only Format 1 instruction
-let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1 in { 
+let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1,
+    Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
+    D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { 
   // pc-relative call:
-  let Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
-    D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
-  def CALL : InstV8<(ops IntRegs:$dst), "call $dst", []> {
+  def CALL : InstV8<(ops calltarget:$dst),
+                    "call $dst",
+                  [(set ICC/*bogus*/, (call tglobaladdr:$dst, ICC/*bogus*/))]> {
     bits<30> disp;
     let op = 1;
     let Inst{29-0} = disp;
   }
 
-  // indirect call (O7 is an EXPLICIT def in indirect calls, so it cannot also
-  // be an implicit def):
-  let Defs = [O0, O1, O2, O3, O4, O5, G1, G2, G3, G4, G5, G6, G7,
-    D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
+  // indirect calls
   def JMPLrr : F3_1<2, 0b111000,
-                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
-                    "jmpl $b+$c, $dst", []>;
+                    (ops MEMrr:$ptr),
+                    "jmpl $ptr",
+                    [(set ICC/*bogus*/, (call  ADDRrr:$ptr, ICC/*bogus*/))]>;
+  def JMPLri : F3_2<2, 0b111000,
+                    (ops MEMri:$ptr),
+                    "jmpl $ptr",
+                    [(set ICC/*bogus*/, (call  ADDRri:$ptr, ICC/*bogus*/))]>;
 }
 
 // Section B.28 - Read State Register Instructions