1 //===-- NVPTXMCExpr.h - NVPTX specific MC expression classes ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // Modeled after ARMMCExpr
10 
11 #ifndef LLVM_LIB_TARGET_NVPTX_NVPTXMCEXPR_H
12 #define LLVM_LIB_TARGET_NVPTX_NVPTXMCEXPR_H
13 
14 #include "llvm/ADT/APFloat.h"
15 #include "llvm/MC/MCExpr.h"
16 #include <utility>
17 
18 namespace llvm {
19 
20 class NVPTXFloatMCExpr : public MCTargetExpr {
21 public:
22   enum VariantKind {
23     VK_NVPTX_None,
24     VK_NVPTX_BFLOAT_PREC_FLOAT, // FP constant in bfloat-precision
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 
createConstantBFPHalf(const APFloat & Flt,MCContext & Ctx)44   static const NVPTXFloatMCExpr *createConstantBFPHalf(const APFloat &Flt,
45                                                        MCContext &Ctx) {
46     return create(VK_NVPTX_BFLOAT_PREC_FLOAT, Flt, Ctx);
47   }
48 
createConstantFPHalf(const APFloat & Flt,MCContext & Ctx)49   static const NVPTXFloatMCExpr *createConstantFPHalf(const APFloat &Flt,
50                                                         MCContext &Ctx) {
51     return create(VK_NVPTX_HALF_PREC_FLOAT, Flt, Ctx);
52   }
53 
createConstantFPSingle(const APFloat & Flt,MCContext & Ctx)54   static const NVPTXFloatMCExpr *createConstantFPSingle(const APFloat &Flt,
55                                                         MCContext &Ctx) {
56     return create(VK_NVPTX_SINGLE_PREC_FLOAT, Flt, Ctx);
57   }
58 
createConstantFPDouble(const APFloat & Flt,MCContext & Ctx)59   static const NVPTXFloatMCExpr *createConstantFPDouble(const APFloat &Flt,
60                                                         MCContext &Ctx) {
61     return create(VK_NVPTX_DOUBLE_PREC_FLOAT, Flt, Ctx);
62   }
63 
64   /// @}
65   /// @name Accessors
66   /// @{
67 
68   /// getOpcode - Get the kind of this expression.
getKind()69   VariantKind getKind() const { return Kind; }
70 
71   /// getSubExpr - Get the child of this expression.
getAPFloat()72   APFloat getAPFloat() const { return Flt; }
73 
74 /// @}
75 
76   void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
evaluateAsRelocatableImpl(MCValue & Res,const MCAsmLayout * Layout,const MCFixup * Fixup)77   bool evaluateAsRelocatableImpl(MCValue &Res,
78                                  const MCAsmLayout *Layout,
79                                  const MCFixup *Fixup) const override {
80     return false;
81   }
visitUsedExpr(MCStreamer & Streamer)82   void visitUsedExpr(MCStreamer &Streamer) const override {};
findAssociatedFragment()83   MCFragment *findAssociatedFragment() const override { return nullptr; }
84 
85   // There are no TLS NVPTXMCExprs at the moment.
fixELFSymbolsInTLSFixups(MCAssembler & Asm)86   void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
87 
classof(const MCExpr * E)88   static bool classof(const MCExpr *E) {
89     return E->getKind() == MCExpr::Target;
90   }
91 };
92 
93 /// A wrapper for MCSymbolRefExpr that tells the assembly printer that the
94 /// symbol should be enclosed by generic().
95 class NVPTXGenericMCSymbolRefExpr : public MCTargetExpr {
96 private:
97   const MCSymbolRefExpr *SymExpr;
98 
NVPTXGenericMCSymbolRefExpr(const MCSymbolRefExpr * _SymExpr)99   explicit NVPTXGenericMCSymbolRefExpr(const MCSymbolRefExpr *_SymExpr)
100       : SymExpr(_SymExpr) {}
101 
102 public:
103   /// @name Construction
104   /// @{
105 
106   static const NVPTXGenericMCSymbolRefExpr
107   *create(const MCSymbolRefExpr *SymExpr, MCContext &Ctx);
108 
109   /// @}
110   /// @name Accessors
111   /// @{
112 
113   /// getOpcode - Get the kind of this expression.
getSymbolExpr()114   const MCSymbolRefExpr *getSymbolExpr() const { return SymExpr; }
115 
116   /// @}
117 
118   void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
evaluateAsRelocatableImpl(MCValue & Res,const MCAsmLayout * Layout,const MCFixup * Fixup)119   bool evaluateAsRelocatableImpl(MCValue &Res,
120                                  const MCAsmLayout *Layout,
121                                  const MCFixup *Fixup) const override {
122     return false;
123   }
visitUsedExpr(MCStreamer & Streamer)124   void visitUsedExpr(MCStreamer &Streamer) const override {};
findAssociatedFragment()125   MCFragment *findAssociatedFragment() const override { return nullptr; }
126 
127   // There are no TLS NVPTXMCExprs at the moment.
fixELFSymbolsInTLSFixups(MCAssembler & Asm)128   void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
129 
classof(const MCExpr * E)130   static bool classof(const MCExpr *E) {
131     return E->getKind() == MCExpr::Target;
132   }
133   };
134 } // end namespace llvm
135 
136 #endif
137