Bug Summary

File:lib/Target/X86/AsmParser/X86AsmParser.cpp
Location:line 1282, column 10
Description:Assigned value is garbage or undefined

Annotated Source Code

1//===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
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 "MCTargetDesc/X86BaseInfo.h"
11#include "X86AsmInstrumentation.h"
12#include "X86AsmParserCommon.h"
13#include "X86Operand.h"
14#include "llvm/ADT/APFloat.h"
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/SmallString.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/StringSwitch.h"
19#include "llvm/ADT/Twine.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/MC/MCParser/MCAsmLexer.h"
25#include "llvm/MC/MCParser/MCAsmParser.h"
26#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
27#include "llvm/MC/MCRegisterInfo.h"
28#include "llvm/MC/MCStreamer.h"
29#include "llvm/MC/MCSubtargetInfo.h"
30#include "llvm/MC/MCSymbol.h"
31#include "llvm/MC/MCTargetAsmParser.h"
32#include "llvm/Support/SourceMgr.h"
33#include "llvm/Support/TargetRegistry.h"
34#include "llvm/Support/raw_ostream.h"
35#include <algorithm>
36#include <memory>
37
38using namespace llvm;
39
40namespace {
41
42static const char OpPrecedence[] = {
43 0, // IC_OR
44 1, // IC_AND
45 2, // IC_LSHIFT
46 2, // IC_RSHIFT
47 3, // IC_PLUS
48 3, // IC_MINUS
49 4, // IC_MULTIPLY
50 4, // IC_DIVIDE
51 5, // IC_RPAREN
52 6, // IC_LPAREN
53 0, // IC_IMM
54 0 // IC_REGISTER
55};
56
57class X86AsmParser : public MCTargetAsmParser {
58 MCSubtargetInfo &STI;
59 const MCInstrInfo &MII;
60 ParseInstructionInfo *InstInfo;
61 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
62private:
63 SMLoc consumeToken() {
64 MCAsmParser &Parser = getParser();
65 SMLoc Result = Parser.getTok().getLoc();
66 Parser.Lex();
67 return Result;
68 }
69
70 enum InfixCalculatorTok {
71 IC_OR = 0,
72 IC_AND,
73 IC_LSHIFT,
74 IC_RSHIFT,
75 IC_PLUS,
76 IC_MINUS,
77 IC_MULTIPLY,
78 IC_DIVIDE,
79 IC_RPAREN,
80 IC_LPAREN,
81 IC_IMM,
82 IC_REGISTER
83 };
84
85 class InfixCalculator {
86 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
87 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
88 SmallVector<ICToken, 4> PostfixStack;
89
90 public:
91 int64_t popOperand() {
92 assert (!PostfixStack.empty() && "Poped an empty stack!")((!PostfixStack.empty() && "Poped an empty stack!") ?
static_cast<void> (0) : __assert_fail ("!PostfixStack.empty() && \"Poped an empty stack!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 92, __PRETTY_FUNCTION__))
;
93 ICToken Op = PostfixStack.pop_back_val();
94 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)(((Op.first == IC_IMM || Op.first == IC_REGISTER) && "Expected and immediate or register!"
) ? static_cast<void> (0) : __assert_fail ("(Op.first == IC_IMM || Op.first == IC_REGISTER) && \"Expected and immediate or register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 95, __PRETTY_FUNCTION__))
95 && "Expected and immediate or register!")(((Op.first == IC_IMM || Op.first == IC_REGISTER) && "Expected and immediate or register!"
) ? static_cast<void> (0) : __assert_fail ("(Op.first == IC_IMM || Op.first == IC_REGISTER) && \"Expected and immediate or register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 95, __PRETTY_FUNCTION__))
;
96 return Op.second;
97 }
98 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
99 assert ((Op == IC_IMM || Op == IC_REGISTER) &&(((Op == IC_IMM || Op == IC_REGISTER) && "Unexpected operand!"
) ? static_cast<void> (0) : __assert_fail ("(Op == IC_IMM || Op == IC_REGISTER) && \"Unexpected operand!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 100, __PRETTY_FUNCTION__))
100 "Unexpected operand!")(((Op == IC_IMM || Op == IC_REGISTER) && "Unexpected operand!"
) ? static_cast<void> (0) : __assert_fail ("(Op == IC_IMM || Op == IC_REGISTER) && \"Unexpected operand!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 100, __PRETTY_FUNCTION__))
;
101 PostfixStack.push_back(std::make_pair(Op, Val));
102 }
103
104 void popOperator() { InfixOperatorStack.pop_back(); }
105 void pushOperator(InfixCalculatorTok Op) {
106 // Push the new operator if the stack is empty.
107 if (InfixOperatorStack.empty()) {
108 InfixOperatorStack.push_back(Op);
109 return;
110 }
111
112 // Push the new operator if it has a higher precedence than the operator
113 // on the top of the stack or the operator on the top of the stack is a
114 // left parentheses.
115 unsigned Idx = InfixOperatorStack.size() - 1;
116 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
117 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
118 InfixOperatorStack.push_back(Op);
119 return;
120 }
121
122 // The operator on the top of the stack has higher precedence than the
123 // new operator.
124 unsigned ParenCount = 0;
125 while (1) {
126 // Nothing to process.
127 if (InfixOperatorStack.empty())
128 break;
129
130 Idx = InfixOperatorStack.size() - 1;
131 StackOp = InfixOperatorStack[Idx];
132 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
133 break;
134
135 // If we have an even parentheses count and we see a left parentheses,
136 // then stop processing.
137 if (!ParenCount && StackOp == IC_LPAREN)
138 break;
139
140 if (StackOp == IC_RPAREN) {
141 ++ParenCount;
142 InfixOperatorStack.pop_back();
143 } else if (StackOp == IC_LPAREN) {
144 --ParenCount;
145 InfixOperatorStack.pop_back();
146 } else {
147 InfixOperatorStack.pop_back();
148 PostfixStack.push_back(std::make_pair(StackOp, 0));
149 }
150 }
151 // Push the new operator.
152 InfixOperatorStack.push_back(Op);
153 }
154 int64_t execute() {
155 // Push any remaining operators onto the postfix stack.
156 while (!InfixOperatorStack.empty()) {
157 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
158 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
159 PostfixStack.push_back(std::make_pair(StackOp, 0));
160 }
161
162 if (PostfixStack.empty())
163 return 0;
164
165 SmallVector<ICToken, 16> OperandStack;
166 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
167 ICToken Op = PostfixStack[i];
168 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
169 OperandStack.push_back(Op);
170 } else {
171 assert (OperandStack.size() > 1 && "Too few operands.")((OperandStack.size() > 1 && "Too few operands.") ?
static_cast<void> (0) : __assert_fail ("OperandStack.size() > 1 && \"Too few operands.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 171, __PRETTY_FUNCTION__))
;
172 int64_t Val;
173 ICToken Op2 = OperandStack.pop_back_val();
174 ICToken Op1 = OperandStack.pop_back_val();
175 switch (Op.first) {
176 default:
177 report_fatal_error("Unexpected operator!");
178 break;
179 case IC_PLUS:
180 Val = Op1.second + Op2.second;
181 OperandStack.push_back(std::make_pair(IC_IMM, Val));
182 break;
183 case IC_MINUS:
184 Val = Op1.second - Op2.second;
185 OperandStack.push_back(std::make_pair(IC_IMM, Val));
186 break;
187 case IC_MULTIPLY:
188 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Multiply operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Multiply operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 189, __PRETTY_FUNCTION__))
189 "Multiply operation with an immediate and a register!")((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Multiply operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Multiply operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 189, __PRETTY_FUNCTION__))
;
190 Val = Op1.second * Op2.second;
191 OperandStack.push_back(std::make_pair(IC_IMM, Val));
192 break;
193 case IC_DIVIDE:
194 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Divide operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Divide operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 195, __PRETTY_FUNCTION__))
195 "Divide operation with an immediate and a register!")((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Divide operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Divide operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 195, __PRETTY_FUNCTION__))
;
196 assert (Op2.second != 0 && "Division by zero!")((Op2.second != 0 && "Division by zero!") ? static_cast
<void> (0) : __assert_fail ("Op2.second != 0 && \"Division by zero!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 196, __PRETTY_FUNCTION__))
;
197 Val = Op1.second / Op2.second;
198 OperandStack.push_back(std::make_pair(IC_IMM, Val));
199 break;
200 case IC_OR:
201 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Or operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Or operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 202, __PRETTY_FUNCTION__))
202 "Or operation with an immediate and a register!")((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Or operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Or operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 202, __PRETTY_FUNCTION__))
;
203 Val = Op1.second | Op2.second;
204 OperandStack.push_back(std::make_pair(IC_IMM, Val));
205 break;
206 case IC_AND:
207 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"And operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"And operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 208, __PRETTY_FUNCTION__))
208 "And operation with an immediate and a register!")((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"And operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"And operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 208, __PRETTY_FUNCTION__))
;
209 Val = Op1.second & Op2.second;
210 OperandStack.push_back(std::make_pair(IC_IMM, Val));
211 break;
212 case IC_LSHIFT:
213 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Left shift operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Left shift operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 214, __PRETTY_FUNCTION__))
214 "Left shift operation with an immediate and a register!")((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Left shift operation with an immediate and a register!") ? static_cast
<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Left shift operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 214, __PRETTY_FUNCTION__))
;
215 Val = Op1.second << Op2.second;
216 OperandStack.push_back(std::make_pair(IC_IMM, Val));
217 break;
218 case IC_RSHIFT:
219 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Right shift operation with an immediate and a register!") ?
static_cast<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Right shift operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 220, __PRETTY_FUNCTION__))
220 "Right shift operation with an immediate and a register!")((Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Right shift operation with an immediate and a register!") ?
static_cast<void> (0) : __assert_fail ("Op1.first == IC_IMM && Op2.first == IC_IMM && \"Right shift operation with an immediate and a register!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 220, __PRETTY_FUNCTION__))
;
221 Val = Op1.second >> Op2.second;
222 OperandStack.push_back(std::make_pair(IC_IMM, Val));
223 break;
224 }
225 }
226 }
227 assert (OperandStack.size() == 1 && "Expected a single result.")((OperandStack.size() == 1 && "Expected a single result."
) ? static_cast<void> (0) : __assert_fail ("OperandStack.size() == 1 && \"Expected a single result.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 227, __PRETTY_FUNCTION__))
;
228 return OperandStack.pop_back_val().second;
229 }
230 };
231
232 enum IntelExprState {
233 IES_OR,
234 IES_AND,
235 IES_LSHIFT,
236 IES_RSHIFT,
237 IES_PLUS,
238 IES_MINUS,
239 IES_NOT,
240 IES_MULTIPLY,
241 IES_DIVIDE,
242 IES_LBRAC,
243 IES_RBRAC,
244 IES_LPAREN,
245 IES_RPAREN,
246 IES_REGISTER,
247 IES_INTEGER,
248 IES_IDENTIFIER,
249 IES_ERROR
250 };
251
252 class IntelExprStateMachine {
253 IntelExprState State, PrevState;
254 unsigned BaseReg, IndexReg, TmpReg, Scale;
255 int64_t Imm;
256 const MCExpr *Sym;
257 StringRef SymName;
258 bool StopOnLBrac, AddImmPrefix;
259 InfixCalculator IC;
260 InlineAsmIdentifierInfo Info;
261 public:
262 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
263 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
264 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
265 AddImmPrefix(addimmprefix) { Info.clear(); }
266
267 unsigned getBaseReg() { return BaseReg; }
268 unsigned getIndexReg() { return IndexReg; }
269 unsigned getScale() { return Scale; }
270 const MCExpr *getSym() { return Sym; }
271 StringRef getSymName() { return SymName; }
272 int64_t getImm() { return Imm + IC.execute(); }
273 bool isValidEndState() {
274 return State == IES_RBRAC || State == IES_INTEGER;
275 }
276 bool getStopOnLBrac() { return StopOnLBrac; }
277 bool getAddImmPrefix() { return AddImmPrefix; }
278 bool hadError() { return State == IES_ERROR; }
279
280 InlineAsmIdentifierInfo &getIdentifierInfo() {
281 return Info;
282 }
283
284 void onOr() {
285 IntelExprState CurrState = State;
286 switch (State) {
287 default:
288 State = IES_ERROR;
289 break;
290 case IES_INTEGER:
291 case IES_RPAREN:
292 case IES_REGISTER:
293 State = IES_OR;
294 IC.pushOperator(IC_OR);
295 break;
296 }
297 PrevState = CurrState;
298 }
299 void onAnd() {
300 IntelExprState CurrState = State;
301 switch (State) {
302 default:
303 State = IES_ERROR;
304 break;
305 case IES_INTEGER:
306 case IES_RPAREN:
307 case IES_REGISTER:
308 State = IES_AND;
309 IC.pushOperator(IC_AND);
310 break;
311 }
312 PrevState = CurrState;
313 }
314 void onLShift() {
315 IntelExprState CurrState = State;
316 switch (State) {
317 default:
318 State = IES_ERROR;
319 break;
320 case IES_INTEGER:
321 case IES_RPAREN:
322 case IES_REGISTER:
323 State = IES_LSHIFT;
324 IC.pushOperator(IC_LSHIFT);
325 break;
326 }
327 PrevState = CurrState;
328 }
329 void onRShift() {
330 IntelExprState CurrState = State;
331 switch (State) {
332 default:
333 State = IES_ERROR;
334 break;
335 case IES_INTEGER:
336 case IES_RPAREN:
337 case IES_REGISTER:
338 State = IES_RSHIFT;
339 IC.pushOperator(IC_RSHIFT);
340 break;
341 }
342 PrevState = CurrState;
343 }
344 void onPlus() {
345 IntelExprState CurrState = State;
346 switch (State) {
347 default:
348 State = IES_ERROR;
349 break;
350 case IES_INTEGER:
351 case IES_RPAREN:
352 case IES_REGISTER:
353 State = IES_PLUS;
354 IC.pushOperator(IC_PLUS);
355 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
356 // If we already have a BaseReg, then assume this is the IndexReg with
357 // a scale of 1.
358 if (!BaseReg) {
359 BaseReg = TmpReg;
360 } else {
361 assert (!IndexReg && "BaseReg/IndexReg already set!")((!IndexReg && "BaseReg/IndexReg already set!") ? static_cast
<void> (0) : __assert_fail ("!IndexReg && \"BaseReg/IndexReg already set!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 361, __PRETTY_FUNCTION__))
;
362 IndexReg = TmpReg;
363 Scale = 1;
364 }
365 }
366 break;
367 }
368 PrevState = CurrState;
369 }
370 void onMinus() {
371 IntelExprState CurrState = State;
372 switch (State) {
373 default:
374 State = IES_ERROR;
375 break;
376 case IES_PLUS:
377 case IES_NOT:
378 case IES_MULTIPLY:
379 case IES_DIVIDE:
380 case IES_LPAREN:
381 case IES_RPAREN:
382 case IES_LBRAC:
383 case IES_RBRAC:
384 case IES_INTEGER:
385 case IES_REGISTER:
386 State = IES_MINUS;
387 // Only push the minus operator if it is not a unary operator.
388 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
389 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
390 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
391 IC.pushOperator(IC_MINUS);
392 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
393 // If we already have a BaseReg, then assume this is the IndexReg with
394 // a scale of 1.
395 if (!BaseReg) {
396 BaseReg = TmpReg;
397 } else {
398 assert (!IndexReg && "BaseReg/IndexReg already set!")((!IndexReg && "BaseReg/IndexReg already set!") ? static_cast
<void> (0) : __assert_fail ("!IndexReg && \"BaseReg/IndexReg already set!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 398, __PRETTY_FUNCTION__))
;
399 IndexReg = TmpReg;
400 Scale = 1;
401 }
402 }
403 break;
404 }
405 PrevState = CurrState;
406 }
407 void onNot() {
408 IntelExprState CurrState = State;
409 switch (State) {
410 default:
411 State = IES_ERROR;
412 break;
413 case IES_PLUS:
414 case IES_NOT:
415 State = IES_NOT;
416 break;
417 }
418 PrevState = CurrState;
419 }
420 void onRegister(unsigned Reg) {
421 IntelExprState CurrState = State;
422 switch (State) {
423 default:
424 State = IES_ERROR;
425 break;
426 case IES_PLUS:
427 case IES_LPAREN:
428 State = IES_REGISTER;
429 TmpReg = Reg;
430 IC.pushOperand(IC_REGISTER);
431 break;
432 case IES_MULTIPLY:
433 // Index Register - Scale * Register
434 if (PrevState == IES_INTEGER) {
435 assert (!IndexReg && "IndexReg already set!")((!IndexReg && "IndexReg already set!") ? static_cast
<void> (0) : __assert_fail ("!IndexReg && \"IndexReg already set!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 435, __PRETTY_FUNCTION__))
;
436 State = IES_REGISTER;
437 IndexReg = Reg;
438 // Get the scale and replace the 'Scale * Register' with '0'.
439 Scale = IC.popOperand();
440 IC.pushOperand(IC_IMM);
441 IC.popOperator();
442 } else {
443 State = IES_ERROR;
444 }
445 break;
446 }
447 PrevState = CurrState;
448 }
449 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
450 PrevState = State;
451 switch (State) {
452 default:
453 State = IES_ERROR;
454 break;
455 case IES_PLUS:
456 case IES_MINUS:
457 case IES_NOT:
458 State = IES_INTEGER;
459 Sym = SymRef;
460 SymName = SymRefName;
461 IC.pushOperand(IC_IMM);
462 break;
463 }
464 }
465 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
466 IntelExprState CurrState = State;
467 switch (State) {
468 default:
469 State = IES_ERROR;
470 break;
471 case IES_PLUS:
472 case IES_MINUS:
473 case IES_NOT:
474 case IES_OR:
475 case IES_AND:
476 case IES_LSHIFT:
477 case IES_RSHIFT:
478 case IES_DIVIDE:
479 case IES_MULTIPLY:
480 case IES_LPAREN:
481 State = IES_INTEGER;
482 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
483 // Index Register - Register * Scale
484 assert (!IndexReg && "IndexReg already set!")((!IndexReg && "IndexReg already set!") ? static_cast
<void> (0) : __assert_fail ("!IndexReg && \"IndexReg already set!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 484, __PRETTY_FUNCTION__))
;
485 IndexReg = TmpReg;
486 Scale = TmpInt;
487 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
488 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
489 return true;
490 }
491 // Get the scale and replace the 'Register * Scale' with '0'.
492 IC.popOperator();
493 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
494 PrevState == IES_OR || PrevState == IES_AND ||
495 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
496 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
497 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
498 PrevState == IES_NOT) &&
499 CurrState == IES_MINUS) {
500 // Unary minus. No need to pop the minus operand because it was never
501 // pushed.
502 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
503 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
504 PrevState == IES_OR || PrevState == IES_AND ||
505 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
506 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
507 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
508 PrevState == IES_NOT) &&
509 CurrState == IES_NOT) {
510 // Unary not. No need to pop the not operand because it was never
511 // pushed.
512 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
513 } else {
514 IC.pushOperand(IC_IMM, TmpInt);
515 }
516 break;
517 }
518 PrevState = CurrState;
519 return false;
520 }
521 void onStar() {
522 PrevState = State;
523 switch (State) {
524 default:
525 State = IES_ERROR;
526 break;
527 case IES_INTEGER:
528 case IES_REGISTER:
529 case IES_RPAREN:
530 State = IES_MULTIPLY;
531 IC.pushOperator(IC_MULTIPLY);
532 break;
533 }
534 }
535 void onDivide() {
536 PrevState = State;
537 switch (State) {
538 default:
539 State = IES_ERROR;
540 break;
541 case IES_INTEGER:
542 case IES_RPAREN:
543 State = IES_DIVIDE;
544 IC.pushOperator(IC_DIVIDE);
545 break;
546 }
547 }
548 void onLBrac() {
549 PrevState = State;
550 switch (State) {
551 default:
552 State = IES_ERROR;
553 break;
554 case IES_RBRAC:
555 State = IES_PLUS;
556 IC.pushOperator(IC_PLUS);
557 break;
558 }
559 }
560 void onRBrac() {
561 IntelExprState CurrState = State;
562 switch (State) {
563 default:
564 State = IES_ERROR;
565 break;
566 case IES_INTEGER:
567 case IES_REGISTER:
568 case IES_RPAREN:
569 State = IES_RBRAC;
570 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
571 // If we already have a BaseReg, then assume this is the IndexReg with
572 // a scale of 1.
573 if (!BaseReg) {
574 BaseReg = TmpReg;
575 } else {
576 assert (!IndexReg && "BaseReg/IndexReg already set!")((!IndexReg && "BaseReg/IndexReg already set!") ? static_cast
<void> (0) : __assert_fail ("!IndexReg && \"BaseReg/IndexReg already set!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 576, __PRETTY_FUNCTION__))
;
577 IndexReg = TmpReg;
578 Scale = 1;
579 }
580 }
581 break;
582 }
583 PrevState = CurrState;
584 }
585 void onLParen() {
586 IntelExprState CurrState = State;
587 switch (State) {
588 default:
589 State = IES_ERROR;
590 break;
591 case IES_PLUS:
592 case IES_MINUS:
593 case IES_NOT:
594 case IES_OR:
595 case IES_AND:
596 case IES_LSHIFT:
597 case IES_RSHIFT:
598 case IES_MULTIPLY:
599 case IES_DIVIDE:
600 case IES_LPAREN:
601 // FIXME: We don't handle this type of unary minus or not, yet.
602 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
603 PrevState == IES_OR || PrevState == IES_AND ||
604 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
605 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
606 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
607 PrevState == IES_NOT) &&
608 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
609 State = IES_ERROR;
610 break;
611 }
612 State = IES_LPAREN;
613 IC.pushOperator(IC_LPAREN);
614 break;
615 }
616 PrevState = CurrState;
617 }
618 void onRParen() {
619 PrevState = State;
620 switch (State) {
621 default:
622 State = IES_ERROR;
623 break;
624 case IES_INTEGER:
625 case IES_REGISTER:
626 case IES_RPAREN:
627 State = IES_RPAREN;
628 IC.pushOperator(IC_RPAREN);
629 break;
630 }
631 }
632 };
633
634 bool Error(SMLoc L, const Twine &Msg,
635 ArrayRef<SMRange> Ranges = None,
636 bool MatchingInlineAsm = false) {
637 MCAsmParser &Parser = getParser();
638 if (MatchingInlineAsm) return true;
639 return Parser.Error(L, Msg, Ranges);
640 }
641
642 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
643 ArrayRef<SMRange> Ranges = None,
644 bool MatchingInlineAsm = false) {
645 MCAsmParser &Parser = getParser();
646 Parser.eatToEndOfStatement();
647 return Error(L, Msg, Ranges, MatchingInlineAsm);
648 }
649
650 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
651 Error(Loc, Msg);
652 return nullptr;
653 }
654
655 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
656 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
657 std::unique_ptr<X86Operand> ParseOperand();
658 std::unique_ptr<X86Operand> ParseATTOperand();
659 std::unique_ptr<X86Operand> ParseIntelOperand();
660 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
661 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
662 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
663 std::unique_ptr<X86Operand>
664 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
665 std::unique_ptr<X86Operand>
666 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
667 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
668 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
669 SMLoc Start,
670 int64_t ImmDisp,
671 unsigned Size);
672 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
673 InlineAsmIdentifierInfo &Info,
674 bool IsUnevaluatedOperand, SMLoc &End);
675
676 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
677
678 std::unique_ptr<X86Operand>
679 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
680 unsigned IndexReg, unsigned Scale, SMLoc Start,
681 SMLoc End, unsigned Size, StringRef Identifier,
682 InlineAsmIdentifierInfo &Info);
683
684 bool ParseDirectiveWord(unsigned Size, SMLoc L);
685 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
686
687 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
688 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
689
690 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
691 /// instrumentation around Inst.
692 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
693
694 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
695 OperandVector &Operands, MCStreamer &Out,
696 uint64_t &ErrorInfo,
697 bool MatchingInlineAsm) override;
698
699 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
700 MCStreamer &Out, bool MatchingInlineAsm);
701
702 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
703 bool MatchingInlineAsm);
704
705 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
706 OperandVector &Operands, MCStreamer &Out,
707 uint64_t &ErrorInfo,
708 bool MatchingInlineAsm);
709
710 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
711 OperandVector &Operands, MCStreamer &Out,
712 uint64_t &ErrorInfo,
713 bool MatchingInlineAsm);
714
715 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
716
717 /// doSrcDstMatch - Returns true if operands are matching in their
718 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
719 /// the parsing mode (Intel vs. AT&T).
720 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
721
722 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
723 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
724 /// \return \c true if no parsing errors occurred, \c false otherwise.
725 bool HandleAVX512Operand(OperandVector &Operands,
726 const MCParsedAsmOperand &Op);
727
728 bool is64BitMode() const {
729 // FIXME: Can tablegen auto-generate this?
730 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
731 }
732 bool is32BitMode() const {
733 // FIXME: Can tablegen auto-generate this?
734 return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
735 }
736 bool is16BitMode() const {
737 // FIXME: Can tablegen auto-generate this?
738 return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
739 }
740 void SwitchMode(uint64_t mode) {
741 uint64_t oldMode = STI.getFeatureBits() &
742 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit);
743 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(oldMode | mode));
744 setAvailableFeatures(FB);
745 assert(mode == (STI.getFeatureBits() &((mode == (STI.getFeatureBits() & (X86::Mode64Bit | X86::
Mode32Bit | X86::Mode16Bit))) ? static_cast<void> (0) :
__assert_fail ("mode == (STI.getFeatureBits() & (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit))"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 746, __PRETTY_FUNCTION__))
746 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit)))((mode == (STI.getFeatureBits() & (X86::Mode64Bit | X86::
Mode32Bit | X86::Mode16Bit))) ? static_cast<void> (0) :
__assert_fail ("mode == (STI.getFeatureBits() & (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit))"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 746, __PRETTY_FUNCTION__))
;
747 }
748
749 unsigned getPointerWidth() {
750 if (is16BitMode()) return 16;
751 if (is32BitMode()) return 32;
752 if (is64BitMode()) return 64;
753 llvm_unreachable("invalid mode")::llvm::llvm_unreachable_internal("invalid mode", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 753)
;
754 }
755
756 bool isParsingIntelSyntax() {
757 return getParser().getAssemblerDialect();
758 }
759
760 /// @name Auto-generated Matcher Functions
761 /// {
762
763#define GET_ASSEMBLER_HEADER
764#include "X86GenAsmMatcher.inc"
765
766 /// }
767
768public:
769 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &Parser,
770 const MCInstrInfo &mii, const MCTargetOptions &Options)
771 : MCTargetAsmParser(), STI(sti), MII(mii), InstInfo(nullptr) {
772
773 // Initialize the set of available features.
774 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
775 Instrumentation.reset(
776 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
777 }
778
779 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
780
781 void SetFrameRegister(unsigned RegNo) override;
782
783 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
784 SMLoc NameLoc, OperandVector &Operands) override;
785
786 bool ParseDirective(AsmToken DirectiveID) override;
787};
788} // end anonymous namespace
789
790/// @name Auto-generated Match Functions
791/// {
792
793static unsigned MatchRegisterName(StringRef Name);
794
795/// }
796
797static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
798 StringRef &ErrMsg) {
799 // If we have both a base register and an index register make sure they are
800 // both 64-bit or 32-bit registers.
801 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
802 if (BaseReg != 0 && IndexReg != 0) {
803 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
804 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
805 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
806 IndexReg != X86::RIZ) {
807 ErrMsg = "base register is 64-bit, but index register is not";
808 return true;
809 }
810 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
811 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
812 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
813 IndexReg != X86::EIZ){
814 ErrMsg = "base register is 32-bit, but index register is not";
815 return true;
816 }
817 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
818 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
819 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
820 ErrMsg = "base register is 16-bit, but index register is not";
821 return true;
822 }
823 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
824 IndexReg != X86::SI && IndexReg != X86::DI) ||
825 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
826 IndexReg != X86::BX && IndexReg != X86::BP)) {
827 ErrMsg = "invalid 16-bit base/index register combination";
828 return true;
829 }
830 }
831 }
832 return false;
833}
834
835bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
836{
837 // Return true and let a normal complaint about bogus operands happen.
838 if (!Op1.isMem() || !Op2.isMem())
839 return true;
840
841 // Actually these might be the other way round if Intel syntax is
842 // being used. It doesn't matter.
843 unsigned diReg = Op1.Mem.BaseReg;
844 unsigned siReg = Op2.Mem.BaseReg;
845
846 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
847 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
848 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
849 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
850 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
851 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
852 // Again, return true and let another error happen.
853 return true;
854}
855
856bool X86AsmParser::ParseRegister(unsigned &RegNo,
857 SMLoc &StartLoc, SMLoc &EndLoc) {
858 MCAsmParser &Parser = getParser();
859 RegNo = 0;
860 const AsmToken &PercentTok = Parser.getTok();
861 StartLoc = PercentTok.getLoc();
862
863 // If we encounter a %, ignore it. This code handles registers with and
864 // without the prefix, unprefixed registers can occur in cfi directives.
865 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
866 Parser.Lex(); // Eat percent token.
867
868 const AsmToken &Tok = Parser.getTok();
869 EndLoc = Tok.getEndLoc();
870
871 if (Tok.isNot(AsmToken::Identifier)) {
872 if (isParsingIntelSyntax()) return true;
873 return Error(StartLoc, "invalid register name",
874 SMRange(StartLoc, EndLoc));
875 }
876
877 RegNo = MatchRegisterName(Tok.getString());
878
879 // If the match failed, try the register name as lowercase.
880 if (RegNo == 0)
881 RegNo = MatchRegisterName(Tok.getString().lower());
882
883 if (!is64BitMode()) {
884 // FIXME: This should be done using Requires<Not64BitMode> and
885 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
886 // checked.
887 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
888 // REX prefix.
889 if (RegNo == X86::RIZ ||
890 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
891 X86II::isX86_64NonExtLowByteReg(RegNo) ||
892 X86II::isX86_64ExtendedReg(RegNo))
893 return Error(StartLoc, "register %"
894 + Tok.getString() + " is only available in 64-bit mode",
895 SMRange(StartLoc, EndLoc));
896 }
897
898 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
899 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
900 RegNo = X86::ST0;
901 Parser.Lex(); // Eat 'st'
902
903 // Check to see if we have '(4)' after %st.
904 if (getLexer().isNot(AsmToken::LParen))
905 return false;
906 // Lex the paren.
907 getParser().Lex();
908
909 const AsmToken &IntTok = Parser.getTok();
910 if (IntTok.isNot(AsmToken::Integer))
911 return Error(IntTok.getLoc(), "expected stack index");
912 switch (IntTok.getIntVal()) {
913 case 0: RegNo = X86::ST0; break;
914 case 1: RegNo = X86::ST1; break;
915 case 2: RegNo = X86::ST2; break;
916 case 3: RegNo = X86::ST3; break;
917 case 4: RegNo = X86::ST4; break;
918 case 5: RegNo = X86::ST5; break;
919 case 6: RegNo = X86::ST6; break;
920 case 7: RegNo = X86::ST7; break;
921 default: return Error(IntTok.getLoc(), "invalid stack index");
922 }
923
924 if (getParser().Lex().isNot(AsmToken::RParen))
925 return Error(Parser.getTok().getLoc(), "expected ')'");
926
927 EndLoc = Parser.getTok().getEndLoc();
928 Parser.Lex(); // Eat ')'
929 return false;
930 }
931
932 EndLoc = Parser.getTok().getEndLoc();
933
934 // If this is "db[0-7]", match it as an alias
935 // for dr[0-7].
936 if (RegNo == 0 && Tok.getString().size() == 3 &&
937 Tok.getString().startswith("db")) {
938 switch (Tok.getString()[2]) {
939 case '0': RegNo = X86::DR0; break;
940 case '1': RegNo = X86::DR1; break;
941 case '2': RegNo = X86::DR2; break;
942 case '3': RegNo = X86::DR3; break;
943 case '4': RegNo = X86::DR4; break;
944 case '5': RegNo = X86::DR5; break;
945 case '6': RegNo = X86::DR6; break;
946 case '7': RegNo = X86::DR7; break;
947 }
948
949 if (RegNo != 0) {
950 EndLoc = Parser.getTok().getEndLoc();
951 Parser.Lex(); // Eat it.
952 return false;
953 }
954 }
955
956 if (RegNo == 0) {
957 if (isParsingIntelSyntax()) return true;
958 return Error(StartLoc, "invalid register name",
959 SMRange(StartLoc, EndLoc));
960 }
961
962 Parser.Lex(); // Eat identifier token.
963 return false;
964}
965
966void X86AsmParser::SetFrameRegister(unsigned RegNo) {
967 Instrumentation->SetInitialFrameRegister(RegNo);
968}
969
970std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
971 unsigned basereg =
972 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
973 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
974 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
975 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
976 Loc, Loc, 0);
977}
978
979std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
980 unsigned basereg =
981 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
982 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
983 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
984 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
985 Loc, Loc, 0);
986}
987
988std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
989 if (isParsingIntelSyntax())
1
Taking true branch
990 return ParseIntelOperand();
2
Calling 'X86AsmParser::ParseIntelOperand'
991 return ParseATTOperand();
992}
993
994/// getIntelMemOperandSize - Return intel memory operand size.
995static unsigned getIntelMemOperandSize(StringRef OpStr) {
996 unsigned Size = StringSwitch<unsigned>(OpStr)
997 .Cases("BYTE", "byte", 8)
998 .Cases("WORD", "word", 16)
999 .Cases("DWORD", "dword", 32)
1000 .Cases("QWORD", "qword", 64)
1001 .Cases("XWORD", "xword", 80)
1002 .Cases("XMMWORD", "xmmword", 128)
1003 .Cases("YMMWORD", "ymmword", 256)
1004 .Cases("ZMMWORD", "zmmword", 512)
1005 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1006 .Default(0);
1007 return Size;
1008}
1009
1010std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1011 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1012 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1013 InlineAsmIdentifierInfo &Info) {
1014 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1015 // some other label reference.
1016 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1017 // Insert an explicit size if the user didn't have one.
1018 if (!Size) {
1019 Size = getPointerWidth();
1020 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1021 /*Len=*/0, Size));
1022 }
1023
1024 // Create an absolute memory reference in order to match against
1025 // instructions taking a PC relative operand.
1026 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1027 Identifier, Info.OpDecl);
1028 }
1029
1030 // We either have a direct symbol reference, or an offset from a symbol. The
1031 // parser always puts the symbol on the LHS, so look there for size
1032 // calculation purposes.
1033 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1034 bool IsSymRef =
1035 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1036 if (IsSymRef) {
1037 if (!Size) {
1038 Size = Info.Type * 8; // Size is in terms of bits in this context.
1039 if (Size)
1040 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1041 /*Len=*/0, Size));
1042 }
1043 }
1044
1045 // When parsing inline assembly we set the base register to a non-zero value
1046 // if we don't know the actual value at this time. This is necessary to
1047 // get the matching correct in some cases.
1048 BaseReg = BaseReg ? BaseReg : 1;
1049 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1050 IndexReg, Scale, Start, End, Size, Identifier,
1051 Info.OpDecl);
1052}
1053
1054static void
1055RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
1056 StringRef SymName, int64_t ImmDisp,
1057 int64_t FinalImmDisp, SMLoc &BracLoc,
1058 SMLoc &StartInBrac, SMLoc &End) {
1059 // Remove the '[' and ']' from the IR string.
1060 AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1));
1061 AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1));
1062
1063 // If ImmDisp is non-zero, then we parsed a displacement before the
1064 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1065 // If ImmDisp doesn't match the displacement computed by the state machine
1066 // then we have an additional displacement in the bracketed expression.
1067 if (ImmDisp != FinalImmDisp) {
1068 if (ImmDisp) {
1069 // We have an immediate displacement before the bracketed expression.
1070 // Adjust this to match the final immediate displacement.
1071 bool Found = false;
1072 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1073 E = AsmRewrites->end(); I != E; ++I) {
1074 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1075 continue;
1076 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1077 assert (!Found && "ImmDisp already rewritten.")((!Found && "ImmDisp already rewritten.") ? static_cast
<void> (0) : __assert_fail ("!Found && \"ImmDisp already rewritten.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1077, __PRETTY_FUNCTION__))
;
1078 (*I).Kind = AOK_Imm;
1079 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1080 (*I).Val = FinalImmDisp;
1081 Found = true;
1082 break;
1083 }
1084 }
1085 assert (Found && "Unable to rewrite ImmDisp.")((Found && "Unable to rewrite ImmDisp.") ? static_cast
<void> (0) : __assert_fail ("Found && \"Unable to rewrite ImmDisp.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1085, __PRETTY_FUNCTION__))
;
1086 (void)Found;
1087 } else {
1088 // We have a symbolic and an immediate displacement, but no displacement
1089 // before the bracketed expression. Put the immediate displacement
1090 // before the bracketed expression.
1091 AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
1092 }
1093 }
1094 // Remove all the ImmPrefix rewrites within the brackets.
1095 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1096 E = AsmRewrites->end(); I != E; ++I) {
1097 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1098 continue;
1099 if ((*I).Kind == AOK_ImmPrefix)
1100 (*I).Kind = AOK_Delete;
1101 }
1102 const char *SymLocPtr = SymName.data();
1103 // Skip everything before the symbol.
1104 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1105 assert(Len > 0 && "Expected a non-negative length.")((Len > 0 && "Expected a non-negative length.") ? static_cast
<void> (0) : __assert_fail ("Len > 0 && \"Expected a non-negative length.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1105, __PRETTY_FUNCTION__))
;
1106 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len));
1107 }
1108 // Skip everything after the symbol.
1109 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1110 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1111 assert(Len > 0 && "Expected a non-negative length.")((Len > 0 && "Expected a non-negative length.") ? static_cast
<void> (0) : __assert_fail ("Len > 0 && \"Expected a non-negative length.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1111, __PRETTY_FUNCTION__))
;
1112 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len));
1113 }
1114}
1115
1116bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1117 MCAsmParser &Parser = getParser();
1118 const AsmToken &Tok = Parser.getTok();
1119
1120 bool Done = false;
1121 while (!Done) {
1122 bool UpdateLocLex = true;
1123
1124 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1125 // identifier. Don't try an parse it as a register.
1126 if (Tok.getString().startswith("."))
1127 break;
1128
1129 // If we're parsing an immediate expression, we don't expect a '['.
1130 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1131 break;
1132
1133 AsmToken::TokenKind TK = getLexer().getKind();
1134 switch (TK) {
1135 default: {
1136 if (SM.isValidEndState()) {
1137 Done = true;
1138 break;
1139 }
1140 return Error(Tok.getLoc(), "unknown token in expression");
1141 }
1142 case AsmToken::EndOfStatement: {
1143 Done = true;
1144 break;
1145 }
1146 case AsmToken::String:
1147 case AsmToken::Identifier: {
1148 // This could be a register or a symbolic displacement.
1149 unsigned TmpReg;
1150 const MCExpr *Val;
1151 SMLoc IdentLoc = Tok.getLoc();
1152 StringRef Identifier = Tok.getString();
1153 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1154 SM.onRegister(TmpReg);
1155 UpdateLocLex = false;
1156 break;
1157 } else {
1158 if (!isParsingInlineAsm()) {
1159 if (getParser().parsePrimaryExpr(Val, End))
1160 return Error(Tok.getLoc(), "Unexpected identifier!");
1161 } else {
1162 // This is a dot operator, not an adjacent identifier.
1163 if (Identifier.find('.') != StringRef::npos) {
1164 return false;
1165 } else {
1166 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1167 if (ParseIntelIdentifier(Val, Identifier, Info,
1168 /*Unevaluated=*/false, End))
1169 return true;
1170 }
1171 }
1172 SM.onIdentifierExpr(Val, Identifier);
1173 UpdateLocLex = false;
1174 break;
1175 }
1176 return Error(Tok.getLoc(), "Unexpected identifier!");
1177 }
1178 case AsmToken::Integer: {
1179 StringRef ErrMsg;
1180 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1181 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1182 Tok.getLoc()));
1183 // Look for 'b' or 'f' following an Integer as a directional label
1184 SMLoc Loc = getTok().getLoc();
1185 int64_t IntVal = getTok().getIntVal();
1186 End = consumeToken();
1187 UpdateLocLex = false;
1188 if (getLexer().getKind() == AsmToken::Identifier) {
1189 StringRef IDVal = getTok().getString();
1190 if (IDVal == "f" || IDVal == "b") {
1191 MCSymbol *Sym =
1192 getContext().GetDirectionalLocalSymbol(IntVal, IDVal == "b");
1193 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1194 const MCExpr *Val =
1195 MCSymbolRefExpr::Create(Sym, Variant, getContext());
1196 if (IDVal == "b" && Sym->isUndefined())
1197 return Error(Loc, "invalid reference to undefined symbol");
1198 StringRef Identifier = Sym->getName();
1199 SM.onIdentifierExpr(Val, Identifier);
1200 End = consumeToken();
1201 } else {
1202 if (SM.onInteger(IntVal, ErrMsg))
1203 return Error(Loc, ErrMsg);
1204 }
1205 } else {
1206 if (SM.onInteger(IntVal, ErrMsg))
1207 return Error(Loc, ErrMsg);
1208 }
1209 break;
1210 }
1211 case AsmToken::Plus: SM.onPlus(); break;
1212 case AsmToken::Minus: SM.onMinus(); break;
1213 case AsmToken::Tilde: SM.onNot(); break;
1214 case AsmToken::Star: SM.onStar(); break;
1215 case AsmToken::Slash: SM.onDivide(); break;
1216 case AsmToken::Pipe: SM.onOr(); break;
1217 case AsmToken::Amp: SM.onAnd(); break;
1218 case AsmToken::LessLess:
1219 SM.onLShift(); break;
1220 case AsmToken::GreaterGreater:
1221 SM.onRShift(); break;
1222 case AsmToken::LBrac: SM.onLBrac(); break;
1223 case AsmToken::RBrac: SM.onRBrac(); break;
1224 case AsmToken::LParen: SM.onLParen(); break;
1225 case AsmToken::RParen: SM.onRParen(); break;
1226 }
1227 if (SM.hadError())
1228 return Error(Tok.getLoc(), "unknown token in expression");
1229
1230 if (!Done && UpdateLocLex)
1231 End = consumeToken();
1232 }
1233 return false;
1234}
1235
1236std::unique_ptr<X86Operand>
1237X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1238 int64_t ImmDisp, unsigned Size) {
1239 MCAsmParser &Parser = getParser();
1240 const AsmToken &Tok = Parser.getTok();
1241 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1242 if (getLexer().isNot(AsmToken::LBrac))
11
Taking false branch
1243 return ErrorOperand(BracLoc, "Expected '[' token!");
1244 Parser.Lex(); // Eat '['
1245
1246 SMLoc StartInBrac = Tok.getLoc();
1247 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1248 // may have already parsed an immediate displacement before the bracketed
1249 // expression.
1250 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1251 if (ParseIntelExpression(SM, End))
12
Taking false branch
1252 return nullptr;
1253
1254 const MCExpr *Disp = nullptr;
1255 if (const MCExpr *Sym = SM.getSym()) {
13
Assuming 'Sym' is null
14
Taking false branch
1256 // A symbolic displacement.
1257 Disp = Sym;
1258 if (isParsingInlineAsm())
1259 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1260 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1261 End);
1262 }
1263
1264 if (SM.getImm() || !Disp) {
15
Taking true branch
1265 const MCExpr *Imm = MCConstantExpr::Create(SM.getImm(), getContext());
1266 if (Disp)
16
Taking false branch
1267 Disp = MCBinaryExpr::CreateAdd(Disp, Imm, getContext());
1268 else
1269 Disp = Imm; // An immediate displacement only.
1270 }
1271
1272 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1273 // will in fact do global lookup the field name inside all global typedefs,
1274 // but we don't emulate that.
1275 if (Tok.getString().find('.') != StringRef::npos) {
17
Taking true branch
1276 const MCExpr *NewDisp;
18
'NewDisp' declared without an initial value
1277 if (ParseIntelDotOperator(Disp, NewDisp))
19
Calling 'X86AsmParser::ParseIntelDotOperator'
24
Returning from 'X86AsmParser::ParseIntelDotOperator'
25
Taking false branch
1278 return nullptr;
1279
1280 End = Tok.getEndLoc();
1281 Parser.Lex(); // Eat the field.
1282 Disp = NewDisp;
26
Assigned value is garbage or undefined
1283 }
1284
1285 int BaseReg = SM.getBaseReg();
1286 int IndexReg = SM.getIndexReg();
1287 int Scale = SM.getScale();
1288 if (!isParsingInlineAsm()) {
1289 // handle [-42]
1290 if (!BaseReg && !IndexReg) {
1291 if (!SegReg)
1292 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1293 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1294 Start, End, Size);
1295 }
1296 StringRef ErrMsg;
1297 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1298 Error(StartInBrac, ErrMsg);
1299 return nullptr;
1300 }
1301 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1302 IndexReg, Scale, Start, End, Size);
1303 }
1304
1305 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1306 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1307 End, Size, SM.getSymName(), Info);
1308}
1309
1310// Inline assembly may use variable names with namespace alias qualifiers.
1311bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1312 StringRef &Identifier,
1313 InlineAsmIdentifierInfo &Info,
1314 bool IsUnevaluatedOperand, SMLoc &End) {
1315 MCAsmParser &Parser = getParser();
1316 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly.")((isParsingInlineAsm() && "Expected to be parsing inline assembly."
) ? static_cast<void> (0) : __assert_fail ("isParsingInlineAsm() && \"Expected to be parsing inline assembly.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1316, __PRETTY_FUNCTION__))
;
1317 Val = nullptr;
1318
1319 StringRef LineBuf(Identifier.data());
1320 void *Result =
1321 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1322
1323 const AsmToken &Tok = Parser.getTok();
1324 SMLoc Loc = Tok.getLoc();
1325
1326 // Advance the token stream until the end of the current token is
1327 // after the end of what the frontend claimed.
1328 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1329 while (true) {
1330 End = Tok.getEndLoc();
1331 getLexer().Lex();
1332
1333 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?")((End.getPointer() <= EndPtr && "frontend claimed part of a token?"
) ? static_cast<void> (0) : __assert_fail ("End.getPointer() <= EndPtr && \"frontend claimed part of a token?\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1333, __PRETTY_FUNCTION__))
;
1334 if (End.getPointer() == EndPtr) break;
1335 }
1336 Identifier = LineBuf;
1337
1338 // If the identifier lookup was unsuccessful, assume that we are dealing with
1339 // a label.
1340 if (!Result) {
1341 StringRef InternalName =
1342 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1343 Loc, false);
1344 assert(InternalName.size() && "We should have an internal name here.")((InternalName.size() && "We should have an internal name here."
) ? static_cast<void> (0) : __assert_fail ("InternalName.size() && \"We should have an internal name here.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1344, __PRETTY_FUNCTION__))
;
1345 // Push a rewrite for replacing the identifier name with the internal name.
1346 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Loc,
1347 Identifier.size(),
1348 InternalName));
1349 }
1350
1351 // Create the symbol reference.
1352 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
1353 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1354 Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());
1355 return false;
1356}
1357
1358/// \brief Parse intel style segment override.
1359std::unique_ptr<X86Operand>
1360X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1361 unsigned Size) {
1362 MCAsmParser &Parser = getParser();
1363 assert(SegReg != 0 && "Tried to parse a segment override without a segment!")((SegReg != 0 && "Tried to parse a segment override without a segment!"
) ? static_cast<void> (0) : __assert_fail ("SegReg != 0 && \"Tried to parse a segment override without a segment!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1363, __PRETTY_FUNCTION__))
;
1364 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1365 if (Tok.isNot(AsmToken::Colon))
1366 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1367 Parser.Lex(); // Eat ':'
1368
1369 int64_t ImmDisp = 0;
1370 if (getLexer().is(AsmToken::Integer)) {
1371 ImmDisp = Tok.getIntVal();
1372 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1373
1374 if (isParsingInlineAsm())
1375 InstInfo->AsmRewrites->push_back(
1376 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1377
1378 if (getLexer().isNot(AsmToken::LBrac)) {
1379 // An immediate following a 'segment register', 'colon' token sequence can
1380 // be followed by a bracketed expression. If it isn't we know we have our
1381 // final segment override.
1382 const MCExpr *Disp = MCConstantExpr::Create(ImmDisp, getContext());
1383 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1384 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1385 Start, ImmDispToken.getEndLoc(), Size);
1386 }
1387 }
1388
1389 if (getLexer().is(AsmToken::LBrac))
1390 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1391
1392 const MCExpr *Val;
1393 SMLoc End;
1394 if (!isParsingInlineAsm()) {
1395 if (getParser().parsePrimaryExpr(Val, End))
1396 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1397
1398 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1399 }
1400
1401 InlineAsmIdentifierInfo Info;
1402 StringRef Identifier = Tok.getString();
1403 if (ParseIntelIdentifier(Val, Identifier, Info,
1404 /*Unevaluated=*/false, End))
1405 return nullptr;
1406 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1407 /*Scale=*/1, Start, End, Size, Identifier, Info);
1408}
1409
1410/// ParseIntelMemOperand - Parse intel style memory operand.
1411std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1412 SMLoc Start,
1413 unsigned Size) {
1414 MCAsmParser &Parser = getParser();
1415 const AsmToken &Tok = Parser.getTok();
1416 SMLoc End;
1417
1418 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1419 if (getLexer().is(AsmToken::LBrac))
9
Taking true branch
1420 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
10
Calling 'X86AsmParser::ParseIntelBracExpression'
1421 assert(ImmDisp == 0)((ImmDisp == 0) ? static_cast<void> (0) : __assert_fail
("ImmDisp == 0", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1421, __PRETTY_FUNCTION__))
;
1422
1423 const MCExpr *Val;
1424 if (!isParsingInlineAsm()) {
1425 if (getParser().parsePrimaryExpr(Val, End))
1426 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1427
1428 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1429 }
1430
1431 InlineAsmIdentifierInfo Info;
1432 StringRef Identifier = Tok.getString();
1433 if (ParseIntelIdentifier(Val, Identifier, Info,
1434 /*Unevaluated=*/false, End))
1435 return nullptr;
1436
1437 if (!getLexer().is(AsmToken::LBrac))
1438 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1439 /*Scale=*/1, Start, End, Size, Identifier, Info);
1440
1441 Parser.Lex(); // Eat '['
1442
1443 // Parse Identifier [ ImmDisp ]
1444 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1445 /*AddImmPrefix=*/false);
1446 if (ParseIntelExpression(SM, End))
1447 return nullptr;
1448
1449 if (SM.getSym()) {
1450 Error(Start, "cannot use more than one symbol in memory operand");
1451 return nullptr;
1452 }
1453 if (SM.getBaseReg()) {
1454 Error(Start, "cannot use base register with variable reference");
1455 return nullptr;
1456 }
1457 if (SM.getIndexReg()) {
1458 Error(Start, "cannot use index register with variable reference");
1459 return nullptr;
1460 }
1461
1462 const MCExpr *Disp = MCConstantExpr::Create(SM.getImm(), getContext());
1463 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1464 // we're pointing to a local variable in memory, so the base register is
1465 // really the frame or stack pointer.
1466 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1467 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1468 Start, End, Size, Identifier, Info.OpDecl);
1469}
1470
1471/// Parse the '.' operator.
1472bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1473 const MCExpr *&NewDisp) {
1474 MCAsmParser &Parser = getParser();
20
Calling 'MCAsmParserExtension::getParser'
21
Returning from 'MCAsmParserExtension::getParser'
1475 const AsmToken &Tok = Parser.getTok();
1476 int64_t OrigDispVal, DotDispVal;
1477
1478 // FIXME: Handle non-constant expressions.
1479 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
22
Assuming 'OrigDisp' is null
23
Taking false branch
1480 OrigDispVal = OrigDisp->getValue();
1481 else
1482 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1483
1484 // Drop the optional '.'.
1485 StringRef DotDispStr = Tok.getString();
1486 if (DotDispStr.startswith("."))
1487 DotDispStr = DotDispStr.drop_front(1);
1488
1489 // .Imm gets lexed as a real.
1490 if (Tok.is(AsmToken::Real)) {
1491 APInt DotDisp;
1492 DotDispStr.getAsInteger(10, DotDisp);
1493 DotDispVal = DotDisp.getZExtValue();
1494 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1495 unsigned DotDisp;
1496 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1497 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1498 DotDisp))
1499 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1500 DotDispVal = DotDisp;
1501 } else
1502 return Error(Tok.getLoc(), "Unexpected token type!");
1503
1504 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1505 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1506 unsigned Len = DotDispStr.size();
1507 unsigned Val = OrigDispVal + DotDispVal;
1508 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1509 Val));
1510 }
1511
1512 NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
1513 return false;
1514}
1515
1516/// Parse the 'offset' operator. This operator is used to specify the
1517/// location rather then the content of a variable.
1518std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1519 MCAsmParser &Parser = getParser();
1520 const AsmToken &Tok = Parser.getTok();
1521 SMLoc OffsetOfLoc = Tok.getLoc();
1522 Parser.Lex(); // Eat offset.
1523
1524 const MCExpr *Val;
1525 InlineAsmIdentifierInfo Info;
1526 SMLoc Start = Tok.getLoc(), End;
1527 StringRef Identifier = Tok.getString();
1528 if (ParseIntelIdentifier(Val, Identifier, Info,
1529 /*Unevaluated=*/false, End))
1530 return nullptr;
1531
1532 // Don't emit the offset operator.
1533 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1534
1535 // The offset operator will have an 'r' constraint, thus we need to create
1536 // register operand to ensure proper matching. Just pick a GPR based on
1537 // the size of a pointer.
1538 unsigned RegNo =
1539 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1540 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1541 OffsetOfLoc, Identifier, Info.OpDecl);
1542}
1543
1544enum IntelOperatorKind {
1545 IOK_LENGTH,
1546 IOK_SIZE,
1547 IOK_TYPE
1548};
1549
1550/// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1551/// returns the number of elements in an array. It returns the value 1 for
1552/// non-array variables. The SIZE operator returns the size of a C or C++
1553/// variable. A variable's size is the product of its LENGTH and TYPE. The
1554/// TYPE operator returns the size of a C or C++ type or variable. If the
1555/// variable is an array, TYPE returns the size of a single element.
1556std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1557 MCAsmParser &Parser = getParser();
1558 const AsmToken &Tok = Parser.getTok();
1559 SMLoc TypeLoc = Tok.getLoc();
1560 Parser.Lex(); // Eat operator.
1561
1562 const MCExpr *Val = nullptr;
1563 InlineAsmIdentifierInfo Info;
1564 SMLoc Start = Tok.getLoc(), End;
1565 StringRef Identifier = Tok.getString();
1566 if (ParseIntelIdentifier(Val, Identifier, Info,
1567 /*Unevaluated=*/true, End))
1568 return nullptr;
1569
1570 if (!Info.OpDecl)
1571 return ErrorOperand(Start, "unable to lookup expression");
1572
1573 unsigned CVal = 0;
1574 switch(OpKind) {
1575 default: llvm_unreachable("Unexpected operand kind!")::llvm::llvm_unreachable_internal("Unexpected operand kind!",
"/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 1575)
;
1576 case IOK_LENGTH: CVal = Info.Length; break;
1577 case IOK_SIZE: CVal = Info.Size; break;
1578 case IOK_TYPE: CVal = Info.Type; break;
1579 }
1580
1581 // Rewrite the type operator and the C or C++ type or variable in terms of an
1582 // immediate. E.g. TYPE foo -> $$4
1583 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1584 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1585
1586 const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext());
1587 return X86Operand::CreateImm(Imm, Start, End);
1588}
1589
1590std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1591 MCAsmParser &Parser = getParser();
1592 const AsmToken &Tok = Parser.getTok();
1593 SMLoc Start, End;
1594
1595 // Offset, length, type and size operators.
1596 if (isParsingInlineAsm()) {
3
Taking false branch
1597 StringRef AsmTokStr = Tok.getString();
1598 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1599 return ParseIntelOffsetOfOperator();
1600 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1601 return ParseIntelOperator(IOK_LENGTH);
1602 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1603 return ParseIntelOperator(IOK_SIZE);
1604 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1605 return ParseIntelOperator(IOK_TYPE);
1606 }
1607
1608 unsigned Size = getIntelMemOperandSize(Tok.getString());
1609 if (Size) {
4
Assuming 'Size' is 0
5
Taking false branch
1610 Parser.Lex(); // Eat operand size (e.g., byte, word).
1611 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1612 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1613 Parser.Lex(); // Eat ptr.
1614 }
1615 Start = Tok.getLoc();
1616
1617 // Immediate.
1618 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
6
Taking false branch
1619 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1620 AsmToken StartTok = Tok;
1621 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1622 /*AddImmPrefix=*/false);
1623 if (ParseIntelExpression(SM, End))
1624 return nullptr;
1625
1626 int64_t Imm = SM.getImm();
1627 if (isParsingInlineAsm()) {
1628 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1629 if (StartTok.getString().size() == Len)
1630 // Just add a prefix if this wasn't a complex immediate expression.
1631 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1632 else
1633 // Otherwise, rewrite the complex expression as a single immediate.
1634 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
1635 }
1636
1637 if (getLexer().isNot(AsmToken::LBrac)) {
1638 // If a directional label (ie. 1f or 2b) was parsed above from
1639 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1640 // to the MCExpr with the directional local symbol and this is a
1641 // memory operand not an immediate operand.
1642 if (SM.getSym())
1643 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1644 Size);
1645
1646 const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext());
1647 return X86Operand::CreateImm(ImmExpr, Start, End);
1648 }
1649
1650 // Only positive immediates are valid.
1651 if (Imm < 0)
1652 return ErrorOperand(Start, "expected a positive immediate displacement "
1653 "before bracketed expr.");
1654
1655 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1656 return ParseIntelMemOperand(Imm, Start, Size);
1657 }
1658
1659 // Register.
1660 unsigned RegNo = 0;
1661 if (!ParseRegister(RegNo, Start, End)) {
7
Taking false branch
1662 // If this is a segment register followed by a ':', then this is the start
1663 // of a segment override, otherwise this is a normal register reference.
1664 if (getLexer().isNot(AsmToken::Colon))
1665 return X86Operand::CreateReg(RegNo, Start, End);
1666
1667 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1668 }
1669
1670 // Memory operand.
1671 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
8
Calling 'X86AsmParser::ParseIntelMemOperand'
1672}
1673
1674std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1675 MCAsmParser &Parser = getParser();
1676 switch (getLexer().getKind()) {
1677 default:
1678 // Parse a memory operand with no segment register.
1679 return ParseMemOperand(0, Parser.getTok().getLoc());
1680 case AsmToken::Percent: {
1681 // Read the register.
1682 unsigned RegNo;
1683 SMLoc Start, End;
1684 if (ParseRegister(RegNo, Start, End)) return nullptr;
1685 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1686 Error(Start, "%eiz and %riz can only be used as index registers",
1687 SMRange(Start, End));
1688 return nullptr;
1689 }
1690
1691 // If this is a segment register followed by a ':', then this is the start
1692 // of a memory reference, otherwise this is a normal register reference.
1693 if (getLexer().isNot(AsmToken::Colon))
1694 return X86Operand::CreateReg(RegNo, Start, End);
1695
1696 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1697 return ErrorOperand(Start, "invalid segment register");
1698
1699 getParser().Lex(); // Eat the colon.
1700 return ParseMemOperand(RegNo, Start);
1701 }
1702 case AsmToken::Dollar: {
1703 // $42 -> immediate.
1704 SMLoc Start = Parser.getTok().getLoc(), End;
1705 Parser.Lex();
1706 const MCExpr *Val;
1707 if (getParser().parseExpression(Val, End))
1708 return nullptr;
1709 return X86Operand::CreateImm(Val, Start, End);
1710 }
1711 }
1712}
1713
1714bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1715 const MCParsedAsmOperand &Op) {
1716 MCAsmParser &Parser = getParser();
1717 if(STI.getFeatureBits() & X86::FeatureAVX512) {
1718 if (getLexer().is(AsmToken::LCurly)) {
1719 // Eat "{" and mark the current place.
1720 const SMLoc consumedToken = consumeToken();
1721 // Distinguish {1to<NUM>} from {%k<NUM>}.
1722 if(getLexer().is(AsmToken::Integer)) {
1723 // Parse memory broadcasting ({1to<NUM>}).
1724 if (getLexer().getTok().getIntVal() != 1)
1725 return !ErrorAndEatStatement(getLexer().getLoc(),
1726 "Expected 1to<NUM> at this point");
1727 Parser.Lex(); // Eat "1" of 1to8
1728 if (!getLexer().is(AsmToken::Identifier) ||
1729 !getLexer().getTok().getIdentifier().startswith("to"))
1730 return !ErrorAndEatStatement(getLexer().getLoc(),
1731 "Expected 1to<NUM> at this point");
1732 // Recognize only reasonable suffixes.
1733 const char *BroadcastPrimitive =
1734 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1735 .Case("to2", "{1to2}")
1736 .Case("to4", "{1to4}")
1737 .Case("to8", "{1to8}")
1738 .Case("to16", "{1to16}")
1739 .Default(nullptr);
1740 if (!BroadcastPrimitive)
1741 return !ErrorAndEatStatement(getLexer().getLoc(),
1742 "Invalid memory broadcast primitive.");
1743 Parser.Lex(); // Eat "toN" of 1toN
1744 if (!getLexer().is(AsmToken::RCurly))
1745 return !ErrorAndEatStatement(getLexer().getLoc(),
1746 "Expected } at this point");
1747 Parser.Lex(); // Eat "}"
1748 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1749 consumedToken));
1750 // No AVX512 specific primitives can pass
1751 // after memory broadcasting, so return.
1752 return true;
1753 } else {
1754 // Parse mask register {%k1}
1755 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1756 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1757 Operands.push_back(std::move(Op));
1758 if (!getLexer().is(AsmToken::RCurly))
1759 return !ErrorAndEatStatement(getLexer().getLoc(),
1760 "Expected } at this point");
1761 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1762
1763 // Parse "zeroing non-masked" semantic {z}
1764 if (getLexer().is(AsmToken::LCurly)) {
1765 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1766 if (!getLexer().is(AsmToken::Identifier) ||
1767 getLexer().getTok().getIdentifier() != "z")
1768 return !ErrorAndEatStatement(getLexer().getLoc(),
1769 "Expected z at this point");
1770 Parser.Lex(); // Eat the z
1771 if (!getLexer().is(AsmToken::RCurly))
1772 return !ErrorAndEatStatement(getLexer().getLoc(),
1773 "Expected } at this point");
1774 Parser.Lex(); // Eat the }
1775 }
1776 }
1777 }
1778 }
1779 }
1780 return true;
1781}
1782
1783/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1784/// has already been parsed if present.
1785std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1786 SMLoc MemStart) {
1787
1788 MCAsmParser &Parser = getParser();
1789 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1790 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1791 // only way to do this without lookahead is to eat the '(' and see what is
1792 // after it.
1793 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1794 if (getLexer().isNot(AsmToken::LParen)) {
1795 SMLoc ExprEnd;
1796 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1797
1798 // After parsing the base expression we could either have a parenthesized
1799 // memory address or not. If not, return now. If so, eat the (.
1800 if (getLexer().isNot(AsmToken::LParen)) {
1801 // Unless we have a segment register, treat this as an immediate.
1802 if (SegReg == 0)
1803 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1804 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1805 MemStart, ExprEnd);
1806 }
1807
1808 // Eat the '('.
1809 Parser.Lex();
1810 } else {
1811 // Okay, we have a '('. We don't know if this is an expression or not, but
1812 // so we have to eat the ( to see beyond it.
1813 SMLoc LParenLoc = Parser.getTok().getLoc();
1814 Parser.Lex(); // Eat the '('.
1815
1816 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1817 // Nothing to do here, fall into the code below with the '(' part of the
1818 // memory operand consumed.
1819 } else {
1820 SMLoc ExprEnd;
1821
1822 // It must be an parenthesized expression, parse it now.
1823 if (getParser().parseParenExpression(Disp, ExprEnd))
1824 return nullptr;
1825
1826 // After parsing the base expression we could either have a parenthesized
1827 // memory address or not. If not, return now. If so, eat the (.
1828 if (getLexer().isNot(AsmToken::LParen)) {
1829 // Unless we have a segment register, treat this as an immediate.
1830 if (SegReg == 0)
1831 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1832 ExprEnd);
1833 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1834 MemStart, ExprEnd);
1835 }
1836
1837 // Eat the '('.
1838 Parser.Lex();
1839 }
1840 }
1841
1842 // If we reached here, then we just ate the ( of the memory operand. Process
1843 // the rest of the memory operand.
1844 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1845 SMLoc IndexLoc, BaseLoc;
1846
1847 if (getLexer().is(AsmToken::Percent)) {
1848 SMLoc StartLoc, EndLoc;
1849 BaseLoc = Parser.getTok().getLoc();
1850 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1851 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1852 Error(StartLoc, "eiz and riz can only be used as index registers",
1853 SMRange(StartLoc, EndLoc));
1854 return nullptr;
1855 }
1856 }
1857
1858 if (getLexer().is(AsmToken::Comma)) {
1859 Parser.Lex(); // Eat the comma.
1860 IndexLoc = Parser.getTok().getLoc();
1861
1862 // Following the comma we should have either an index register, or a scale
1863 // value. We don't support the later form, but we want to parse it
1864 // correctly.
1865 //
1866 // Not that even though it would be completely consistent to support syntax
1867 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1868 if (getLexer().is(AsmToken::Percent)) {
1869 SMLoc L;
1870 if (ParseRegister(IndexReg, L, L)) return nullptr;
1871
1872 if (getLexer().isNot(AsmToken::RParen)) {
1873 // Parse the scale amount:
1874 // ::= ',' [scale-expression]
1875 if (getLexer().isNot(AsmToken::Comma)) {
1876 Error(Parser.getTok().getLoc(),
1877 "expected comma in scale expression");
1878 return nullptr;
1879 }
1880 Parser.Lex(); // Eat the comma.
1881
1882 if (getLexer().isNot(AsmToken::RParen)) {
1883 SMLoc Loc = Parser.getTok().getLoc();
1884
1885 int64_t ScaleVal;
1886 if (getParser().parseAbsoluteExpression(ScaleVal)){
1887 Error(Loc, "expected scale expression");
1888 return nullptr;
1889 }
1890
1891 // Validate the scale amount.
1892 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1893 ScaleVal != 1) {
1894 Error(Loc, "scale factor in 16-bit address must be 1");
1895 return nullptr;
1896 }
1897 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1898 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1899 return nullptr;
1900 }
1901 Scale = (unsigned)ScaleVal;
1902 }
1903 }
1904 } else if (getLexer().isNot(AsmToken::RParen)) {
1905 // A scale amount without an index is ignored.
1906 // index.
1907 SMLoc Loc = Parser.getTok().getLoc();
1908
1909 int64_t Value;
1910 if (getParser().parseAbsoluteExpression(Value))
1911 return nullptr;
1912
1913 if (Value != 1)
1914 Warning(Loc, "scale factor without index register is ignored");
1915 Scale = 1;
1916 }
1917 }
1918
1919 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
1920 if (getLexer().isNot(AsmToken::RParen)) {
1921 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
1922 return nullptr;
1923 }
1924 SMLoc MemEnd = Parser.getTok().getEndLoc();
1925 Parser.Lex(); // Eat the ')'.
1926
1927 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
1928 // and then only in non-64-bit modes. Except for DX, which is a special case
1929 // because an unofficial form of in/out instructions uses it.
1930 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1931 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
1932 BaseReg != X86::SI && BaseReg != X86::DI)) &&
1933 BaseReg != X86::DX) {
1934 Error(BaseLoc, "invalid 16-bit base register");
1935 return nullptr;
1936 }
1937 if (BaseReg == 0 &&
1938 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
1939 Error(IndexLoc, "16-bit memory operand may not include only index register");
1940 return nullptr;
1941 }
1942
1943 StringRef ErrMsg;
1944 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1945 Error(BaseLoc, ErrMsg);
1946 return nullptr;
1947 }
1948
1949 if (SegReg || BaseReg || IndexReg)
1950 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1951 IndexReg, Scale, MemStart, MemEnd);
1952 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
1953}
1954
1955bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1956 SMLoc NameLoc, OperandVector &Operands) {
1957 MCAsmParser &Parser = getParser();
1958 InstInfo = &Info;
1959 StringRef PatchedName = Name;
1960
1961 // FIXME: Hack to recognize setneb as setne.
1962 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
1963 PatchedName != "setb" && PatchedName != "setnb")
1964 PatchedName = PatchedName.substr(0, Name.size()-1);
1965
1966 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
1967 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
1968 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
1969 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
1970 bool IsVCMP = PatchedName[0] == 'v';
1971 unsigned CCIdx = IsVCMP ? 4 : 3;
1972 unsigned ComparisonCode = StringSwitch<unsigned>(
1973 PatchedName.slice(CCIdx, PatchedName.size() - 2))
1974 .Case("eq", 0x00)
1975 .Case("lt", 0x01)
1976 .Case("le", 0x02)
1977 .Case("unord", 0x03)
1978 .Case("neq", 0x04)
1979 .Case("nlt", 0x05)
1980 .Case("nle", 0x06)
1981 .Case("ord", 0x07)
1982 /* AVX only from here */
1983 .Case("eq_uq", 0x08)
1984 .Case("nge", 0x09)
1985 .Case("ngt", 0x0A)
1986 .Case("false", 0x0B)
1987 .Case("neq_oq", 0x0C)
1988 .Case("ge", 0x0D)
1989 .Case("gt", 0x0E)
1990 .Case("true", 0x0F)
1991 .Case("eq_os", 0x10)
1992 .Case("lt_oq", 0x11)
1993 .Case("le_oq", 0x12)
1994 .Case("unord_s", 0x13)
1995 .Case("neq_us", 0x14)
1996 .Case("nlt_uq", 0x15)
1997 .Case("nle_uq", 0x16)
1998 .Case("ord_s", 0x17)
1999 .Case("eq_us", 0x18)
2000 .Case("nge_uq", 0x19)
2001 .Case("ngt_uq", 0x1A)
2002 .Case("false_os", 0x1B)
2003 .Case("neq_os", 0x1C)
2004 .Case("ge_oq", 0x1D)
2005 .Case("gt_oq", 0x1E)
2006 .Case("true_us", 0x1F)
2007 .Default(~0U);
2008 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2009
2010 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2011 NameLoc));
2012
2013 const MCExpr *ImmOp = MCConstantExpr::Create(ComparisonCode,
2014 getParser().getContext());
2015 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2016
2017 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2018 }
2019 }
2020
2021 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2022 if (PatchedName.startswith("vpcmp") &&
2023 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2024 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2025 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2026 unsigned ComparisonCode = StringSwitch<unsigned>(
2027 PatchedName.slice(5, PatchedName.size() - CCIdx))
2028 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2029 .Case("lt", 0x1)
2030 .Case("le", 0x2)
2031 //.Case("false", 0x3) // Not a documented alias.
2032 .Case("neq", 0x4)
2033 .Case("nlt", 0x5)
2034 .Case("nle", 0x6)
2035 //.Case("true", 0x7) // Not a documented alias.
2036 .Default(~0U);
2037 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2038 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2039
2040 const MCExpr *ImmOp = MCConstantExpr::Create(ComparisonCode,
2041 getParser().getContext());
2042 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2043
2044 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2045 }
2046 }
2047
2048 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2049 if (PatchedName.startswith("vpcom") &&
2050 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2051 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2052 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2053 unsigned ComparisonCode = StringSwitch<unsigned>(
2054 PatchedName.slice(5, PatchedName.size() - CCIdx))
2055 .Case("lt", 0x0)
2056 .Case("le", 0x1)
2057 .Case("gt", 0x2)
2058 .Case("ge", 0x3)
2059 .Case("eq", 0x4)
2060 .Case("neq", 0x5)
2061 .Case("false", 0x6)
2062 .Case("true", 0x7)
2063 .Default(~0U);
2064 if (ComparisonCode != ~0U) {
2065 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2066
2067 const MCExpr *ImmOp = MCConstantExpr::Create(ComparisonCode,
2068 getParser().getContext());
2069 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2070
2071 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2072 }
2073 }
2074
2075 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2076
2077 // Determine whether this is an instruction prefix.
2078 bool isPrefix =
2079 Name == "lock" || Name == "rep" ||
2080 Name == "repe" || Name == "repz" ||
2081 Name == "repne" || Name == "repnz" ||
2082 Name == "rex64" || Name == "data16";
2083
2084
2085 // This does the actual operand parsing. Don't parse any more if we have a
2086 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2087 // just want to parse the "lock" as the first instruction and the "incl" as
2088 // the next one.
2089 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2090
2091 // Parse '*' modifier.
2092 if (getLexer().is(AsmToken::Star))
2093 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2094
2095 // Read the operands.
2096 while(1) {
2097 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2098 Operands.push_back(std::move(Op));
2099 if (!HandleAVX512Operand(Operands, *Operands.back()))
2100 return true;
2101 } else {
2102 Parser.eatToEndOfStatement();
2103 return true;
2104 }
2105 // check for comma and eat it
2106 if (getLexer().is(AsmToken::Comma))
2107 Parser.Lex();
2108 else
2109 break;
2110 }
2111
2112 if (getLexer().isNot(AsmToken::EndOfStatement))
2113 return ErrorAndEatStatement(getLexer().getLoc(),
2114 "unexpected token in argument list");
2115 }
2116
2117 // Consume the EndOfStatement or the prefix separator Slash
2118 if (getLexer().is(AsmToken::EndOfStatement) ||
2119 (isPrefix && getLexer().is(AsmToken::Slash)))
2120 Parser.Lex();
2121
2122 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2123 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2124 // documented form in various unofficial manuals, so a lot of code uses it.
2125 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2126 Operands.size() == 3) {
2127 X86Operand &Op = (X86Operand &)*Operands.back();
2128 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2129 isa<MCConstantExpr>(Op.Mem.Disp) &&
2130 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2131 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2132 SMLoc Loc = Op.getEndLoc();
2133 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2134 }
2135 }
2136 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2137 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2138 Operands.size() == 3) {
2139 X86Operand &Op = (X86Operand &)*Operands[1];
2140 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2141 isa<MCConstantExpr>(Op.Mem.Disp) &&
2142 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2143 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2144 SMLoc Loc = Op.getEndLoc();
2145 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2146 }
2147 }
2148
2149 // Append default arguments to "ins[bwld]"
2150 if (Name.startswith("ins") && Operands.size() == 1 &&
2151 (Name == "insb" || Name == "insw" || Name == "insl" ||
2152 Name == "insd" )) {
2153 if (isParsingIntelSyntax()) {
2154 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2155 Operands.push_back(DefaultMemDIOperand(NameLoc));
2156 } else {
2157 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2158 Operands.push_back(DefaultMemDIOperand(NameLoc));
2159 }
2160 }
2161
2162 // Append default arguments to "outs[bwld]"
2163 if (Name.startswith("outs") && Operands.size() == 1 &&
2164 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2165 Name == "outsd" )) {
2166 if (isParsingIntelSyntax()) {
2167 Operands.push_back(DefaultMemSIOperand(NameLoc));
2168 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2169 } else {
2170 Operands.push_back(DefaultMemSIOperand(NameLoc));
2171 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2172 }
2173 }
2174
2175 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2176 // values of $SIREG according to the mode. It would be nice if this
2177 // could be achieved with InstAlias in the tables.
2178 if (Name.startswith("lods") && Operands.size() == 1 &&
2179 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2180 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2181 Operands.push_back(DefaultMemSIOperand(NameLoc));
2182
2183 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2184 // values of $DIREG according to the mode. It would be nice if this
2185 // could be achieved with InstAlias in the tables.
2186 if (Name.startswith("stos") && Operands.size() == 1 &&
2187 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2188 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2189 Operands.push_back(DefaultMemDIOperand(NameLoc));
2190
2191 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2192 // values of $DIREG according to the mode. It would be nice if this
2193 // could be achieved with InstAlias in the tables.
2194 if (Name.startswith("scas") && Operands.size() == 1 &&
2195 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2196 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2197 Operands.push_back(DefaultMemDIOperand(NameLoc));
2198
2199 // Add default SI and DI operands to "cmps[bwlq]".
2200 if (Name.startswith("cmps") &&
2201 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2202 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2203 if (Operands.size() == 1) {
2204 if (isParsingIntelSyntax()) {
2205 Operands.push_back(DefaultMemSIOperand(NameLoc));
2206 Operands.push_back(DefaultMemDIOperand(NameLoc));
2207 } else {
2208 Operands.push_back(DefaultMemDIOperand(NameLoc));
2209 Operands.push_back(DefaultMemSIOperand(NameLoc));
2210 }
2211 } else if (Operands.size() == 3) {
2212 X86Operand &Op = (X86Operand &)*Operands[1];
2213 X86Operand &Op2 = (X86Operand &)*Operands[2];
2214 if (!doSrcDstMatch(Op, Op2))
2215 return Error(Op.getStartLoc(),
2216 "mismatching source and destination index registers");
2217 }
2218 }
2219
2220 // Add default SI and DI operands to "movs[bwlq]".
2221 if ((Name.startswith("movs") &&
2222 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2223 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2224 (Name.startswith("smov") &&
2225 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2226 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2227 if (Operands.size() == 1) {
2228 if (Name == "movsd")
2229 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2230 if (isParsingIntelSyntax()) {
2231 Operands.push_back(DefaultMemDIOperand(NameLoc));
2232 Operands.push_back(DefaultMemSIOperand(NameLoc));
2233 } else {
2234 Operands.push_back(DefaultMemSIOperand(NameLoc));
2235 Operands.push_back(DefaultMemDIOperand(NameLoc));
2236 }
2237 } else if (Operands.size() == 3) {
2238 X86Operand &Op = (X86Operand &)*Operands[1];
2239 X86Operand &Op2 = (X86Operand &)*Operands[2];
2240 if (!doSrcDstMatch(Op, Op2))
2241 return Error(Op.getStartLoc(),
2242 "mismatching source and destination index registers");
2243 }
2244 }
2245
2246 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2247 // "shift <op>".
2248 if ((Name.startswith("shr") || Name.startswith("sar") ||
2249 Name.startswith("shl") || Name.startswith("sal") ||
2250 Name.startswith("rcl") || Name.startswith("rcr") ||
2251 Name.startswith("rol") || Name.startswith("ror")) &&
2252 Operands.size() == 3) {
2253 if (isParsingIntelSyntax()) {
2254 // Intel syntax
2255 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2256 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2257 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2258 Operands.pop_back();
2259 } else {
2260 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2261 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2262 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2263 Operands.erase(Operands.begin() + 1);
2264 }
2265 }
2266
2267 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2268 // instalias with an immediate operand yet.
2269 if (Name == "int" && Operands.size() == 2) {
2270 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2271 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2272 cast<MCConstantExpr>(Op1.getImm())->getValue() == 3) {
2273 Operands.erase(Operands.begin() + 1);
2274 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2275 }
2276 }
2277
2278 return false;
2279}
2280
2281static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2282 bool isCmp) {
2283 MCInst TmpInst;
2284 TmpInst.setOpcode(Opcode);
2285 if (!isCmp)
2286 TmpInst.addOperand(MCOperand::CreateReg(Reg));
2287 TmpInst.addOperand(MCOperand::CreateReg(Reg));
2288 TmpInst.addOperand(Inst.getOperand(0));
2289 Inst = TmpInst;
2290 return true;
2291}
2292
2293static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2294 bool isCmp = false) {
2295 if (!Inst.getOperand(0).isImm() ||
2296 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2297 return false;
2298
2299 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2300}
2301
2302static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2303 bool isCmp = false) {
2304 if (!Inst.getOperand(0).isImm() ||
2305 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2306 return false;
2307
2308 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2309}
2310
2311static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2312 bool isCmp = false) {
2313 if (!Inst.getOperand(0).isImm() ||
2314 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2315 return false;
2316
2317 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2318}
2319
2320bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2321 switch (Inst.getOpcode()) {
2322 default: return true;
2323 case X86::INT:
2324 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2325 assert(Op.isImm() && "expected immediate")((Op.isImm() && "expected immediate") ? static_cast<
void> (0) : __assert_fail ("Op.isImm() && \"expected immediate\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2325, __PRETTY_FUNCTION__))
;
2326 int64_t Res;
2327 if (!Op.getImm()->EvaluateAsAbsolute(Res) || Res > 255) {
2328 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2329 return false;
2330 }
2331 return true;
2332 }
2333 llvm_unreachable("handle the instruction appropriately")::llvm::llvm_unreachable_internal("handle the instruction appropriately"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2333)
;
2334}
2335
2336bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2337 switch (Inst.getOpcode()) {
2338 default: return false;
2339 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2340 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2341 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2342 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2343 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2344 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2345 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2346 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2347 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2348 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2349 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2350 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2351 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2352 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2353 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2354 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2355 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2356 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2357 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2358 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2359 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2360 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2361 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2362 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2363 case X86::VMOVAPDrr:
2364 case X86::VMOVAPDYrr:
2365 case X86::VMOVAPSrr:
2366 case X86::VMOVAPSYrr:
2367 case X86::VMOVDQArr:
2368 case X86::VMOVDQAYrr:
2369 case X86::VMOVDQUrr:
2370 case X86::VMOVDQUYrr:
2371 case X86::VMOVUPDrr:
2372 case X86::VMOVUPDYrr:
2373 case X86::VMOVUPSrr:
2374 case X86::VMOVUPSYrr: {
2375 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2376 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2377 return false;
2378
2379 unsigned NewOpc;
2380 switch (Inst.getOpcode()) {
2381 default: llvm_unreachable("Invalid opcode")::llvm::llvm_unreachable_internal("Invalid opcode", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2381)
;
2382 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2383 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2384 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2385 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2386 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2387 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2388 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2389 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2390 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2391 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2392 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2393 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2394 }
2395 Inst.setOpcode(NewOpc);
2396 return true;
2397 }
2398 case X86::VMOVSDrr:
2399 case X86::VMOVSSrr: {
2400 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2401 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2402 return false;
2403 unsigned NewOpc;
2404 switch (Inst.getOpcode()) {
2405 default: llvm_unreachable("Invalid opcode")::llvm::llvm_unreachable_internal("Invalid opcode", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2405)
;
2406 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2407 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2408 }
2409 Inst.setOpcode(NewOpc);
2410 return true;
2411 }
2412 }
2413}
2414
2415static const char *getSubtargetFeatureName(uint64_t Val);
2416
2417void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2418 MCStreamer &Out) {
2419 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2420 MII, Out);
2421}
2422
2423bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2424 OperandVector &Operands,
2425 MCStreamer &Out, uint64_t &ErrorInfo,
2426 bool MatchingInlineAsm) {
2427 if (isParsingIntelSyntax())
2428 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2429 MatchingInlineAsm);
2430 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2431 MatchingInlineAsm);
2432}
2433
2434void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2435 OperandVector &Operands, MCStreamer &Out,
2436 bool MatchingInlineAsm) {
2437 // FIXME: This should be replaced with a real .td file alias mechanism.
2438 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2439 // call.
2440 const char *Repl = StringSwitch<const char *>(Op.getToken())
2441 .Case("finit", "fninit")
2442 .Case("fsave", "fnsave")
2443 .Case("fstcw", "fnstcw")
2444 .Case("fstcww", "fnstcw")
2445 .Case("fstenv", "fnstenv")
2446 .Case("fstsw", "fnstsw")
2447 .Case("fstsww", "fnstsw")
2448 .Case("fclex", "fnclex")
2449 .Default(nullptr);
2450 if (Repl) {
2451 MCInst Inst;
2452 Inst.setOpcode(X86::WAIT);
2453 Inst.setLoc(IDLoc);
2454 if (!MatchingInlineAsm)
2455 EmitInstruction(Inst, Operands, Out);
2456 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2457 }
2458}
2459
2460bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2461 bool MatchingInlineAsm) {
2462 assert(ErrorInfo && "Unknown missing feature!")((ErrorInfo && "Unknown missing feature!") ? static_cast
<void> (0) : __assert_fail ("ErrorInfo && \"Unknown missing feature!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2462, __PRETTY_FUNCTION__))
;
2463 ArrayRef<SMRange> EmptyRanges = None;
2464 SmallString<126> Msg;
2465 raw_svector_ostream OS(Msg);
2466 OS << "instruction requires:";
2467 uint64_t Mask = 1;
2468 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2469 if (ErrorInfo & Mask)
2470 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2471 Mask <<= 1;
2472 }
2473 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2474}
2475
2476bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2477 OperandVector &Operands,
2478 MCStreamer &Out,
2479 uint64_t &ErrorInfo,
2480 bool MatchingInlineAsm) {
2481 assert(!Operands.empty() && "Unexpect empty operand list!")((!Operands.empty() && "Unexpect empty operand list!"
) ? static_cast<void> (0) : __assert_fail ("!Operands.empty() && \"Unexpect empty operand list!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2481, __PRETTY_FUNCTION__))
;
2482 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2483 assert(Op.isToken() && "Leading operand should always be a mnemonic!")((Op.isToken() && "Leading operand should always be a mnemonic!"
) ? static_cast<void> (0) : __assert_fail ("Op.isToken() && \"Leading operand should always be a mnemonic!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2483, __PRETTY_FUNCTION__))
;
2484 ArrayRef<SMRange> EmptyRanges = None;
2485
2486 // First, handle aliases that expand to multiple instructions.
2487 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2488
2489 bool WasOriginallyInvalidOperand = false;
2490 MCInst Inst;
2491
2492 // First, try a direct match.
2493 switch (MatchInstructionImpl(Operands, Inst,
2494 ErrorInfo, MatchingInlineAsm,
2495 isParsingIntelSyntax())) {
2496 default: llvm_unreachable("Unexpected match result!")::llvm::llvm_unreachable_internal("Unexpected match result!",
"/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2496)
;
2497 case Match_Success:
2498 if (!validateInstruction(Inst, Operands))
2499 return true;
2500
2501 // Some instructions need post-processing to, for example, tweak which
2502 // encoding is selected. Loop on it while changes happen so the
2503 // individual transformations can chain off each other.
2504 if (!MatchingInlineAsm)
2505 while (processInstruction(Inst, Operands))
2506 ;
2507
2508 Inst.setLoc(IDLoc);
2509 if (!MatchingInlineAsm)
2510 EmitInstruction(Inst, Operands, Out);
2511 Opcode = Inst.getOpcode();
2512 return false;
2513 case Match_MissingFeature:
2514 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2515 case Match_InvalidOperand:
2516 WasOriginallyInvalidOperand = true;
2517 break;
2518 case Match_MnemonicFail:
2519 break;
2520 }
2521
2522 // FIXME: Ideally, we would only attempt suffix matches for things which are
2523 // valid prefixes, and we could just infer the right unambiguous
2524 // type. However, that requires substantially more matcher support than the
2525 // following hack.
2526
2527 // Change the operand to point to a temporary token.
2528 StringRef Base = Op.getToken();
2529 SmallString<16> Tmp;
2530 Tmp += Base;
2531 Tmp += ' ';
2532 Op.setTokenValue(Tmp.str());
2533
2534 // If this instruction starts with an 'f', then it is a floating point stack
2535 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2536 // 80-bit floating point, which use the suffixes s,l,t respectively.
2537 //
2538 // Otherwise, we assume that this may be an integer instruction, which comes
2539 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2540 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2541
2542 // Check for the various suffix matches.
2543 uint64_t ErrorInfoIgnore;
2544 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2545 unsigned Match[4];
2546
2547 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2548 Tmp.back() = Suffixes[I];
2549 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2550 MatchingInlineAsm, isParsingIntelSyntax());
2551 // If this returned as a missing feature failure, remember that.
2552 if (Match[I] == Match_MissingFeature)
2553 ErrorInfoMissingFeature = ErrorInfoIgnore;
2554 }
2555
2556 // Restore the old token.
2557 Op.setTokenValue(Base);
2558
2559 // If exactly one matched, then we treat that as a successful match (and the
2560 // instruction will already have been filled in correctly, since the failing
2561 // matches won't have modified it).
2562 unsigned NumSuccessfulMatches =
2563 std::count(std::begin(Match), std::end(Match), Match_Success);
2564 if (NumSuccessfulMatches == 1) {
2565 Inst.setLoc(IDLoc);
2566 if (!MatchingInlineAsm)
2567 EmitInstruction(Inst, Operands, Out);
2568 Opcode = Inst.getOpcode();
2569 return false;
2570 }
2571
2572 // Otherwise, the match failed, try to produce a decent error message.
2573
2574 // If we had multiple suffix matches, then identify this as an ambiguous
2575 // match.
2576 if (NumSuccessfulMatches > 1) {
2577 char MatchChars[4];
2578 unsigned NumMatches = 0;
2579 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2580 if (Match[I] == Match_Success)
2581 MatchChars[NumMatches++] = Suffixes[I];
2582
2583 SmallString<126> Msg;
2584 raw_svector_ostream OS(Msg);
2585 OS << "ambiguous instructions require an explicit suffix (could be ";
2586 for (unsigned i = 0; i != NumMatches; ++i) {
2587 if (i != 0)
2588 OS << ", ";
2589 if (i + 1 == NumMatches)
2590 OS << "or ";
2591 OS << "'" << Base << MatchChars[i] << "'";
2592 }
2593 OS << ")";
2594 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2595 return true;
2596 }
2597
2598 // Okay, we know that none of the variants matched successfully.
2599
2600 // If all of the instructions reported an invalid mnemonic, then the original
2601 // mnemonic was invalid.
2602 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2603 if (!WasOriginallyInvalidOperand) {
2604 ArrayRef<SMRange> Ranges =
2605 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2606 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2607 Ranges, MatchingInlineAsm);
2608 }
2609
2610 // Recover location info for the operand if we know which was the problem.
2611 if (ErrorInfo != ~0ULL) {
2612 if (ErrorInfo >= Operands.size())
2613 return Error(IDLoc, "too few operands for instruction",
2614 EmptyRanges, MatchingInlineAsm);
2615
2616 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2617 if (Operand.getStartLoc().isValid()) {
2618 SMRange OperandRange = Operand.getLocRange();
2619 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2620 OperandRange, MatchingInlineAsm);
2621 }
2622 }
2623
2624 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2625 MatchingInlineAsm);
2626 }
2627
2628 // If one instruction matched with a missing feature, report this as a
2629 // missing feature.
2630 if (std::count(std::begin(Match), std::end(Match),
2631 Match_MissingFeature) == 1) {
2632 ErrorInfo = ErrorInfoMissingFeature;
2633 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2634 MatchingInlineAsm);
2635 }
2636
2637 // If one instruction matched with an invalid operand, report this as an
2638 // operand failure.
2639 if (std::count(std::begin(Match), std::end(Match),
2640 Match_InvalidOperand) == 1) {
2641 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2642 MatchingInlineAsm);
2643 }
2644
2645 // If all of these were an outright failure, report it in a useless way.
2646 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2647 EmptyRanges, MatchingInlineAsm);
2648 return true;
2649}
2650
2651bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2652 OperandVector &Operands,
2653 MCStreamer &Out,
2654 uint64_t &ErrorInfo,
2655 bool MatchingInlineAsm) {
2656 assert(!Operands.empty() && "Unexpect empty operand list!")((!Operands.empty() && "Unexpect empty operand list!"
) ? static_cast<void> (0) : __assert_fail ("!Operands.empty() && \"Unexpect empty operand list!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2656, __PRETTY_FUNCTION__))
;
2657 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2658 assert(Op.isToken() && "Leading operand should always be a mnemonic!")((Op.isToken() && "Leading operand should always be a mnemonic!"
) ? static_cast<void> (0) : __assert_fail ("Op.isToken() && \"Leading operand should always be a mnemonic!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2658, __PRETTY_FUNCTION__))
;
2659 StringRef Mnemonic = Op.getToken();
2660 ArrayRef<SMRange> EmptyRanges = None;
2661
2662 // First, handle aliases that expand to multiple instructions.
2663 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2664
2665 MCInst Inst;
2666
2667 // Find one unsized memory operand, if present.
2668 X86Operand *UnsizedMemOp = nullptr;
2669 for (const auto &Op : Operands) {
2670 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2671 if (X86Op->isMemUnsized())
2672 UnsizedMemOp = X86Op;
2673 }
2674
2675 // Allow some instructions to have implicitly pointer-sized operands. This is
2676 // compatible with gas.
2677 if (UnsizedMemOp) {
2678 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2679 for (const char *Instr : PtrSizedInstrs) {
2680 if (Mnemonic == Instr) {
2681 UnsizedMemOp->Mem.Size = getPointerWidth();
2682 break;
2683 }
2684 }
2685 }
2686
2687 // If an unsized memory operand is present, try to match with each memory
2688 // operand size. In Intel assembly, the size is not part of the instruction
2689 // mnemonic.
2690 SmallVector<unsigned, 8> Match;
2691 uint64_t ErrorInfoMissingFeature = 0;
2692 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2693 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2694 for (unsigned Size : MopSizes) {
2695 UnsizedMemOp->Mem.Size = Size;
2696 uint64_t ErrorInfoIgnore;
2697 unsigned LastOpcode = Inst.getOpcode();
2698 unsigned M =
2699 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2700 MatchingInlineAsm, isParsingIntelSyntax());
2701 if (Match.empty() || LastOpcode != Inst.getOpcode())
2702 Match.push_back(M);
2703
2704 // If this returned as a missing feature failure, remember that.
2705 if (Match.back() == Match_MissingFeature)
2706 ErrorInfoMissingFeature = ErrorInfoIgnore;
2707 }
2708
2709 // Restore the size of the unsized memory operand if we modified it.
2710 if (UnsizedMemOp)
2711 UnsizedMemOp->Mem.Size = 0;
2712 }
2713
2714 // If we haven't matched anything yet, this is not a basic integer or FPU
2715 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2716 // matching with the unsized operand.
2717 if (Match.empty()) {
2718 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2719 MatchingInlineAsm,
2720 isParsingIntelSyntax()));
2721 // If this returned as a missing feature failure, remember that.
2722 if (Match.back() == Match_MissingFeature)
2723 ErrorInfoMissingFeature = ErrorInfo;
2724 }
2725
2726 // Restore the size of the unsized memory operand if we modified it.
2727 if (UnsizedMemOp)
2728 UnsizedMemOp->Mem.Size = 0;
2729
2730 // If it's a bad mnemonic, all results will be the same.
2731 if (Match.back() == Match_MnemonicFail) {
2732 ArrayRef<SMRange> Ranges =
2733 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2734 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2735 Ranges, MatchingInlineAsm);
2736 }
2737
2738 // If exactly one matched, then we treat that as a successful match (and the
2739 // instruction will already have been filled in correctly, since the failing
2740 // matches won't have modified it).
2741 unsigned NumSuccessfulMatches =
2742 std::count(std::begin(Match), std::end(Match), Match_Success);
2743 if (NumSuccessfulMatches == 1) {
2744 if (!validateInstruction(Inst, Operands))
2745 return true;
2746
2747 // Some instructions need post-processing to, for example, tweak which
2748 // encoding is selected. Loop on it while changes happen so the individual
2749 // transformations can chain off each other.
2750 if (!MatchingInlineAsm)
2751 while (processInstruction(Inst, Operands))
2752 ;
2753 Inst.setLoc(IDLoc);
2754 if (!MatchingInlineAsm)
2755 EmitInstruction(Inst, Operands, Out);
2756 Opcode = Inst.getOpcode();
2757 return false;
2758 } else if (NumSuccessfulMatches > 1) {
2759 assert(UnsizedMemOp &&((UnsizedMemOp && "multiple matches only possible with unsized memory operands"
) ? static_cast<void> (0) : __assert_fail ("UnsizedMemOp && \"multiple matches only possible with unsized memory operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2760, __PRETTY_FUNCTION__))
2760 "multiple matches only possible with unsized memory operands")((UnsizedMemOp && "multiple matches only possible with unsized memory operands"
) ? static_cast<void> (0) : __assert_fail ("UnsizedMemOp && \"multiple matches only possible with unsized memory operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230941/lib/Target/X86/AsmParser/X86AsmParser.cpp"
, 2760, __PRETTY_FUNCTION__))
;
2761 ArrayRef<SMRange> Ranges =
2762 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2763 return Error(UnsizedMemOp->getStartLoc(),
2764 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2765 Ranges, MatchingInlineAsm);
2766 }
2767
2768 // If one instruction matched with a missing feature, report this as a
2769 // missing feature.
2770 if (std::count(std::begin(Match), std::end(Match),
2771 Match_MissingFeature) == 1) {
2772 ErrorInfo = ErrorInfoMissingFeature;
2773 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2774 MatchingInlineAsm);
2775 }
2776
2777 // If one instruction matched with an invalid operand, report this as an
2778 // operand failure.
2779 if (std::count(std::begin(Match), std::end(Match),
2780 Match_InvalidOperand) == 1) {
2781 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2782 MatchingInlineAsm);
2783 }
2784
2785 // If all of these were an outright failure, report it in a useless way.
2786 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2787 MatchingInlineAsm);
2788}
2789
2790bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2791 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2792}
2793
2794bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2795 MCAsmParser &Parser = getParser();
2796 StringRef IDVal = DirectiveID.getIdentifier();
2797 if (IDVal == ".word")
2798 return ParseDirectiveWord(2, DirectiveID.getLoc());
2799 else if (IDVal.startswith(".code"))
2800 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2801 else if (IDVal.startswith(".att_syntax")) {
2802 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2803 if (Parser.getTok().getString() == "prefix")
2804 Parser.Lex();
2805 else if (Parser.getTok().getString() == "noprefix")
2806 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2807 "supported: registers must have a "
2808 "'%' prefix in .att_syntax");
2809 }
2810 getParser().setAssemblerDialect(0);
2811 return false;
2812 } else if (IDVal.startswith(".intel_syntax")) {
2813 getParser().setAssemblerDialect(1);
2814 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2815 if (Parser.getTok().getString() == "noprefix")
2816 Parser.Lex();
2817 else if (Parser.getTok().getString() == "prefix")
2818 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2819 "supported: registers must not have "
2820 "a '%' prefix in .intel_syntax");
2821 }
2822 return false;
2823 }
2824 return true;
2825}
2826
2827/// ParseDirectiveWord
2828/// ::= .word [ expression (, expression)* ]
2829bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2830 MCAsmParser &Parser = getParser();
2831 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2832 for (;;) {
2833 const MCExpr *Value;
2834 if (getParser().parseExpression(Value))
2835 return false;
2836
2837 getParser().getStreamer().EmitValue(Value, Size);
2838
2839 if (getLexer().is(AsmToken::EndOfStatement))
2840 break;
2841
2842 // FIXME: Improve diagnostic.
2843 if (getLexer().isNot(AsmToken::Comma)) {
2844 Error(L, "unexpected token in directive");
2845 return false;
2846 }
2847 Parser.Lex();
2848 }
2849 }
2850
2851 Parser.Lex();
2852 return false;
2853}
2854
2855/// ParseDirectiveCode
2856/// ::= .code16 | .code32 | .code64
2857bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2858 MCAsmParser &Parser = getParser();
2859 if (IDVal == ".code16") {
2860 Parser.Lex();
2861 if (!is16BitMode()) {
2862 SwitchMode(X86::Mode16Bit);
2863 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2864 }
2865 } else if (IDVal == ".code32") {
2866 Parser.Lex();
2867 if (!is32BitMode()) {
2868 SwitchMode(X86::Mode32Bit);
2869 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2870 }
2871 } else if (IDVal == ".code64") {
2872 Parser.Lex();
2873 if (!is64BitMode()) {
2874 SwitchMode(X86::Mode64Bit);
2875 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2876 }
2877 } else {
2878 Error(L, "unknown directive " + IDVal);
2879 return false;
2880 }
2881
2882 return false;
2883}
2884
2885// Force static initialization.
2886extern "C" void LLVMInitializeX86AsmParser() {
2887 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2888 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2889}
2890
2891#define GET_REGISTER_MATCHER
2892#define GET_MATCHER_IMPLEMENTATION
2893#define GET_SUBTARGET_FEATURE_NAME
2894#include "X86GenAsmMatcher.inc"