ARMAsmParser.cpp revision c223e2b10b4753a63dfe7e6980c650b179139983
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//                     The LLVM Compiler Infrastructure
4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source
6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details.
7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===//
9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
10ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "ARM.h"
113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h"
12c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
15ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
16ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
17ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h"
19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h"
20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
21fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
22c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
23345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
24c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
26ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
27a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby// The shift types for register controlled shifts in arm memory addressing
28a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbyenum ShiftType {
29a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Lsl,
30a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Lsr,
31a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Asr,
32a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Ror,
33a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Rrx
34a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
35a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
363a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  struct ARMOperand;
383a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
39ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser {
40ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
41d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  TargetMachine &TM;
42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyprivate:
44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  ARMOperand *MaybeParseRegister(bool ParseWriteBack);
53c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  ARMOperand *ParseRegisterList();
54550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  ARMOperand *ParseMemory();
55a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  bool ParseMemoryOffsetReg(bool &Negative,
579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetRegShifted,
589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            enum ShiftType &ShiftType,
599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&ShiftAmount,
609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&Offset,
619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetIsReg,
62762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            int &OffsetRegNum,
63762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            SMLoc &E);
649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
65762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E);
66a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
67550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  ARMOperand *ParseOperand();
68a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
69ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
70ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
71515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumb(SMLoc L);
72515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumbFunc(SMLoc L);
74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveCode(SMLoc L);
76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveSyntax(SMLoc L);
78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
797036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
807c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
81fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                               MCStreamer &Out);
82fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
83a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
84a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
860692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
870692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
88a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
89a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
90a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
91a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
92ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
93d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
94d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar    : TargetAsmParser(T), Parser(_Parser), TM(_TM) {}
95ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
9638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
979898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
98ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
99ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
100ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
1013a69756e392942bc522193f38d7f33958ed3b131Chris Lattner} // end anonymous namespace
102ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
1033a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
1077659389d0d4d315d30877592221da6a6f663114aChris Lattnerstruct ARMOperand : public MCParsedAsmOperand {
108762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananpublic:
109762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
111cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
1128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
1138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
115a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
116a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
117762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
119a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
120a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
125a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
13199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby      bool Writeback;
132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
134cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    struct {
135cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
136cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
137762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // This is for all forms of ARM address expressions
139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
141a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned OffsetRegNum; // used when OffsetIsReg is true
1429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      const MCExpr *Offset; // used when OffsetIsReg is false
143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const MCExpr *ShiftAmount; // used when OffsetRegShifted is true
1449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      enum ShiftType ShiftType;  // used when OffsetRegShifted is true
1459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      unsigned
1469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        OffsetRegShifted : 1, // only used when OffsetIsReg is true
1479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        Preindexed : 1,
1489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        Postindexed : 1,
1499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        OffsetIsReg : 1,
1509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        Negative : 1, // only used when OffsetIsReg is true
1519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        Writeback : 1;
152a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
153a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
154a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
155762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
156762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
157762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
158762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
1618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
1628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
1638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
164762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
1658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
166762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
167762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
168762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
169762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
170762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
171762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
173762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
176762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
177762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
178762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
179762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
182762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1848462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
1858462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
1868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
1878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
1888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
189a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
190a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
192a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
195a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Register && "Invalid access!");
196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return Reg.RegNum;
197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
199cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
200cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
201cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
202cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
203cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
2048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
2053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool isReg() const { return Kind == Register; }
20714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
20814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
2093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
2103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
21114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
21214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
21314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
21414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
2163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
2173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
2183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
2193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
2208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
221345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
2228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
223345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    // FIXME: What belongs here?
224345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(0));
2258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
2268462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
227a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
228a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
229a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
230a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
231a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
2333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
2343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
2353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
23614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner
23714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner
23814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemMode5() const {
23914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // FIXME: Is this right?  What about postindexed and Writeback?
24014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
24114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner        Mem.Preindexed || Mem.Negative)
24214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      return false;
24314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner
24414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    return true;
24514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
24614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner
24714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
24814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
24914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner
25014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
25114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    assert(!Mem.OffsetIsReg && "invalid mode 5 operand");
25214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    addExpr(Inst, Mem.Offset);
25314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
2543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
255fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  virtual void dump(raw_ostream &OS) const;
256b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
2573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
2583a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
259345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
260345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
261345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
2623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
263345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
264345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
2663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
2713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2743a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateReg(unsigned RegNum, bool Writeback, SMLoc S,
2753a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc E) {
2763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.Writeback = Writeback;
279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
2813a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
282a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
2853a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
2893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
290cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
291cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
2923a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
2933a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               const MCExpr *Offset, unsigned OffsetRegNum,
2943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               bool OffsetRegShifted, enum ShiftType ShiftType,
2953a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               const MCExpr *ShiftAmount, bool Preindexed,
2963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               bool Postindexed, bool Negative, bool Writeback,
2973a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
2983a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetIsReg = OffsetIsReg;
301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Offset = Offset;
302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegNum = OffsetRegNum;
303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegShifted = OffsetRegShifted;
304762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
305762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftAmount = ShiftAmount;
306762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Preindexed = Preindexed;
307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Postindexed = Postindexed;
308762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Negative = Negative;
309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Writeback = Writeback;
310762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
3133a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
3153a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
3163a69756e392942bc522193f38d7f33958ed3b131Chris Lattnerprivate:
3173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  ARMOperand(KindTy K) : Kind(K) {}
318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
319a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
322fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const {
323fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
324fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
325fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << ARMCondCodeToString(getCondCode());
326fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
327fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
328fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
329fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
330fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
331fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "<memory>";
332fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
333fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
334fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "<register " << getReg() << ">";
335fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
336fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
337fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
338fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
339fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
340fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
3413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
3423483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
3433483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
3443483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
3453483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
3463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
3473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
3483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
3499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
3503a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// and if it is a register name the token is eaten and a Reg operand is created
3513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// and returned.  Otherwise return null.
3523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
3539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO this is likely to change to allow different register types and or to
3549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// parse for a specific register type.
3553a69756e392942bc522193f38d7f33958ed3b131Chris LattnerARMOperand *ARMAsmParser::MaybeParseRegister(bool ParseWriteBack) {
356762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
35718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
358a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
359a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
360a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
361a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
362d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  int RegNum;
363a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
364a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  RegNum = MatchRegisterName(Tok.getString());
365d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  if (RegNum == -1)
3663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return 0;
367762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
368762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Tok.getLoc();
369762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
370b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
371762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
372762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = Parser.getTok().getLoc();
373a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
37499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  bool Writeback = false;
3759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (ParseWriteBack) {
37618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
3779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
378762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      E = ExclaimTok.getLoc();
3799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      Writeback = true;
380b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
3819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
38299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
38399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
3843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  return ARMOperand::CreateReg(RegNum, Writeback, S, E);
385a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
386a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
387c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
388c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
389c0ddfaa134fe60c09686906b3a8f489531653453Chris LattnerARMOperand *ARMAsmParser::ParseRegisterList() {
390762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
39118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
392cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby         "Token is not an Left Curly Brace");
393762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
394b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left curly brace token.
395d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
39618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RegTok = Parser.getTok();
397d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  SMLoc RegLoc = RegTok.getLoc();
398c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RegTok.isNot(AsmToken::Identifier)) {
399c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RegLoc, "register expected");
400c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    return 0;
401c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
402d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  int RegNum = MatchRegisterName(RegTok.getString());
403c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RegNum == -1) {
404c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RegLoc, "register expected");
405c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    return 0;
406c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
407c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner
408b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
409d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  unsigned RegList = 1 << RegNum;
410d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
411d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  int HighRegNum = RegNum;
412d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  // TODO ranges like "{Rn-Rm}"
41318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  while (Parser.getTok().is(AsmToken::Comma)) {
414b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
415d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
41618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
417d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
418c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
419c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
420c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      return 0;
421c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
422d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    int RegNum = MatchRegisterName(RegTok.getString());
423c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
424c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
425c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      return 0;
426c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
427d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
428d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    if (RegList & (1 << RegNum))
429d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby      Warning(RegLoc, "register duplicated in register list");
430d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    else if (RegNum <= HighRegNum)
431d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby      Warning(RegLoc, "register not in ascending order in register list");
432d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    RegList |= 1 << RegNum;
433d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    HighRegNum = RegNum;
434d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
435b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat identifier token.
436d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  }
43718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
438c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
439c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
440c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    return 0;
441c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
442762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = RCurlyTok.getLoc();
443b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left curly brace token.
444d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
445c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  // FIXME: Need to return an operand!
446c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  Error(E, "FIXME: register list parsing not implemented");
447c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  return 0;
448d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
449d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
4509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true
4519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
4529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed
4539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do.
454550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseMemory() {
455762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
45618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
4576bd266e56799703cd2773cadc4da8bc3c5107fdfKevin Enderby         "Token is not an Left Bracket");
458762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
459b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
46118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
462550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  if (BaseRegTok.isNot(AsmToken::Identifier)) {
463550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
464550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return 0;
465550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
466550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  int BaseRegNum = 0;
467550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  if (ARMOperand *Op = MaybeParseRegister(false))
468550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    BaseRegNum = Op->getReg();
469550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  else {
470550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
471550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return 0;
472550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
473a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
474a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Preindexed = false;
475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Postindexed = false;
476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool OffsetIsReg = false;
477a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Negative = false;
478a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Writeback = false;
479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // First look for preindexed address forms, that is after the "[Rn" we now
4819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // have to see if the next token is a comma.
48218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.is(AsmToken::Comma)) {
484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Preindexed = true;
485b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
4869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    int OffsetRegNum;
4879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    bool OffsetRegShifted;
488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    enum ShiftType ShiftType;
489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    const MCExpr *ShiftAmount;
490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    const MCExpr *Offset;
491550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
492550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                             Offset, OffsetIsReg, OffsetRegNum, E))
493550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      return 0;
49418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RBracTok = Parser.getTok();
495550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (RBracTok.isNot(AsmToken::RBrac)) {
496550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      Error(RBracTok.getLoc(), "']' expected");
497550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      return 0;
498550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    }
499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = RBracTok.getLoc();
500b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
501a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
50218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
503a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
504762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      E = ExclaimTok.getLoc();
505a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      Writeback = true;
506b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
508550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                                 OffsetRegShifted, ShiftType, ShiftAmount,
510550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                                 Preindexed, Postindexed, Negative, Writeback,
511550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                                 S, E);
512a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
513a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // The "[Rn" we have so far was not followed by a comma.
514a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (Tok.is(AsmToken::RBrac)) {
5159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // This is a post indexing addressing forms, that is a ']' follows after
5169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // the "[Rn".
517a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Postindexed = true;
518a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Writeback = true;
519762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
520b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
521a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
522e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    int OffsetRegNum = 0;
523a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    bool OffsetRegShifted = false;
524a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    enum ShiftType ShiftType;
525a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    const MCExpr *ShiftAmount;
52614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    const MCExpr *Offset = 0;
527a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
52818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &NextTok = Parser.getTok();
529e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    if (NextTok.isNot(AsmToken::EndOfStatement)) {
530550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (NextTok.isNot(AsmToken::Comma)) {
531550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        Error(NextTok.getLoc(), "',' expected");
532550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        return 0;
533550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      }
534b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
535550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
536550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                               ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
537550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                               E))
538550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        return 0;
539a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
540e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
541550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
542550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                                 OffsetRegShifted, ShiftType, ShiftAmount,
543550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                                 Preindexed, Postindexed, Negative, Writeback,
544550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                                 S, E);
545a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
546a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
547550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  return 0;
548a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
5519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is
5529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional):
5539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm
5549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm, shift
5559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   #offset
5569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise.
5579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
558762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        bool &OffsetRegShifted,
5599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        enum ShiftType &ShiftType,
5609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&ShiftAmount,
5619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&Offset,
5629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        bool &OffsetIsReg,
563762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        int &OffsetRegNum,
564762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        SMLoc &E) {
5659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  Negative = false;
5669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegShifted = false;
5679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetIsReg = false;
5689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegNum = -1;
56918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &NextTok = Parser.getTok();
570762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = NextTok.getLoc();
5719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (NextTok.is(AsmToken::Plus))
572b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat plus token.
5739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else if (NextTok.is(AsmToken::Minus)) {
5749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    Negative = true;
575b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat minus token
5769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
5779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
57818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &OffsetRegTok = Parser.getTok();
5799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegTok.is(AsmToken::Identifier)) {
580550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ARMOperand *Op = MaybeParseRegister(false)) {
581550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      OffsetIsReg = true;
582762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      E = Op->getEndLoc();
583762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      OffsetRegNum = Op->getReg();
584550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      delete Op;
585762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
5869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
5879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // If we parsed a register as the offset then their can be a shift after that
5889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegNum != -1) {
5899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for a comma then a shift
59018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &Tok = Parser.getTok();
5919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (Tok.is(AsmToken::Comma)) {
592b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
5939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
59418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      const AsmToken &Tok = Parser.getTok();
595762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      if (ParseShift(ShiftType, ShiftAmount, E))
5963472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(Tok.getLoc(), "shift expected");
5979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      OffsetRegShifted = true;
5989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
5999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
6009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
6019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for #offset following the "[Rn," or "[Rn],"
60218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &HashTok = Parser.getTok();
6039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (HashTok.isNot(AsmToken::Hash))
6049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return Error(HashTok.getLoc(), "'#' expected");
605762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
606b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat hash token.
6079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
6089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (getParser().ParseExpression(Offset))
6099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby     return true;
610762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
6129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
6139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
6149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
615a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two:
616a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
617a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
618a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false.
6193a69756e392942bc522193f38d7f33958ed3b131Chris Lattnerbool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount,
620762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                              SMLoc &E) {
62118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
62438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
625a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
6269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Lsl;
627a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
6289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Lsr;
629a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
6309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Asr;
631a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
6329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Ror;
633a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
6349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Rrx;
635a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
636a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
637b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
638a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
6399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Rrx stands alone.
6409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (St == Rrx)
6419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return false;
642a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
6439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Otherwise, there must be a '#' and a shift amount.
64418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &HashTok = Parser.getTok();
6459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (HashTok.isNot(AsmToken::Hash))
6469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return Error(HashTok.getLoc(), "'#' expected");
647b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat hash token.
6489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
6499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (getParser().ParseExpression(ShiftAmount))
6509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return true;
651a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
652a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
6559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
6569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
657550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseOperand() {
658762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
659762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
660a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
661a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::Identifier:
662550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ARMOperand *Op = MaybeParseRegister(true))
663550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      return Op;
664550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner
665515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
666515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
667515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
668762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
669515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
670550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      return 0;
671762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
672550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return ARMOperand::CreateImm(IdVal, S, E);
673a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
674550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return ParseMemory();
675d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
676550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return ParseRegisterList();
677d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
678079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
679079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
680762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
681b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
682515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
684550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      return 0;
685762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
686550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return ARMOperand::CreateImm(ImmVal, S, E);
687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  default:
688550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(Parser.getTok().getLoc(), "unexpected token in operand");
689550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    return 0;
690a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
692a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
6939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands.
69438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
6959898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
6965747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
6975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
6985747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  StringRef Head = Name.slice(Start, Next);
6995747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
700345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Determine the predicate, if any.
701345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  //
702345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // FIXME: We need a way to check whether a prefix supports predication,
703345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // otherwise we will end up with an ambiguity for instructions that happen to
704345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // end with a predicate name.
705345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2))
706345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("eq", ARMCC::EQ)
707345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ne", ARMCC::NE)
708345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("hs", ARMCC::HS)
709345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("lo", ARMCC::LO)
710345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("mi", ARMCC::MI)
711345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("pl", ARMCC::PL)
712345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("vs", ARMCC::VS)
713345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("vc", ARMCC::VC)
714345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("hi", ARMCC::HI)
715345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ls", ARMCC::LS)
716345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ge", ARMCC::GE)
717345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("lt", ARMCC::LT)
718345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("gt", ARMCC::GT)
719345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("le", ARMCC::LE)
720345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("al", ARMCC::AL)
721345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Default(~0U);
7223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
7233a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  if (CC != ~0U)
724345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Head = Head.slice(0, Head.size() - 2);
7253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  else
726345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    CC = ARMCC::AL;
727345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
7283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
7293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), NameLoc));
730345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
731345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
7325747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
7335747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
7345747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
7355747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Head = Name.slice(Start, Next);
736a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
7373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
7385747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
7395747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
7405747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
7415747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
742a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
743550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ARMOperand *Op = ParseOperand())
744550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      Operands.push_back(Op);
745550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    else {
746cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
747cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
748cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
749a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
750a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
751b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
752a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
753a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
754550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (ARMOperand *Op = ParseOperand())
755550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        Operands.push_back(Op);
756550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      else {
757cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
758cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
759cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
760a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
761a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
76234e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner
763cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
764cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
76534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
766cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
76734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
7689898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
769ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
770ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
771fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
772fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
773fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
774fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
775fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
776fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
777e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) {
778e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
779fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
780fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
781e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner
782e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
783e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
784e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
785e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
786e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
787e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
788e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
789e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
790e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner
791e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
792e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
793e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
794e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner
795e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
796e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
797e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
798e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(IDLoc, "unrecognized instruction mnemonic");
799fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
800c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher
801c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
802fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
803fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
804fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
805fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
806515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives
807ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
808ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
809ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
810ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    return ParseDirectiveWord(4, DirectiveID.getLoc());
811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
812515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumb(DirectiveID.getLoc());
813515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
814515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
815515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
816515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveCode(DirectiveID.getLoc());
817515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
818515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveSyntax(DirectiveID.getLoc());
819ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
820ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
821ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
822ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord
823ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
824ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
825ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
826ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
827ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
828ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
829ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
830ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
831aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
832ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
833ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
834ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
835ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
836ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
837ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
838ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
839b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
840ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
841ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
842ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
843b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
844ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
845ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
846ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
847515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb
848515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
849515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
850515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
851515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
852b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
853515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
854515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
855515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
856515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
857515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
858515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
859515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
860515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc
861515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
862515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
86318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
864515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
865515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
866b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Consume the identifier token.
867515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
868515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
869515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
870b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
871515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
872515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: mark symbol as a thumb symbol
873515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
874515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
875515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
876515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
877515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax
878515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
879515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
88018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
881515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
882515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
88338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
88458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
885b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
88658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
887b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
888515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
889515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
890515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
891515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
89218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
893b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
894515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
895515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
896515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
897515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
898515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
899515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
900515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode
901515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
902515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
90318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
904515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
905515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
90618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
90758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
908b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
90958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
910b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
911515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
912515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
913515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
914515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
91518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
916b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
917515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
918515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
919515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
920515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
921515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
922515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
92390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
92490b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
9259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
926ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
927ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
928ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
92990b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
930ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
9313483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9320692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
9330692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
9343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
935