blob: 33eff14b82157d0741fb65b99be67fe75df9ea84 [file] [log] [blame]
Eugene Zelenko90562df2017-02-06 21:55:43 +00001//===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
Evgeniy Stepanove3804d42014-02-28 12:28:07 +00002//
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
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000010#ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
11#define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000012
13#include "X86AsmParserCommon.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000014#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/StringRef.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000016#include "llvm/MC/MCExpr.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000017#include "llvm/MC/MCInst.h"
18#include "llvm/MC/MCRegisterInfo.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000019#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000020#include "llvm/Support/Casting.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/SMLoc.h"
23#include <cassert>
24#include <memory>
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000025
26namespace llvm {
27
28/// X86Operand - Instances of this class represent a parsed X86 machine
29/// instruction.
30struct X86Operand : public MCParsedAsmOperand {
31 enum KindTy {
32 Token,
33 Register,
34 Immediate,
35 Memory
36 } Kind;
37
38 SMLoc StartLoc, EndLoc;
Peter Collingbourne0da86302016-10-10 22:49:37 +000039 SMLoc OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000040 StringRef SymName;
41 void *OpDecl;
42 bool AddressOf;
43
44 struct TokOp {
45 const char *Data;
46 unsigned Length;
47 };
48
49 struct RegOp {
50 unsigned RegNo;
51 };
52
53 struct ImmOp {
54 const MCExpr *Val;
55 };
56
57 struct MemOp {
58 unsigned SegReg;
59 const MCExpr *Disp;
60 unsigned BaseReg;
61 unsigned IndexReg;
62 unsigned Scale;
63 unsigned Size;
Craig Topper055845f2015-01-02 07:02:25 +000064 unsigned ModeSize;
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +000065
66 /// If the memory operand is unsized and there are multiple instruction
67 /// matches, prefer the one with this size.
68 unsigned FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000069 };
70
71 union {
72 struct TokOp Tok;
73 struct RegOp Reg;
74 struct ImmOp Imm;
75 struct MemOp Mem;
76 };
77
78 X86Operand(KindTy K, SMLoc Start, SMLoc End)
79 : Kind(K), StartLoc(Start), EndLoc(End) {}
80
Craig Topper39012cc2014-03-09 18:03:14 +000081 StringRef getSymName() override { return SymName; }
82 void *getOpDecl() override { return OpDecl; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000083
84 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper39012cc2014-03-09 18:03:14 +000085 SMLoc getStartLoc() const override { return StartLoc; }
Eugene Zelenko90562df2017-02-06 21:55:43 +000086
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000087 /// getEndLoc - Get the location of the last token of this operand.
Peter Collingbourne0da86302016-10-10 22:49:37 +000088 SMLoc getEndLoc() const override { return EndLoc; }
Eugene Zelenko90562df2017-02-06 21:55:43 +000089
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000090 /// getLocRange - Get the range between the first and last token of this
91 /// operand.
92 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
Eugene Zelenko90562df2017-02-06 21:55:43 +000093
Peter Collingbourne0da86302016-10-10 22:49:37 +000094 /// getOffsetOfLoc - Get the location of the offset operator.
95 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000096
Craig Topper39012cc2014-03-09 18:03:14 +000097 void print(raw_ostream &OS) const override {}
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000098
99 StringRef getToken() const {
100 assert(Kind == Token && "Invalid access!");
101 return StringRef(Tok.Data, Tok.Length);
102 }
103 void setTokenValue(StringRef Value) {
104 assert(Kind == Token && "Invalid access!");
105 Tok.Data = Value.data();
106 Tok.Length = Value.size();
107 }
108
Craig Topper39012cc2014-03-09 18:03:14 +0000109 unsigned getReg() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000110 assert(Kind == Register && "Invalid access!");
111 return Reg.RegNo;
112 }
113
114 const MCExpr *getImm() const {
115 assert(Kind == Immediate && "Invalid access!");
116 return Imm.Val;
117 }
118
119 const MCExpr *getMemDisp() const {
120 assert(Kind == Memory && "Invalid access!");
121 return Mem.Disp;
122 }
123 unsigned getMemSegReg() const {
124 assert(Kind == Memory && "Invalid access!");
125 return Mem.SegReg;
126 }
127 unsigned getMemBaseReg() const {
128 assert(Kind == Memory && "Invalid access!");
129 return Mem.BaseReg;
130 }
131 unsigned getMemIndexReg() const {
132 assert(Kind == Memory && "Invalid access!");
133 return Mem.IndexReg;
134 }
135 unsigned getMemScale() const {
136 assert(Kind == Memory && "Invalid access!");
137 return Mem.Scale;
138 }
Craig Topper055845f2015-01-02 07:02:25 +0000139 unsigned getMemModeSize() const {
140 assert(Kind == Memory && "Invalid access!");
141 return Mem.ModeSize;
142 }
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000143 unsigned getMemFrontendSize() const {
144 assert(Kind == Memory && "Invalid access!");
145 return Mem.FrontendSize;
146 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000147
Craig Topper39012cc2014-03-09 18:03:14 +0000148 bool isToken() const override {return Kind == Token; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000149
Craig Topper39012cc2014-03-09 18:03:14 +0000150 bool isImm() const override { return Kind == Immediate; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000151
152 bool isImmSExti16i8() const {
153 if (!isImm())
154 return false;
155
156 // If this isn't a constant expr, just assume it fits and let relaxation
157 // handle it.
158 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
159 if (!CE)
160 return true;
161
162 // Otherwise, check the value is in a range that makes sense for this
163 // extension.
164 return isImmSExti16i8Value(CE->getValue());
165 }
166 bool isImmSExti32i8() const {
167 if (!isImm())
168 return false;
169
170 // If this isn't a constant expr, just assume it fits and let relaxation
171 // handle it.
172 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
173 if (!CE)
174 return true;
175
176 // Otherwise, check the value is in a range that makes sense for this
177 // extension.
178 return isImmSExti32i8Value(CE->getValue());
179 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000180 bool isImmSExti64i8() const {
181 if (!isImm())
182 return false;
183
184 // If this isn't a constant expr, just assume it fits and let relaxation
185 // handle it.
186 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
187 if (!CE)
188 return true;
189
190 // Otherwise, check the value is in a range that makes sense for this
191 // extension.
192 return isImmSExti64i8Value(CE->getValue());
193 }
194 bool isImmSExti64i32() const {
195 if (!isImm())
196 return false;
197
198 // If this isn't a constant expr, just assume it fits and let relaxation
199 // handle it.
200 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
201 if (!CE)
202 return true;
203
204 // Otherwise, check the value is in a range that makes sense for this
205 // extension.
206 return isImmSExti64i32Value(CE->getValue());
207 }
208
Craig Topperf38dea12015-01-21 06:07:53 +0000209 bool isImmUnsignedi8() const {
210 if (!isImm()) return false;
Peter Collingbournec7766772016-10-20 01:58:34 +0000211 // If this isn't a constant expr, just assume it fits and let relaxation
212 // handle it.
Craig Topperf38dea12015-01-21 06:07:53 +0000213 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
Peter Collingbournec7766772016-10-20 01:58:34 +0000214 if (!CE) return true;
Craig Topperf38dea12015-01-21 06:07:53 +0000215 return isImmUnsignedi8Value(CE->getValue());
216 }
217
Peter Collingbourne0da86302016-10-10 22:49:37 +0000218 bool isOffsetOf() const override {
219 return OffsetOfLoc.getPointer();
220 }
221
Craig Topper39012cc2014-03-09 18:03:14 +0000222 bool needAddressOf() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000223 return AddressOf;
224 }
225
Craig Topper39012cc2014-03-09 18:03:14 +0000226 bool isMem() const override { return Kind == Memory; }
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000227 bool isMemUnsized() const {
228 return Kind == Memory && Mem.Size == 0;
229 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000230 bool isMem8() const {
231 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
232 }
233 bool isMem16() const {
234 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
235 }
236 bool isMem32() const {
237 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
238 }
239 bool isMem64() const {
240 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
241 }
242 bool isMem80() const {
243 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
244 }
245 bool isMem128() const {
246 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
247 }
248 bool isMem256() const {
249 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
250 }
251 bool isMem512() const {
252 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
253 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000254 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
255 assert(Kind == Memory && "Invalid access!");
256 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
257 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000258
Igor Breger45ef10f2016-02-25 13:30:17 +0000259 bool isMem64_RC128() const {
260 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000261 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000262 bool isMem128_RC128() const {
263 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000264 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000265 bool isMem128_RC256() const {
266 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000267 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000268 bool isMem256_RC128() const {
269 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000270 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000271 bool isMem256_RC256() const {
272 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000273 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000274
275 bool isMem64_RC128X() const {
276 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000277 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000278 bool isMem128_RC128X() const {
279 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000280 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000281 bool isMem128_RC256X() const {
282 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000283 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000284 bool isMem256_RC128X() const {
285 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000286 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000287 bool isMem256_RC256X() const {
288 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
289 }
Craig Topper7dfd5832017-01-16 00:55:58 +0000290 bool isMem256_RC512() const {
291 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
292 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000293 bool isMem512_RC256X() const {
294 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
295 }
296 bool isMem512_RC512() const {
297 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000298 }
299
300 bool isAbsMem() const {
301 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
302 !getMemIndexReg() && getMemScale() == 1;
303 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000304 bool isAVX512RC() const{
305 return isImm();
306 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000307
Craig Topper63944542015-01-06 08:59:30 +0000308 bool isAbsMem16() const {
309 return isAbsMem() && Mem.ModeSize == 16;
310 }
311
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000312 bool isSrcIdx() const {
313 return !getMemIndexReg() && getMemScale() == 1 &&
314 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
315 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
316 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
317 }
318 bool isSrcIdx8() const {
319 return isMem8() && isSrcIdx();
320 }
321 bool isSrcIdx16() const {
322 return isMem16() && isSrcIdx();
323 }
324 bool isSrcIdx32() const {
325 return isMem32() && isSrcIdx();
326 }
327 bool isSrcIdx64() const {
328 return isMem64() && isSrcIdx();
329 }
330
331 bool isDstIdx() const {
332 return !getMemIndexReg() && getMemScale() == 1 &&
333 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
334 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
335 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
336 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
337 }
338 bool isDstIdx8() const {
339 return isMem8() && isDstIdx();
340 }
341 bool isDstIdx16() const {
342 return isMem16() && isDstIdx();
343 }
344 bool isDstIdx32() const {
345 return isMem32() && isDstIdx();
346 }
347 bool isDstIdx64() const {
348 return isMem64() && isDstIdx();
349 }
350
Craig Topper055845f2015-01-02 07:02:25 +0000351 bool isMemOffs() const {
352 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
353 getMemScale() == 1;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000354 }
Craig Topper055845f2015-01-02 07:02:25 +0000355
356 bool isMemOffs16_8() const {
357 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000358 }
Craig Topper055845f2015-01-02 07:02:25 +0000359 bool isMemOffs16_16() const {
360 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000361 }
Craig Topper055845f2015-01-02 07:02:25 +0000362 bool isMemOffs16_32() const {
363 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
364 }
365 bool isMemOffs32_8() const {
366 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
367 }
368 bool isMemOffs32_16() const {
369 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
370 }
371 bool isMemOffs32_32() const {
372 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
373 }
Craig Topperae8e1b32015-01-03 00:00:20 +0000374 bool isMemOffs32_64() const {
375 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
376 }
Craig Topper055845f2015-01-02 07:02:25 +0000377 bool isMemOffs64_8() const {
378 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
379 }
380 bool isMemOffs64_16() const {
381 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
382 }
383 bool isMemOffs64_32() const {
384 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
385 }
386 bool isMemOffs64_64() const {
387 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000388 }
389
Craig Topper39012cc2014-03-09 18:03:14 +0000390 bool isReg() const override { return Kind == Register; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000391
392 bool isGR32orGR64() const {
393 return Kind == Register &&
394 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
395 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
396 }
397
398 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
399 // Add as immediates when possible.
400 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000401 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000402 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000403 Inst.addOperand(MCOperand::createExpr(Expr));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000404 }
405
406 void addRegOperands(MCInst &Inst, unsigned N) const {
407 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000408 Inst.addOperand(MCOperand::createReg(getReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000409 }
410
411 static unsigned getGR32FromGR64(unsigned RegNo) {
412 switch (RegNo) {
413 default: llvm_unreachable("Unexpected register");
414 case X86::RAX: return X86::EAX;
415 case X86::RCX: return X86::ECX;
416 case X86::RDX: return X86::EDX;
417 case X86::RBX: return X86::EBX;
418 case X86::RBP: return X86::EBP;
419 case X86::RSP: return X86::ESP;
420 case X86::RSI: return X86::ESI;
421 case X86::RDI: return X86::EDI;
422 case X86::R8: return X86::R8D;
423 case X86::R9: return X86::R9D;
424 case X86::R10: return X86::R10D;
425 case X86::R11: return X86::R11D;
426 case X86::R12: return X86::R12D;
427 case X86::R13: return X86::R13D;
428 case X86::R14: return X86::R14D;
429 case X86::R15: return X86::R15D;
430 case X86::RIP: return X86::EIP;
431 }
432 }
433
434 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
435 assert(N == 1 && "Invalid number of operands!");
436 unsigned RegNo = getReg();
437 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
438 RegNo = getGR32FromGR64(RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +0000439 Inst.addOperand(MCOperand::createReg(RegNo));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000440 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000441
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000442 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
443 assert(N == 1 && "Invalid number of operands!");
444 addExpr(Inst, getImm());
445 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000446
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000447 void addImmOperands(MCInst &Inst, unsigned N) const {
448 assert(N == 1 && "Invalid number of operands!");
449 addExpr(Inst, getImm());
450 }
451
452 void addMemOperands(MCInst &Inst, unsigned N) const {
453 assert((N == 5) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000454 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
455 Inst.addOperand(MCOperand::createImm(getMemScale()));
456 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000457 addExpr(Inst, getMemDisp());
Jim Grosbache9119e42015-05-13 18:37:00 +0000458 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000459 }
460
461 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
462 assert((N == 1) && "Invalid number of operands!");
463 // Add as immediates when possible.
464 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000465 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000466 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000467 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000468 }
469
470 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
471 assert((N == 2) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000472 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
473 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000474 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000475
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000476 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
477 assert((N == 1) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000478 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000479 }
480
481 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
482 assert((N == 2) && "Invalid number of operands!");
483 // Add as immediates when possible.
484 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000485 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000486 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000487 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
488 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000489 }
490
David Blaikie960ea3f2014-06-08 16:18:35 +0000491 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000492 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000493 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000494 Res->Tok.Data = Str.data();
495 Res->Tok.Length = Str.size();
496 return Res;
497 }
498
David Blaikie960ea3f2014-06-08 16:18:35 +0000499 static std::unique_ptr<X86Operand>
500 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
Peter Collingbourne0da86302016-10-10 22:49:37 +0000501 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
502 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000503 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000504 Res->Reg.RegNo = RegNo;
505 Res->AddressOf = AddressOf;
Peter Collingbourne0da86302016-10-10 22:49:37 +0000506 Res->OffsetOfLoc = OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000507 Res->SymName = SymName;
508 Res->OpDecl = OpDecl;
509 return Res;
510 }
511
David Blaikie960ea3f2014-06-08 16:18:35 +0000512 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
513 SMLoc StartLoc, SMLoc EndLoc) {
514 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000515 Res->Imm.Val = Val;
516 return Res;
517 }
518
519 /// Create an absolute memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000520 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000521 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
522 unsigned Size = 0, StringRef SymName = StringRef(),
Daniel Jasper07a17712017-05-05 07:31:40 +0000523 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000524 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000525 Res->Mem.SegReg = 0;
526 Res->Mem.Disp = Disp;
527 Res->Mem.BaseReg = 0;
528 Res->Mem.IndexReg = 0;
529 Res->Mem.Scale = 1;
530 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000531 Res->Mem.ModeSize = ModeSize;
Daniel Jasper07a17712017-05-05 07:31:40 +0000532 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000533 Res->SymName = SymName;
534 Res->OpDecl = OpDecl;
535 Res->AddressOf = false;
536 return Res;
537 }
538
539 /// Create a generalized memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000540 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000541 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
542 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
543 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000544 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000545 // We should never just have a displacement, that should be parsed as an
546 // absolute memory operand.
547 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
548
549 // The scale should always be one of {1,2,4,8}.
550 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
551 "Invalid scale!");
David Blaikie960ea3f2014-06-08 16:18:35 +0000552 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000553 Res->Mem.SegReg = SegReg;
554 Res->Mem.Disp = Disp;
555 Res->Mem.BaseReg = BaseReg;
556 Res->Mem.IndexReg = IndexReg;
557 Res->Mem.Scale = Scale;
558 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000559 Res->Mem.ModeSize = ModeSize;
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000560 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000561 Res->SymName = SymName;
562 Res->OpDecl = OpDecl;
563 Res->AddressOf = false;
564 return Res;
565 }
566};
567
Eugene Zelenko90562df2017-02-06 21:55:43 +0000568} // end namespace llvm
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000569
Eugene Zelenko90562df2017-02-06 21:55:43 +0000570#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H