Taints the non-acquire RMW's store address with the load part
[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/MCInst.h"
16 #include "llvm/MC/MCRegisterInfo.h"
17 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "MCTargetDesc/X86MCTargetDesc.h"
20
21 namespace llvm {
22
23 /// X86Operand - Instances of this class represent a parsed X86 machine
24 /// instruction.
25 struct 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;
59     unsigned ModeSize;
60   };
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
72   StringRef getSymName() override { return SymName; }
73   void *getOpDecl() override { return OpDecl; }
74
75   /// getStartLoc - Get the location of the first token of this operand.
76   SMLoc getStartLoc() const override { return StartLoc; }
77   /// getEndLoc - Get the location of the last token of this operand.
78   SMLoc getEndLoc() const override { return EndLoc; }
79   /// 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.
83   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
84
85   void print(raw_ostream &OS) const override {}
86
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
97   unsigned getReg() const override {
98     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   }
127   unsigned getMemModeSize() const {
128     assert(Kind == Memory && "Invalid access!");
129     return Mem.ModeSize;
130   }
131
132   bool isToken() const override {return Kind == Token; }
133
134   bool isImm() const override { return Kind == Immediate; }
135
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   }
164   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
193   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
200   bool isOffsetOf() const override {
201     return OffsetOfLoc.getPointer();
202   }
203
204   bool needAddressOf() const override {
205     return AddressOf;
206   }
207
208   bool isMem() const override { return Kind == Memory; }
209   bool isMemUnsized() const {
210     return Kind == Memory && Mem.Size == 0;
211   }
212   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   }
236
237   bool isMemVX32() const {
238     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
239       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
240   }
241   bool isMemVX32X() const {
242     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
243       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM31;
244   }
245   bool isMemVY32() const {
246     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
247       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
248   }
249   bool isMemVY32X() const {
250     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
251       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM31;
252   }
253   bool isMemVX64() const {
254     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
255       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
256   }
257   bool isMemVX64X() const {
258     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
259       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM31;
260   }
261   bool isMemVY64() const {
262     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
263       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
264   }
265   bool isMemVY64X() const {
266     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
267       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM31;
268   }
269   bool isMemVZ32() const {
270     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
271       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
272   }
273   bool isMemVZ64() const {
274     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
275       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
276   }
277
278   bool isAbsMem() const {
279     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
280       !getMemIndexReg() && getMemScale() == 1;
281   }
282   bool isAVX512RC() const{
283       return isImm();
284   }
285
286   bool isAbsMem16() const {
287     return isAbsMem() && Mem.ModeSize == 16;
288   }
289
290   bool isSrcIdx() const {
291     return !getMemIndexReg() && getMemScale() == 1 &&
292       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
293        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
294       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
295   }
296   bool isSrcIdx8() const {
297     return isMem8() && isSrcIdx();
298   }
299   bool isSrcIdx16() const {
300     return isMem16() && isSrcIdx();
301   }
302   bool isSrcIdx32() const {
303     return isMem32() && isSrcIdx();
304   }
305   bool isSrcIdx64() const {
306     return isMem64() && isSrcIdx();
307   }
308
309   bool isDstIdx() const {
310     return !getMemIndexReg() && getMemScale() == 1 &&
311       (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
312       (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
313        getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
314       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
315   }
316   bool isDstIdx8() const {
317     return isMem8() && isDstIdx();
318   }
319   bool isDstIdx16() const {
320     return isMem16() && isDstIdx();
321   }
322   bool isDstIdx32() const {
323     return isMem32() && isDstIdx();
324   }
325   bool isDstIdx64() const {
326     return isMem64() && isDstIdx();
327   }
328
329   bool isMemOffs() const {
330     return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
331       getMemScale() == 1;
332   }
333
334   bool isMemOffs16_8() const {
335     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
336   }
337   bool isMemOffs16_16() const {
338     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
339   }
340   bool isMemOffs16_32() const {
341     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
342   }
343   bool isMemOffs32_8() const {
344     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
345   }
346   bool isMemOffs32_16() const {
347     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
348   }
349   bool isMemOffs32_32() const {
350     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
351   }
352   bool isMemOffs32_64() const {
353     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
354   }
355   bool isMemOffs64_8() const {
356     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
357   }
358   bool isMemOffs64_16() const {
359     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
360   }
361   bool isMemOffs64_32() const {
362     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
363   }
364   bool isMemOffs64_64() const {
365     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
366   }
367
368   bool isReg() const override { return Kind == Register; }
369
370   bool isGR32orGR64() const {
371     return Kind == Register &&
372       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
373       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
374   }
375
376   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
377     // Add as immediates when possible.
378     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
379       Inst.addOperand(MCOperand::createImm(CE->getValue()));
380     else
381       Inst.addOperand(MCOperand::createExpr(Expr));
382   }
383
384   void addRegOperands(MCInst &Inst, unsigned N) const {
385     assert(N == 1 && "Invalid number of operands!");
386     Inst.addOperand(MCOperand::createReg(getReg()));
387   }
388
389   static unsigned getGR32FromGR64(unsigned RegNo) {
390     switch (RegNo) {
391     default: llvm_unreachable("Unexpected register");
392     case X86::RAX: return X86::EAX;
393     case X86::RCX: return X86::ECX;
394     case X86::RDX: return X86::EDX;
395     case X86::RBX: return X86::EBX;
396     case X86::RBP: return X86::EBP;
397     case X86::RSP: return X86::ESP;
398     case X86::RSI: return X86::ESI;
399     case X86::RDI: return X86::EDI;
400     case X86::R8: return X86::R8D;
401     case X86::R9: return X86::R9D;
402     case X86::R10: return X86::R10D;
403     case X86::R11: return X86::R11D;
404     case X86::R12: return X86::R12D;
405     case X86::R13: return X86::R13D;
406     case X86::R14: return X86::R14D;
407     case X86::R15: return X86::R15D;
408     case X86::RIP: return X86::EIP;
409     }
410   }
411
412   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
413     assert(N == 1 && "Invalid number of operands!");
414     unsigned RegNo = getReg();
415     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
416       RegNo = getGR32FromGR64(RegNo);
417     Inst.addOperand(MCOperand::createReg(RegNo));
418   }
419   void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
420     assert(N == 1 && "Invalid number of operands!");
421     addExpr(Inst, getImm());
422   }
423   void addImmOperands(MCInst &Inst, unsigned N) const {
424     assert(N == 1 && "Invalid number of operands!");
425     addExpr(Inst, getImm());
426   }
427
428   void addMemOperands(MCInst &Inst, unsigned N) const {
429     assert((N == 5) && "Invalid number of operands!");
430     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
431     Inst.addOperand(MCOperand::createImm(getMemScale()));
432     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
433     addExpr(Inst, getMemDisp());
434     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
435   }
436
437   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
438     assert((N == 1) && "Invalid number of operands!");
439     // Add as immediates when possible.
440     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
441       Inst.addOperand(MCOperand::createImm(CE->getValue()));
442     else
443       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
444   }
445
446   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
447     assert((N == 2) && "Invalid number of operands!");
448     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
449     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
450   }
451   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
452     assert((N == 1) && "Invalid number of operands!");
453     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
454   }
455
456   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
457     assert((N == 2) && "Invalid number of operands!");
458     // Add as immediates when possible.
459     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
460       Inst.addOperand(MCOperand::createImm(CE->getValue()));
461     else
462       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
463     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
464   }
465
466   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
467     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
468     auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
469     Res->Tok.Data = Str.data();
470     Res->Tok.Length = Str.size();
471     return Res;
472   }
473
474   static std::unique_ptr<X86Operand>
475   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
476             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
477             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
478     auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
479     Res->Reg.RegNo = RegNo;
480     Res->AddressOf = AddressOf;
481     Res->OffsetOfLoc = OffsetOfLoc;
482     Res->SymName = SymName;
483     Res->OpDecl = OpDecl;
484     return Res;
485   }
486
487   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
488                                                SMLoc StartLoc, SMLoc EndLoc) {
489     auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
490     Res->Imm.Val = Val;
491     return Res;
492   }
493
494   /// Create an absolute memory operand.
495   static std::unique_ptr<X86Operand>
496   CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
497             unsigned Size = 0, StringRef SymName = StringRef(),
498             void *OpDecl = nullptr) {
499     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
500     Res->Mem.SegReg   = 0;
501     Res->Mem.Disp     = Disp;
502     Res->Mem.BaseReg  = 0;
503     Res->Mem.IndexReg = 0;
504     Res->Mem.Scale    = 1;
505     Res->Mem.Size     = Size;
506     Res->Mem.ModeSize = ModeSize;
507     Res->SymName      = SymName;
508     Res->OpDecl       = OpDecl;
509     Res->AddressOf    = false;
510     return Res;
511   }
512
513   /// Create a generalized memory operand.
514   static std::unique_ptr<X86Operand>
515   CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
516             unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
517             SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
518             void *OpDecl = nullptr) {
519     // We should never just have a displacement, that should be parsed as an
520     // absolute memory operand.
521     assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
522
523     // The scale should always be one of {1,2,4,8}.
524     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
525            "Invalid scale!");
526     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
527     Res->Mem.SegReg   = SegReg;
528     Res->Mem.Disp     = Disp;
529     Res->Mem.BaseReg  = BaseReg;
530     Res->Mem.IndexReg = IndexReg;
531     Res->Mem.Scale    = Scale;
532     Res->Mem.Size     = Size;
533     Res->Mem.ModeSize = ModeSize;
534     Res->SymName      = SymName;
535     Res->OpDecl       = OpDecl;
536     Res->AddressOf    = false;
537     return Res;
538   }
539 };
540
541 } // End of namespace llvm
542
543 #endif