1//===- AMDGPUMCExpr.h - AMDGPU 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#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
10#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
11
12#include "llvm/ADT/ArrayRef.h"
13#include "llvm/MC/MCExpr.h"
14
15namespace llvm {
16
17class Function;
18class GCNSubtarget;
19
20enum class LitModifier { None, Lit, Lit64 };
21
22/// AMDGPU target specific MCExpr operations.
23///
24/// Takes in a minimum of 1 argument to be used with an operation. The supported
25/// operations are:
26/// - (bitwise) or
27/// - max
28///
29/// \note If the 'or'/'max' operations are provided only a single argument, the
30/// operation will act as a no-op and simply resolve as the provided argument.
31///
32class AMDGPUMCExpr : public MCTargetExpr {
33public:
34 enum VariantKind {
35 AGVK_None,
36 AGVK_Or,
37 AGVK_Max,
38 AGVK_ExtraSGPRs,
39 AGVK_TotalNumVGPRs,
40 AGVK_AlignTo,
41 AGVK_Occupancy,
42 AGVK_Lit,
43 AGVK_Lit64,
44 };
45
46 // Relocation specifiers.
47 enum Specifier {
48 S_None,
49 S_GOTPCREL, // symbol@gotpcrel
50 S_GOTPCREL32_LO, // symbol@gotpcrel32@lo
51 S_GOTPCREL32_HI, // symbol@gotpcrel32@hi
52 S_REL32_LO, // symbol@rel32@lo
53 S_REL32_HI, // symbol@rel32@hi
54 S_REL64, // symbol@rel64
55 S_ABS32_LO, // symbol@abs32@lo
56 S_ABS32_HI, // symbol@abs32@hi
57 S_ABS64, // symbol@abs64
58 };
59
60private:
61 VariantKind Kind;
62 MCContext &Ctx;
63 const MCExpr **RawArgs;
64 ArrayRef<const MCExpr *> Args;
65
66 AMDGPUMCExpr(VariantKind Kind, ArrayRef<const MCExpr *> Args, MCContext &Ctx);
67 ~AMDGPUMCExpr() override;
68
69 bool evaluateExtraSGPRs(MCValue &Res, const MCAssembler *Asm) const;
70 bool evaluateTotalNumVGPR(MCValue &Res, const MCAssembler *Asm) const;
71 bool evaluateAlignTo(MCValue &Res, const MCAssembler *Asm) const;
72 bool evaluateOccupancy(MCValue &Res, const MCAssembler *Asm) const;
73
74public:
75 static const AMDGPUMCExpr *
76 create(VariantKind Kind, ArrayRef<const MCExpr *> Args, MCContext &Ctx);
77
78 static const AMDGPUMCExpr *createOr(ArrayRef<const MCExpr *> Args,
79 MCContext &Ctx) {
80 return create(Kind: VariantKind::AGVK_Or, Args, Ctx);
81 }
82
83 static const AMDGPUMCExpr *createMax(ArrayRef<const MCExpr *> Args,
84 MCContext &Ctx) {
85 return create(Kind: VariantKind::AGVK_Max, Args, Ctx);
86 }
87
88 static const AMDGPUMCExpr *createExtraSGPRs(const MCExpr *VCCUsed,
89 const MCExpr *FlatScrUsed,
90 bool XNACKUsed, MCContext &Ctx);
91
92 static const AMDGPUMCExpr *createTotalNumVGPR(const MCExpr *NumAGPR,
93 const MCExpr *NumVGPR,
94 MCContext &Ctx);
95
96 static const AMDGPUMCExpr *
97 createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx) {
98 return create(Kind: VariantKind::AGVK_AlignTo, Args: {Value, Align}, Ctx);
99 }
100
101 static const AMDGPUMCExpr *createLit(LitModifier Lit, int64_t Value,
102 MCContext &Ctx);
103
104 ArrayRef<const MCExpr *> getArgs() const { return Args; }
105 VariantKind getKind() const { return Kind; }
106 const MCExpr *getSubExpr(size_t Index) const;
107
108 void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
109 bool evaluateAsRelocatableImpl(MCValue &Res,
110 const MCAssembler *Asm) const override;
111 void visitUsedExpr(MCStreamer &Streamer) const override;
112 MCFragment *findAssociatedFragment() const override;
113
114 static bool classof(const MCExpr *E) {
115 return E->getKind() == MCExpr::Target;
116 }
117 static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *E);
118};
119
120namespace AMDGPU {
121// Tries to leverage KnownBits for MCExprs to reduce and limit any composed
122// MCExprs printing. E.g., for an expression such as
123// ((unevaluatable_sym | 1) & 1) won't evaluate due to unevaluatable_sym and
124// would verbosely print the full expression; however, KnownBits should deduce
125// the value to be 1. Particularly useful for AMDGPU metadata MCExprs.
126void printAMDGPUMCExpr(const MCExpr *Expr, raw_ostream &OS,
127 const MCAsmInfo *MAI);
128
129const MCExpr *foldAMDGPUMCExpr(const MCExpr *Expr, MCContext &Ctx);
130
131static inline AMDGPUMCExpr::Specifier getSpecifier(const MCSymbolRefExpr *SRE) {
132 return AMDGPUMCExpr::Specifier(SRE->getKind());
133}
134
135LLVM_READONLY bool isLitExpr(const MCExpr *Expr);
136
137LLVM_READONLY int64_t getLitValue(const MCExpr *Expr);
138
139} // end namespace AMDGPU
140} // end namespace llvm
141
142#endif // LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
143