]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r198909-sparc.diff
1 Pull 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
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7 Index: 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));
19 Index: 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)>;
38 Index: 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  {
86 Index: 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);
102 Index: 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
165 Index: 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  
206 Index: 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