]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r198658-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-r198658-sparc.diff
1 Pull in r198658 from upstream llvm trunk:
2
3   [Sparc] Add support for parsing memory operands in sparc AsmParser.
4
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7 Index: test/MC/Sparc/sparc-ctrl-instructions.s
8 ===================================================================
9 --- test/MC/Sparc/sparc-ctrl-instructions.s
10 +++ test/MC/Sparc/sparc-ctrl-instructions.s
11 @@ -0,0 +1,23 @@
12 +! RUN: llvm-mc %s -arch=sparc   -show-encoding | FileCheck %s
13 +! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
14 +
15 +        ! CHECK: call foo
16 +        call foo
17 +
18 +        ! CHECK: call %g1+%i2
19 +        call %g1 + %i2
20 +
21 +        ! CHECK: call %o1+8
22 +        call %o1 + 8
23 +
24 +        ! CHECK: call %g1
25 +        call %g1
26 +
27 +        ! CHECK: jmp %g1+%i2
28 +        jmp %g1 + %i2
29 +
30 +        ! CHECK: jmp %o1+8
31 +        jmp %o1 + 8
32 +
33 +        ! CHECK: jmp %g1
34 +        jmp %g1
35 Index: test/MC/Sparc/sparc-mem-instructions.s
36 ===================================================================
37 --- test/MC/Sparc/sparc-mem-instructions.s
38 +++ test/MC/Sparc/sparc-mem-instructions.s
39 @@ -0,0 +1,58 @@
40 +! RUN: llvm-mc %s -arch=sparc   -show-encoding | FileCheck %s
41 +! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
42 +
43 +        ! CHECK: ldsb [%i0+%l6], %o2  ! encoding: [0xd4,0x4e,0x00,0x16]
44 +        ldsb [%i0 + %l6], %o2
45 +        ! CHECK: ldsb [%i0+32], %o2   ! encoding: [0xd4,0x4e,0x20,0x20]
46 +        ldsb [%i0 + 32], %o2
47 +        ! CHECK: ldsb [%g1], %o4      ! encoding: [0xd8,0x48,0x60,0x00]
48 +        ldsb [%g1], %o4
49 +
50 +        ! CHECK: ldsh [%i0+%l6], %o2  ! encoding: [0xd4,0x56,0x00,0x16]
51 +        ldsh [%i0 + %l6], %o2
52 +        ! CHECK: ldsh [%i0+32], %o2   ! encoding: [0xd4,0x56,0x20,0x20]
53 +        ldsh [%i0 + 32], %o2
54 +        ! CHECK: ldsh [%g1], %o4      ! encoding: [0xd8,0x50,0x60,0x00]
55 +        ldsh [%g1], %o4
56 +
57 +        ! CHECK: ldub [%i0+%l6], %o2  ! encoding: [0xd4,0x0e,0x00,0x16]
58 +        ldub [%i0 + %l6], %o2
59 +        ! CHECK: ldub [%i0+32], %o2   ! encoding: [0xd4,0x0e,0x20,0x20]
60 +        ldub [%i0 + 32], %o2
61 +        ! CHECK: ldub [%g1], %o2      ! encoding: [0xd4,0x08,0x60,0x00]
62 +        ldub [%g1], %o2
63 +
64 +        ! CHECK: lduh [%i0+%l6], %o2  ! encoding: [0xd4,0x16,0x00,0x16]
65 +        lduh [%i0 + %l6], %o2
66 +        ! CHECK: lduh [%i0+32], %o2   ! encoding: [0xd4,0x16,0x20,0x20]
67 +        lduh [%i0 + 32], %o2
68 +        ! CHECK: lduh [%g1], %o2      ! encoding: [0xd4,0x10,0x60,0x00]
69 +        lduh [%g1], %o2
70 +
71 +        ! CHECK: ld [%i0+%l6], %o2    ! encoding: [0xd4,0x06,0x00,0x16]
72 +        ld [%i0 + %l6], %o2
73 +        ! CHECK: ld [%i0+32], %o2     ! encoding: [0xd4,0x06,0x20,0x20]
74 +        ld [%i0 + 32], %o2
75 +        ! CHECK: ld [%g1], %o2        ! encoding: [0xd4,0x00,0x60,0x00]
76 +        ld [%g1], %o2
77 +
78 +        ! CHECK: stb %o2, [%i0+%l6]   ! encoding: [0xd4,0x2e,0x00,0x16]
79 +        stb %o2, [%i0 + %l6]
80 +        ! CHECK: stb %o2, [%i0+32]    ! encoding: [0xd4,0x2e,0x20,0x20]
81 +        stb %o2, [%i0 + 32]
82 +        ! CHECK: stb %o2, [%g1]       ! encoding: [0xd4,0x28,0x60,0x00]
83 +        stb %o2, [%g1]
84 +
85 +        ! CHECK: sth %o2, [%i0+%l6]   ! encoding: [0xd4,0x36,0x00,0x16]
86 +        sth %o2, [%i0 + %l6]
87 +        ! CHECK: sth %o2, [%i0+32]    ! encoding: [0xd4,0x36,0x20,0x20]
88 +        sth %o2, [%i0 + 32]
89 +        ! CHECK: sth %o2, [%g1]       ! encoding: [0xd4,0x30,0x60,0x00]
90 +        sth %o2, [%g1]
91 +
92 +        ! CHECK: st %o2, [%i0+%l6]    ! encoding: [0xd4,0x26,0x00,0x16]
93 +        st %o2, [%i0 + %l6]
94 +        ! CHECK: st %o2, [%i0+32]     ! encoding: [0xd4,0x26,0x20,0x20]
95 +        st %o2, [%i0 + 32]
96 +        ! CHECK: st %o2, [%g1]        ! encoding: [0xd4,0x20,0x60,0x00]
97 +        st %o2, [%g1]
98 Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
99 ===================================================================
100 --- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
101 +++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
102 @@ -28,6 +28,7 @@ namespace llvm {
103  }
104  
105  namespace {
106 +class SparcOperand;
107  class SparcAsmParser : public MCTargetAsmParser {
108  
109    MCSubtargetInfo &STI;
110 @@ -55,18 +56,15 @@ class SparcAsmParser : public MCTargetAsmParser {
111  
112    // Custom parse functions for Sparc specific operands.
113    OperandMatchResultTy
114 -  parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
115 -  OperandMatchResultTy
116 -  parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
117 +  parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
118  
119    OperandMatchResultTy
120 -  parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
121 -                  int ImmOffsetOrReg);
122 -
123 -  OperandMatchResultTy
124    parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
125                 StringRef Name);
126  
127 +  OperandMatchResultTy
128 +  parseSparcAsmOperand(SparcOperand *&Operand);
129 +
130    // returns true if Tok is matched to a register and returns register in RegNo.
131    bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
132                           bool isQFP);
133 @@ -298,7 +296,35 @@ class SparcOperand : public MCParsedAsmOperand {
134      return Op;
135    }
136  
137 +  static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
138 +    unsigned offsetReg = Op->getReg();
139 +    Op->Kind = k_MemoryReg;
140 +    Op->Mem.Base = Base;
141 +    Op->Mem.OffsetReg = offsetReg;
142 +    Op->Mem.Off = 0;
143 +    return Op;
144 +  }
145  
146 +  static SparcOperand *CreateMEMri(unsigned Base,
147 +                                 const MCExpr *Off,
148 +                                 SMLoc S, SMLoc E) {
149 +    SparcOperand *Op = new SparcOperand(k_MemoryImm);
150 +    Op->Mem.Base = Base;
151 +    Op->Mem.OffsetReg = 0;
152 +    Op->Mem.Off = Off;
153 +    Op->StartLoc = S;
154 +    Op->EndLoc = E;
155 +    return Op;
156 +  }
157 +
158 +  static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) {
159 +    const MCExpr *Imm  = Op->getImm();
160 +    Op->Kind = k_MemoryImm;
161 +    Op->Mem.Base = Base;
162 +    Op->Mem.OffsetReg = 0;
163 +    Op->Mem.Off = Imm;
164 +    return Op;
165 +  }
166  };
167  
168  } // end namespace
169 @@ -412,23 +438,42 @@ ParseDirective(AsmToken DirectiveID)
170  }
171  
172  SparcAsmParser::OperandMatchResultTy SparcAsmParser::
173 -parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
174 -                int ImmOffsetOrReg)
175 +parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
176  {
177 -  // FIXME: Implement memory operand parsing here.
178 -  return MatchOperand_NoMatch;
179 -}
180  
181 -SparcAsmParser::OperandMatchResultTy SparcAsmParser::
182 -parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
183 -{
184 -  return parseMEMOperand(Operands, 2);
185 -}
186 +  SMLoc S, E;
187 +  unsigned BaseReg = 0;
188  
189 -SparcAsmParser::OperandMatchResultTy SparcAsmParser::
190 -parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
191 -{
192 -  return parseMEMOperand(Operands, 1);
193 +  if (ParseRegister(BaseReg, S, E)) {
194 +    return MatchOperand_NoMatch;
195 +  }
196 +
197 +  switch (getLexer().getKind()) {
198 +  default: return MatchOperand_NoMatch;
199 +
200 +  case AsmToken::RBrac:
201 +  case AsmToken::EndOfStatement:
202 +    Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
203 +    return MatchOperand_Success;
204 +
205 +  case AsmToken:: Plus:
206 +    Parser.Lex(); // Eat the '+'
207 +    break;
208 +  case AsmToken::Minus:
209 +    break;
210 +  }
211 +
212 +  SparcOperand *Offset = 0;
213 +  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
214 +  if (ResTy != MatchOperand_Success || !Offset)
215 +    return MatchOperand_NoMatch;
216 +
217 +  Offset = (Offset->isImm()
218 +            ? SparcOperand::MorphToMEMri(BaseReg, Offset)
219 +            : SparcOperand::MorphToMEMrr(BaseReg, Offset));
220 +
221 +  Operands.push_back(Offset);
222 +  return MatchOperand_Success;
223  }
224  
225  SparcAsmParser::OperandMatchResultTy SparcAsmParser::
226 @@ -435,20 +480,57 @@ SparcAsmParser::OperandMatchResultTy SparcAsmParse
227  parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
228               StringRef Mnemonic)
229  {
230 +
231    OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
232 -  if (ResTy == MatchOperand_Success)
233 -    return ResTy;
234 +
235    // If there wasn't a custom match, try the generic matcher below. Otherwise,
236    // there was a match, but an error occurred, in which case, just return that
237    // the operand parsing failed.
238 -  if (ResTy == MatchOperand_ParseFail)
239 +  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
240      return ResTy;
241  
242 +  if (getLexer().is(AsmToken::LBrac)) {
243 +    // Memory operand
244 +    Operands.push_back(SparcOperand::CreateToken("[",
245 +                                                 Parser.getTok().getLoc()));
246 +    Parser.Lex(); // Eat the [
247 +
248 +    ResTy = parseMEMOperand(Operands);
249 +    if (ResTy != MatchOperand_Success)
250 +      return ResTy;
251 +
252 +    if (!getLexer().is(AsmToken::RBrac))
253 +      return MatchOperand_ParseFail;
254 +
255 +    Operands.push_back(SparcOperand::CreateToken("]",
256 +                                                 Parser.getTok().getLoc()));
257 +    Parser.Lex(); // Eat the ]
258 +    return MatchOperand_Success;
259 +  }
260 +
261 +  SparcOperand *Op = 0;
262 +  ResTy = parseSparcAsmOperand(Op);
263 +  if (ResTy != MatchOperand_Success || !Op)
264 +    return MatchOperand_ParseFail;
265 +
266 +  // Push the parsed operand into the list of operands
267 +  Operands.push_back(Op);
268 +
269 +  return MatchOperand_Success;
270 +}
271 +
272 +SparcAsmParser::OperandMatchResultTy
273 +SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
274 +{
275 +
276    SMLoc S = Parser.getTok().getLoc();
277    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
278    const MCExpr *EVal;
279 -  SparcOperand *Op;
280 +
281 +  Op = 0;
282    switch (getLexer().getKind()) {
283 +  default:  break;
284 +
285    case AsmToken::Percent:
286      Parser.Lex(); // Eat the '%'.
287      unsigned RegNo;
288 @@ -458,40 +540,30 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*>
289        break;
290      }
291      // FIXME: Handle modifiers like %hi, %lo etc.,
292 -    return MatchOperand_ParseFail;
293 +    break;
294  
295    case AsmToken::Minus:
296    case AsmToken::Integer:
297 -    if (getParser().parseExpression(EVal))
298 -      return MatchOperand_ParseFail;
299 -
300 -    Op = SparcOperand::CreateImm(EVal, S, E);
301 +    if (!getParser().parseExpression(EVal))
302 +      Op = SparcOperand::CreateImm(EVal, S, E);
303      break;
304  
305    case AsmToken::Identifier: {
306      StringRef Identifier;
307 -    if (getParser().parseIdentifier(Identifier))
308 -      return MatchOperand_ParseFail;
309 -    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
310 -    MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
311 +    if (!getParser().parseIdentifier(Identifier)) {
312 +      SMLoc E = SMLoc::getFromPointer(Parser.getTok().
313 +                                      getLoc().getPointer() - 1);
314 +      MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
315  
316 -    // Otherwise create a symbol reference.
317 -    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
318 -                                                getContext());
319 +      const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
320 +                                                  getContext());
321  
322 -    Op = SparcOperand::CreateImm(Res, S, E);
323 +      Op = SparcOperand::CreateImm(Res, S, E);
324 +    }
325      break;
326    }
327 -
328 -  case AsmToken::LBrac:  // handle [
329 -    return parseMEMOperand(Operands, 0);
330 -
331 -  default:
332 -    return MatchOperand_ParseFail;
333    }
334 -  // Push the parsed operand into the list of operands
335 -  Operands.push_back(Op);
336 -  return MatchOperand_Success;
337 +  return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
338  }
339  
340  bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
341 Index: lib/Target/Sparc/SparcInstrInfo.td
342 ===================================================================
343 --- lib/Target/Sparc/SparcInstrInfo.td
344 +++ lib/Target/Sparc/SparcInstrInfo.td
345 @@ -78,12 +78,12 @@ def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri
346  // Address operands
347  def SparcMEMrrAsmOperand : AsmOperandClass {
348    let Name = "MEMrr";
349 -  let ParserMethod = "parseMEMrrOperand";
350 +  let ParserMethod = "parseMEMOperand";
351  }
352  
353  def SparcMEMriAsmOperand : AsmOperandClass {
354    let Name = "MEMri";
355 -  let ParserMethod = "parseMEMriOperand";
356 +  let ParserMethod = "parseMEMOperand";
357  }
358  
359  def MEMrr : Operand<iPTR> {