1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
//===- AMDGPUMCExpr.cpp - AMDGPU specific MC expression classes -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "AMDGPUMCExpr.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
using namespace llvm;
const AMDGPUVariadicMCExpr *
AMDGPUVariadicMCExpr::create(VariadicKind Kind, ArrayRef<const MCExpr *> Args,
MCContext &Ctx) {
return new (Ctx) AMDGPUVariadicMCExpr(Kind, Args);
}
const MCExpr *AMDGPUVariadicMCExpr::getSubExpr(size_t Index) const {
assert(Index < Args.size() &&
"Indexing out of bounds AMDGPUVariadicMCExpr sub-expr");
return Args[Index];
}
void AMDGPUVariadicMCExpr::printImpl(raw_ostream &OS,
const MCAsmInfo *MAI) const {
switch (Kind) {
default:
llvm_unreachable("Unknown AMDGPUVariadicMCExpr kind.");
case AGVK_Or:
OS << "or(";
break;
case AGVK_Max:
OS << "max(";
break;
}
for (auto It = Args.begin(); It != Args.end(); ++It) {
(*It)->print(OS, MAI, /*InParens=*/false);
if ((It + 1) != Args.end())
OS << ", ";
}
OS << ')';
}
static int64_t op(AMDGPUVariadicMCExpr::VariadicKind Kind, int64_t Arg1,
int64_t Arg2) {
switch (Kind) {
default:
llvm_unreachable("Unknown AMDGPUVariadicMCExpr kind.");
case AMDGPUVariadicMCExpr::AGVK_Max:
return std::max(Arg1, Arg2);
case AMDGPUVariadicMCExpr::AGVK_Or:
return Arg1 | Arg2;
}
}
bool AMDGPUVariadicMCExpr::evaluateAsRelocatableImpl(
MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const {
std::optional<int64_t> Total;
for (const MCExpr *Arg : Args) {
MCValue ArgRes;
if (!Arg->evaluateAsRelocatable(ArgRes, Layout, Fixup) ||
!ArgRes.isAbsolute())
return false;
if (!Total.has_value())
Total = ArgRes.getConstant();
Total = op(Kind, *Total, ArgRes.getConstant());
}
Res = MCValue::get(*Total);
return true;
}
void AMDGPUVariadicMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
for (const MCExpr *Arg : Args)
Streamer.visitUsedExpr(*Arg);
}
MCFragment *AMDGPUVariadicMCExpr::findAssociatedFragment() const {
for (const MCExpr *Arg : Args) {
if (Arg->findAssociatedFragment())
return Arg->findAssociatedFragment();
}
return nullptr;
}
|