1 //===-- NVPTXMCExpr.h - NVPTX specific MC expression classes ----*- C++ -*-===//
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 // Modeled after ARMMCExpr
11 
12 #ifndef LLVM_LIB_TARGET_NVPTX_NVPTXMCEXPR_H
13 #define LLVM_LIB_TARGET_NVPTX_NVPTXMCEXPR_H
14 
15 #include "llvm/ADT/APFloat.h"
16 #include "llvm/MC/MCExpr.h"
17 #include <utility>
18 
19 namespace llvm {
20 
21 class NVPTXFloatMCExpr : public MCTargetExpr {
22 public:
23   enum VariantKind {
24     VK_NVPTX_None,
25     VK_NVPTX_HALF_PREC_FLOAT,   // FP constant in half-precision
26     VK_NVPTX_SINGLE_PREC_FLOAT, // FP constant in single-precision
27     VK_NVPTX_DOUBLE_PREC_FLOAT  // FP constant in double-precision
28   };
29 
30 private:
31   const VariantKind Kind;
32   const APFloat Flt;
33 
NVPTXFloatMCExpr(VariantKind Kind,APFloat Flt)34   explicit NVPTXFloatMCExpr(VariantKind Kind, APFloat Flt)
35       : Kind(Kind), Flt(std::move(Flt)) {}
36 
37 public:
38   /// @name Construction
39   /// @{
40 
41   static const NVPTXFloatMCExpr *create(VariantKind Kind, const APFloat &Flt,
42                                         MCContext &Ctx);
43 
createConstantFPHalf(const APFloat & Flt,MCContext & Ctx)44   static const NVPTXFloatMCExpr *createConstantFPHalf(const APFloat &Flt,
45                                                         MCContext &Ctx) {
46     return create(VK_NVPTX_HALF_PREC_FLOAT, Flt, Ctx);
47   }
48 
createConstantFPSingle(const APFloat & Flt,MCContext & Ctx)49   static const NVPTXFloatMCExpr *createConstantFPSingle(const APFloat &Flt,
50                                                         MCContext &Ctx) {
51     return create(VK_NVPTX_SINGLE_PREC_FLOAT, Flt, Ctx);
52   }
53 
createConstantFPDouble(const APFloat & Flt,MCContext & Ctx)54   static const NVPTXFloatMCExpr *createConstantFPDouble(const APFloat &Flt,
55                                                         MCContext &Ctx) {
56     return create(VK_NVPTX_DOUBLE_PREC_FLOAT, Flt, Ctx);
57   }
58 
59   /// @}
60   /// @name Accessors
61   /// @{
62 
63   /// getOpcode - Get the kind of this expression.
getKind()64   VariantKind getKind() const { return Kind; }
65 
66   /// getSubExpr - Get the child of this expression.
getAPFloat()67   APFloat getAPFloat() const { return Flt; }
68 
69 /// @}
70 
71   void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
evaluateAsRelocatableImpl(MCValue & Res,const MCAsmLayout * Layout,const MCFixup * Fixup)72   bool evaluateAsRelocatableImpl(MCValue &Res,
73                                  const MCAsmLayout *Layout,
74                                  const MCFixup *Fixup) const override {
75     return false;
76   }
visitUsedExpr(MCStreamer & Streamer)77   void visitUsedExpr(MCStreamer &Streamer) const override {};
findAssociatedFragment()78   MCFragment *findAssociatedFragment() const override { return nullptr; }
79 
80   // There are no TLS NVPTXMCExprs at the moment.
fixELFSymbolsInTLSFixups(MCAssembler & Asm)81   void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
82 
classof(const MCExpr * E)83   static bool classof(const MCExpr *E) {
84     return E->getKind() == MCExpr::Target;
85   }
86 };
87 
88 /// A wrapper for MCSymbolRefExpr that tells the assembly printer that the
89 /// symbol should be enclosed by generic().
90 class NVPTXGenericMCSymbolRefExpr : public MCTargetExpr {
91 private:
92   const MCSymbolRefExpr *SymExpr;
93 
NVPTXGenericMCSymbolRefExpr(const MCSymbolRefExpr * _SymExpr)94   explicit NVPTXGenericMCSymbolRefExpr(const MCSymbolRefExpr *_SymExpr)
95       : SymExpr(_SymExpr) {}
96 
97 public:
98   /// @name Construction
99   /// @{
100 
101   static const NVPTXGenericMCSymbolRefExpr
102   *create(const MCSymbolRefExpr *SymExpr, MCContext &Ctx);
103 
104   /// @}
105   /// @name Accessors
106   /// @{
107 
108   /// getOpcode - Get the kind of this expression.
getSymbolExpr()109   const MCSymbolRefExpr *getSymbolExpr() const { return SymExpr; }
110 
111   /// @}
112 
113   void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
evaluateAsRelocatableImpl(MCValue & Res,const MCAsmLayout * Layout,const MCFixup * Fixup)114   bool evaluateAsRelocatableImpl(MCValue &Res,
115                                  const MCAsmLayout *Layout,
116                                  const MCFixup *Fixup) const override {
117     return false;
118   }
visitUsedExpr(MCStreamer & Streamer)119   void visitUsedExpr(MCStreamer &Streamer) const override {};
findAssociatedFragment()120   MCFragment *findAssociatedFragment() const override { return nullptr; }
121 
122   // There are no TLS NVPTXMCExprs at the moment.
fixELFSymbolsInTLSFixups(MCAssembler & Asm)123   void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
124 
classof(const MCExpr * E)125   static bool classof(const MCExpr *E) {
126     return E->getKind() == MCExpr::Target;
127   }
128   };
129 } // end namespace llvm
130 
131 #endif
132