blob: 6672cbfe98151f2e22b873623701c2fbbba30db1 [file] [log] [blame]
Evgeniy Stepanove3804d42014-02-28 12:28:07 +00001//===-- X86Operand.h - Parsed X86 machine instruction --------------------===//
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
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"
14#include "llvm/MC/MCExpr.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000015#include "llvm/MC/MCInst.h"
16#include "llvm/MC/MCRegisterInfo.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000017#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
David Blaikie960ea3f2014-06-08 16:18:35 +000018#include "llvm/ADT/STLExtras.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000019#include "MCTargetDesc/X86MCTargetDesc.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000020
21namespace llvm {
22
23/// X86Operand - Instances of this class represent a parsed X86 machine
24/// instruction.
25struct X86Operand : public MCParsedAsmOperand {
26 enum KindTy {
27 Token,
28 Register,
29 Immediate,
30 Memory
31 } Kind;
32
33 SMLoc StartLoc, EndLoc;
Peter Collingbourne0da86302016-10-10 22:49:37 +000034 SMLoc OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000035 StringRef SymName;
36 void *OpDecl;
37 bool AddressOf;
38
39 struct TokOp {
40 const char *Data;
41 unsigned Length;
42 };
43
44 struct RegOp {
45 unsigned RegNo;
46 };
47
48 struct ImmOp {
49 const MCExpr *Val;
50 };
51
52 struct MemOp {
53 unsigned SegReg;
54 const MCExpr *Disp;
55 unsigned BaseReg;
56 unsigned IndexReg;
57 unsigned Scale;
58 unsigned Size;
Craig Topper055845f2015-01-02 07:02:25 +000059 unsigned ModeSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000060 };
61
62 union {
63 struct TokOp Tok;
64 struct RegOp Reg;
65 struct ImmOp Imm;
66 struct MemOp Mem;
67 };
68
69 X86Operand(KindTy K, SMLoc Start, SMLoc End)
70 : Kind(K), StartLoc(Start), EndLoc(End) {}
71
Craig Topper39012cc2014-03-09 18:03:14 +000072 StringRef getSymName() override { return SymName; }
73 void *getOpDecl() override { return OpDecl; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000074
75 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper39012cc2014-03-09 18:03:14 +000076 SMLoc getStartLoc() const override { return StartLoc; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000077 /// getEndLoc - Get the location of the last token of this operand.
Peter Collingbourne0da86302016-10-10 22:49:37 +000078 SMLoc getEndLoc() const override { return EndLoc; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000079 /// getLocRange - Get the range between the first and last token of this
80 /// operand.
81 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
Peter Collingbourne0da86302016-10-10 22:49:37 +000082 /// getOffsetOfLoc - Get the location of the offset operator.
83 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000084
Craig Topper39012cc2014-03-09 18:03:14 +000085 void print(raw_ostream &OS) const override {}
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000086
87 StringRef getToken() const {
88 assert(Kind == Token && "Invalid access!");
89 return StringRef(Tok.Data, Tok.Length);
90 }
91 void setTokenValue(StringRef Value) {
92 assert(Kind == Token && "Invalid access!");
93 Tok.Data = Value.data();
94 Tok.Length = Value.size();
95 }
96
Craig Topper39012cc2014-03-09 18:03:14 +000097 unsigned getReg() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000098 assert(Kind == Register && "Invalid access!");
99 return Reg.RegNo;
100 }
101
102 const MCExpr *getImm() const {
103 assert(Kind == Immediate && "Invalid access!");
104 return Imm.Val;
105 }
106
107 const MCExpr *getMemDisp() const {
108 assert(Kind == Memory && "Invalid access!");
109 return Mem.Disp;
110 }
111 unsigned getMemSegReg() const {
112 assert(Kind == Memory && "Invalid access!");
113 return Mem.SegReg;
114 }
115 unsigned getMemBaseReg() const {
116 assert(Kind == Memory && "Invalid access!");
117 return Mem.BaseReg;
118 }
119 unsigned getMemIndexReg() const {
120 assert(Kind == Memory && "Invalid access!");
121 return Mem.IndexReg;
122 }
123 unsigned getMemScale() const {
124 assert(Kind == Memory && "Invalid access!");
125 return Mem.Scale;
126 }
Craig Topper055845f2015-01-02 07:02:25 +0000127 unsigned getMemModeSize() const {
128 assert(Kind == Memory && "Invalid access!");
129 return Mem.ModeSize;
130 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000131
Craig Topper39012cc2014-03-09 18:03:14 +0000132 bool isToken() const override {return Kind == Token; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000133
Craig Topper39012cc2014-03-09 18:03:14 +0000134 bool isImm() const override { return Kind == Immediate; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000135
136 bool isImmSExti16i8() const {
137 if (!isImm())
138 return false;
139
140 // If this isn't a constant expr, just assume it fits and let relaxation
141 // handle it.
142 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
143 if (!CE)
144 return true;
145
146 // Otherwise, check the value is in a range that makes sense for this
147 // extension.
148 return isImmSExti16i8Value(CE->getValue());
149 }
150 bool isImmSExti32i8() const {
151 if (!isImm())
152 return false;
153
154 // If this isn't a constant expr, just assume it fits and let relaxation
155 // handle it.
156 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
157 if (!CE)
158 return true;
159
160 // Otherwise, check the value is in a range that makes sense for this
161 // extension.
162 return isImmSExti32i8Value(CE->getValue());
163 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000164 bool isImmSExti64i8() const {
165 if (!isImm())
166 return false;
167
168 // If this isn't a constant expr, just assume it fits and let relaxation
169 // handle it.
170 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
171 if (!CE)
172 return true;
173
174 // Otherwise, check the value is in a range that makes sense for this
175 // extension.
176 return isImmSExti64i8Value(CE->getValue());
177 }
178 bool isImmSExti64i32() const {
179 if (!isImm())
180 return false;
181
182 // If this isn't a constant expr, just assume it fits and let relaxation
183 // handle it.
184 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
185 if (!CE)
186 return true;
187
188 // Otherwise, check the value is in a range that makes sense for this
189 // extension.
190 return isImmSExti64i32Value(CE->getValue());
191 }
192
Craig Topperf38dea12015-01-21 06:07:53 +0000193 bool isImmUnsignedi8() const {
194 if (!isImm()) return false;
Peter Collingbournec7766772016-10-20 01:58:34 +0000195 // If this isn't a constant expr, just assume it fits and let relaxation
196 // handle it.
Craig Topperf38dea12015-01-21 06:07:53 +0000197 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
Peter Collingbournec7766772016-10-20 01:58:34 +0000198 if (!CE) return true;
Craig Topperf38dea12015-01-21 06:07:53 +0000199 return isImmUnsignedi8Value(CE->getValue());
200 }
201
Peter Collingbourne0da86302016-10-10 22:49:37 +0000202 bool isOffsetOf() const override {
203 return OffsetOfLoc.getPointer();
204 }
205
Craig Topper39012cc2014-03-09 18:03:14 +0000206 bool needAddressOf() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000207 return AddressOf;
208 }
209
Craig Topper39012cc2014-03-09 18:03:14 +0000210 bool isMem() const override { return Kind == Memory; }
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000211 bool isMemUnsized() const {
212 return Kind == Memory && Mem.Size == 0;
213 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000214 bool isMem8() const {
215 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
216 }
217 bool isMem16() const {
218 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
219 }
220 bool isMem32() const {
221 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
222 }
223 bool isMem64() const {
224 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
225 }
226 bool isMem80() const {
227 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
228 }
229 bool isMem128() const {
230 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
231 }
232 bool isMem256() const {
233 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
234 }
235 bool isMem512() const {
236 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
237 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000238 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
239 assert(Kind == Memory && "Invalid access!");
240 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
241 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000242
Igor Breger45ef10f2016-02-25 13:30:17 +0000243 bool isMem64_RC128() const {
244 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000245 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000246 bool isMem128_RC128() const {
247 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000248 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000249 bool isMem128_RC256() const {
250 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000251 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000252 bool isMem256_RC128() const {
253 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000254 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000255 bool isMem256_RC256() const {
256 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000257 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000258
259 bool isMem64_RC128X() const {
260 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000261 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000262 bool isMem128_RC128X() const {
263 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000264 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000265 bool isMem128_RC256X() const {
266 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000267 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000268 bool isMem256_RC128X() const {
269 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000270 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000271 bool isMem256_RC256X() const {
272 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
273 }
Craig Topper7dfd5832017-01-16 00:55:58 +0000274 bool isMem256_RC512() const {
275 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
276 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000277 bool isMem512_RC256X() const {
278 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
279 }
280 bool isMem512_RC512() const {
281 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000282 }
283
284 bool isAbsMem() const {
285 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
286 !getMemIndexReg() && getMemScale() == 1;
287 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000288 bool isAVX512RC() const{
289 return isImm();
290 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000291
Craig Topper63944542015-01-06 08:59:30 +0000292 bool isAbsMem16() const {
293 return isAbsMem() && Mem.ModeSize == 16;
294 }
295
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000296 bool isSrcIdx() const {
297 return !getMemIndexReg() && getMemScale() == 1 &&
298 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
299 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
300 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
301 }
302 bool isSrcIdx8() const {
303 return isMem8() && isSrcIdx();
304 }
305 bool isSrcIdx16() const {
306 return isMem16() && isSrcIdx();
307 }
308 bool isSrcIdx32() const {
309 return isMem32() && isSrcIdx();
310 }
311 bool isSrcIdx64() const {
312 return isMem64() && isSrcIdx();
313 }
314
315 bool isDstIdx() const {
316 return !getMemIndexReg() && getMemScale() == 1 &&
317 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
318 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
319 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
320 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
321 }
322 bool isDstIdx8() const {
323 return isMem8() && isDstIdx();
324 }
325 bool isDstIdx16() const {
326 return isMem16() && isDstIdx();
327 }
328 bool isDstIdx32() const {
329 return isMem32() && isDstIdx();
330 }
331 bool isDstIdx64() const {
332 return isMem64() && isDstIdx();
333 }
334
Craig Topper055845f2015-01-02 07:02:25 +0000335 bool isMemOffs() const {
336 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
337 getMemScale() == 1;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000338 }
Craig Topper055845f2015-01-02 07:02:25 +0000339
340 bool isMemOffs16_8() const {
341 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000342 }
Craig Topper055845f2015-01-02 07:02:25 +0000343 bool isMemOffs16_16() const {
344 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000345 }
Craig Topper055845f2015-01-02 07:02:25 +0000346 bool isMemOffs16_32() const {
347 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
348 }
349 bool isMemOffs32_8() const {
350 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
351 }
352 bool isMemOffs32_16() const {
353 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
354 }
355 bool isMemOffs32_32() const {
356 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
357 }
Craig Topperae8e1b32015-01-03 00:00:20 +0000358 bool isMemOffs32_64() const {
359 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
360 }
Craig Topper055845f2015-01-02 07:02:25 +0000361 bool isMemOffs64_8() const {
362 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
363 }
364 bool isMemOffs64_16() const {
365 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
366 }
367 bool isMemOffs64_32() const {
368 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
369 }
370 bool isMemOffs64_64() const {
371 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000372 }
373
Craig Topper39012cc2014-03-09 18:03:14 +0000374 bool isReg() const override { return Kind == Register; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000375
376 bool isGR32orGR64() const {
377 return Kind == Register &&
378 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
379 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
380 }
381
382 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
383 // Add as immediates when possible.
384 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000385 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000386 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000387 Inst.addOperand(MCOperand::createExpr(Expr));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000388 }
389
390 void addRegOperands(MCInst &Inst, unsigned N) const {
391 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000392 Inst.addOperand(MCOperand::createReg(getReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000393 }
394
395 static unsigned getGR32FromGR64(unsigned RegNo) {
396 switch (RegNo) {
397 default: llvm_unreachable("Unexpected register");
398 case X86::RAX: return X86::EAX;
399 case X86::RCX: return X86::ECX;
400 case X86::RDX: return X86::EDX;
401 case X86::RBX: return X86::EBX;
402 case X86::RBP: return X86::EBP;
403 case X86::RSP: return X86::ESP;
404 case X86::RSI: return X86::ESI;
405 case X86::RDI: return X86::EDI;
406 case X86::R8: return X86::R8D;
407 case X86::R9: return X86::R9D;
408 case X86::R10: return X86::R10D;
409 case X86::R11: return X86::R11D;
410 case X86::R12: return X86::R12D;
411 case X86::R13: return X86::R13D;
412 case X86::R14: return X86::R14D;
413 case X86::R15: return X86::R15D;
414 case X86::RIP: return X86::EIP;
415 }
416 }
417
418 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
419 assert(N == 1 && "Invalid number of operands!");
420 unsigned RegNo = getReg();
421 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
422 RegNo = getGR32FromGR64(RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +0000423 Inst.addOperand(MCOperand::createReg(RegNo));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000424 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000425 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
426 assert(N == 1 && "Invalid number of operands!");
427 addExpr(Inst, getImm());
428 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000429 void addImmOperands(MCInst &Inst, unsigned N) const {
430 assert(N == 1 && "Invalid number of operands!");
431 addExpr(Inst, getImm());
432 }
433
434 void addMemOperands(MCInst &Inst, unsigned N) const {
435 assert((N == 5) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000436 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
437 Inst.addOperand(MCOperand::createImm(getMemScale()));
438 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000439 addExpr(Inst, getMemDisp());
Jim Grosbache9119e42015-05-13 18:37:00 +0000440 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000441 }
442
443 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
444 assert((N == 1) && "Invalid number of operands!");
445 // Add as immediates when possible.
446 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000447 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000448 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000449 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000450 }
451
452 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
453 assert((N == 2) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000454 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
455 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000456 }
457 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
458 assert((N == 1) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000459 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000460 }
461
462 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
463 assert((N == 2) && "Invalid number of operands!");
464 // Add as immediates when possible.
465 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000466 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000467 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000468 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
469 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000470 }
471
David Blaikie960ea3f2014-06-08 16:18:35 +0000472 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000473 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000474 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000475 Res->Tok.Data = Str.data();
476 Res->Tok.Length = Str.size();
477 return Res;
478 }
479
David Blaikie960ea3f2014-06-08 16:18:35 +0000480 static std::unique_ptr<X86Operand>
481 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
Peter Collingbourne0da86302016-10-10 22:49:37 +0000482 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
483 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000484 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000485 Res->Reg.RegNo = RegNo;
486 Res->AddressOf = AddressOf;
Peter Collingbourne0da86302016-10-10 22:49:37 +0000487 Res->OffsetOfLoc = OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000488 Res->SymName = SymName;
489 Res->OpDecl = OpDecl;
490 return Res;
491 }
492
David Blaikie960ea3f2014-06-08 16:18:35 +0000493 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
494 SMLoc StartLoc, SMLoc EndLoc) {
495 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000496 Res->Imm.Val = Val;
497 return Res;
498 }
499
500 /// Create an absolute memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000501 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000502 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
503 unsigned Size = 0, StringRef SymName = StringRef(),
504 void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000505 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000506 Res->Mem.SegReg = 0;
507 Res->Mem.Disp = Disp;
508 Res->Mem.BaseReg = 0;
509 Res->Mem.IndexReg = 0;
510 Res->Mem.Scale = 1;
511 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000512 Res->Mem.ModeSize = ModeSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000513 Res->SymName = SymName;
514 Res->OpDecl = OpDecl;
515 Res->AddressOf = false;
516 return Res;
517 }
518
519 /// Create a generalized 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, unsigned SegReg, const MCExpr *Disp,
522 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
523 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
David Blaikie960ea3f2014-06-08 16:18:35 +0000524 void *OpDecl = nullptr) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000525 // We should never just have a displacement, that should be parsed as an
526 // absolute memory operand.
527 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
528
529 // The scale should always be one of {1,2,4,8}.
530 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
531 "Invalid scale!");
David Blaikie960ea3f2014-06-08 16:18:35 +0000532 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000533 Res->Mem.SegReg = SegReg;
534 Res->Mem.Disp = Disp;
535 Res->Mem.BaseReg = BaseReg;
536 Res->Mem.IndexReg = IndexReg;
537 Res->Mem.Scale = Scale;
538 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000539 Res->Mem.ModeSize = ModeSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000540 Res->SymName = SymName;
541 Res->OpDecl = OpDecl;
542 Res->AddressOf = false;
543 return Res;
544 }
545};
546
547} // End of namespace llvm
548
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000549#endif