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