blob: 9f1fa6c65907044bc918f99315e92400b76c2485 [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;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000065 };
66
67 union {
68 struct TokOp Tok;
69 struct RegOp Reg;
70 struct ImmOp Imm;
71 struct MemOp Mem;
72 };
73
74 X86Operand(KindTy K, SMLoc Start, SMLoc End)
75 : Kind(K), StartLoc(Start), EndLoc(End) {}
76
Craig Topper39012cc2014-03-09 18:03:14 +000077 StringRef getSymName() override { return SymName; }
78 void *getOpDecl() override { return OpDecl; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000079
80 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper39012cc2014-03-09 18:03:14 +000081 SMLoc getStartLoc() const override { return StartLoc; }
Eugene Zelenko90562df2017-02-06 21:55:43 +000082
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000083 /// getEndLoc - Get the location of the last token of this operand.
Peter Collingbourne0da86302016-10-10 22:49:37 +000084 SMLoc getEndLoc() const override { return EndLoc; }
Eugene Zelenko90562df2017-02-06 21:55:43 +000085
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000086 /// getLocRange - Get the range between the first and last token of this
87 /// operand.
88 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
Eugene Zelenko90562df2017-02-06 21:55:43 +000089
Peter Collingbourne0da86302016-10-10 22:49:37 +000090 /// getOffsetOfLoc - Get the location of the offset operator.
91 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000092
Craig Topper39012cc2014-03-09 18:03:14 +000093 void print(raw_ostream &OS) const override {}
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000094
95 StringRef getToken() const {
96 assert(Kind == Token && "Invalid access!");
97 return StringRef(Tok.Data, Tok.Length);
98 }
99 void setTokenValue(StringRef Value) {
100 assert(Kind == Token && "Invalid access!");
101 Tok.Data = Value.data();
102 Tok.Length = Value.size();
103 }
104
Craig Topper39012cc2014-03-09 18:03:14 +0000105 unsigned getReg() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000106 assert(Kind == Register && "Invalid access!");
107 return Reg.RegNo;
108 }
109
110 const MCExpr *getImm() const {
111 assert(Kind == Immediate && "Invalid access!");
112 return Imm.Val;
113 }
114
115 const MCExpr *getMemDisp() const {
116 assert(Kind == Memory && "Invalid access!");
117 return Mem.Disp;
118 }
119 unsigned getMemSegReg() const {
120 assert(Kind == Memory && "Invalid access!");
121 return Mem.SegReg;
122 }
123 unsigned getMemBaseReg() const {
124 assert(Kind == Memory && "Invalid access!");
125 return Mem.BaseReg;
126 }
127 unsigned getMemIndexReg() const {
128 assert(Kind == Memory && "Invalid access!");
129 return Mem.IndexReg;
130 }
131 unsigned getMemScale() const {
132 assert(Kind == Memory && "Invalid access!");
133 return Mem.Scale;
134 }
Craig Topper055845f2015-01-02 07:02:25 +0000135 unsigned getMemModeSize() const {
136 assert(Kind == Memory && "Invalid access!");
137 return Mem.ModeSize;
138 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000139
Craig Topper39012cc2014-03-09 18:03:14 +0000140 bool isToken() const override {return Kind == Token; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000141
Craig Topper39012cc2014-03-09 18:03:14 +0000142 bool isImm() const override { return Kind == Immediate; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000143
144 bool isImmSExti16i8() const {
145 if (!isImm())
146 return false;
147
148 // If this isn't a constant expr, just assume it fits and let relaxation
149 // handle it.
150 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
151 if (!CE)
152 return true;
153
154 // Otherwise, check the value is in a range that makes sense for this
155 // extension.
156 return isImmSExti16i8Value(CE->getValue());
157 }
158 bool isImmSExti32i8() const {
159 if (!isImm())
160 return false;
161
162 // If this isn't a constant expr, just assume it fits and let relaxation
163 // handle it.
164 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
165 if (!CE)
166 return true;
167
168 // Otherwise, check the value is in a range that makes sense for this
169 // extension.
170 return isImmSExti32i8Value(CE->getValue());
171 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000172 bool isImmSExti64i8() const {
173 if (!isImm())
174 return false;
175
176 // If this isn't a constant expr, just assume it fits and let relaxation
177 // handle it.
178 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
179 if (!CE)
180 return true;
181
182 // Otherwise, check the value is in a range that makes sense for this
183 // extension.
184 return isImmSExti64i8Value(CE->getValue());
185 }
186 bool isImmSExti64i32() const {
187 if (!isImm())
188 return false;
189
190 // If this isn't a constant expr, just assume it fits and let relaxation
191 // handle it.
192 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
193 if (!CE)
194 return true;
195
196 // Otherwise, check the value is in a range that makes sense for this
197 // extension.
198 return isImmSExti64i32Value(CE->getValue());
199 }
200
Craig Topperf38dea12015-01-21 06:07:53 +0000201 bool isImmUnsignedi8() const {
202 if (!isImm()) return false;
Peter Collingbournec7766772016-10-20 01:58:34 +0000203 // If this isn't a constant expr, just assume it fits and let relaxation
204 // handle it.
Craig Topperf38dea12015-01-21 06:07:53 +0000205 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
Peter Collingbournec7766772016-10-20 01:58:34 +0000206 if (!CE) return true;
Craig Topperf38dea12015-01-21 06:07:53 +0000207 return isImmUnsignedi8Value(CE->getValue());
208 }
209
Peter Collingbourne0da86302016-10-10 22:49:37 +0000210 bool isOffsetOf() const override {
211 return OffsetOfLoc.getPointer();
212 }
213
Craig Topper39012cc2014-03-09 18:03:14 +0000214 bool needAddressOf() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000215 return AddressOf;
216 }
217
Craig Topper39012cc2014-03-09 18:03:14 +0000218 bool isMem() const override { return Kind == Memory; }
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000219 bool isMemUnsized() const {
220 return Kind == Memory && Mem.Size == 0;
221 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000222 bool isMem8() const {
223 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
224 }
225 bool isMem16() const {
226 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
227 }
228 bool isMem32() const {
229 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
230 }
231 bool isMem64() const {
232 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
233 }
234 bool isMem80() const {
235 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
236 }
237 bool isMem128() const {
238 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
239 }
240 bool isMem256() const {
241 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
242 }
243 bool isMem512() const {
244 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
245 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000246 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
247 assert(Kind == Memory && "Invalid access!");
248 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
249 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000250
Igor Breger45ef10f2016-02-25 13:30:17 +0000251 bool isMem64_RC128() const {
252 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000253 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000254 bool isMem128_RC128() const {
255 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000256 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000257 bool isMem128_RC256() const {
258 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000259 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000260 bool isMem256_RC128() const {
261 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000262 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000263 bool isMem256_RC256() const {
264 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000265 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000266
267 bool isMem64_RC128X() const {
268 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000269 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000270 bool isMem128_RC128X() const {
271 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000272 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000273 bool isMem128_RC256X() const {
274 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000275 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000276 bool isMem256_RC128X() const {
277 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000278 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000279 bool isMem256_RC256X() const {
280 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
281 }
Craig Topper7dfd5832017-01-16 00:55:58 +0000282 bool isMem256_RC512() const {
283 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
284 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000285 bool isMem512_RC256X() const {
286 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
287 }
288 bool isMem512_RC512() const {
289 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000290 }
291
292 bool isAbsMem() const {
293 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
294 !getMemIndexReg() && getMemScale() == 1;
295 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000296 bool isAVX512RC() const{
297 return isImm();
298 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000299
Craig Topper63944542015-01-06 08:59:30 +0000300 bool isAbsMem16() const {
301 return isAbsMem() && Mem.ModeSize == 16;
302 }
303
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000304 bool isSrcIdx() const {
305 return !getMemIndexReg() && getMemScale() == 1 &&
306 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
307 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
308 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
309 }
310 bool isSrcIdx8() const {
311 return isMem8() && isSrcIdx();
312 }
313 bool isSrcIdx16() const {
314 return isMem16() && isSrcIdx();
315 }
316 bool isSrcIdx32() const {
317 return isMem32() && isSrcIdx();
318 }
319 bool isSrcIdx64() const {
320 return isMem64() && isSrcIdx();
321 }
322
323 bool isDstIdx() const {
324 return !getMemIndexReg() && getMemScale() == 1 &&
325 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
326 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
327 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
328 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
329 }
330 bool isDstIdx8() const {
331 return isMem8() && isDstIdx();
332 }
333 bool isDstIdx16() const {
334 return isMem16() && isDstIdx();
335 }
336 bool isDstIdx32() const {
337 return isMem32() && isDstIdx();
338 }
339 bool isDstIdx64() const {
340 return isMem64() && isDstIdx();
341 }
342
Craig Topper055845f2015-01-02 07:02:25 +0000343 bool isMemOffs() const {
344 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
345 getMemScale() == 1;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000346 }
Craig Topper055845f2015-01-02 07:02:25 +0000347
348 bool isMemOffs16_8() const {
349 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000350 }
Craig Topper055845f2015-01-02 07:02:25 +0000351 bool isMemOffs16_16() const {
352 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000353 }
Craig Topper055845f2015-01-02 07:02:25 +0000354 bool isMemOffs16_32() const {
355 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
356 }
357 bool isMemOffs32_8() const {
358 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
359 }
360 bool isMemOffs32_16() const {
361 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
362 }
363 bool isMemOffs32_32() const {
364 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
365 }
Craig Topperae8e1b32015-01-03 00:00:20 +0000366 bool isMemOffs32_64() const {
367 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
368 }
Craig Topper055845f2015-01-02 07:02:25 +0000369 bool isMemOffs64_8() const {
370 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
371 }
372 bool isMemOffs64_16() const {
373 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
374 }
375 bool isMemOffs64_32() const {
376 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
377 }
378 bool isMemOffs64_64() const {
379 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000380 }
381
Craig Topper39012cc2014-03-09 18:03:14 +0000382 bool isReg() const override { return Kind == Register; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000383
384 bool isGR32orGR64() const {
385 return Kind == Register &&
386 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
387 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
388 }
389
390 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
391 // Add as immediates when possible.
392 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000393 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000394 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000395 Inst.addOperand(MCOperand::createExpr(Expr));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000396 }
397
398 void addRegOperands(MCInst &Inst, unsigned N) const {
399 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000400 Inst.addOperand(MCOperand::createReg(getReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000401 }
402
403 static unsigned getGR32FromGR64(unsigned RegNo) {
404 switch (RegNo) {
405 default: llvm_unreachable("Unexpected register");
406 case X86::RAX: return X86::EAX;
407 case X86::RCX: return X86::ECX;
408 case X86::RDX: return X86::EDX;
409 case X86::RBX: return X86::EBX;
410 case X86::RBP: return X86::EBP;
411 case X86::RSP: return X86::ESP;
412 case X86::RSI: return X86::ESI;
413 case X86::RDI: return X86::EDI;
414 case X86::R8: return X86::R8D;
415 case X86::R9: return X86::R9D;
416 case X86::R10: return X86::R10D;
417 case X86::R11: return X86::R11D;
418 case X86::R12: return X86::R12D;
419 case X86::R13: return X86::R13D;
420 case X86::R14: return X86::R14D;
421 case X86::R15: return X86::R15D;
422 case X86::RIP: return X86::EIP;
423 }
424 }
425
426 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
427 assert(N == 1 && "Invalid number of operands!");
428 unsigned RegNo = getReg();
429 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
430 RegNo = getGR32FromGR64(RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +0000431 Inst.addOperand(MCOperand::createReg(RegNo));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000432 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000433
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000434 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
435 assert(N == 1 && "Invalid number of operands!");
436 addExpr(Inst, getImm());
437 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000438
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000439 void addImmOperands(MCInst &Inst, unsigned N) const {
440 assert(N == 1 && "Invalid number of operands!");
441 addExpr(Inst, getImm());
442 }
443
444 void addMemOperands(MCInst &Inst, unsigned N) const {
445 assert((N == 5) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000446 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
447 Inst.addOperand(MCOperand::createImm(getMemScale()));
448 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000449 addExpr(Inst, getMemDisp());
Jim Grosbache9119e42015-05-13 18:37:00 +0000450 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000451 }
452
453 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
454 assert((N == 1) && "Invalid number of operands!");
455 // Add as immediates when possible.
456 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000457 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000458 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000459 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000460 }
461
462 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
463 assert((N == 2) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000464 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
465 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000466 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000467
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000468 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
469 assert((N == 1) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000470 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000471 }
472
473 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
474 assert((N == 2) && "Invalid number of operands!");
475 // Add as immediates when possible.
476 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000477 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000478 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000479 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
480 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000481 }
482
David Blaikie960ea3f2014-06-08 16:18:35 +0000483 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000484 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000485 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000486 Res->Tok.Data = Str.data();
487 Res->Tok.Length = Str.size();
488 return Res;
489 }
490
David Blaikie960ea3f2014-06-08 16:18:35 +0000491 static std::unique_ptr<X86Operand>
492 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
Peter Collingbourne0da86302016-10-10 22:49:37 +0000493 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
494 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000495 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000496 Res->Reg.RegNo = RegNo;
497 Res->AddressOf = AddressOf;
Peter Collingbourne0da86302016-10-10 22:49:37 +0000498 Res->OffsetOfLoc = OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000499 Res->SymName = SymName;
500 Res->OpDecl = OpDecl;
501 return Res;
502 }
503
David Blaikie960ea3f2014-06-08 16:18:35 +0000504 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
505 SMLoc StartLoc, SMLoc EndLoc) {
506 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000507 Res->Imm.Val = Val;
508 return Res;
509 }
510
511 /// Create an absolute memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000512 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000513 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
514 unsigned Size = 0, StringRef SymName = StringRef(),
515 void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000516 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000517 Res->Mem.SegReg = 0;
518 Res->Mem.Disp = Disp;
519 Res->Mem.BaseReg = 0;
520 Res->Mem.IndexReg = 0;
521 Res->Mem.Scale = 1;
522 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000523 Res->Mem.ModeSize = ModeSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000524 Res->SymName = SymName;
525 Res->OpDecl = OpDecl;
526 Res->AddressOf = false;
527 return Res;
528 }
529
530 /// Create a generalized memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000531 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000532 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
533 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
534 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
David Blaikie960ea3f2014-06-08 16:18:35 +0000535 void *OpDecl = nullptr) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000536 // We should never just have a displacement, that should be parsed as an
537 // absolute memory operand.
538 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
539
540 // The scale should always be one of {1,2,4,8}.
541 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
542 "Invalid scale!");
David Blaikie960ea3f2014-06-08 16:18:35 +0000543 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000544 Res->Mem.SegReg = SegReg;
545 Res->Mem.Disp = Disp;
546 Res->Mem.BaseReg = BaseReg;
547 Res->Mem.IndexReg = IndexReg;
548 Res->Mem.Scale = Scale;
549 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000550 Res->Mem.ModeSize = ModeSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000551 Res->SymName = SymName;
552 Res->OpDecl = OpDecl;
553 Res->AddressOf = false;
554 return Res;
555 }
556};
557
Eugene Zelenko90562df2017-02-06 21:55:43 +0000558} // end namespace llvm
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000559
Eugene Zelenko90562df2017-02-06 21:55:43 +0000560#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H