patch-r262261-llvm-r198658-sparc.diff revision 269012
1Pull in r198658 from upstream llvm trunk:
2
3  [Sparc] Add support for parsing memory operands in sparc AsmParser.
4
5Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7Index: 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
35Index: 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]
98Index: 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,
341Index: 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> {
360