blob: a04c2f5c84a530acde8dc6557fb1052e16ee9225 [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;
34 SMLoc OffsetOfLoc;
35 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.
Craig Topper39012cc2014-03-09 18:03:14 +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); }
82 /// getOffsetOfLoc - Get the location of the offset operator.
Craig Topper39012cc2014-03-09 18:03:14 +000083 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;
195 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
196 if (!CE) return false;
197 return isImmUnsignedi8Value(CE->getValue());
198 }
199
Craig Topper39012cc2014-03-09 18:03:14 +0000200 bool isOffsetOf() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000201 return OffsetOfLoc.getPointer();
202 }
203
Craig Topper39012cc2014-03-09 18:03:14 +0000204 bool needAddressOf() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000205 return AddressOf;
206 }
207
Craig Topper39012cc2014-03-09 18:03:14 +0000208 bool isMem() const override { return Kind == Memory; }
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000209 bool isMemUnsized() const {
210 return Kind == Memory && Mem.Size == 0;
211 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000212 bool isMem8() const {
213 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
214 }
215 bool isMem16() const {
216 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
217 }
218 bool isMem32() const {
219 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
220 }
221 bool isMem64() const {
222 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
223 }
224 bool isMem80() const {
225 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
226 }
227 bool isMem128() const {
228 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
229 }
230 bool isMem256() const {
231 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
232 }
233 bool isMem512() const {
234 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
235 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000236 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
237 assert(Kind == Memory && "Invalid access!");
238 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
239 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000240
Igor Breger45ef10f2016-02-25 13:30:17 +0000241 bool isMem64_RC128() const {
242 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000243 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000244 bool isMem128_RC128() const {
245 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000246 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000247 bool isMem128_RC256() const {
248 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000249 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000250 bool isMem256_RC128() const {
251 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000252 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000253 bool isMem256_RC256() const {
254 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000255 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000256
257 bool isMem64_RC128X() const {
258 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000259 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000260 bool isMem128_RC128X() const {
261 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000262 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000263 bool isMem128_RC256X() const {
264 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000265 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000266 bool isMem256_RC128X() const {
267 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000268 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000269 bool isMem256_RC256X() const {
270 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
271 }
272 bool isMem512_RC256X() const {
273 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
274 }
275 bool isMem512_RC512() const {
276 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000277 }
278
279 bool isAbsMem() const {
280 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
281 !getMemIndexReg() && getMemScale() == 1;
282 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000283 bool isAVX512RC() const{
284 return isImm();
285 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000286
Craig Topper63944542015-01-06 08:59:30 +0000287 bool isAbsMem16() const {
288 return isAbsMem() && Mem.ModeSize == 16;
289 }
290
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000291 bool isSrcIdx() const {
292 return !getMemIndexReg() && getMemScale() == 1 &&
293 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
294 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
295 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
296 }
297 bool isSrcIdx8() const {
298 return isMem8() && isSrcIdx();
299 }
300 bool isSrcIdx16() const {
301 return isMem16() && isSrcIdx();
302 }
303 bool isSrcIdx32() const {
304 return isMem32() && isSrcIdx();
305 }
306 bool isSrcIdx64() const {
307 return isMem64() && isSrcIdx();
308 }
309
310 bool isDstIdx() const {
311 return !getMemIndexReg() && getMemScale() == 1 &&
312 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
313 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
314 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
315 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
316 }
317 bool isDstIdx8() const {
318 return isMem8() && isDstIdx();
319 }
320 bool isDstIdx16() const {
321 return isMem16() && isDstIdx();
322 }
323 bool isDstIdx32() const {
324 return isMem32() && isDstIdx();
325 }
326 bool isDstIdx64() const {
327 return isMem64() && isDstIdx();
328 }
329
Craig Topper055845f2015-01-02 07:02:25 +0000330 bool isMemOffs() const {
331 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
332 getMemScale() == 1;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000333 }
Craig Topper055845f2015-01-02 07:02:25 +0000334
335 bool isMemOffs16_8() const {
336 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000337 }
Craig Topper055845f2015-01-02 07:02:25 +0000338 bool isMemOffs16_16() const {
339 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000340 }
Craig Topper055845f2015-01-02 07:02:25 +0000341 bool isMemOffs16_32() const {
342 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
343 }
344 bool isMemOffs32_8() const {
345 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
346 }
347 bool isMemOffs32_16() const {
348 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
349 }
350 bool isMemOffs32_32() const {
351 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
352 }
Craig Topperae8e1b32015-01-03 00:00:20 +0000353 bool isMemOffs32_64() const {
354 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
355 }
Craig Topper055845f2015-01-02 07:02:25 +0000356 bool isMemOffs64_8() const {
357 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
358 }
359 bool isMemOffs64_16() const {
360 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
361 }
362 bool isMemOffs64_32() const {
363 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
364 }
365 bool isMemOffs64_64() const {
366 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000367 }
368
Craig Topper39012cc2014-03-09 18:03:14 +0000369 bool isReg() const override { return Kind == Register; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000370
371 bool isGR32orGR64() const {
372 return Kind == Register &&
373 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
374 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
375 }
376
377 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
378 // Add as immediates when possible.
379 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000380 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000381 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000382 Inst.addOperand(MCOperand::createExpr(Expr));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000383 }
384
385 void addRegOperands(MCInst &Inst, unsigned N) const {
386 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000387 Inst.addOperand(MCOperand::createReg(getReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000388 }
389
390 static unsigned getGR32FromGR64(unsigned RegNo) {
391 switch (RegNo) {
392 default: llvm_unreachable("Unexpected register");
393 case X86::RAX: return X86::EAX;
394 case X86::RCX: return X86::ECX;
395 case X86::RDX: return X86::EDX;
396 case X86::RBX: return X86::EBX;
397 case X86::RBP: return X86::EBP;
398 case X86::RSP: return X86::ESP;
399 case X86::RSI: return X86::ESI;
400 case X86::RDI: return X86::EDI;
401 case X86::R8: return X86::R8D;
402 case X86::R9: return X86::R9D;
403 case X86::R10: return X86::R10D;
404 case X86::R11: return X86::R11D;
405 case X86::R12: return X86::R12D;
406 case X86::R13: return X86::R13D;
407 case X86::R14: return X86::R14D;
408 case X86::R15: return X86::R15D;
409 case X86::RIP: return X86::EIP;
410 }
411 }
412
413 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
414 assert(N == 1 && "Invalid number of operands!");
415 unsigned RegNo = getReg();
416 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
417 RegNo = getGR32FromGR64(RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +0000418 Inst.addOperand(MCOperand::createReg(RegNo));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000419 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000420 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
421 assert(N == 1 && "Invalid number of operands!");
422 addExpr(Inst, getImm());
423 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000424 void addImmOperands(MCInst &Inst, unsigned N) const {
425 assert(N == 1 && "Invalid number of operands!");
426 addExpr(Inst, getImm());
427 }
428
429 void addMemOperands(MCInst &Inst, unsigned N) const {
430 assert((N == 5) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000431 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
432 Inst.addOperand(MCOperand::createImm(getMemScale()));
433 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000434 addExpr(Inst, getMemDisp());
Jim Grosbache9119e42015-05-13 18:37:00 +0000435 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000436 }
437
438 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
439 assert((N == 1) && "Invalid number of operands!");
440 // Add as immediates when possible.
441 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000442 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000443 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000444 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000445 }
446
447 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
448 assert((N == 2) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000449 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
450 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000451 }
452 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
453 assert((N == 1) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000454 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000455 }
456
457 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
458 assert((N == 2) && "Invalid number of operands!");
459 // Add as immediates when possible.
460 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000461 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000462 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000463 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
464 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000465 }
466
David Blaikie960ea3f2014-06-08 16:18:35 +0000467 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000468 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000469 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000470 Res->Tok.Data = Str.data();
471 Res->Tok.Length = Str.size();
472 return Res;
473 }
474
David Blaikie960ea3f2014-06-08 16:18:35 +0000475 static std::unique_ptr<X86Operand>
476 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
477 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
478 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
479 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000480 Res->Reg.RegNo = RegNo;
481 Res->AddressOf = AddressOf;
482 Res->OffsetOfLoc = OffsetOfLoc;
483 Res->SymName = SymName;
484 Res->OpDecl = OpDecl;
485 return Res;
486 }
487
David Blaikie960ea3f2014-06-08 16:18:35 +0000488 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
489 SMLoc StartLoc, SMLoc EndLoc) {
490 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000491 Res->Imm.Val = Val;
492 return Res;
493 }
494
495 /// Create an absolute memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000496 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000497 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
498 unsigned Size = 0, StringRef SymName = StringRef(),
499 void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000500 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000501 Res->Mem.SegReg = 0;
502 Res->Mem.Disp = Disp;
503 Res->Mem.BaseReg = 0;
504 Res->Mem.IndexReg = 0;
505 Res->Mem.Scale = 1;
506 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000507 Res->Mem.ModeSize = ModeSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000508 Res->SymName = SymName;
509 Res->OpDecl = OpDecl;
510 Res->AddressOf = false;
511 return Res;
512 }
513
514 /// Create a generalized memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000515 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000516 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
517 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
518 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
David Blaikie960ea3f2014-06-08 16:18:35 +0000519 void *OpDecl = nullptr) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000520 // We should never just have a displacement, that should be parsed as an
521 // absolute memory operand.
522 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
523
524 // The scale should always be one of {1,2,4,8}.
525 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
526 "Invalid scale!");
David Blaikie960ea3f2014-06-08 16:18:35 +0000527 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000528 Res->Mem.SegReg = SegReg;
529 Res->Mem.Disp = Disp;
530 Res->Mem.BaseReg = BaseReg;
531 Res->Mem.IndexReg = IndexReg;
532 Res->Mem.Scale = Scale;
533 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000534 Res->Mem.ModeSize = ModeSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000535 Res->SymName = SymName;
536 Res->OpDecl = OpDecl;
537 Res->AddressOf = false;
538 return Res;
539 }
540};
541
542} // End of namespace llvm
543
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000544#endif