ARMAsmParser.cpp revision 345a9a6269318c96f333c0492b23733e29d952df
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/Compiler.h"
21c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
22fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
23762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan#include "llvm/ADT/OwningPtr.h"
24c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
25345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
27ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
28ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
29ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbynamespace {
30ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbystruct ARMOperand;
31ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
32a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby// The shift types for register controlled shifts in arm memory addressing
33a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbyenum ShiftType {
34a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Lsl,
35a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Lsr,
36a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Asr,
37a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Ror,
38a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  Rrx
39a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
40a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser {
42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
43d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  TargetMachine &TM;
44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyprivate:
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
52ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
53ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
54762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  bool MaybeParseRegister(OwningPtr<ARMOperand> &Op, bool ParseWriteBack);
55a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
56762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  bool ParseRegisterList(OwningPtr<ARMOperand> &Op);
57d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
58762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  bool ParseMemory(OwningPtr<ARMOperand> &Op);
59a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  bool ParseMemoryOffsetReg(bool &Negative,
619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetRegShifted,
629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            enum ShiftType &ShiftType,
639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&ShiftAmount,
649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&Offset,
659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetIsReg,
66762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            int &OffsetRegNum,
67762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            SMLoc &E);
689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
69762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E);
70a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
71762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  bool ParseOperand(OwningPtr<ARMOperand> &Op);
72a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
73ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
74ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumb(SMLoc L);
76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumbFunc(SMLoc L);
78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
79515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveCode(SMLoc L);
80515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
81515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveSyntax(SMLoc L);
82515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
83a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
84a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  unsigned ComputeAvailableFeatures(const ARMSubtarget *Subtarget) const;
873483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
889898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
89a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby                        MCInst &Inst);
90a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
91a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
92a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
94ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
95d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
96d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar    : TargetAsmParser(T), Parser(_Parser), TM(_TM) {}
97ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
9838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
999898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
100ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
101ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
102ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
103ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
104a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
1067659389d0d4d315d30877592221da6a6f663114aChris Lattnerstruct ARMOperand : public MCParsedAsmOperand {
107762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananprivate:
108762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand() {}
109762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananpublic:
110762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
112cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
1138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
1148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
116a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
117a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
118762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
119a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
120a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
121a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
13299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby      bool Writeback;
133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
135cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    struct {
136cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
137cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
138762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // This is for all forms of ARM address expressions
140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
141a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned OffsetRegNum; // used when OffsetIsReg is true
1439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      const MCExpr *Offset; // used when OffsetIsReg is false
144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const MCExpr *ShiftAmount; // used when OffsetRegShifted is true
1459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      enum ShiftType ShiftType;  // used when OffsetRegShifted is true
1469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      unsigned
1479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        OffsetRegShifted : 1, // only used when OffsetIsReg is true
1489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        Preindexed : 1,
1499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        Postindexed : 1,
1509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        OffsetIsReg : 1,
1519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        Negative : 1, // only used when OffsetIsReg is true
1529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        Writeback : 1;
153a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
154a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
155a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
156762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
157762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(KindTy K, SMLoc S, SMLoc E)
158762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    : Kind(K), StartLoc(S), EndLoc(E) {}
159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
161762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
163762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
164762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
1658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
1668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
1678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
168762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
1698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
170762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
171762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
173762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
176762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
177762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
178762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
179762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
182762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
183762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
184762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
185762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
186762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
187a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
1898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
1908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
1918462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
1928462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
195a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Register && "Invalid access!");
200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return Reg.RegNum;
201a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
203cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
204cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
205cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
206cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
207cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
2088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
2098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
2103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool isReg() const { return Kind == Register; }
213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isToken() const {return Kind == Token; }
2153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
2163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    // Add as immediates when possible.
2183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
2203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
2213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
2223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
2233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
2248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
225345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
2268462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
227345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    // FIXME: What belongs here?
228345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(0));
2298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
2308462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
231a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
232a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
233a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
235a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
2373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
2383483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
2393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
2403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
241fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  virtual void dump(raw_ostream &OS) const;
242b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
243345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  static void CreateCondCode(OwningPtr<ARMOperand> &Op, ARMCC::CondCodes CC,
244345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar                             SMLoc S) {
245345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op.reset(new ARMOperand);
246345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->Kind = CondCode;
247345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
248345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
249345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
250345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
251345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
252762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  static void CreateToken(OwningPtr<ARMOperand> &Op, StringRef Str,
253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                          SMLoc S) {
254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op.reset(new ARMOperand);
255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Kind = Token;
256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
259762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
260a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
261a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  static void CreateReg(OwningPtr<ARMOperand> &Op, unsigned RegNum,
263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                        bool Writeback, SMLoc S, SMLoc E) {
264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op.reset(new ARMOperand);
265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Kind = Register;
266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.Writeback = Writeback;
268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
271a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  static void CreateImm(OwningPtr<ARMOperand> &Op, const MCExpr *Val,
274762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                        SMLoc S, SMLoc E) {
275762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op.reset(new ARMOperand);
276762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Kind = Immediate;
277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
281cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
282cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
283762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  static void CreateMem(OwningPtr<ARMOperand> &Op,
284762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                        unsigned BaseRegNum, bool OffsetIsReg,
285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                        const MCExpr *Offset, unsigned OffsetRegNum,
286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                        bool OffsetRegShifted, enum ShiftType ShiftType,
287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                        const MCExpr *ShiftAmount, bool Preindexed,
288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                        bool Postindexed, bool Negative, bool Writeback,
289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                        SMLoc S, SMLoc E) {
290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op.reset(new ARMOperand);
291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Kind = Memory;
292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
293762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetIsReg = OffsetIsReg;
294762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Offset = Offset;
295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegNum = OffsetRegNum;
296762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegShifted = OffsetRegShifted;
297762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftAmount = ShiftAmount;
299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Preindexed = Preindexed;
300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Postindexed = Postindexed;
301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Negative = Negative;
302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Writeback = Writeback;
303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
304762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
305762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
310a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
311fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const {
312fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
313fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
314fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << ARMCondCodeToString(getCondCode());
315fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
316fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
317fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
318fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
319fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
320fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "<memory>";
321fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
322fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
323fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "<register " << getReg() << ">";
324fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
325fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
326fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
327fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
328fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
329fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
3303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
3313483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
3323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
3333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
3343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
3353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
3363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
3373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
3389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
3399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and if it is a register name a Reg operand is created, the token is eaten
3409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and false is returned.  Else true is returned and no token is eaten.
3419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO this is likely to change to allow different register types and or to
3429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// parse for a specific register type.
343762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::MaybeParseRegister
344762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  (OwningPtr<ARMOperand> &Op, bool ParseWriteBack) {
345762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
34618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
347a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
348a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
349a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
350a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
351d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  int RegNum;
352a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
353a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  RegNum = MatchRegisterName(Tok.getString());
354d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  if (RegNum == -1)
355a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
356762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
357762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Tok.getLoc();
358762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
359b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
360762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
361762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = Parser.getTok().getLoc();
362a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
36399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  bool Writeback = false;
3649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (ParseWriteBack) {
36518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
3669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
367762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      E = ExclaimTok.getLoc();
3689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      Writeback = true;
369b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
3709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
37199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
37299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
373762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand::CreateReg(Op, RegNum, Writeback, S, E);
37499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
375a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
376a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a register list, return false if successful else return true or an
3799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// error.  The first token must be a '{' when called.
380762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseRegisterList(OwningPtr<ARMOperand> &Op) {
381762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
38218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
383cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby         "Token is not an Left Curly Brace");
384762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
385b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left curly brace token.
386d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
38718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RegTok = Parser.getTok();
388d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  SMLoc RegLoc = RegTok.getLoc();
389d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  if (RegTok.isNot(AsmToken::Identifier))
390d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    return Error(RegLoc, "register expected");
391d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  int RegNum = MatchRegisterName(RegTok.getString());
392d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  if (RegNum == -1)
393d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    return Error(RegLoc, "register expected");
394b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
395d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  unsigned RegList = 1 << RegNum;
396d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
397d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  int HighRegNum = RegNum;
398d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  // TODO ranges like "{Rn-Rm}"
39918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  while (Parser.getTok().is(AsmToken::Comma)) {
400b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
401d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
40218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
403d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
404d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    if (RegTok.isNot(AsmToken::Identifier))
405d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby      return Error(RegLoc, "register expected");
406d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    int RegNum = MatchRegisterName(RegTok.getString());
407d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    if (RegNum == -1)
408d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby      return Error(RegLoc, "register expected");
409d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
410d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    if (RegList & (1 << RegNum))
411d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby      Warning(RegLoc, "register duplicated in register list");
412d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    else if (RegNum <= HighRegNum)
413d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby      Warning(RegLoc, "register not in ascending order in register list");
414d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    RegList |= 1 << RegNum;
415d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    HighRegNum = RegNum;
416d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
417b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat identifier token.
418d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  }
41918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
420d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  if (RCurlyTok.isNot(AsmToken::RCurly))
421d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    return Error(RCurlyTok.getLoc(), "'}' expected");
422762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = RCurlyTok.getLoc();
423b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left curly brace token.
424d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
425d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  return false;
426d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
427d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
4289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true
4299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
4309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed
4319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do.
432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand> &Op) {
433762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
43418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
4356bd266e56799703cd2773cadc4da8bc3c5107fdfKevin Enderby         "Token is not an Left Bracket");
436762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
437b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
438a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
43918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
440a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (BaseRegTok.isNot(AsmToken::Identifier))
441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return Error(BaseRegTok.getLoc(), "register expected");
4429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (MaybeParseRegister(Op, false))
443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return Error(BaseRegTok.getLoc(), "register expected");
444762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  int BaseRegNum = Op->getReg();
445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
446a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Preindexed = false;
447a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Postindexed = false;
448a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool OffsetIsReg = false;
449a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Negative = false;
450a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Writeback = false;
451a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // First look for preindexed address forms, that is after the "[Rn" we now
4539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // have to see if the next token is a comma.
45418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
455a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.is(AsmToken::Comma)) {
456a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Preindexed = true;
457b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
4589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    int OffsetRegNum;
4599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    bool OffsetRegShifted;
460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    enum ShiftType ShiftType;
461a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    const MCExpr *ShiftAmount;
462a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    const MCExpr *Offset;
4639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
464762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            Offset, OffsetIsReg, OffsetRegNum, E))
4659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return true;
46618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RBracTok = Parser.getTok();
467a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (RBracTok.isNot(AsmToken::RBrac))
468a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      return Error(RBracTok.getLoc(), "']' expected");
469762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = RBracTok.getLoc();
470b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
471a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
47218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
473a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      E = ExclaimTok.getLoc();
475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      Writeback = true;
476b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
477a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
479762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                          OffsetRegShifted, ShiftType, ShiftAmount,
480762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                          Preindexed, Postindexed, Negative, Writeback, S, E);
481a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return false;
482a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // The "[Rn" we have so far was not followed by a comma.
484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (Tok.is(AsmToken::RBrac)) {
4859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // This is a post indexing addressing forms, that is a ']' follows after
4869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // the "[Rn".
487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Postindexed = true;
488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Writeback = true;
489762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
490b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
492e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    int OffsetRegNum = 0;
493a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    bool OffsetRegShifted = false;
494a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    enum ShiftType ShiftType;
495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    const MCExpr *ShiftAmount;
496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    const MCExpr *Offset;
497a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
49818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &NextTok = Parser.getTok();
499e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    if (NextTok.isNot(AsmToken::EndOfStatement)) {
500e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby      if (NextTok.isNot(AsmToken::Comma))
5013472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(NextTok.getLoc(), "',' expected");
502b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
5039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
504762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                              ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
505762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                              E))
5069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby        return true;
507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
508e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
509762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
510762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                          OffsetRegShifted, ShiftType, ShiftAmount,
511762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                          Preindexed, Postindexed, Negative, Writeback, S, E);
512a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return false;
513a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
514a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
515a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return true;
516a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
517a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
5199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is
5209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional):
5219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm
5229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm, shift
5239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   #offset
5249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise.
5259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
526762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        bool &OffsetRegShifted,
5279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        enum ShiftType &ShiftType,
5289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&ShiftAmount,
5299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&Offset,
5309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        bool &OffsetIsReg,
531762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        int &OffsetRegNum,
532762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        SMLoc &E) {
533762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  OwningPtr<ARMOperand> Op;
5349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  Negative = false;
5359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegShifted = false;
5369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetIsReg = false;
5379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegNum = -1;
53818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &NextTok = Parser.getTok();
539762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = NextTok.getLoc();
5409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (NextTok.is(AsmToken::Plus))
541b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat plus token.
5429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else if (NextTok.is(AsmToken::Minus)) {
5439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    Negative = true;
544b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat minus token
5459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
5469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
54718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &OffsetRegTok = Parser.getTok();
5489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegTok.is(AsmToken::Identifier)) {
5499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    OffsetIsReg = !MaybeParseRegister(Op, false);
550762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    if (OffsetIsReg) {
551762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      E = Op->getEndLoc();
552762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      OffsetRegNum = Op->getReg();
553762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
5549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
5559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // If we parsed a register as the offset then their can be a shift after that
5569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegNum != -1) {
5579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for a comma then a shift
55818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &Tok = Parser.getTok();
5599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (Tok.is(AsmToken::Comma)) {
560b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
5619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
56218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      const AsmToken &Tok = Parser.getTok();
563762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      if (ParseShift(ShiftType, ShiftAmount, E))
5643472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(Tok.getLoc(), "shift expected");
5659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      OffsetRegShifted = true;
5669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
5679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
5689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
5699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for #offset following the "[Rn," or "[Rn],"
57018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &HashTok = Parser.getTok();
5719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (HashTok.isNot(AsmToken::Hash))
5729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return Error(HashTok.getLoc(), "'#' expected");
573762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
574b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat hash token.
5759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
5769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (getParser().ParseExpression(Offset))
5779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby     return true;
578762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
5809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
5819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
5829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
583a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two:
584a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
585a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
586a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false.
587762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseShift(ShiftType &St,
588762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                              const MCExpr *&ShiftAmount,
589762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                              SMLoc &E) {
59018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
591a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
592a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
59338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
594a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
5959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Lsl;
596a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
5979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Lsr;
598a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
5999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Asr;
600a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
6019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Ror;
602a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
6039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    St = Rrx;
604a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
605a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
606b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
6089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Rrx stands alone.
6099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (St == Rrx)
6109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return false;
611a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
6129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Otherwise, there must be a '#' and a shift amount.
61318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &HashTok = Parser.getTok();
6149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (HashTok.isNot(AsmToken::Hash))
6159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return Error(HashTok.getLoc(), "'#' expected");
616b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat hash token.
6179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
6189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (getParser().ParseExpression(ShiftAmount))
6199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return true;
620a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
621a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
6249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
6259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
626762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseOperand(OwningPtr<ARMOperand> &Op) {
627762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
628762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan
629a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
630a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::Identifier:
6319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (!MaybeParseRegister(Op, true))
632a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      return false;
633515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
634515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
635515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
636762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
637515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
638515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby      return true;
639762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
640762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    ARMOperand::CreateImm(Op, IdVal, S, E);
641515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return false;
642a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
643515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseMemory(Op);
644d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
645515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseRegisterList(Op);
646d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
647079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
648079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
649762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
650b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
651515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
652515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
653cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      return true;
654762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
655762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    ARMOperand::CreateImm(Op, ImmVal, S, E);
656cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return false;
657a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  default:
65818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in operand");
659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
660a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
661a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
6629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands.
66338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
6649898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
665762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  OwningPtr<ARMOperand> Op;
6665747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
6675747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
6685747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
6695747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  StringRef Head = Name.slice(Start, Next);
6705747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
671345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Determine the predicate, if any.
672345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  //
673345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // FIXME: We need a way to check whether a prefix supports predication,
674345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // otherwise we will end up with an ambiguity for instructions that happen to
675345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // end with a predicate name.
676345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2))
677345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("eq", ARMCC::EQ)
678345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ne", ARMCC::NE)
679345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("hs", ARMCC::HS)
680345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("lo", ARMCC::LO)
681345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("mi", ARMCC::MI)
682345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("pl", ARMCC::PL)
683345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("vs", ARMCC::VS)
684345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("vc", ARMCC::VC)
685345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("hi", ARMCC::HI)
686345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ls", ARMCC::LS)
687345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ge", ARMCC::GE)
688345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("lt", ARMCC::LT)
689345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("gt", ARMCC::GT)
690345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("le", ARMCC::LE)
691345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("al", ARMCC::AL)
692345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Default(~0U);
693345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  if (CC != ~0U) {
694345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Head = Head.slice(0, Head.size() - 2);
695345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  } else
696345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    CC = ARMCC::AL;
697345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
6985747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  ARMOperand::CreateToken(Op, Head, NameLoc);
699762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  Operands.push_back(Op.take());
700a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
701345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  ARMOperand::CreateCondCode(Op, ARMCC::CondCodes(CC), NameLoc);
702345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  Operands.push_back(Op.take());
703345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
704345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
7055747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
7065747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
7075747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
7085747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Head = Name.slice(Start, Next);
709a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
7105747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    ARMOperand::CreateToken(Op, Head, NameLoc);
7115747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Operands.push_back(Op.take());
7125747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
7135747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
7145747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
7155747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
716a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
717762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    OwningPtr<ARMOperand> Op;
7189898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner    if (ParseOperand(Op)) return true;
719762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Operands.push_back(Op.take());
720a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
721a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
722b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
723a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
724a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
7259898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner      if (ParseOperand(Op)) return true;
726762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Operands.push_back(Op.take());
727a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
728a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
7299898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
730ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
731ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
732515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives
733ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
734ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
735ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
736ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    return ParseDirectiveWord(4, DirectiveID.getLoc());
737515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
738515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumb(DirectiveID.getLoc());
739515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
740515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
741515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
742515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveCode(DirectiveID.getLoc());
743515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
744515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveSyntax(DirectiveID.getLoc());
745ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
746ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
747ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
748ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord
749ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
750ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
751ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
752ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
753ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
754ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
755ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
756ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
757aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
758ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
759ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
760ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
761ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
762ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
763ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
764ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
765b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
766ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
767ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
768ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
769b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
770ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
771ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
772ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
773515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb
774515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
775515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
776515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
777515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
778b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
779515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
780515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
781515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
782515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
783515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
784515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
785515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
786515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc
787515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
788515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
78918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
790515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
791515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
79218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier();
793b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Consume the identifier token.
794515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
796515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
797b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
798515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
799515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: mark symbol as a thumb symbol
800515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
801515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
802515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
803515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
804515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax
805515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
806515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
80718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
808515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
809515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
81038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
81158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
812b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
81358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
814b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
815515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
816515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
817515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
818515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
81918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
820b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
821515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
822515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
823515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
824515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
825515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
826515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
827515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode
828515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
829515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
83018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
831515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
832515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
83318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
83458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
835b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
83658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
837b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
838515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
839515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
840515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
841515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
84218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
843b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
844515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
845515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
846515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
847515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
848515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
849515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
85090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
85190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
8529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
853ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
854ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
855ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
85690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
857ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
8583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
8593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
860