blob: 43a0561e769b25fa59354da16a98e99ab5d19fa6 [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
David Blaikie1032b512017-10-24 21:29:15 +000013#include "MCTargetDesc/X86MCTargetDesc.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000014#include "X86AsmParserCommon.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000015#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/StringRef.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000017#include "llvm/MC/MCExpr.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000018#include "llvm/MC/MCInst.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000019#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000020#include "llvm/MC/MCRegisterInfo.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000021#include "llvm/Support/Casting.h"
22#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/SMLoc.h"
24#include <cassert>
25#include <memory>
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000026
27namespace llvm {
28
29/// X86Operand - Instances of this class represent a parsed X86 machine
30/// instruction.
31struct X86Operand : public MCParsedAsmOperand {
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +000032 enum KindTy { Token, Register, Immediate, Memory, Prefix } Kind;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000033
34 SMLoc StartLoc, EndLoc;
Peter Collingbourne0da86302016-10-10 22:49:37 +000035 SMLoc OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000036 StringRef SymName;
37 void *OpDecl;
38 bool AddressOf;
39
40 struct TokOp {
41 const char *Data;
42 unsigned Length;
43 };
44
45 struct RegOp {
46 unsigned RegNo;
47 };
48
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +000049 struct PrefOp {
50 unsigned Prefixes;
51 };
52
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000053 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;
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +000076 struct PrefOp Pref;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000077 };
78
79 X86Operand(KindTy K, SMLoc Start, SMLoc End)
80 : Kind(K), StartLoc(Start), EndLoc(End) {}
81
Craig Topper39012cc2014-03-09 18:03:14 +000082 StringRef getSymName() override { return SymName; }
83 void *getOpDecl() override { return OpDecl; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000084
85 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper39012cc2014-03-09 18:03:14 +000086 SMLoc getStartLoc() const override { return StartLoc; }
Eugene Zelenko90562df2017-02-06 21:55:43 +000087
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000088 /// getEndLoc - Get the location of the last token of this operand.
Peter Collingbourne0da86302016-10-10 22:49:37 +000089 SMLoc getEndLoc() const override { return EndLoc; }
Eugene Zelenko90562df2017-02-06 21:55:43 +000090
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000091 /// getLocRange - Get the range between the first and last token of this
92 /// operand.
93 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
Eugene Zelenko90562df2017-02-06 21:55:43 +000094
Peter Collingbourne0da86302016-10-10 22:49:37 +000095 /// getOffsetOfLoc - Get the location of the offset operator.
96 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000097
Craig Topper39012cc2014-03-09 18:03:14 +000098 void print(raw_ostream &OS) const override {}
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000099
100 StringRef getToken() const {
101 assert(Kind == Token && "Invalid access!");
102 return StringRef(Tok.Data, Tok.Length);
103 }
104 void setTokenValue(StringRef Value) {
105 assert(Kind == Token && "Invalid access!");
106 Tok.Data = Value.data();
107 Tok.Length = Value.size();
108 }
109
Craig Topper39012cc2014-03-09 18:03:14 +0000110 unsigned getReg() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000111 assert(Kind == Register && "Invalid access!");
112 return Reg.RegNo;
113 }
114
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000115 unsigned getPrefix() const {
116 assert(Kind == Prefix && "Invalid access!");
117 return Pref.Prefixes;
118 }
119
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000120 const MCExpr *getImm() const {
121 assert(Kind == Immediate && "Invalid access!");
122 return Imm.Val;
123 }
124
125 const MCExpr *getMemDisp() const {
126 assert(Kind == Memory && "Invalid access!");
127 return Mem.Disp;
128 }
129 unsigned getMemSegReg() const {
130 assert(Kind == Memory && "Invalid access!");
131 return Mem.SegReg;
132 }
133 unsigned getMemBaseReg() const {
134 assert(Kind == Memory && "Invalid access!");
135 return Mem.BaseReg;
136 }
137 unsigned getMemIndexReg() const {
138 assert(Kind == Memory && "Invalid access!");
139 return Mem.IndexReg;
140 }
141 unsigned getMemScale() const {
142 assert(Kind == Memory && "Invalid access!");
143 return Mem.Scale;
144 }
Craig Topper055845f2015-01-02 07:02:25 +0000145 unsigned getMemModeSize() const {
146 assert(Kind == Memory && "Invalid access!");
147 return Mem.ModeSize;
148 }
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000149 unsigned getMemFrontendSize() const {
150 assert(Kind == Memory && "Invalid access!");
151 return Mem.FrontendSize;
152 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000153
Craig Topper39012cc2014-03-09 18:03:14 +0000154 bool isToken() const override {return Kind == Token; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000155
Craig Topper39012cc2014-03-09 18:03:14 +0000156 bool isImm() const override { return Kind == Immediate; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000157
158 bool isImmSExti16i8() 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 isImmSExti16i8Value(CE->getValue());
171 }
172 bool isImmSExti32i8() 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 isImmSExti32i8Value(CE->getValue());
185 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000186 bool isImmSExti64i8() 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 isImmSExti64i8Value(CE->getValue());
199 }
200 bool isImmSExti64i32() const {
201 if (!isImm())
202 return false;
203
204 // If this isn't a constant expr, just assume it fits and let relaxation
205 // handle it.
206 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
207 if (!CE)
208 return true;
209
210 // Otherwise, check the value is in a range that makes sense for this
211 // extension.
212 return isImmSExti64i32Value(CE->getValue());
213 }
214
Craig Topperf38dea12015-01-21 06:07:53 +0000215 bool isImmUnsignedi8() const {
216 if (!isImm()) return false;
Peter Collingbournec7766772016-10-20 01:58:34 +0000217 // If this isn't a constant expr, just assume it fits and let relaxation
218 // handle it.
Craig Topperf38dea12015-01-21 06:07:53 +0000219 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
Peter Collingbournec7766772016-10-20 01:58:34 +0000220 if (!CE) return true;
Craig Topperf38dea12015-01-21 06:07:53 +0000221 return isImmUnsignedi8Value(CE->getValue());
222 }
223
Peter Collingbourne0da86302016-10-10 22:49:37 +0000224 bool isOffsetOf() const override {
225 return OffsetOfLoc.getPointer();
226 }
227
Craig Topper39012cc2014-03-09 18:03:14 +0000228 bool needAddressOf() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000229 return AddressOf;
230 }
231
Craig Topper39012cc2014-03-09 18:03:14 +0000232 bool isMem() const override { return Kind == Memory; }
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000233 bool isMemUnsized() const {
234 return Kind == Memory && Mem.Size == 0;
235 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000236 bool isMem8() const {
237 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
238 }
239 bool isMem16() const {
240 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
241 }
242 bool isMem32() const {
243 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
244 }
245 bool isMem64() const {
246 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
247 }
248 bool isMem80() const {
249 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
250 }
251 bool isMem128() const {
252 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
253 }
254 bool isMem256() const {
255 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
256 }
257 bool isMem512() const {
258 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
259 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000260 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
261 assert(Kind == Memory && "Invalid access!");
262 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
263 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000264
Igor Breger45ef10f2016-02-25 13:30:17 +0000265 bool isMem64_RC128() const {
266 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000267 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000268 bool isMem128_RC128() const {
269 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000270 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000271 bool isMem128_RC256() const {
272 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000273 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000274 bool isMem256_RC128() const {
275 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000276 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000277 bool isMem256_RC256() const {
278 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000279 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000280
281 bool isMem64_RC128X() const {
282 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000283 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000284 bool isMem128_RC128X() const {
285 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000286 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000287 bool isMem128_RC256X() const {
288 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000289 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000290 bool isMem256_RC128X() const {
291 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000292 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000293 bool isMem256_RC256X() const {
294 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
295 }
Craig Topper7dfd5832017-01-16 00:55:58 +0000296 bool isMem256_RC512() const {
297 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
298 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000299 bool isMem512_RC256X() const {
300 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
301 }
302 bool isMem512_RC512() const {
303 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000304 }
305
306 bool isAbsMem() const {
307 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
308 !getMemIndexReg() && getMemScale() == 1;
309 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000310 bool isAVX512RC() const{
311 return isImm();
312 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000313
Craig Topper63944542015-01-06 08:59:30 +0000314 bool isAbsMem16() const {
315 return isAbsMem() && Mem.ModeSize == 16;
316 }
317
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000318 bool isSrcIdx() const {
319 return !getMemIndexReg() && getMemScale() == 1 &&
320 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
321 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
322 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
323 }
324 bool isSrcIdx8() const {
325 return isMem8() && isSrcIdx();
326 }
327 bool isSrcIdx16() const {
328 return isMem16() && isSrcIdx();
329 }
330 bool isSrcIdx32() const {
331 return isMem32() && isSrcIdx();
332 }
333 bool isSrcIdx64() const {
334 return isMem64() && isSrcIdx();
335 }
336
337 bool isDstIdx() const {
338 return !getMemIndexReg() && getMemScale() == 1 &&
339 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
340 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
341 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
342 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
343 }
344 bool isDstIdx8() const {
345 return isMem8() && isDstIdx();
346 }
347 bool isDstIdx16() const {
348 return isMem16() && isDstIdx();
349 }
350 bool isDstIdx32() const {
351 return isMem32() && isDstIdx();
352 }
353 bool isDstIdx64() const {
354 return isMem64() && isDstIdx();
355 }
356
Craig Topper055845f2015-01-02 07:02:25 +0000357 bool isMemOffs() const {
358 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
359 getMemScale() == 1;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000360 }
Craig Topper055845f2015-01-02 07:02:25 +0000361
362 bool isMemOffs16_8() const {
363 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000364 }
Craig Topper055845f2015-01-02 07:02:25 +0000365 bool isMemOffs16_16() const {
366 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000367 }
Craig Topper055845f2015-01-02 07:02:25 +0000368 bool isMemOffs16_32() const {
369 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
370 }
371 bool isMemOffs32_8() const {
372 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
373 }
374 bool isMemOffs32_16() const {
375 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
376 }
377 bool isMemOffs32_32() const {
378 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
379 }
Craig Topperae8e1b32015-01-03 00:00:20 +0000380 bool isMemOffs32_64() const {
381 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
382 }
Craig Topper055845f2015-01-02 07:02:25 +0000383 bool isMemOffs64_8() const {
384 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
385 }
386 bool isMemOffs64_16() const {
387 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
388 }
389 bool isMemOffs64_32() const {
390 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
391 }
392 bool isMemOffs64_64() const {
393 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000394 }
395
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000396 bool isPrefix() const { return Kind == Prefix; }
Craig Topper39012cc2014-03-09 18:03:14 +0000397 bool isReg() const override { return Kind == Register; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000398
399 bool isGR32orGR64() const {
400 return Kind == Register &&
401 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
402 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
403 }
404
405 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
406 // Add as immediates when possible.
407 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000408 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000409 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000410 Inst.addOperand(MCOperand::createExpr(Expr));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000411 }
412
413 void addRegOperands(MCInst &Inst, unsigned N) const {
414 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000415 Inst.addOperand(MCOperand::createReg(getReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000416 }
417
418 static unsigned getGR32FromGR64(unsigned RegNo) {
419 switch (RegNo) {
420 default: llvm_unreachable("Unexpected register");
421 case X86::RAX: return X86::EAX;
422 case X86::RCX: return X86::ECX;
423 case X86::RDX: return X86::EDX;
424 case X86::RBX: return X86::EBX;
425 case X86::RBP: return X86::EBP;
426 case X86::RSP: return X86::ESP;
427 case X86::RSI: return X86::ESI;
428 case X86::RDI: return X86::EDI;
429 case X86::R8: return X86::R8D;
430 case X86::R9: return X86::R9D;
431 case X86::R10: return X86::R10D;
432 case X86::R11: return X86::R11D;
433 case X86::R12: return X86::R12D;
434 case X86::R13: return X86::R13D;
435 case X86::R14: return X86::R14D;
436 case X86::R15: return X86::R15D;
437 case X86::RIP: return X86::EIP;
438 }
439 }
440
441 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
442 assert(N == 1 && "Invalid number of operands!");
443 unsigned RegNo = getReg();
444 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
445 RegNo = getGR32FromGR64(RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +0000446 Inst.addOperand(MCOperand::createReg(RegNo));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000447 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000448
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000449 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
450 assert(N == 1 && "Invalid number of operands!");
451 addExpr(Inst, getImm());
452 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000453
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000454 void addImmOperands(MCInst &Inst, unsigned N) const {
455 assert(N == 1 && "Invalid number of operands!");
456 addExpr(Inst, getImm());
457 }
458
459 void addMemOperands(MCInst &Inst, unsigned N) const {
460 assert((N == 5) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000461 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
462 Inst.addOperand(MCOperand::createImm(getMemScale()));
463 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000464 addExpr(Inst, getMemDisp());
Jim Grosbache9119e42015-05-13 18:37:00 +0000465 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000466 }
467
468 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
469 assert((N == 1) && "Invalid number of operands!");
470 // Add as immediates when possible.
471 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000472 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000473 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000474 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000475 }
476
477 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
478 assert((N == 2) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000479 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
480 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000481 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000482
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000483 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
484 assert((N == 1) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000485 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000486 }
487
488 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
489 assert((N == 2) && "Invalid number of operands!");
490 // Add as immediates when possible.
491 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000492 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000493 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000494 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
495 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000496 }
497
David Blaikie960ea3f2014-06-08 16:18:35 +0000498 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000499 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000500 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000501 Res->Tok.Data = Str.data();
502 Res->Tok.Length = Str.size();
503 return Res;
504 }
505
David Blaikie960ea3f2014-06-08 16:18:35 +0000506 static std::unique_ptr<X86Operand>
507 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
Peter Collingbourne0da86302016-10-10 22:49:37 +0000508 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
509 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000510 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000511 Res->Reg.RegNo = RegNo;
512 Res->AddressOf = AddressOf;
Peter Collingbourne0da86302016-10-10 22:49:37 +0000513 Res->OffsetOfLoc = OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000514 Res->SymName = SymName;
515 Res->OpDecl = OpDecl;
516 return Res;
517 }
518
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000519 static std::unique_ptr<X86Operand>
520 CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
521 auto Res = llvm::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
522 Res->Pref.Prefixes = Prefixes;
523 return Res;
524 }
525
David Blaikie960ea3f2014-06-08 16:18:35 +0000526 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
527 SMLoc StartLoc, SMLoc EndLoc) {
528 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000529 Res->Imm.Val = Val;
530 return Res;
531 }
532
533 /// Create an absolute memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000534 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000535 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
536 unsigned Size = 0, StringRef SymName = StringRef(),
Daniel Jasper07a17712017-05-05 07:31:40 +0000537 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000538 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000539 Res->Mem.SegReg = 0;
540 Res->Mem.Disp = Disp;
541 Res->Mem.BaseReg = 0;
542 Res->Mem.IndexReg = 0;
543 Res->Mem.Scale = 1;
544 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000545 Res->Mem.ModeSize = ModeSize;
Daniel Jasper07a17712017-05-05 07:31:40 +0000546 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000547 Res->SymName = SymName;
548 Res->OpDecl = OpDecl;
549 Res->AddressOf = false;
550 return Res;
551 }
552
553 /// Create a generalized memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000554 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000555 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
556 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
557 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000558 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000559 // We should never just have a displacement, that should be parsed as an
560 // absolute memory operand.
561 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
562
563 // The scale should always be one of {1,2,4,8}.
564 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
565 "Invalid scale!");
David Blaikie960ea3f2014-06-08 16:18:35 +0000566 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000567 Res->Mem.SegReg = SegReg;
568 Res->Mem.Disp = Disp;
569 Res->Mem.BaseReg = BaseReg;
570 Res->Mem.IndexReg = IndexReg;
571 Res->Mem.Scale = Scale;
572 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000573 Res->Mem.ModeSize = ModeSize;
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000574 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000575 Res->SymName = SymName;
576 Res->OpDecl = OpDecl;
577 Res->AddressOf = false;
578 return Res;
579 }
580};
581
Eugene Zelenko90562df2017-02-06 21:55:43 +0000582} // end namespace llvm
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000583
Eugene Zelenko90562df2017-02-06 21:55:43 +0000584#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H