aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
new file mode 100644
index 0000000..0659937
--- /dev/null
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
@@ -0,0 +1,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;
+}