llvm.org GIT mirror llvm / d7894f1
Added another bit of the ARM target assembler to llvm-mc to parse register lists. Changed ARMAsmParser::MatchRegisterName to return -1 instead of 0 on errors so 0-15 values could be returned as register numbers. Also added the rest of the arm register names to the currently hacked up version to allow more testing. Some changes to ARMAsmParser::ParseOperand to give different errors for things not yet supported and some additions to the hacked ARMAsmParser::MatchInstruction to allow more testing for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83673 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 11 years ago
1 changed file(s) with 104 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
4545
4646 bool ParseRegister(ARMOperand &Op);
4747
48 bool ParseRegisterList(ARMOperand &Op);
49
4850 bool ParseMemory(ARMOperand &Op);
4951
5052 bool ParseShift(enum ShiftType *St, const MCExpr *ShiftAmount);
6163 bool MatchInstruction(SmallVectorImpl &Operands,
6264 MCInst &Inst);
6365
64 /// MatchRegisterName - Match the given string to a register name, or 0 if
65 /// there is no match.
66 unsigned MatchRegisterName(const StringRef &Name);
66 /// MatchRegisterName - Match the given string to a register name and return
67 /// its register number, or -1 if there is no match. To allow return values
68 /// to be used directly in register lists, arm registers have values between
69 /// 0 and 15.
70 int MatchRegisterName(const StringRef &Name);
6771
6872 /// }
6973
189193
190194 // FIXME: Validate register for the current architecture; we have to do
191195 // validation later, so maybe there is no need for this here.
192 unsigned RegNum;
196 int RegNum;
193197
194198 RegNum = MatchRegisterName(Tok.getString());
195 if (RegNum == 0)
199 if (RegNum == -1)
196200 return true;
197201 getLexer().Lex(); // Eat identifier token.
198202
204208 }
205209
206210 Op = ARMOperand::CreateReg(RegNum, Writeback);
211
212 return false;
213 }
214
215 // Try to parse a register list. The first token must be a '{' when called
216 // for now.
217 bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
218 const AsmToken &LCurlyTok = getLexer().getTok();
219 assert(LCurlyTok.is(AsmToken::LCurly) && "Token is not an Left Curly Brace");
220 getLexer().Lex(); // Eat left curly brace token.
221
222 const AsmToken &RegTok = getLexer().getTok();
223 SMLoc RegLoc = RegTok.getLoc();
224 if (RegTok.isNot(AsmToken::Identifier))
225 return Error(RegLoc, "register expected");
226 int RegNum = MatchRegisterName(RegTok.getString());
227 if (RegNum == -1)
228 return Error(RegLoc, "register expected");
229 getLexer().Lex(); // Eat identifier token.
230 unsigned RegList = 1 << RegNum;
231
232 int HighRegNum = RegNum;
233 // TODO ranges like "{Rn-Rm}"
234 while (getLexer().getTok().is(AsmToken::Comma)) {
235 getLexer().Lex(); // Eat comma token.
236
237 const AsmToken &RegTok = getLexer().getTok();
238 SMLoc RegLoc = RegTok.getLoc();
239 if (RegTok.isNot(AsmToken::Identifier))
240 return Error(RegLoc, "register expected");
241 int RegNum = MatchRegisterName(RegTok.getString());
242 if (RegNum == -1)
243 return Error(RegLoc, "register expected");
244
245 if (RegList & (1 << RegNum))
246 Warning(RegLoc, "register duplicated in register list");
247 else if (RegNum <= HighRegNum)
248 Warning(RegLoc, "register not in ascending order in register list");
249 RegList |= 1 << RegNum;
250 HighRegNum = RegNum;
251
252 getLexer().Lex(); // Eat identifier token.
253 }
254 const AsmToken &RCurlyTok = getLexer().getTok();
255 if (RCurlyTok.isNot(AsmToken::RCurly))
256 return Error(RCurlyTok.getLoc(), "'}' expected");
257 getLexer().Lex(); // Eat left curly brace token.
207258
208259 return false;
209260 }
219270 const AsmToken &BaseRegTok = getLexer().getTok();
220271 if (BaseRegTok.isNot(AsmToken::Identifier))
221272 return Error(BaseRegTok.getLoc(), "register expected");
222 unsigned BaseRegNum = MatchRegisterName(BaseRegTok.getString());
223 if (BaseRegNum == 0)
273 int BaseRegNum = MatchRegisterName(BaseRegTok.getString());
274 if (BaseRegNum == -1)
224275 return Error(BaseRegTok.getLoc(), "register expected");
225276 getLexer().Lex(); // Eat identifier token.
226277
250301
251302 // See if there is a register following the "[Rn," we have so far.
252303 const AsmToken &OffsetRegTok = getLexer().getTok();
253 unsigned OffsetRegNum = MatchRegisterName(OffsetRegTok.getString());
304 int OffsetRegNum = MatchRegisterName(OffsetRegTok.getString());
254305 bool OffsetRegShifted = false;
255306 enum ShiftType ShiftType;
256307 const MCExpr *ShiftAmount;
257308 const MCExpr *Offset;
258 if (OffsetRegNum != 0) {
309 if (OffsetRegNum != -1) {
259310 OffsetIsReg = true;
260311 getLexer().Lex(); // Eat identifier token for the offset register.
261312 // Look for a comma then a shift
320371
321372 // See if there is a register following the "[Rn]," we have so far.
322373 const AsmToken &OffsetRegTok = getLexer().getTok();
323 unsigned OffsetRegNum = MatchRegisterName(OffsetRegTok.getString());
374 int OffsetRegNum = MatchRegisterName(OffsetRegTok.getString());
324375 bool OffsetRegShifted = false;
325376 enum ShiftType ShiftType;
326377 const MCExpr *ShiftAmount;
327378 const MCExpr *Offset;
328 if (OffsetRegNum != 0) {
379 if (OffsetRegNum != -1) {
329380 OffsetIsReg = true;
330381 getLexer().Lex(); // Eat identifier token for the offset register.
331382 // Look for a comma then a shift
397448 }
398449
399450 // A hack to allow some testing
400 unsigned ARMAsmParser::MatchRegisterName(const StringRef &Name) {
401 if (Name == "r1")
451 int ARMAsmParser::MatchRegisterName(const StringRef &Name) {
452 if (Name == "r0" || Name == "R0")
453 return 0;
454 else if (Name == "r1" || Name == "R1")
402455 return 1;
403 else if (Name == "r2")
456 else if (Name == "r2" || Name == "R2")
404457 return 2;
405 else if (Name == "r3")
458 else if (Name == "r3" || Name == "R3")
406459 return 3;
407 else if (Name == "sp")
460 else if (Name == "r3" || Name == "R3")
461 return 3;
462 else if (Name == "r4" || Name == "R4")
463 return 4;
464 else if (Name == "r5" || Name == "R5")
465 return 5;
466 else if (Name == "r6" || Name == "R6")
467 return 6;
468 else if (Name == "r7" || Name == "R7")
469 return 7;
470 else if (Name == "r8" || Name == "R8")
471 return 8;
472 else if (Name == "r9" || Name == "R9")
473 return 9;
474 else if (Name == "r10" || Name == "R10")
475 return 10;
476 else if (Name == "r11" || Name == "R11" || Name == "fp")
477 return 11;
478 else if (Name == "r12" || Name == "R12" || Name == "ip")
479 return 12;
480 else if (Name == "r13" || Name == "R13" || Name == "sp")
408481 return 13;
409 return 0;
482 else if (Name == "r14" || Name == "R14" || Name == "lr")
483 return 14;
484 else if (Name == "r15" || Name == "R15" || Name == "pc")
485 return 15;
486 return -1;
410487 }
411488
412489 // A hack to allow some testing
419496 Mnemonic == "stmfd" ||
420497 Mnemonic == "str" ||
421498 Mnemonic == "ldmfd" ||
422 Mnemonic == "ldr")
499 Mnemonic == "ldr" ||
500 Mnemonic == "mov")
423501 return false;
424502
425503 return true;
431509 case AsmToken::Identifier:
432510 if (!ParseRegister(Op))
433511 return false;
434 // TODO parse other operands that start with an identifier
435 return true;
512 // TODO parse other operands that start with an identifier like labels
513 return Error(getLexer().getTok().getLoc(), "labels not yet supported");
436514 case AsmToken::LBrac:
437515 if (!ParseMemory(Op))
438516 return false;
517 case AsmToken::LCurly:
518 if (!ParseRegisterList(Op))
519 return(false);
520 case AsmToken::Hash:
521 return Error(getLexer().getTok().getLoc(), "immediates not yet supported");
439522 default:
440 return true;
523 return Error(getLexer().getTok().getLoc(), "unexpected token in operand");
441524 }
442525 }
443526