45fe2a9d0c29caa4edb4e1454901cdd8e83446bf
1 //===-- 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 //===----------------------------------------------------------------------===//
10 #ifndef X86_OPERAND_H
11 #define X86_OPERAND_H
13 #include "X86AsmParserCommon.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
17 namespace llvm {
19 /// X86Operand - Instances of this class represent a parsed X86 machine
20 /// instruction.
21 struct X86Operand : public MCParsedAsmOperand {
22 enum KindTy {
23 Token,
24 Register,
25 Immediate,
26 Memory
27 } Kind;
29 SMLoc StartLoc, EndLoc;
30 SMLoc OffsetOfLoc;
31 StringRef SymName;
32 void *OpDecl;
33 bool AddressOf;
35 struct TokOp {
36 const char *Data;
37 unsigned Length;
38 };
40 struct RegOp {
41 unsigned RegNo;
42 };
44 struct ImmOp {
45 const MCExpr *Val;
46 };
48 struct MemOp {
49 unsigned SegReg;
50 const MCExpr *Disp;
51 unsigned BaseReg;
52 unsigned IndexReg;
53 unsigned Scale;
54 unsigned Size;
55 };
57 union {
58 struct TokOp Tok;
59 struct RegOp Reg;
60 struct ImmOp Imm;
61 struct MemOp Mem;
62 };
64 X86Operand(KindTy K, SMLoc Start, SMLoc End)
65 : Kind(K), StartLoc(Start), EndLoc(End) {}
67 StringRef getSymName() override { return SymName; }
68 void *getOpDecl() override { return OpDecl; }
70 /// getStartLoc - Get the location of the first token of this operand.
71 SMLoc getStartLoc() const override { return StartLoc; }
72 /// getEndLoc - Get the location of the last token of this operand.
73 SMLoc getEndLoc() const override { return EndLoc; }
74 /// getLocRange - Get the range between the first and last token of this
75 /// operand.
76 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
77 /// getOffsetOfLoc - Get the location of the offset operator.
78 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
80 void print(raw_ostream &OS) const override {}
82 StringRef getToken() const {
83 assert(Kind == Token && "Invalid access!");
84 return StringRef(Tok.Data, Tok.Length);
85 }
86 void setTokenValue(StringRef Value) {
87 assert(Kind == Token && "Invalid access!");
88 Tok.Data = Value.data();
89 Tok.Length = Value.size();
90 }
92 unsigned getReg() const override {
93 assert(Kind == Register && "Invalid access!");
94 return Reg.RegNo;
95 }
97 const MCExpr *getImm() const {
98 assert(Kind == Immediate && "Invalid access!");
99 return Imm.Val;
100 }
102 const MCExpr *getMemDisp() const {
103 assert(Kind == Memory && "Invalid access!");
104 return Mem.Disp;
105 }
106 unsigned getMemSegReg() const {
107 assert(Kind == Memory && "Invalid access!");
108 return Mem.SegReg;
109 }
110 unsigned getMemBaseReg() const {
111 assert(Kind == Memory && "Invalid access!");
112 return Mem.BaseReg;
113 }
114 unsigned getMemIndexReg() const {
115 assert(Kind == Memory && "Invalid access!");
116 return Mem.IndexReg;
117 }
118 unsigned getMemScale() const {
119 assert(Kind == Memory && "Invalid access!");
120 return Mem.Scale;
121 }
123 bool isToken() const override {return Kind == Token; }
125 bool isImm() const override { return Kind == Immediate; }
127 bool isImmSExti16i8() const {
128 if (!isImm())
129 return false;
131 // If this isn't a constant expr, just assume it fits and let relaxation
132 // handle it.
133 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
134 if (!CE)
135 return true;
137 // Otherwise, check the value is in a range that makes sense for this
138 // extension.
139 return isImmSExti16i8Value(CE->getValue());
140 }
141 bool isImmSExti32i8() const {
142 if (!isImm())
143 return false;
145 // If this isn't a constant expr, just assume it fits and let relaxation
146 // handle it.
147 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
148 if (!CE)
149 return true;
151 // Otherwise, check the value is in a range that makes sense for this
152 // extension.
153 return isImmSExti32i8Value(CE->getValue());
154 }
155 bool isImmZExtu32u8() const {
156 if (!isImm())
157 return false;
159 // If this isn't a constant expr, just assume it fits and let relaxation
160 // handle it.
161 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
162 if (!CE)
163 return true;
165 // Otherwise, check the value is in a range that makes sense for this
166 // extension.
167 return isImmZExtu32u8Value(CE->getValue());
168 }
169 bool isImmSExti64i8() const {
170 if (!isImm())
171 return false;
173 // If this isn't a constant expr, just assume it fits and let relaxation
174 // handle it.
175 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
176 if (!CE)
177 return true;
179 // Otherwise, check the value is in a range that makes sense for this
180 // extension.
181 return isImmSExti64i8Value(CE->getValue());
182 }
183 bool isImmSExti64i32() const {
184 if (!isImm())
185 return false;
187 // If this isn't a constant expr, just assume it fits and let relaxation
188 // handle it.
189 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
190 if (!CE)
191 return true;
193 // Otherwise, check the value is in a range that makes sense for this
194 // extension.
195 return isImmSExti64i32Value(CE->getValue());
196 }
198 bool isOffsetOf() const override {
199 return OffsetOfLoc.getPointer();
200 }
202 bool needAddressOf() const override {
203 return AddressOf;
204 }
206 bool isMem() const override { return Kind == Memory; }
207 bool isMem8() const {
208 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
209 }
210 bool isMem16() const {
211 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
212 }
213 bool isMem32() const {
214 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
215 }
216 bool isMem64() const {
217 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
218 }
219 bool isMem80() const {
220 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
221 }
222 bool isMem128() const {
223 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
224 }
225 bool isMem256() const {
226 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
227 }
228 bool isMem512() const {
229 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
230 }
232 bool isMemVX32() const {
233 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
234 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
235 }
236 bool isMemVY32() const {
237 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
238 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
239 }
240 bool isMemVX64() const {
241 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
242 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
243 }
244 bool isMemVY64() const {
245 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
246 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
247 }
248 bool isMemVZ32() const {
249 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
250 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
251 }
252 bool isMemVZ64() const {
253 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
254 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
255 }
257 bool isAbsMem() const {
258 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
259 !getMemIndexReg() && getMemScale() == 1;
260 }
262 bool isSrcIdx() const {
263 return !getMemIndexReg() && getMemScale() == 1 &&
264 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
265 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
266 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
267 }
268 bool isSrcIdx8() const {
269 return isMem8() && isSrcIdx();
270 }
271 bool isSrcIdx16() const {
272 return isMem16() && isSrcIdx();
273 }
274 bool isSrcIdx32() const {
275 return isMem32() && isSrcIdx();
276 }
277 bool isSrcIdx64() const {
278 return isMem64() && isSrcIdx();
279 }
281 bool isDstIdx() const {
282 return !getMemIndexReg() && getMemScale() == 1 &&
283 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
284 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
285 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
286 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
287 }
288 bool isDstIdx8() const {
289 return isMem8() && isDstIdx();
290 }
291 bool isDstIdx16() const {
292 return isMem16() && isDstIdx();
293 }
294 bool isDstIdx32() const {
295 return isMem32() && isDstIdx();
296 }
297 bool isDstIdx64() const {
298 return isMem64() && isDstIdx();
299 }
301 bool isMemOffs8() const {
302 return Kind == Memory && !getMemBaseReg() &&
303 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
304 }
305 bool isMemOffs16() const {
306 return Kind == Memory && !getMemBaseReg() &&
307 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
308 }
309 bool isMemOffs32() const {
310 return Kind == Memory && !getMemBaseReg() &&
311 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
312 }
313 bool isMemOffs64() const {
314 return Kind == Memory && !getMemBaseReg() &&
315 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
316 }
318 bool isReg() const override { return Kind == Register; }
320 bool isGR32orGR64() const {
321 return Kind == Register &&
322 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
323 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
324 }
326 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
327 // Add as immediates when possible.
328 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
329 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
330 else
331 Inst.addOperand(MCOperand::CreateExpr(Expr));
332 }
334 void addRegOperands(MCInst &Inst, unsigned N) const {
335 assert(N == 1 && "Invalid number of operands!");
336 Inst.addOperand(MCOperand::CreateReg(getReg()));
337 }
339 static unsigned getGR32FromGR64(unsigned RegNo) {
340 switch (RegNo) {
341 default: llvm_unreachable("Unexpected register");
342 case X86::RAX: return X86::EAX;
343 case X86::RCX: return X86::ECX;
344 case X86::RDX: return X86::EDX;
345 case X86::RBX: return X86::EBX;
346 case X86::RBP: return X86::EBP;
347 case X86::RSP: return X86::ESP;
348 case X86::RSI: return X86::ESI;
349 case X86::RDI: return X86::EDI;
350 case X86::R8: return X86::R8D;
351 case X86::R9: return X86::R9D;
352 case X86::R10: return X86::R10D;
353 case X86::R11: return X86::R11D;
354 case X86::R12: return X86::R12D;
355 case X86::R13: return X86::R13D;
356 case X86::R14: return X86::R14D;
357 case X86::R15: return X86::R15D;
358 case X86::RIP: return X86::EIP;
359 }
360 }
362 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
363 assert(N == 1 && "Invalid number of operands!");
364 unsigned RegNo = getReg();
365 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
366 RegNo = getGR32FromGR64(RegNo);
367 Inst.addOperand(MCOperand::CreateReg(RegNo));
368 }
370 void addImmOperands(MCInst &Inst, unsigned N) const {
371 assert(N == 1 && "Invalid number of operands!");
372 addExpr(Inst, getImm());
373 }
375 void addMemOperands(MCInst &Inst, unsigned N) const {
376 assert((N == 5) && "Invalid number of operands!");
377 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
378 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
379 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
380 addExpr(Inst, getMemDisp());
381 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
382 }
384 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
385 assert((N == 1) && "Invalid number of operands!");
386 // Add as immediates when possible.
387 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
388 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
389 else
390 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
391 }
393 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
394 assert((N == 2) && "Invalid number of operands!");
395 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
396 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
397 }
398 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
399 assert((N == 1) && "Invalid number of operands!");
400 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
401 }
403 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
404 assert((N == 2) && "Invalid number of operands!");
405 // Add as immediates when possible.
406 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
407 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
408 else
409 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
410 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
411 }
413 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
414 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
415 X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
416 Res->Tok.Data = Str.data();
417 Res->Tok.Length = Str.size();
418 return Res;
419 }
421 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
422 bool AddressOf = false,
423 SMLoc OffsetOfLoc = SMLoc(),
424 StringRef SymName = StringRef(),
425 void *OpDecl = 0) {
426 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
427 Res->Reg.RegNo = RegNo;
428 Res->AddressOf = AddressOf;
429 Res->OffsetOfLoc = OffsetOfLoc;
430 Res->SymName = SymName;
431 Res->OpDecl = OpDecl;
432 return Res;
433 }
435 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
436 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
437 Res->Imm.Val = Val;
438 return Res;
439 }
441 /// Create an absolute memory operand.
442 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
443 unsigned Size = 0, StringRef SymName = StringRef(),
444 void *OpDecl = 0) {
445 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
446 Res->Mem.SegReg = 0;
447 Res->Mem.Disp = Disp;
448 Res->Mem.BaseReg = 0;
449 Res->Mem.IndexReg = 0;
450 Res->Mem.Scale = 1;
451 Res->Mem.Size = Size;
452 Res->SymName = SymName;
453 Res->OpDecl = OpDecl;
454 Res->AddressOf = false;
455 return Res;
456 }
458 /// Create a generalized memory operand.
459 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
460 unsigned BaseReg, unsigned IndexReg,
461 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
462 unsigned Size = 0,
463 StringRef SymName = StringRef(),
464 void *OpDecl = 0) {
465 // We should never just have a displacement, that should be parsed as an
466 // absolute memory operand.
467 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
469 // The scale should always be one of {1,2,4,8}.
470 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
471 "Invalid scale!");
472 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
473 Res->Mem.SegReg = SegReg;
474 Res->Mem.Disp = Disp;
475 Res->Mem.BaseReg = BaseReg;
476 Res->Mem.IndexReg = IndexReg;
477 Res->Mem.Scale = Scale;
478 Res->Mem.Size = Size;
479 Res->SymName = SymName;
480 Res->OpDecl = OpDecl;
481 Res->AddressOf = false;
482 return Res;
483 }
484 };
486 } // End of namespace llvm
488 #endif // X86_OPERAND