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