blob: 5bb5d98ccc9b90793942026fce4b9a31418aebe7 [file] [log] [blame]
Michael J. Spencerc8dbdfd2010-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 Grosbach38b1ed82011-07-25 17:55:35 +000011#include "llvm/ADT/StringSwitch.h"
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +000012#include "llvm/ADT/Twine.h"
13#include "llvm/MC/MCAsmInfo.h"
14#include "llvm/MC/MCContext.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "llvm/MC/MCExpr.h"
Saleem Abdulrasoolbdbc0082014-06-22 22:25:01 +000016#include "llvm/MC/MCObjectFileInfo.h"
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +000017#include "llvm/MC/MCParser/MCAsmLexer.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000018#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Evan Chengd60fa58b2011-07-18 20:57:22 +000019#include "llvm/MC/MCRegisterInfo.h"
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +000020#include "llvm/MC/MCSectionCOFF.h"
21#include "llvm/MC/MCStreamer.h"
22#include "llvm/Support/COFF.h"
23using namespace llvm;
24
25namespace {
26
27class COFFAsmParser : public MCAsmParserExtension {
Eli Bendersky29b9f472013-01-16 00:50:52 +000028 template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
Jim Grosbachd2037eb2013-02-20 22:21:35 +000029 void addDirectiveHandler(StringRef Directive) {
Eli Bendersky29b9f472013-01-16 00:50:52 +000030 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
31 this, HandleDirective<COFFAsmParser, HandlerMethod>);
Jim Grosbachd2037eb2013-02-20 22:21:35 +000032 getParser().addDirectiveHandler(Directive, Handler);
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +000033 }
34
35 bool ParseSectionSwitch(StringRef Section,
36 unsigned Characteristics,
37 SectionKind Kind);
38
Rafael Espindola60ec3832013-11-19 19:52:52 +000039 bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
40 SectionKind Kind, StringRef COMDATSymName,
Rafael Espindola0766ae02014-06-06 19:26:12 +000041 COFF::COMDATType Type);
Rafael Espindola60ec3832013-11-19 19:52:52 +000042
Nico Rieck1558c5a2013-07-04 21:32:07 +000043 bool ParseSectionName(StringRef &SectionName);
Reid Kleckner31263732016-09-14 22:41:50 +000044 bool ParseSectionFlags(StringRef SectionName, StringRef FlagsString,
45 unsigned *Flags);
Nico Rieck1558c5a2013-07-04 21:32:07 +000046
Craig Topper59be68f2014-03-08 07:14:16 +000047 void Initialize(MCAsmParser &Parser) override {
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +000048 // Call the base implementation.
49 MCAsmParserExtension::Initialize(Parser);
50
Jim Grosbachd2037eb2013-02-20 22:21:35 +000051 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
52 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
53 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
Nico Rieck1558c5a2013-07-04 21:32:07 +000054 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000055 addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
56 addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
57 addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
58 addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
59 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
Timur Iskhodzhanovc1fb2d62013-12-20 18:15:00 +000060 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
David Majnemer4eecd302015-05-30 04:56:02 +000061 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(".safeseh");
Nico Riecka37acf72013-07-06 12:13:10 +000062 addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
Charles Davisc7250fa2011-05-22 21:12:15 +000063
64 // Win64 EH directives.
Jim Grosbachd2037eb2013-02-20 22:21:35 +000065 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
Charles Davisc7250fa2011-05-22 21:12:15 +000066 ".seh_proc");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000067 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
Charles Davisc7250fa2011-05-22 21:12:15 +000068 ".seh_endproc");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000069 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
Charles Davisc7250fa2011-05-22 21:12:15 +000070 ".seh_startchained");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000071 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
Charles Davisc7250fa2011-05-22 21:12:15 +000072 ".seh_endchained");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000073 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
Charles Davisc7250fa2011-05-22 21:12:15 +000074 ".seh_handler");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000075 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
Charles Davisc7250fa2011-05-22 21:12:15 +000076 ".seh_handlerdata");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000077 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
Charles Davisc7250fa2011-05-22 21:12:15 +000078 ".seh_pushreg");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000079 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
Charles Davisc7250fa2011-05-22 21:12:15 +000080 ".seh_setframe");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000081 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
Charles Davisc7250fa2011-05-22 21:12:15 +000082 ".seh_stackalloc");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000083 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
Charles Davisc7250fa2011-05-22 21:12:15 +000084 ".seh_savereg");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000085 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
Charles Davisc7250fa2011-05-22 21:12:15 +000086 ".seh_savexmm");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000087 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
Charles Davisc7250fa2011-05-22 21:12:15 +000088 ".seh_pushframe");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000089 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
Charles Davisc7250fa2011-05-22 21:12:15 +000090 ".seh_endprologue");
Jim Grosbachd2037eb2013-02-20 22:21:35 +000091 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +000092 }
93
94 bool ParseSectionDirectiveText(StringRef, SMLoc) {
95 return ParseSectionSwitch(".text",
96 COFF::IMAGE_SCN_CNT_CODE
97 | COFF::IMAGE_SCN_MEM_EXECUTE
98 | COFF::IMAGE_SCN_MEM_READ,
99 SectionKind::getText());
100 }
101 bool ParseSectionDirectiveData(StringRef, SMLoc) {
Rafael Espindola449711c2015-11-18 06:02:15 +0000102 return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
103 COFF::IMAGE_SCN_MEM_READ |
104 COFF::IMAGE_SCN_MEM_WRITE,
105 SectionKind::getData());
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000106 }
107 bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
108 return ParseSectionSwitch(".bss",
109 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
110 | COFF::IMAGE_SCN_MEM_READ
111 | COFF::IMAGE_SCN_MEM_WRITE,
112 SectionKind::getBSS());
113 }
114
Nico Rieck1558c5a2013-07-04 21:32:07 +0000115 bool ParseDirectiveSection(StringRef, SMLoc);
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000116 bool ParseDirectiveDef(StringRef, SMLoc);
117 bool ParseDirectiveScl(StringRef, SMLoc);
118 bool ParseDirectiveType(StringRef, SMLoc);
119 bool ParseDirectiveEndef(StringRef, SMLoc);
Rafael Espindolad3df3d32011-12-17 01:14:52 +0000120 bool ParseDirectiveSecRel32(StringRef, SMLoc);
Timur Iskhodzhanovc1fb2d62013-12-20 18:15:00 +0000121 bool ParseDirectiveSecIdx(StringRef, SMLoc);
David Majnemer4eecd302015-05-30 04:56:02 +0000122 bool ParseDirectiveSafeSEH(StringRef, SMLoc);
Rafael Espindola0766ae02014-06-06 19:26:12 +0000123 bool parseCOMDATType(COFF::COMDATType &Type);
Nico Riecka37acf72013-07-06 12:13:10 +0000124 bool ParseDirectiveLinkOnce(StringRef, SMLoc);
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000125
Charles Davisc7250fa2011-05-22 21:12:15 +0000126 // Win64 EH directives.
127 bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
128 bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
129 bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
130 bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
131 bool ParseSEHDirectiveHandler(StringRef, SMLoc);
132 bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
Charles Davis7f6176c2011-05-24 20:06:30 +0000133 bool ParseSEHDirectivePushReg(StringRef, SMLoc);
134 bool ParseSEHDirectiveSetFrame(StringRef, SMLoc);
135 bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
136 bool ParseSEHDirectiveSaveReg(StringRef, SMLoc);
137 bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc);
138 bool ParseSEHDirectivePushFrame(StringRef, SMLoc);
Charles Davisc7250fa2011-05-22 21:12:15 +0000139 bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
140
141 bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
Charles Davis7f6176c2011-05-24 20:06:30 +0000142 bool ParseSEHRegisterNumber(unsigned &RegNo);
Jim Grosbach38b1ed82011-07-25 17:55:35 +0000143 bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000144public:
145 COFFAsmParser() {}
146};
147
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000148} // end annonomous namespace.
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000149
Nico Rieck1558c5a2013-07-04 21:32:07 +0000150static SectionKind computeSectionKind(unsigned Flags) {
151 if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
152 return SectionKind::getText();
153 if (Flags & COFF::IMAGE_SCN_MEM_READ &&
154 (Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0)
155 return SectionKind::getReadOnly();
Rafael Espindola449711c2015-11-18 06:02:15 +0000156 return SectionKind::getData();
Nico Rieck1558c5a2013-07-04 21:32:07 +0000157}
158
Reid Kleckner31263732016-09-14 22:41:50 +0000159bool COFFAsmParser::ParseSectionFlags(StringRef SectionName,
160 StringRef FlagsString, unsigned *Flags) {
Nico Rieck1558c5a2013-07-04 21:32:07 +0000161 enum {
Reid Kleckner31263732016-09-14 22:41:50 +0000162 None = 0,
163 Alloc = 1 << 0,
164 Code = 1 << 1,
165 Load = 1 << 2,
166 InitData = 1 << 3,
167 Shared = 1 << 4,
168 NoLoad = 1 << 5,
169 NoRead = 1 << 6,
170 NoWrite = 1 << 7,
171 Discardable = 1 << 8,
Nico Rieck1558c5a2013-07-04 21:32:07 +0000172 };
173
174 bool ReadOnlyRemoved = false;
175 unsigned SecFlags = None;
176
David Majnemerbee5f752014-07-04 23:15:28 +0000177 for (char FlagChar : FlagsString) {
178 switch (FlagChar) {
Nico Rieck1558c5a2013-07-04 21:32:07 +0000179 case 'a':
180 // Ignored.
181 break;
182
183 case 'b': // bss section
184 SecFlags |= Alloc;
185 if (SecFlags & InitData)
186 return TokError("conflicting section flags 'b' and 'd'.");
187 SecFlags &= ~Load;
188 break;
189
190 case 'd': // data section
191 SecFlags |= InitData;
192 if (SecFlags & Alloc)
193 return TokError("conflicting section flags 'b' and 'd'.");
194 SecFlags &= ~NoWrite;
195 if ((SecFlags & NoLoad) == 0)
196 SecFlags |= Load;
197 break;
198
199 case 'n': // section is not loaded
200 SecFlags |= NoLoad;
201 SecFlags &= ~Load;
202 break;
203
Reid Kleckner31263732016-09-14 22:41:50 +0000204 case 'D': // discardable
205 SecFlags |= Discardable;
206 break;
207
Nico Rieck1558c5a2013-07-04 21:32:07 +0000208 case 'r': // read-only
209 ReadOnlyRemoved = false;
210 SecFlags |= NoWrite;
211 if ((SecFlags & Code) == 0)
212 SecFlags |= InitData;
213 if ((SecFlags & NoLoad) == 0)
214 SecFlags |= Load;
215 break;
216
217 case 's': // shared section
218 SecFlags |= Shared | InitData;
219 SecFlags &= ~NoWrite;
220 if ((SecFlags & NoLoad) == 0)
221 SecFlags |= Load;
222 break;
223
224 case 'w': // writable
225 SecFlags &= ~NoWrite;
226 ReadOnlyRemoved = true;
227 break;
228
229 case 'x': // executable section
230 SecFlags |= Code;
231 if ((SecFlags & NoLoad) == 0)
232 SecFlags |= Load;
233 if (!ReadOnlyRemoved)
234 SecFlags |= NoWrite;
235 break;
236
237 case 'y': // not readable
238 SecFlags |= NoRead | NoWrite;
239 break;
240
241 default:
242 return TokError("unknown flag");
243 }
244 }
245
246 *Flags = 0;
247
248 if (SecFlags == None)
249 SecFlags = InitData;
250
251 if (SecFlags & Code)
252 *Flags |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE;
253 if (SecFlags & InitData)
254 *Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
255 if ((SecFlags & Alloc) && (SecFlags & Load) == 0)
256 *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
257 if (SecFlags & NoLoad)
258 *Flags |= COFF::IMAGE_SCN_LNK_REMOVE;
Reid Kleckner31263732016-09-14 22:41:50 +0000259 if ((SecFlags & Discardable) ||
260 MCSectionCOFF::isImplicitlyDiscardable(SectionName))
261 *Flags |= COFF::IMAGE_SCN_MEM_DISCARDABLE;
Nico Rieck1558c5a2013-07-04 21:32:07 +0000262 if ((SecFlags & NoRead) == 0)
263 *Flags |= COFF::IMAGE_SCN_MEM_READ;
264 if ((SecFlags & NoWrite) == 0)
265 *Flags |= COFF::IMAGE_SCN_MEM_WRITE;
266 if (SecFlags & Shared)
267 *Flags |= COFF::IMAGE_SCN_MEM_SHARED;
268
269 return false;
270}
271
Jim Grosbach38b1ed82011-07-25 17:55:35 +0000272/// ParseDirectiveSymbolAttribute
273/// ::= { ".weak", ... } [ identifier ( , identifier )* ]
274bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
275 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
276 .Case(".weak", MCSA_Weak)
277 .Default(MCSA_Invalid);
278 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
279 if (getLexer().isNot(AsmToken::EndOfStatement)) {
280 for (;;) {
281 StringRef Name;
282
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000283 if (getParser().parseIdentifier(Name))
Jim Grosbach38b1ed82011-07-25 17:55:35 +0000284 return TokError("expected identifier in directive");
285
Jim Grosbach6f482002015-05-18 18:43:14 +0000286 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
Jim Grosbach38b1ed82011-07-25 17:55:35 +0000287
288 getStreamer().EmitSymbolAttribute(Sym, Attr);
289
290 if (getLexer().is(AsmToken::EndOfStatement))
291 break;
292
293 if (getLexer().isNot(AsmToken::Comma))
294 return TokError("unexpected token in directive");
295 Lex();
296 }
297 }
298
299 Lex();
300 return false;
301}
302
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000303bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
304 unsigned Characteristics,
305 SectionKind Kind) {
David Majnemerc57d0382014-06-27 17:19:44 +0000306 return ParseSectionSwitch(Section, Characteristics, Kind, "", (COFF::COMDATType)0);
Rafael Espindola60ec3832013-11-19 19:52:52 +0000307}
308
309bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
310 unsigned Characteristics,
311 SectionKind Kind,
312 StringRef COMDATSymName,
Rafael Espindola0766ae02014-06-06 19:26:12 +0000313 COFF::COMDATType Type) {
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000314 if (getLexer().isNot(AsmToken::EndOfStatement))
315 return TokError("unexpected token in section switching directive");
316 Lex();
317
318 getStreamer().SwitchSection(getContext().getCOFFSection(
Rafael Espindola0766ae02014-06-06 19:26:12 +0000319 Section, Characteristics, Kind, COMDATSymName, Type));
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000320
321 return false;
322}
323
Nico Rieck1558c5a2013-07-04 21:32:07 +0000324bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
Hans Wennborg7ddcdc82013-10-18 02:14:40 +0000325 if (!getLexer().is(AsmToken::Identifier))
326 return true;
327
328 SectionName = getTok().getIdentifier();
329 Lex();
330 return false;
Nico Rieck1558c5a2013-07-04 21:32:07 +0000331}
332
Rafael Espindola60ec3832013-11-19 19:52:52 +0000333// .section name [, "flags"] [, identifier [ identifier ], identifier]
Nico Rieck1558c5a2013-07-04 21:32:07 +0000334//
335// Supported flags:
336// a: Ignored.
337// b: BSS section (uninitialized data)
338// d: data section (initialized data)
Reid Kleckner31263732016-09-14 22:41:50 +0000339// n: "noload" section (removed by linker)
340// D: Discardable section
Nico Rieck1558c5a2013-07-04 21:32:07 +0000341// r: Readable section
342// s: Shared section
343// w: Writable section
344// x: Executable section
345// y: Not-readable section (clears 'r')
346//
347// Subsections are not supported.
348bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
349 StringRef SectionName;
350
351 if (ParseSectionName(SectionName))
352 return TokError("expected identifier in directive");
353
354 unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
355 COFF::IMAGE_SCN_MEM_READ |
356 COFF::IMAGE_SCN_MEM_WRITE;
357
358 if (getLexer().is(AsmToken::Comma)) {
359 Lex();
360
361 if (getLexer().isNot(AsmToken::String))
362 return TokError("expected string in directive");
363
364 StringRef FlagsStr = getTok().getStringContents();
365 Lex();
366
Reid Kleckner31263732016-09-14 22:41:50 +0000367 if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
Nico Rieck1558c5a2013-07-04 21:32:07 +0000368 return true;
369 }
370
David Majnemerc57d0382014-06-27 17:19:44 +0000371 COFF::COMDATType Type = (COFF::COMDATType)0;
Rafael Espindola60ec3832013-11-19 19:52:52 +0000372 StringRef COMDATSymName;
373 if (getLexer().is(AsmToken::Comma)) {
Aaron Ballman3182ee92015-06-09 12:03:46 +0000374 Type = COFF::IMAGE_COMDAT_SELECT_ANY;
Rafael Espindola60ec3832013-11-19 19:52:52 +0000375 Lex();
376
377 Flags |= COFF::IMAGE_SCN_LNK_COMDAT;
378
Reid Kleckner21aedc42014-08-11 18:34:43 +0000379 if (!getLexer().is(AsmToken::Identifier))
380 return TokError("expected comdat type such as 'discard' or 'largest' "
381 "after protection bits");
382
Rafael Espindola0766ae02014-06-06 19:26:12 +0000383 if (parseCOMDATType(Type))
Rafael Espindola60ec3832013-11-19 19:52:52 +0000384 return true;
385
386 if (getLexer().isNot(AsmToken::Comma))
387 return TokError("expected comma in directive");
388 Lex();
389
390 if (getParser().parseIdentifier(COMDATSymName))
391 return TokError("expected identifier in directive");
392 }
393
Nico Rieck1558c5a2013-07-04 21:32:07 +0000394 if (getLexer().isNot(AsmToken::EndOfStatement))
395 return TokError("unexpected token in directive");
396
397 SectionKind Kind = computeSectionKind(Flags);
Saleem Abdulrasoolbdbc0082014-06-22 22:25:01 +0000398 if (Kind.isText()) {
399 const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
400 if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
401 Flags |= COFF::IMAGE_SCN_MEM_16BIT;
402 }
Rafael Espindola0766ae02014-06-06 19:26:12 +0000403 ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
Nico Rieck1558c5a2013-07-04 21:32:07 +0000404 return false;
405}
406
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000407bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
408 StringRef SymbolName;
409
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000410 if (getParser().parseIdentifier(SymbolName))
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000411 return TokError("expected identifier in directive");
412
Jim Grosbach6f482002015-05-18 18:43:14 +0000413 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000414
415 getStreamer().BeginCOFFSymbolDef(Sym);
416
417 Lex();
418 return false;
419}
420
421bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
422 int64_t SymbolStorageClass;
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000423 if (getParser().parseAbsoluteExpression(SymbolStorageClass))
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000424 return true;
425
426 if (getLexer().isNot(AsmToken::EndOfStatement))
427 return TokError("unexpected token in directive");
428
429 Lex();
430 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
431 return false;
432}
433
434bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
435 int64_t Type;
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000436 if (getParser().parseAbsoluteExpression(Type))
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000437 return true;
438
439 if (getLexer().isNot(AsmToken::EndOfStatement))
440 return TokError("unexpected token in directive");
441
442 Lex();
443 getStreamer().EmitCOFFSymbolType(Type);
444 return false;
445}
446
447bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
448 Lex();
449 getStreamer().EndCOFFSymbolDef();
450 return false;
451}
452
Rafael Espindolad3df3d32011-12-17 01:14:52 +0000453bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
454 StringRef SymbolID;
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000455 if (getParser().parseIdentifier(SymbolID))
Timur Iskhodzhanovc1fb2d62013-12-20 18:15:00 +0000456 return TokError("expected identifier in directive");
Rafael Espindolad3df3d32011-12-17 01:14:52 +0000457
458 if (getLexer().isNot(AsmToken::EndOfStatement))
459 return TokError("unexpected token in directive");
460
Jim Grosbach6f482002015-05-18 18:43:14 +0000461 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
Rafael Espindolad3df3d32011-12-17 01:14:52 +0000462
463 Lex();
464 getStreamer().EmitCOFFSecRel32(Symbol);
465 return false;
466}
467
David Majnemer4eecd302015-05-30 04:56:02 +0000468bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) {
469 StringRef SymbolID;
470 if (getParser().parseIdentifier(SymbolID))
471 return TokError("expected identifier in directive");
472
473 if (getLexer().isNot(AsmToken::EndOfStatement))
474 return TokError("unexpected token in directive");
475
476 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
477
478 Lex();
479 getStreamer().EmitCOFFSafeSEH(Symbol);
480 return false;
481}
482
Timur Iskhodzhanovc1fb2d62013-12-20 18:15:00 +0000483bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
484 StringRef SymbolID;
485 if (getParser().parseIdentifier(SymbolID))
486 return TokError("expected identifier in directive");
487
488 if (getLexer().isNot(AsmToken::EndOfStatement))
489 return TokError("unexpected token in directive");
490
Jim Grosbach6f482002015-05-18 18:43:14 +0000491 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
Timur Iskhodzhanovc1fb2d62013-12-20 18:15:00 +0000492
493 Lex();
494 getStreamer().EmitCOFFSectionIndex(Symbol);
495 return false;
496}
497
Rafael Espindola0766ae02014-06-06 19:26:12 +0000498/// ::= [ identifier ]
499bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
Rafael Espindola60ec3832013-11-19 19:52:52 +0000500 StringRef TypeId = getTok().getIdentifier();
Nico Riecka37acf72013-07-06 12:13:10 +0000501
Rafael Espindola60ec3832013-11-19 19:52:52 +0000502 Type = StringSwitch<COFF::COMDATType>(TypeId)
503 .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
504 .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY)
505 .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE)
506 .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH)
507 .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
508 .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST)
509 .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST)
510 .Default((COFF::COMDATType)0);
Nico Riecka37acf72013-07-06 12:13:10 +0000511
Rafael Espindola60ec3832013-11-19 19:52:52 +0000512 if (Type == 0)
513 return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
Nico Riecka37acf72013-07-06 12:13:10 +0000514
Rafael Espindola60ec3832013-11-19 19:52:52 +0000515 Lex();
Nico Riecka37acf72013-07-06 12:13:10 +0000516
Rafael Espindola60ec3832013-11-19 19:52:52 +0000517 return false;
518}
519
520/// ParseDirectiveLinkOnce
Rafael Espindola0766ae02014-06-06 19:26:12 +0000521/// ::= .linkonce [ identifier ]
Rafael Espindola60ec3832013-11-19 19:52:52 +0000522bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
523 COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
Rafael Espindola60ec3832013-11-19 19:52:52 +0000524 if (getLexer().is(AsmToken::Identifier))
Rafael Espindola0766ae02014-06-06 19:26:12 +0000525 if (parseCOMDATType(Type))
Rafael Espindola60ec3832013-11-19 19:52:52 +0000526 return true;
527
528 const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>(
529 getStreamer().getCurrentSection().first);
530
Rafael Espindola0766ae02014-06-06 19:26:12 +0000531 if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
532 return Error(Loc, "cannot make section associative with .linkonce");
Rafael Espindola60ec3832013-11-19 19:52:52 +0000533
Nico Riecka37acf72013-07-06 12:13:10 +0000534 if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
535 return Error(Loc, Twine("section '") + Current->getSectionName() +
536 "' is already linkonce");
537
Rafael Espindola0766ae02014-06-06 19:26:12 +0000538 Current->setSelection(Type);
Nico Riecka37acf72013-07-06 12:13:10 +0000539
540 if (getLexer().isNot(AsmToken::EndOfStatement))
541 return TokError("unexpected token in directive");
542
543 return false;
544}
545
Charles Davisc7250fa2011-05-22 21:12:15 +0000546bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000547 StringRef SymbolID;
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000548 if (getParser().parseIdentifier(SymbolID))
Charles Davisc7250fa2011-05-22 21:12:15 +0000549 return true;
550
Charles Davisc7250fa2011-05-22 21:12:15 +0000551 if (getLexer().isNot(AsmToken::EndOfStatement))
552 return TokError("unexpected token in directive");
553
Jim Grosbach6f482002015-05-18 18:43:14 +0000554 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000555
Charles Davisc7250fa2011-05-22 21:12:15 +0000556 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000557 getStreamer().EmitWinCFIStartProc(Symbol);
Charles Davisc7250fa2011-05-22 21:12:15 +0000558 return false;
559}
560
561bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
562 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000563 getStreamer().EmitWinCFIEndProc();
Charles Davisc7250fa2011-05-22 21:12:15 +0000564 return false;
565}
566
567bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
568 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000569 getStreamer().EmitWinCFIStartChained();
Charles Davisc7250fa2011-05-22 21:12:15 +0000570 return false;
571}
572
573bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
574 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000575 getStreamer().EmitWinCFIEndChained();
Charles Davisc7250fa2011-05-22 21:12:15 +0000576 return false;
577}
578
579bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000580 StringRef SymbolID;
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000581 if (getParser().parseIdentifier(SymbolID))
Charles Davisc7250fa2011-05-22 21:12:15 +0000582 return true;
583
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000584 if (getLexer().isNot(AsmToken::Comma))
585 return TokError("you must specify one or both of @unwind or @except");
586 Lex();
Charles Davisc7250fa2011-05-22 21:12:15 +0000587 bool unwind = false, except = false;
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000588 if (ParseAtUnwindOrAtExcept(unwind, except))
589 return true;
Charles Davisc7250fa2011-05-22 21:12:15 +0000590 if (getLexer().is(AsmToken::Comma)) {
591 Lex();
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000592 if (ParseAtUnwindOrAtExcept(unwind, except))
Charles Davisc7250fa2011-05-22 21:12:15 +0000593 return true;
594 }
595 if (getLexer().isNot(AsmToken::EndOfStatement))
596 return TokError("unexpected token in directive");
597
Jim Grosbach6f482002015-05-18 18:43:14 +0000598 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000599
Charles Davisc7250fa2011-05-22 21:12:15 +0000600 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000601 getStreamer().EmitWinEHHandler(handler, unwind, except);
Charles Davisc7250fa2011-05-22 21:12:15 +0000602 return false;
603}
604
605bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
606 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000607 getStreamer().EmitWinEHHandlerData();
Charles Davisc7250fa2011-05-22 21:12:15 +0000608 return false;
609}
610
611bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
Michael Ilseman5be22a12014-12-12 21:48:03 +0000612 unsigned Reg = 0;
Charles Davis7f6176c2011-05-24 20:06:30 +0000613 if (ParseSEHRegisterNumber(Reg))
614 return true;
615
616 if (getLexer().isNot(AsmToken::EndOfStatement))
617 return TokError("unexpected token in directive");
618
619 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000620 getStreamer().EmitWinCFIPushReg(Reg);
Charles Davis7f6176c2011-05-24 20:06:30 +0000621 return false;
Charles Davisc7250fa2011-05-22 21:12:15 +0000622}
623
624bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
Michael Ilseman5be22a12014-12-12 21:48:03 +0000625 unsigned Reg = 0;
Charles Davis7f6176c2011-05-24 20:06:30 +0000626 int64_t Off;
627 if (ParseSEHRegisterNumber(Reg))
628 return true;
Charles Davis2f6ecea2011-05-25 21:43:45 +0000629 if (getLexer().isNot(AsmToken::Comma))
630 return TokError("you must specify a stack pointer offset");
631
632 Lex();
Charles Davis7f6176c2011-05-24 20:06:30 +0000633 SMLoc startLoc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000634 if (getParser().parseAbsoluteExpression(Off))
Charles Davis7f6176c2011-05-24 20:06:30 +0000635 return true;
636
637 if (Off & 0x0F)
638 return Error(startLoc, "offset is not a multiple of 16");
639
640 if (getLexer().isNot(AsmToken::EndOfStatement))
641 return TokError("unexpected token in directive");
642
643 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000644 getStreamer().EmitWinCFISetFrame(Reg, Off);
Charles Davis7f6176c2011-05-24 20:06:30 +0000645 return false;
Charles Davisc7250fa2011-05-22 21:12:15 +0000646}
647
Charles Davisd9eafdc2011-05-23 16:43:09 +0000648bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
649 int64_t Size;
Charles Davis7f6176c2011-05-24 20:06:30 +0000650 SMLoc startLoc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000651 if (getParser().parseAbsoluteExpression(Size))
Charles Davisd9eafdc2011-05-23 16:43:09 +0000652 return true;
653
Charles Davis7f6176c2011-05-24 20:06:30 +0000654 if (Size & 7)
655 return Error(startLoc, "size is not a multiple of 8");
656
Charles Davisd9eafdc2011-05-23 16:43:09 +0000657 if (getLexer().isNot(AsmToken::EndOfStatement))
658 return TokError("unexpected token in directive");
659
660 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000661 getStreamer().EmitWinCFIAllocStack(Size);
Charles Davisd9eafdc2011-05-23 16:43:09 +0000662 return false;
Charles Davisc7250fa2011-05-22 21:12:15 +0000663}
664
665bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
Michael Ilseman5be22a12014-12-12 21:48:03 +0000666 unsigned Reg = 0;
Charles Davis7f6176c2011-05-24 20:06:30 +0000667 int64_t Off;
668 if (ParseSEHRegisterNumber(Reg))
669 return true;
Charles Davis828b00c2011-05-25 04:51:25 +0000670 if (getLexer().isNot(AsmToken::Comma))
Charles Davis2f6ecea2011-05-25 21:43:45 +0000671 return TokError("you must specify an offset on the stack");
Charles Davis828b00c2011-05-25 04:51:25 +0000672
673 Lex();
Charles Davis7f6176c2011-05-24 20:06:30 +0000674 SMLoc startLoc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000675 if (getParser().parseAbsoluteExpression(Off))
Charles Davis7f6176c2011-05-24 20:06:30 +0000676 return true;
677
678 if (Off & 7)
679 return Error(startLoc, "size is not a multiple of 8");
680
681 if (getLexer().isNot(AsmToken::EndOfStatement))
682 return TokError("unexpected token in directive");
683
684 Lex();
685 // FIXME: Err on %xmm* registers
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000686 getStreamer().EmitWinCFISaveReg(Reg, Off);
Charles Davis7f6176c2011-05-24 20:06:30 +0000687 return false;
Charles Davisc7250fa2011-05-22 21:12:15 +0000688}
689
Charles Davis7f6176c2011-05-24 20:06:30 +0000690// FIXME: This method is inherently x86-specific. It should really be in the
691// x86 backend.
Charles Davisc7250fa2011-05-22 21:12:15 +0000692bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
Michael Ilseman5be22a12014-12-12 21:48:03 +0000693 unsigned Reg = 0;
Charles Davis7f6176c2011-05-24 20:06:30 +0000694 int64_t Off;
695 if (ParseSEHRegisterNumber(Reg))
696 return true;
Charles Davis828b00c2011-05-25 04:51:25 +0000697 if (getLexer().isNot(AsmToken::Comma))
Charles Davis2f6ecea2011-05-25 21:43:45 +0000698 return TokError("you must specify an offset on the stack");
Charles Davis828b00c2011-05-25 04:51:25 +0000699
700 Lex();
Charles Davis7f6176c2011-05-24 20:06:30 +0000701 SMLoc startLoc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000702 if (getParser().parseAbsoluteExpression(Off))
Charles Davis7f6176c2011-05-24 20:06:30 +0000703 return true;
704
705 if (getLexer().isNot(AsmToken::EndOfStatement))
706 return TokError("unexpected token in directive");
707
708 if (Off & 0x0F)
709 return Error(startLoc, "offset is not a multiple of 16");
710
711 Lex();
712 // FIXME: Err on non-%xmm* registers
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000713 getStreamer().EmitWinCFISaveXMM(Reg, Off);
Charles Davis7f6176c2011-05-24 20:06:30 +0000714 return false;
Charles Davisc7250fa2011-05-22 21:12:15 +0000715}
716
Charles Davisd9eafdc2011-05-23 16:43:09 +0000717bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
Charles Davisb0c4f392011-05-25 04:08:15 +0000718 bool Code = false;
Charles Davisd9eafdc2011-05-23 16:43:09 +0000719 StringRef CodeID;
Charles Davisb0c4f392011-05-25 04:08:15 +0000720 if (getLexer().is(AsmToken::At)) {
721 SMLoc startLoc = getLexer().getLoc();
722 Lex();
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000723 if (!getParser().parseIdentifier(CodeID)) {
Charles Davisb0c4f392011-05-25 04:08:15 +0000724 if (CodeID != "code")
725 return Error(startLoc, "expected @code");
726 Code = true;
727 }
Charles Davisd9eafdc2011-05-23 16:43:09 +0000728 }
729
730 if (getLexer().isNot(AsmToken::EndOfStatement))
731 return TokError("unexpected token in directive");
732
733 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000734 getStreamer().EmitWinCFIPushFrame(Code);
Charles Davisd9eafdc2011-05-23 16:43:09 +0000735 return false;
Charles Davisc7250fa2011-05-22 21:12:15 +0000736}
737
738bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
739 Lex();
Saleem Abdulrasool7206a522014-06-29 01:52:01 +0000740 getStreamer().EmitWinCFIEndProlog();
Charles Davisc7250fa2011-05-22 21:12:15 +0000741 return false;
742}
743
744bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
745 StringRef identifier;
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000746 if (getLexer().isNot(AsmToken::At))
747 return TokError("a handler attribute must begin with '@'");
Charles Davisc7250fa2011-05-22 21:12:15 +0000748 SMLoc startLoc = getLexer().getLoc();
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000749 Lex();
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000750 if (getParser().parseIdentifier(identifier))
Charles Davisc7250fa2011-05-22 21:12:15 +0000751 return Error(startLoc, "expected @unwind or @except");
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000752 if (identifier == "unwind")
Charles Davisc7250fa2011-05-22 21:12:15 +0000753 unwind = true;
Charles Davisfc1e7ce2011-05-25 01:33:42 +0000754 else if (identifier == "except")
Charles Davisc7250fa2011-05-22 21:12:15 +0000755 except = true;
756 else
757 return Error(startLoc, "expected @unwind or @except");
758 return false;
759}
760
Charles Davis7f6176c2011-05-24 20:06:30 +0000761bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
Charles Davis7f6176c2011-05-24 20:06:30 +0000762 SMLoc startLoc = getLexer().getLoc();
Charles Davis828b00c2011-05-25 04:51:25 +0000763 if (getLexer().is(AsmToken::Percent)) {
Bill Wendlingbc07a892013-06-18 07:20:20 +0000764 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
Charles Davis7f6176c2011-05-24 20:06:30 +0000765 SMLoc endLoc;
766 unsigned LLVMRegNo;
767 if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
Charles Davis828b00c2011-05-25 04:51:25 +0000768 return true;
Charles Davis7f6176c2011-05-24 20:06:30 +0000769
Evan Chengd60fa58b2011-07-18 20:57:22 +0000770#if 0
771 // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
772 // violation so this validation code is disabled.
773
Charles Davis7f6176c2011-05-24 20:06:30 +0000774 // Check that this is a non-volatile register.
Evan Chenga83b37a2011-07-15 02:09:41 +0000775 const unsigned *NVRegs = TAI.getCalleeSavedRegs();
Charles Davis7f6176c2011-05-24 20:06:30 +0000776 unsigned i;
777 for (i = 0; NVRegs[i] != 0; ++i)
778 if (NVRegs[i] == LLVMRegNo)
779 break;
780 if (NVRegs[i] == 0)
781 return Error(startLoc, "expected non-volatile register");
Evan Chengd60fa58b2011-07-18 20:57:22 +0000782#endif
Charles Davis7f6176c2011-05-24 20:06:30 +0000783
Bill Wendlingbc07a892013-06-18 07:20:20 +0000784 int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo);
Charles Davis7f6176c2011-05-24 20:06:30 +0000785 if (SEHRegNo < 0)
786 return Error(startLoc,"register can't be represented in SEH unwind info");
787 RegNo = SEHRegNo;
788 }
Charles Davis828b00c2011-05-25 04:51:25 +0000789 else {
790 int64_t n;
Jim Grosbachd2037eb2013-02-20 22:21:35 +0000791 if (getParser().parseAbsoluteExpression(n))
Charles Davis828b00c2011-05-25 04:51:25 +0000792 return true;
793 if (n > 15)
794 return Error(startLoc, "register number is too high");
Charles Davis7f6176c2011-05-24 20:06:30 +0000795 RegNo = n;
Charles Davis828b00c2011-05-25 04:51:25 +0000796 }
Charles Davis7f6176c2011-05-24 20:06:30 +0000797
Charles Davis7f6176c2011-05-24 20:06:30 +0000798 return false;
799}
800
Michael J. Spencerc8dbdfd2010-10-09 11:01:07 +0000801namespace llvm {
802
803MCAsmParserExtension *createCOFFAsmParser() {
804 return new COFFAsmParser;
805}
806
807}