172062f5744557e270a38192554c3126ea5f97434Tim Northover//===-- AArch64MCExpr.cpp - AArch64 specific MC expression classes --------===//
272062f5744557e270a38192554c3126ea5f97434Tim Northover//
372062f5744557e270a38192554c3126ea5f97434Tim Northover//                     The LLVM Compiler Infrastructure
472062f5744557e270a38192554c3126ea5f97434Tim Northover//
572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source
672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details.
772062f5744557e270a38192554c3126ea5f97434Tim Northover//
872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
95bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//
105bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// This file contains the implementation of the assembly expression modifiers
115bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// accepted by the AArch64 architecture (e.g. ":lo12:", ":gottprel_g1:", ...).
125bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//
135bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//===----------------------------------------------------------------------===//
1472062f5744557e270a38192554c3126ea5f97434Tim Northover
1572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64MCExpr.h"
1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCAssembler.h"
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCContext.h"
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCELF.h"
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCSymbol.h"
20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCValue.h"
2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Object/ELF.h"
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/ErrorHandling.h"
2372062f5744557e270a38192554c3126ea5f97434Tim Northover
2472062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
2572062f5744557e270a38192554c3126ea5f97434Tim Northover
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "aarch64symbolrefexpr"
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesconst AArch64MCExpr *AArch64MCExpr::Create(const MCExpr *Expr, VariantKind Kind,
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       MCContext &Ctx) {
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return new (Ctx) AArch64MCExpr(Expr, Kind);
31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesStringRef AArch64MCExpr::getVariantKindName() const {
34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (static_cast<uint32_t>(getKind())) {
35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_CALL:                return "";
36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_LO12:                return ":lo12:";
37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G3:              return ":abs_g3:";
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G2:              return ":abs_g2:";
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G2_S:            return ":abs_g2_s:";
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G2_NC:           return ":abs_g2_nc:";
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G1:              return ":abs_g1:";
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G1_S:            return ":abs_g1_s:";
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G1_NC:           return ":abs_g1_nc:";
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G0:              return ":abs_g0:";
45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G0_S:            return ":abs_g0_s:";
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_G0_NC:           return ":abs_g0_nc:";
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL_G2:           return ":dtprel_g2:";
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL_G1:           return ":dtprel_g1:";
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL_G1_NC:        return ":dtprel_g1_nc:";
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL_G0:           return ":dtprel_g0:";
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL_G0_NC:        return ":dtprel_g0_nc:";
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL_HI12:         return ":dtprel_hi12:";
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL_LO12:         return ":dtprel_lo12:";
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL_LO12_NC:      return ":dtprel_lo12_nc:";
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL_G2:            return ":tprel_g2:";
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL_G1:            return ":tprel_g1:";
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL_G1_NC:         return ":tprel_g1_nc:";
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL_G0:            return ":tprel_g0:";
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL_G0_NC:         return ":tprel_g0_nc:";
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL_HI12:          return ":tprel_hi12:";
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL_LO12:          return ":tprel_lo12:";
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL_LO12_NC:       return ":tprel_lo12_nc:";
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TLSDESC_LO12:        return ":tlsdesc_lo12:";
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_ABS_PAGE:            return "";
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_GOT_PAGE:            return ":got:";
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_GOT_LO12:            return ":got_lo12:";
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_GOTTPREL_PAGE:       return ":gottprel:";
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_GOTTPREL_LO12_NC:    return ":gottprel_lo12:";
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_GOTTPREL_G1:         return ":gottprel_g1:";
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_GOTTPREL_G0_NC:      return ":gottprel_g0_nc:";
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TLSDESC:             return "";
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TLSDESC_PAGE:        return ":tlsdesc:";
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm_unreachable("Invalid ELF symbol kind");
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
7672062f5744557e270a38192554c3126ea5f97434Tim Northover}
7772062f5744557e270a38192554c3126ea5f97434Tim Northover
7872062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64MCExpr::PrintImpl(raw_ostream &OS) const {
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getKind() != VK_NONE)
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << getVariantKindName();
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OS << *Expr;
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
84cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid AArch64MCExpr::visitUsedExpr(MCStreamer &Streamer) const {
85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Streamer.visitUsedExpr(*getSubExpr());
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
8772062f5744557e270a38192554c3126ea5f97434Tim Northover
88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesconst MCSection *AArch64MCExpr::FindAssociatedSection() const {
89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  llvm_unreachable("FIXME: what goes here?");
9072062f5744557e270a38192554c3126ea5f97434Tim Northover}
9172062f5744557e270a38192554c3126ea5f97434Tim Northover
92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            const MCAsmLayout *Layout) const {
94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!getSubExpr()->EvaluateAsRelocatable(Res, Layout))
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Res =
98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
10172062f5744557e270a38192554c3126ea5f97434Tim Northover}
10272062f5744557e270a38192554c3126ea5f97434Tim Northover
10372062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
10472062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Expr->getKind()) {
10572062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Target:
10672062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm_unreachable("Can't handle nested target expression");
10772062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
10872062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Constant:
10972062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
11072062f5744557e270a38192554c3126ea5f97434Tim Northover
11172062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Binary: {
11272062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
11372062f5744557e270a38192554c3126ea5f97434Tim Northover    fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
11472062f5744557e270a38192554c3126ea5f97434Tim Northover    fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
11572062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
11672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
11772062f5744557e270a38192554c3126ea5f97434Tim Northover
11872062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::SymbolRef: {
11972062f5744557e270a38192554c3126ea5f97434Tim Northover    // We're known to be under a TLS fixup, so any symbol should be
12072062f5744557e270a38192554c3126ea5f97434Tim Northover    // modified. There should be only one.
12172062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
12272062f5744557e270a38192554c3126ea5f97434Tim Northover    MCSymbolData &SD = Asm.getOrCreateSymbolData(SymRef.getSymbol());
12372062f5744557e270a38192554c3126ea5f97434Tim Northover    MCELF::SetType(SD, ELF::STT_TLS);
12472062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
12572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
12672062f5744557e270a38192554c3126ea5f97434Tim Northover
12772062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Unary:
12872062f5744557e270a38192554c3126ea5f97434Tim Northover    fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
12972062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
13072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
13172062f5744557e270a38192554c3126ea5f97434Tim Northover}
13272062f5744557e270a38192554c3126ea5f97434Tim Northover
13372062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64MCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (getSymbolLoc(Kind)) {
13572062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
13672062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_DTPREL:
138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_GOTTPREL:
139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TPREL:
140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case VK_TLSDESC:
14172062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
14272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
14372062f5744557e270a38192554c3126ea5f97434Tim Northover
14472062f5744557e270a38192554c3126ea5f97434Tim Northover  fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
14572062f5744557e270a38192554c3126ea5f97434Tim Northover}
146