1 Pull in r198658 from upstream llvm trunk:
3 [Sparc] Add support for parsing memory operands in sparc AsmParser.
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
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
12 +! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
13 +! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
18 + ! CHECK: call %g1+%i2
27 + ! CHECK: jmp %g1+%i2
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
40 +! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
41 +! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
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]
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]
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]
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]
71 + ! CHECK: ld [%i0+%l6], %o2 ! encoding: [0xd4,0x06,0x00,0x16]
73 + ! CHECK: ld [%i0+32], %o2 ! encoding: [0xd4,0x06,0x20,0x20]
75 + ! CHECK: ld [%g1], %o2 ! encoding: [0xd4,0x00,0x60,0x00]
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]
82 + ! CHECK: stb %o2, [%g1] ! encoding: [0xd4,0x28,0x60,0x00]
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]
89 + ! CHECK: sth %o2, [%g1] ! encoding: [0xd4,0x30,0x60,0x00]
92 + ! CHECK: st %o2, [%i0+%l6] ! encoding: [0xd4,0x26,0x00,0x16]
94 + ! CHECK: st %o2, [%i0+32] ! encoding: [0xd4,0x26,0x20,0x20]
96 + ! CHECK: st %o2, [%g1] ! encoding: [0xd4,0x20,0x60,0x00]
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 {
107 class SparcAsmParser : public MCTargetAsmParser {
109 MCSubtargetInfo &STI;
110 @@ -55,18 +56,15 @@ class SparcAsmParser : public MCTargetAsmParser {
112 // Custom parse functions for Sparc specific operands.
114 - parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
115 - OperandMatchResultTy
116 - parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
117 + parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
120 - parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
121 - int ImmOffsetOrReg);
123 - OperandMatchResultTy
124 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
127 + OperandMatchResultTy
128 + parseSparcAsmOperand(SparcOperand *&Operand);
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,
133 @@ -298,7 +296,35 @@ class SparcOperand : public MCParsedAsmOperand {
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;
146 + static SparcOperand *CreateMEMri(unsigned Base,
148 + SMLoc S, SMLoc E) {
149 + SparcOperand *Op = new SparcOperand(k_MemoryImm);
150 + Op->Mem.Base = Base;
151 + Op->Mem.OffsetReg = 0;
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;
169 @@ -412,23 +438,42 @@ ParseDirective(AsmToken DirectiveID)
172 SparcAsmParser::OperandMatchResultTy SparcAsmParser::
173 -parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
174 - int ImmOffsetOrReg)
175 +parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
177 - // FIXME: Implement memory operand parsing here.
178 - return MatchOperand_NoMatch;
181 -SparcAsmParser::OperandMatchResultTy SparcAsmParser::
182 -parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
184 - return parseMEMOperand(Operands, 2);
187 + unsigned BaseReg = 0;
189 -SparcAsmParser::OperandMatchResultTy SparcAsmParser::
190 -parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
192 - return parseMEMOperand(Operands, 1);
193 + if (ParseRegister(BaseReg, S, E)) {
194 + return MatchOperand_NoMatch;
197 + switch (getLexer().getKind()) {
198 + default: return MatchOperand_NoMatch;
200 + case AsmToken::RBrac:
201 + case AsmToken::EndOfStatement:
202 + Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
203 + return MatchOperand_Success;
205 + case AsmToken:: Plus:
206 + Parser.Lex(); // Eat the '+'
208 + case AsmToken::Minus:
212 + SparcOperand *Offset = 0;
213 + OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
214 + if (ResTy != MatchOperand_Success || !Offset)
215 + return MatchOperand_NoMatch;
217 + Offset = (Offset->isImm()
218 + ? SparcOperand::MorphToMEMri(BaseReg, Offset)
219 + : SparcOperand::MorphToMEMrr(BaseReg, Offset));
221 + Operands.push_back(Offset);
222 + return MatchOperand_Success;
225 SparcAsmParser::OperandMatchResultTy SparcAsmParser::
226 @@ -435,20 +480,57 @@ SparcAsmParser::OperandMatchResultTy SparcAsmParse
227 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
231 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
232 - if (ResTy == MatchOperand_Success)
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)
242 + if (getLexer().is(AsmToken::LBrac)) {
244 + Operands.push_back(SparcOperand::CreateToken("[",
245 + Parser.getTok().getLoc()));
246 + Parser.Lex(); // Eat the [
248 + ResTy = parseMEMOperand(Operands);
249 + if (ResTy != MatchOperand_Success)
252 + if (!getLexer().is(AsmToken::RBrac))
253 + return MatchOperand_ParseFail;
255 + Operands.push_back(SparcOperand::CreateToken("]",
256 + Parser.getTok().getLoc()));
257 + Parser.Lex(); // Eat the ]
258 + return MatchOperand_Success;
261 + SparcOperand *Op = 0;
262 + ResTy = parseSparcAsmOperand(Op);
263 + if (ResTy != MatchOperand_Success || !Op)
264 + return MatchOperand_ParseFail;
266 + // Push the parsed operand into the list of operands
267 + Operands.push_back(Op);
269 + return MatchOperand_Success;
272 +SparcAsmParser::OperandMatchResultTy
273 +SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
276 SMLoc S = Parser.getTok().getLoc();
277 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
282 switch (getLexer().getKind()) {
285 case AsmToken::Percent:
286 Parser.Lex(); // Eat the '%'.
288 @@ -458,40 +540,30 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*>
291 // FIXME: Handle modifiers like %hi, %lo etc.,
292 - return MatchOperand_ParseFail;
295 case AsmToken::Minus:
296 case AsmToken::Integer:
297 - if (getParser().parseExpression(EVal))
298 - return MatchOperand_ParseFail;
300 - Op = SparcOperand::CreateImm(EVal, S, E);
301 + if (!getParser().parseExpression(EVal))
302 + Op = SparcOperand::CreateImm(EVal, S, E);
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);
316 - // Otherwise create a symbol reference.
317 - const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
319 + const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
322 - Op = SparcOperand::CreateImm(Res, S, E);
323 + Op = SparcOperand::CreateImm(Res, S, E);
328 - case AsmToken::LBrac: // handle [
329 - return parseMEMOperand(Operands, 0);
332 - return MatchOperand_ParseFail;
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;
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
347 def SparcMEMrrAsmOperand : AsmOperandClass {
349 - let ParserMethod = "parseMEMrrOperand";
350 + let ParserMethod = "parseMEMOperand";
353 def SparcMEMriAsmOperand : AsmOperandClass {
355 - let ParserMethod = "parseMEMriOperand";
356 + let ParserMethod = "parseMEMOperand";
359 def MEMrr : Operand<iPTR> {