blob: 185b5168bd6cc1a641e2531045bbeac70d66db3d [file] [log] [blame]
Michael J. Spencer7d490042010-10-09 11:01:07 +00001//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/MC/MCParser/MCAsmParserExtension.h"
Jim Grosbachf2a35fb2011-07-25 17:55:35 +000011#include "llvm/ADT/StringSwitch.h"
Michael J. Spencer7d490042010-10-09 11:01:07 +000012#include "llvm/ADT/Twine.h"
13#include "llvm/MC/MCAsmInfo.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCParser/MCAsmLexer.h"
Evan Cheng0e6a0522011-07-18 20:57:22 +000016#include "llvm/MC/MCRegisterInfo.h"
Michael J. Spencer7d490042010-10-09 11:01:07 +000017#include "llvm/MC/MCSectionCOFF.h"
18#include "llvm/MC/MCStreamer.h"
Charles Davisfbc539f2011-05-22 21:12:15 +000019#include "llvm/MC/MCExpr.h"
Evan Cheng94b95502011-07-26 00:24:13 +000020#include "llvm/MC/MCTargetAsmParser.h"
Michael J. Spencer7d490042010-10-09 11:01:07 +000021#include "llvm/Support/COFF.h"
22using namespace llvm;
23
24namespace {
25
26class COFFAsmParser : public MCAsmParserExtension {
27 template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
28 void AddDirectiveHandler(StringRef Directive) {
29 getParser().AddDirectiveHandler(this, Directive,
30 HandleDirective<COFFAsmParser, Handler>);
31 }
32
33 bool ParseSectionSwitch(StringRef Section,
34 unsigned Characteristics,
35 SectionKind Kind);
36
37 virtual void Initialize(MCAsmParser &Parser) {
38 // Call the base implementation.
39 MCAsmParserExtension::Initialize(Parser);
40
41 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
42 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
43 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
44 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
45 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
46 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
47 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
Charles Davisfbc539f2011-05-22 21:12:15 +000048
49 // Win64 EH directives.
50 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
51 ".seh_proc");
52 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
53 ".seh_endproc");
54 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
55 ".seh_startchained");
56 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
57 ".seh_endchained");
58 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
59 ".seh_handler");
60 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
61 ".seh_handlerdata");
62 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
63 ".seh_pushreg");
64 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
65 ".seh_setframe");
66 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
67 ".seh_stackalloc");
68 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
69 ".seh_savereg");
70 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
71 ".seh_savexmm");
72 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
73 ".seh_pushframe");
74 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
75 ".seh_endprologue");
Jim Grosbachf2a35fb2011-07-25 17:55:35 +000076 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
Michael J. Spencer7d490042010-10-09 11:01:07 +000077 }
78
79 bool ParseSectionDirectiveText(StringRef, SMLoc) {
80 return ParseSectionSwitch(".text",
81 COFF::IMAGE_SCN_CNT_CODE
82 | COFF::IMAGE_SCN_MEM_EXECUTE
83 | COFF::IMAGE_SCN_MEM_READ,
84 SectionKind::getText());
85 }
86 bool ParseSectionDirectiveData(StringRef, SMLoc) {
87 return ParseSectionSwitch(".data",
88 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
89 | COFF::IMAGE_SCN_MEM_READ
90 | COFF::IMAGE_SCN_MEM_WRITE,
91 SectionKind::getDataRel());
92 }
93 bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
94 return ParseSectionSwitch(".bss",
95 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
96 | COFF::IMAGE_SCN_MEM_READ
97 | COFF::IMAGE_SCN_MEM_WRITE,
98 SectionKind::getBSS());
99 }
100
101 bool ParseDirectiveDef(StringRef, SMLoc);
102 bool ParseDirectiveScl(StringRef, SMLoc);
103 bool ParseDirectiveType(StringRef, SMLoc);
104 bool ParseDirectiveEndef(StringRef, SMLoc);
105
Charles Davisfbc539f2011-05-22 21:12:15 +0000106 // Win64 EH directives.
107 bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
108 bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
109 bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
110 bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
111 bool ParseSEHDirectiveHandler(StringRef, SMLoc);
112 bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
Charles Davis3b32d022011-05-24 20:06:30 +0000113 bool ParseSEHDirectivePushReg(StringRef, SMLoc);
114 bool ParseSEHDirectiveSetFrame(StringRef, SMLoc);
115 bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
116 bool ParseSEHDirectiveSaveReg(StringRef, SMLoc);
117 bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc);
118 bool ParseSEHDirectivePushFrame(StringRef, SMLoc);
Charles Davisfbc539f2011-05-22 21:12:15 +0000119 bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
120
121 bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
Charles Davis3b32d022011-05-24 20:06:30 +0000122 bool ParseSEHRegisterNumber(unsigned &RegNo);
Jim Grosbachf2a35fb2011-07-25 17:55:35 +0000123 bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
Michael J. Spencer7d490042010-10-09 11:01:07 +0000124public:
125 COFFAsmParser() {}
126};
127
128} // end annonomous namespace.
129
Jim Grosbachf2a35fb2011-07-25 17:55:35 +0000130/// ParseDirectiveSymbolAttribute
131/// ::= { ".weak", ... } [ identifier ( , identifier )* ]
132bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
133 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
134 .Case(".weak", MCSA_Weak)
135 .Default(MCSA_Invalid);
136 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
137 if (getLexer().isNot(AsmToken::EndOfStatement)) {
138 for (;;) {
139 StringRef Name;
140
141 if (getParser().ParseIdentifier(Name))
142 return TokError("expected identifier in directive");
143
144 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
145
146 getStreamer().EmitSymbolAttribute(Sym, Attr);
147
148 if (getLexer().is(AsmToken::EndOfStatement))
149 break;
150
151 if (getLexer().isNot(AsmToken::Comma))
152 return TokError("unexpected token in directive");
153 Lex();
154 }
155 }
156
157 Lex();
158 return false;
159}
160
Michael J. Spencer7d490042010-10-09 11:01:07 +0000161bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
162 unsigned Characteristics,
163 SectionKind Kind) {
164 if (getLexer().isNot(AsmToken::EndOfStatement))
165 return TokError("unexpected token in section switching directive");
166 Lex();
167
168 getStreamer().SwitchSection(getContext().getCOFFSection(
169 Section, Characteristics, Kind));
170
171 return false;
172}
173
174bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
175 StringRef SymbolName;
176
177 if (getParser().ParseIdentifier(SymbolName))
178 return TokError("expected identifier in directive");
179
180 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
181
182 getStreamer().BeginCOFFSymbolDef(Sym);
183
184 Lex();
185 return false;
186}
187
188bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
189 int64_t SymbolStorageClass;
190 if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
191 return true;
192
193 if (getLexer().isNot(AsmToken::EndOfStatement))
194 return TokError("unexpected token in directive");
195
196 Lex();
197 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
198 return false;
199}
200
201bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
202 int64_t Type;
203 if (getParser().ParseAbsoluteExpression(Type))
204 return true;
205
206 if (getLexer().isNot(AsmToken::EndOfStatement))
207 return TokError("unexpected token in directive");
208
209 Lex();
210 getStreamer().EmitCOFFSymbolType(Type);
211 return false;
212}
213
214bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
215 Lex();
216 getStreamer().EndCOFFSymbolDef();
217 return false;
218}
219
Charles Davisfbc539f2011-05-22 21:12:15 +0000220bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
Charles Davis30921322011-05-25 01:33:42 +0000221 StringRef SymbolID;
222 if (getParser().ParseIdentifier(SymbolID))
Charles Davisfbc539f2011-05-22 21:12:15 +0000223 return true;
224
Charles Davisfbc539f2011-05-22 21:12:15 +0000225 if (getLexer().isNot(AsmToken::EndOfStatement))
226 return TokError("unexpected token in directive");
227
Charles Davis30921322011-05-25 01:33:42 +0000228 MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
229
Charles Davisfbc539f2011-05-22 21:12:15 +0000230 Lex();
Charles Davis30921322011-05-25 01:33:42 +0000231 getStreamer().EmitWin64EHStartProc(Symbol);
Charles Davisfbc539f2011-05-22 21:12:15 +0000232 return false;
233}
234
235bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
236 Lex();
237 getStreamer().EmitWin64EHEndProc();
238 return false;
239}
240
241bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
242 Lex();
243 getStreamer().EmitWin64EHStartChained();
244 return false;
245}
246
247bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
248 Lex();
249 getStreamer().EmitWin64EHEndChained();
250 return false;
251}
252
253bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
Charles Davis30921322011-05-25 01:33:42 +0000254 StringRef SymbolID;
255 if (getParser().ParseIdentifier(SymbolID))
Charles Davisfbc539f2011-05-22 21:12:15 +0000256 return true;
257
Charles Davis30921322011-05-25 01:33:42 +0000258 if (getLexer().isNot(AsmToken::Comma))
259 return TokError("you must specify one or both of @unwind or @except");
260 Lex();
Charles Davisfbc539f2011-05-22 21:12:15 +0000261 bool unwind = false, except = false;
Charles Davis30921322011-05-25 01:33:42 +0000262 if (ParseAtUnwindOrAtExcept(unwind, except))
263 return true;
Charles Davisfbc539f2011-05-22 21:12:15 +0000264 if (getLexer().is(AsmToken::Comma)) {
265 Lex();
Charles Davis30921322011-05-25 01:33:42 +0000266 if (ParseAtUnwindOrAtExcept(unwind, except))
Charles Davisfbc539f2011-05-22 21:12:15 +0000267 return true;
268 }
269 if (getLexer().isNot(AsmToken::EndOfStatement))
270 return TokError("unexpected token in directive");
271
Charles Davis30921322011-05-25 01:33:42 +0000272 MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID);
273
Charles Davisfbc539f2011-05-22 21:12:15 +0000274 Lex();
Charles Davis30921322011-05-25 01:33:42 +0000275 getStreamer().EmitWin64EHHandler(handler, unwind, except);
Charles Davisfbc539f2011-05-22 21:12:15 +0000276 return false;
277}
278
279bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
280 Lex();
281 getStreamer().EmitWin64EHHandlerData();
282 return false;
283}
284
285bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
Charles Davis3b32d022011-05-24 20:06:30 +0000286 unsigned Reg;
287 if (ParseSEHRegisterNumber(Reg))
288 return true;
289
290 if (getLexer().isNot(AsmToken::EndOfStatement))
291 return TokError("unexpected token in directive");
292
293 Lex();
294 getStreamer().EmitWin64EHPushReg(Reg);
295 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000296}
297
298bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
Charles Davis3b32d022011-05-24 20:06:30 +0000299 unsigned Reg;
300 int64_t Off;
301 if (ParseSEHRegisterNumber(Reg))
302 return true;
Charles Davis410ef2b2011-05-25 21:43:45 +0000303 if (getLexer().isNot(AsmToken::Comma))
304 return TokError("you must specify a stack pointer offset");
305
306 Lex();
Charles Davis3b32d022011-05-24 20:06:30 +0000307 SMLoc startLoc = getLexer().getLoc();
308 if (getParser().ParseAbsoluteExpression(Off))
309 return true;
310
311 if (Off & 0x0F)
312 return Error(startLoc, "offset is not a multiple of 16");
313
314 if (getLexer().isNot(AsmToken::EndOfStatement))
315 return TokError("unexpected token in directive");
316
317 Lex();
318 getStreamer().EmitWin64EHSetFrame(Reg, Off);
319 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000320}
321
Charles Davis16e1b3f2011-05-23 16:43:09 +0000322bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
323 int64_t Size;
Charles Davis3b32d022011-05-24 20:06:30 +0000324 SMLoc startLoc = getLexer().getLoc();
Charles Davis16e1b3f2011-05-23 16:43:09 +0000325 if (getParser().ParseAbsoluteExpression(Size))
326 return true;
327
Charles Davis3b32d022011-05-24 20:06:30 +0000328 if (Size & 7)
329 return Error(startLoc, "size is not a multiple of 8");
330
Charles Davis16e1b3f2011-05-23 16:43:09 +0000331 if (getLexer().isNot(AsmToken::EndOfStatement))
332 return TokError("unexpected token in directive");
333
334 Lex();
335 getStreamer().EmitWin64EHAllocStack(Size);
336 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000337}
338
339bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
Charles Davis3b32d022011-05-24 20:06:30 +0000340 unsigned Reg;
341 int64_t Off;
342 if (ParseSEHRegisterNumber(Reg))
343 return true;
Charles Davis575630c2011-05-25 04:51:25 +0000344 if (getLexer().isNot(AsmToken::Comma))
Charles Davis410ef2b2011-05-25 21:43:45 +0000345 return TokError("you must specify an offset on the stack");
Charles Davis575630c2011-05-25 04:51:25 +0000346
347 Lex();
Charles Davis3b32d022011-05-24 20:06:30 +0000348 SMLoc startLoc = getLexer().getLoc();
349 if (getParser().ParseAbsoluteExpression(Off))
350 return true;
351
352 if (Off & 7)
353 return Error(startLoc, "size is not a multiple of 8");
354
355 if (getLexer().isNot(AsmToken::EndOfStatement))
356 return TokError("unexpected token in directive");
357
358 Lex();
359 // FIXME: Err on %xmm* registers
360 getStreamer().EmitWin64EHSaveReg(Reg, Off);
361 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000362}
363
Charles Davis3b32d022011-05-24 20:06:30 +0000364// FIXME: This method is inherently x86-specific. It should really be in the
365// x86 backend.
Charles Davisfbc539f2011-05-22 21:12:15 +0000366bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
Charles Davis3b32d022011-05-24 20:06:30 +0000367 unsigned Reg;
368 int64_t Off;
369 if (ParseSEHRegisterNumber(Reg))
370 return true;
Charles Davis575630c2011-05-25 04:51:25 +0000371 if (getLexer().isNot(AsmToken::Comma))
Charles Davis410ef2b2011-05-25 21:43:45 +0000372 return TokError("you must specify an offset on the stack");
Charles Davis575630c2011-05-25 04:51:25 +0000373
374 Lex();
Charles Davis3b32d022011-05-24 20:06:30 +0000375 SMLoc startLoc = getLexer().getLoc();
376 if (getParser().ParseAbsoluteExpression(Off))
377 return true;
378
379 if (getLexer().isNot(AsmToken::EndOfStatement))
380 return TokError("unexpected token in directive");
381
382 if (Off & 0x0F)
383 return Error(startLoc, "offset is not a multiple of 16");
384
385 Lex();
386 // FIXME: Err on non-%xmm* registers
387 getStreamer().EmitWin64EHSaveXMM(Reg, Off);
388 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000389}
390
Charles Davis16e1b3f2011-05-23 16:43:09 +0000391bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
Charles Davis47268162011-05-25 04:08:15 +0000392 bool Code = false;
Charles Davis16e1b3f2011-05-23 16:43:09 +0000393 StringRef CodeID;
Charles Davis47268162011-05-25 04:08:15 +0000394 if (getLexer().is(AsmToken::At)) {
395 SMLoc startLoc = getLexer().getLoc();
396 Lex();
397 if (!getParser().ParseIdentifier(CodeID)) {
398 if (CodeID != "code")
399 return Error(startLoc, "expected @code");
400 Code = true;
401 }
Charles Davis16e1b3f2011-05-23 16:43:09 +0000402 }
403
404 if (getLexer().isNot(AsmToken::EndOfStatement))
405 return TokError("unexpected token in directive");
406
407 Lex();
408 getStreamer().EmitWin64EHPushFrame(Code);
409 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000410}
411
412bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
413 Lex();
414 getStreamer().EmitWin64EHEndProlog();
415 return false;
416}
417
418bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
419 StringRef identifier;
Charles Davis30921322011-05-25 01:33:42 +0000420 if (getLexer().isNot(AsmToken::At))
421 return TokError("a handler attribute must begin with '@'");
Charles Davisfbc539f2011-05-22 21:12:15 +0000422 SMLoc startLoc = getLexer().getLoc();
Charles Davis30921322011-05-25 01:33:42 +0000423 Lex();
424 if (getParser().ParseIdentifier(identifier))
Charles Davisfbc539f2011-05-22 21:12:15 +0000425 return Error(startLoc, "expected @unwind or @except");
Charles Davis30921322011-05-25 01:33:42 +0000426 if (identifier == "unwind")
Charles Davisfbc539f2011-05-22 21:12:15 +0000427 unwind = true;
Charles Davis30921322011-05-25 01:33:42 +0000428 else if (identifier == "except")
Charles Davisfbc539f2011-05-22 21:12:15 +0000429 except = true;
430 else
431 return Error(startLoc, "expected @unwind or @except");
432 return false;
433}
434
Charles Davis3b32d022011-05-24 20:06:30 +0000435bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
Charles Davis3b32d022011-05-24 20:06:30 +0000436 SMLoc startLoc = getLexer().getLoc();
Charles Davis575630c2011-05-25 04:51:25 +0000437 if (getLexer().is(AsmToken::Percent)) {
Evan Cheng0e6a0522011-07-18 20:57:22 +0000438 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
Charles Davis3b32d022011-05-24 20:06:30 +0000439 SMLoc endLoc;
440 unsigned LLVMRegNo;
441 if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
Charles Davis575630c2011-05-25 04:51:25 +0000442 return true;
Charles Davis3b32d022011-05-24 20:06:30 +0000443
Evan Cheng0e6a0522011-07-18 20:57:22 +0000444#if 0
445 // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
446 // violation so this validation code is disabled.
447
Charles Davis3b32d022011-05-24 20:06:30 +0000448 // Check that this is a non-volatile register.
Evan Cheng1be0e272011-07-15 02:09:41 +0000449 const unsigned *NVRegs = TAI.getCalleeSavedRegs();
Charles Davis3b32d022011-05-24 20:06:30 +0000450 unsigned i;
451 for (i = 0; NVRegs[i] != 0; ++i)
452 if (NVRegs[i] == LLVMRegNo)
453 break;
454 if (NVRegs[i] == 0)
455 return Error(startLoc, "expected non-volatile register");
Evan Cheng0e6a0522011-07-18 20:57:22 +0000456#endif
Charles Davis3b32d022011-05-24 20:06:30 +0000457
Evan Cheng0e6a0522011-07-18 20:57:22 +0000458 int SEHRegNo = MRI.getSEHRegNum(LLVMRegNo);
Charles Davis3b32d022011-05-24 20:06:30 +0000459 if (SEHRegNo < 0)
460 return Error(startLoc,"register can't be represented in SEH unwind info");
461 RegNo = SEHRegNo;
462 }
Charles Davis575630c2011-05-25 04:51:25 +0000463 else {
464 int64_t n;
465 if (getParser().ParseAbsoluteExpression(n))
466 return true;
467 if (n > 15)
468 return Error(startLoc, "register number is too high");
Charles Davis3b32d022011-05-24 20:06:30 +0000469 RegNo = n;
Charles Davis575630c2011-05-25 04:51:25 +0000470 }
Charles Davis3b32d022011-05-24 20:06:30 +0000471
Charles Davis3b32d022011-05-24 20:06:30 +0000472 return false;
473}
474
Michael J. Spencer7d490042010-10-09 11:01:07 +0000475namespace llvm {
476
477MCAsmParserExtension *createCOFFAsmParser() {
478 return new COFFAsmParser;
479}
480
481}