1Pull in r198909 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3  [Sparc] Add support for parsing jmpl instruction and make indirect call and jmp instructions as aliases to jmpl.
4
5Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
8===================================================================
9--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
10+++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
11@@ -453,6 +453,7 @@ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand
12   switch (getLexer().getKind()) {
13   default: return MatchOperand_NoMatch;
14 
15+  case AsmToken::Comma:
16   case AsmToken::RBrac:
17   case AsmToken::EndOfStatement:
18     Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
19Index: lib/Target/Sparc/SparcInstrAliases.td
20===================================================================
21--- lib/Target/Sparc/SparcInstrAliases.td
22+++ lib/Target/Sparc/SparcInstrAliases.td
23@@ -117,3 +117,14 @@ defm : fp_cond_alias<"uge",   0b1100>;
24 defm : fp_cond_alias<"le",    0b1101>;
25 defm : fp_cond_alias<"ule",   0b1110>;
26 defm : fp_cond_alias<"o",     0b1111>;
27+
28+
29+// Instruction aliases for JMPL.
30+
31+// jmp addr -> jmpl addr, %g0
32+def : InstAlias<"jmp $addr", (JMPLrr G0, MEMrr:$addr)>;
33+def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$addr)>;
34+
35+// call addr -> jmpl addr, %o7
36+def : InstAlias<"call $addr", (JMPLrr O7, MEMrr:$addr)>;
37+def : InstAlias<"call $addr", (JMPLri O7, MEMri:$addr)>;
38Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
39===================================================================
40--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
41+++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
42@@ -23,6 +23,7 @@
43 using namespace llvm;
44 
45 #define GET_INSTRUCTION_NAME
46+#define PRINT_ALIAS_INSTR
47 #include "SparcGenAsmWriter.inc"
48 
49 void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
50@@ -33,10 +34,34 @@ void SparcInstPrinter::printRegName(raw_ostream &O
51 void SparcInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
52                                StringRef Annot)
53 {
54-  printInstruction(MI, O);
55+  if (!printAliasInstr(MI, O) && !printSparcAliasInstr(MI, O))
56+    printInstruction(MI, O);
57   printAnnotation(O, Annot);
58 }
59 
60+bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O)
61+{
62+  switch (MI->getOpcode()) {
63+  default: return false;
64+  case SP::JMPLrr:
65+  case SP::JMPLri: {
66+    if (MI->getNumOperands() != 3)
67+      return false;
68+    if (!MI->getOperand(0).isReg())
69+      return false;
70+    switch (MI->getOperand(0).getReg()) {
71+    default: return false;
72+    case SP::G0: // jmp $addr
73+      O << "\tjmp "; printMemOperand(MI, 1, O);
74+      return true;
75+    case SP::O7: // call $addr
76+      O << "\tcall "; printMemOperand(MI, 1, O);
77+      return true;
78+    }
79+  }
80+  }
81+}
82+
83 void SparcInstPrinter::printOperand(const MCInst *MI, int opNum,
84                                     raw_ostream &O)
85 {
86Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
87===================================================================
88--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
89+++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
90@@ -29,9 +29,11 @@ class SparcInstPrinter : public MCInstPrinter {
91 
92   virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
93   virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
94+  bool printSparcAliasInstr(const MCInst *MI, raw_ostream &OS);
95 
96   // Autogenerated by tblgen.
97   void printInstruction(const MCInst *MI, raw_ostream &O);
98+  bool printAliasInstr(const MCInst *MI, raw_ostream &O);
99   static const char *getRegisterName(unsigned RegNo);
100 
101   void printOperand(const MCInst *MI, int opNum, raw_ostream &OS);
102Index: lib/Target/Sparc/SparcInstrInfo.td
103===================================================================
104--- lib/Target/Sparc/SparcInstrInfo.td
105+++ lib/Target/Sparc/SparcInstrInfo.td
106@@ -362,10 +362,18 @@ let usesCustomInserter = 1, Uses = [FCC] in {
107             [(set f128:$dst, (SPselectfcc f128:$T, f128:$F, imm:$Cond))]>;
108 }
109 
110+// JMPL Instruction.
111+let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in {
112+  def JMPLrr: F3_1<2, 0b111000, (outs IntRegs:$dst), (ins MEMrr:$addr),
113+                  "jmpl $addr, $dst", []>;
114+  def JMPLri: F3_2<2, 0b111000, (outs IntRegs:$dst), (ins MEMri:$addr),
115+                  "jmpl $addr, $dst", []>;
116+}
117 
118 // Section A.3 - Synthetic Instructions, p. 85
119 // special cases of JMPL:
120-let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in {
121+let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
122+    isCodeGenOnly = 1 in {
123   let rd = 0, rs1 = 15 in
124     def RETL: F3_2<2, 0b111000, (outs), (ins i32imm:$val),
125                    "jmp %o7+$val", [(retflag simm13:$val)]>;
126@@ -519,9 +527,8 @@ class BranchSP<dag ins, string asmstr, list<dag> p
127 }
128 
129 // Indirect branch instructions.
130-let isTerminator = 1, isBarrier = 1,
131-     hasDelaySlot = 1, isBranch =1,
132-     isIndirectBranch = 1, rd = 0 in {
133+let isTerminator = 1, isBarrier = 1,  hasDelaySlot = 1, isBranch =1,
134+     isIndirectBranch = 1, rd = 0, isCodeGenOnly = 1 in {
135   def BINDrr  : F3_1<2, 0b111000,
136                    (outs), (ins MEMrr:$ptr),
137                    "jmp $ptr",
138@@ -564,15 +571,17 @@ let Uses = [O6],
139     let Inst{29-0} = disp;
140   }
141 
142-  // indirect calls
143-  def JMPLrr : F3_1<2, 0b111000,
144-                    (outs), (ins MEMrr:$ptr, variable_ops),
145-                    "call $ptr",
146-                    [(call ADDRrr:$ptr)]> { let rd = 15; }
147-  def JMPLri : F3_2<2, 0b111000,
148-                    (outs), (ins MEMri:$ptr, variable_ops),
149-                    "call $ptr",
150-                    [(call ADDRri:$ptr)]> { let rd = 15; }
151+  // indirect calls: special cases of JMPL.
152+  let isCodeGenOnly = 1, rd = 15 in {
153+    def CALLrr : F3_1<2, 0b111000,
154+                      (outs), (ins MEMrr:$ptr, variable_ops),
155+                      "call $ptr",
156+                      [(call ADDRrr:$ptr)]>;
157+    def CALLri : F3_2<2, 0b111000,
158+                      (outs), (ins MEMri:$ptr, variable_ops),
159+                      "call $ptr",
160+                      [(call ADDRri:$ptr)]>;
161+  }
162 }
163 
164 // Section B.28 - Read State Register Instructions
165Index: lib/Target/Sparc/DelaySlotFiller.cpp
166===================================================================
167--- lib/Target/Sparc/DelaySlotFiller.cpp
168+++ lib/Target/Sparc/DelaySlotFiller.cpp
169@@ -278,19 +278,19 @@ void Filler::insertCallDefsUses(MachineBasicBlock:
170   switch(MI->getOpcode()) {
171   default: llvm_unreachable("Unknown opcode.");
172   case SP::CALL: break;
173-  case SP::JMPLrr:
174-  case SP::JMPLri:
175+  case SP::CALLrr:
176+  case SP::CALLri:
177     assert(MI->getNumOperands() >= 2);
178     const MachineOperand &Reg = MI->getOperand(0);
179-    assert(Reg.isReg() && "JMPL first operand is not a register.");
180-    assert(Reg.isUse() && "JMPL first operand is not a use.");
181+    assert(Reg.isReg() && "CALL first operand is not a register.");
182+    assert(Reg.isUse() && "CALL first operand is not a use.");
183     RegUses.insert(Reg.getReg());
184 
185     const MachineOperand &RegOrImm = MI->getOperand(1);
186     if (RegOrImm.isImm())
187         break;
188-    assert(RegOrImm.isReg() && "JMPLrr second operand is not a register.");
189-    assert(RegOrImm.isUse() && "JMPLrr second operand is not a use.");
190+    assert(RegOrImm.isReg() && "CALLrr second operand is not a register.");
191+    assert(RegOrImm.isUse() && "CALLrr second operand is not a use.");
192     RegUses.insert(RegOrImm.getReg());
193     break;
194   }
195@@ -353,8 +353,8 @@ bool Filler::needsUnimp(MachineBasicBlock::iterato
196   switch (I->getOpcode()) {
197   default: llvm_unreachable("Unknown call opcode.");
198   case SP::CALL: structSizeOpNum = 1; break;
199-  case SP::JMPLrr:
200-  case SP::JMPLri: structSizeOpNum = 2; break;
201+  case SP::CALLrr:
202+  case SP::CALLri: structSizeOpNum = 2; break;
203   case SP::TLS_CALL: return false;
204   }
205 
206Index: test/MC/Sparc/sparc-ctrl-instructions.s
207===================================================================
208--- test/MC/Sparc/sparc-ctrl-instructions.s
209+++ test/MC/Sparc/sparc-ctrl-instructions.s
210@@ -31,6 +31,19 @@
211         ! CHECK-NEXT:                ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
212         jmp %g1+%lo(sym)
213 
214+        ! CHECK: jmpl %g1+%i2, %g2  ! encoding: [0x85,0xc0,0x40,0x1a]
215+        jmpl %g1 + %i2, %g2
216+
217+        ! CHECK: jmpl %o1+8, %g2    ! encoding: [0x85,0xc2,0x60,0x08]
218+        jmpl %o1 + 8, %g2
219+
220+        ! CHECK: jmpl %g1, %g2      ! encoding: [0x85,0xc0,0x60,0x00]
221+        jmpl %g1, %g2
222+
223+        ! CHECK: jmpl %g1+%lo(sym), %g2   ! encoding: [0x85,0xc0,0b011000AA,A]
224+        ! CHECK-NEXT:                     ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
225+        jmpl %g1+%lo(sym), %g2
226+
227         ! CHECK: ba .BB0      ! encoding: [0x10,0b10AAAAAA,A,A]
228         ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
229         ba .BB0
230