]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/blob - lib/Target/X86/AsmParser/X86Operand.h
[C++] Use 'nullptr'.
[opencl/llvm.git] / lib / Target / X86 / AsmParser / X86Operand.h
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 = nullptr) {
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 = nullptr) {
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 = nullptr) {
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