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#define DEBUG_TYPE "aarch64mcexpr"
1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64MCExpr.h"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCContext.h"
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCAssembler.h"
1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCELF.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Object/ELF.h"
2172062f5744557e270a38192554c3126ea5f97434Tim Northover
2272062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
2372062f5744557e270a38192554c3126ea5f97434Tim Northover
2472062f5744557e270a38192554c3126ea5f97434Tim Northoverconst AArch64MCExpr*
2572062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64MCExpr::Create(VariantKind Kind, const MCExpr *Expr,
2672062f5744557e270a38192554c3126ea5f97434Tim Northover                      MCContext &Ctx) {
2772062f5744557e270a38192554c3126ea5f97434Tim Northover  return new (Ctx) AArch64MCExpr(Kind, Expr);
2872062f5744557e270a38192554c3126ea5f97434Tim Northover}
2972062f5744557e270a38192554c3126ea5f97434Tim Northover
3072062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64MCExpr::PrintImpl(raw_ostream &OS) const {
3172062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Kind) {
3272062f5744557e270a38192554c3126ea5f97434Tim Northover  default: llvm_unreachable("Invalid kind!");
3372062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOT:              OS << ":got:"; break;
3472062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOT_LO12:         OS << ":got_lo12:"; break;
3572062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_LO12:             OS << ":lo12:"; break;
3672062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_ABS_G0:           OS << ":abs_g0:"; break;
3772062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_ABS_G0_NC:        OS << ":abs_g0_nc:"; break;
3872062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_ABS_G1:           OS << ":abs_g1:"; break;
3972062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_ABS_G1_NC:        OS << ":abs_g1_nc:"; break;
4072062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_ABS_G2:           OS << ":abs_g2:"; break;
4172062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_ABS_G2_NC:        OS << ":abs_g2_nc:"; break;
4272062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_ABS_G3:           OS << ":abs_g3:"; break;
4372062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_SABS_G0:          OS << ":abs_g0_s:"; break;
4472062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_SABS_G1:          OS << ":abs_g1_s:"; break;
4572062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_SABS_G2:          OS << ":abs_g2_s:"; break;
4672062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G2:        OS << ":dtprel_g2:"; break;
4772062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G1:        OS << ":dtprel_g1:"; break;
4872062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G1_NC:     OS << ":dtprel_g1_nc:"; break;
4972062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G0:        OS << ":dtprel_g0:"; break;
5072062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G0_NC:     OS << ":dtprel_g0_nc:"; break;
5172062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_HI12:      OS << ":dtprel_hi12:"; break;
5272062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_LO12:      OS << ":dtprel_lo12:"; break;
5372062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_LO12_NC:   OS << ":dtprel_lo12_nc:"; break;
5472062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOTTPREL_G1:      OS << ":gottprel_g1:"; break;
5572062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOTTPREL_G0_NC:   OS << ":gottprel_g0_nc:"; break;
5672062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOTTPREL:         OS << ":gottprel:"; break;
5772062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOTTPREL_LO12:    OS << ":gottprel_lo12:"; break;
5872062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G2:         OS << ":tprel_g2:"; break;
5972062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G1:         OS << ":tprel_g1:"; break;
6072062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G1_NC:      OS << ":tprel_g1_nc:"; break;
6172062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G0:         OS << ":tprel_g0:"; break;
6272062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G0_NC:      OS << ":tprel_g0_nc:"; break;
6372062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_HI12:       OS << ":tprel_hi12:"; break;
6472062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_LO12:       OS << ":tprel_lo12:"; break;
6572062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_LO12_NC:    OS << ":tprel_lo12_nc:"; break;
6672062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TLSDESC:          OS << ":tlsdesc:"; break;
6772062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TLSDESC_LO12:     OS << ":tlsdesc_lo12:"; break;
6872062f5744557e270a38192554c3126ea5f97434Tim Northover
6972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
7072062f5744557e270a38192554c3126ea5f97434Tim Northover
7172062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCExpr *Expr = getSubExpr();
7272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Expr->getKind() != MCExpr::SymbolRef)
7372062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << '(';
7472062f5744557e270a38192554c3126ea5f97434Tim Northover  Expr->print(OS);
7572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Expr->getKind() != MCExpr::SymbolRef)
7672062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << ')';
7772062f5744557e270a38192554c3126ea5f97434Tim Northover}
7872062f5744557e270a38192554c3126ea5f97434Tim Northover
7972062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
8072062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
8172062f5744557e270a38192554c3126ea5f97434Tim Northover                                         const MCAsmLayout *Layout) const {
8272062f5744557e270a38192554c3126ea5f97434Tim Northover  return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
8372062f5744557e270a38192554c3126ea5f97434Tim Northover}
8472062f5744557e270a38192554c3126ea5f97434Tim Northover
8572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
8672062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Expr->getKind()) {
8772062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Target:
8872062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm_unreachable("Can't handle nested target expression");
8972062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
9072062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Constant:
9172062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
9272062f5744557e270a38192554c3126ea5f97434Tim Northover
9372062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Binary: {
9472062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
9572062f5744557e270a38192554c3126ea5f97434Tim Northover    fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
9672062f5744557e270a38192554c3126ea5f97434Tim Northover    fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
9772062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
9872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
9972062f5744557e270a38192554c3126ea5f97434Tim Northover
10072062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::SymbolRef: {
10172062f5744557e270a38192554c3126ea5f97434Tim Northover    // We're known to be under a TLS fixup, so any symbol should be
10272062f5744557e270a38192554c3126ea5f97434Tim Northover    // modified. There should be only one.
10372062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
10472062f5744557e270a38192554c3126ea5f97434Tim Northover    MCSymbolData &SD = Asm.getOrCreateSymbolData(SymRef.getSymbol());
10572062f5744557e270a38192554c3126ea5f97434Tim Northover    MCELF::SetType(SD, ELF::STT_TLS);
10672062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
10772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
10872062f5744557e270a38192554c3126ea5f97434Tim Northover
10972062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Unary:
11072062f5744557e270a38192554c3126ea5f97434Tim Northover    fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
11172062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
11272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
11372062f5744557e270a38192554c3126ea5f97434Tim Northover}
11472062f5744557e270a38192554c3126ea5f97434Tim Northover
11572062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64MCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
11672062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (getKind()) {
11772062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
11872062f5744557e270a38192554c3126ea5f97434Tim Northover    return;
11972062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G2:
12072062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G1:
12172062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G1_NC:
12272062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G0:
12372062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_G0_NC:
12472062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_HI12:
12572062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_LO12:
12672062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_DTPREL_LO12_NC:
12772062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOTTPREL_G1:
12872062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOTTPREL_G0_NC:
12972062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOTTPREL:
13072062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_GOTTPREL_LO12:
13172062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G2:
13272062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G1:
13372062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G1_NC:
13472062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G0:
13572062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_G0_NC:
13672062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_HI12:
13772062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_LO12:
13872062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TPREL_LO12_NC:
13972062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TLSDESC:
14072062f5744557e270a38192554c3126ea5f97434Tim Northover  case VK_AARCH64_TLSDESC_LO12:
14172062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
14272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
14372062f5744557e270a38192554c3126ea5f97434Tim Northover
14472062f5744557e270a38192554c3126ea5f97434Tim Northover  fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
14572062f5744557e270a38192554c3126ea5f97434Tim Northover}
14672062f5744557e270a38192554c3126ea5f97434Tim Northover
14772062f5744557e270a38192554c3126ea5f97434Tim Northover// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps
14872062f5744557e270a38192554c3126ea5f97434Tim Northover// that method should be made public?
14972062f5744557e270a38192554c3126ea5f97434Tim Northover// FIXME: really do above: now that two backends are using it.
15072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) {
15172062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Value->getKind()) {
15272062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Target:
15372062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm_unreachable("Can't handle nested target expr!");
15472062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
15572062f5744557e270a38192554c3126ea5f97434Tim Northover
15672062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Constant:
15772062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
15872062f5744557e270a38192554c3126ea5f97434Tim Northover
15972062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Binary: {
16072062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
16172062f5744557e270a38192554c3126ea5f97434Tim Northover    AddValueSymbolsImpl(BE->getLHS(), Asm);
16272062f5744557e270a38192554c3126ea5f97434Tim Northover    AddValueSymbolsImpl(BE->getRHS(), Asm);
16372062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
16472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
16572062f5744557e270a38192554c3126ea5f97434Tim Northover
16672062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::SymbolRef:
16772062f5744557e270a38192554c3126ea5f97434Tim Northover    Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
16872062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
16972062f5744557e270a38192554c3126ea5f97434Tim Northover
17072062f5744557e270a38192554c3126ea5f97434Tim Northover  case MCExpr::Unary:
17172062f5744557e270a38192554c3126ea5f97434Tim Northover    AddValueSymbolsImpl(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm);
17272062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
17372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
17472062f5744557e270a38192554c3126ea5f97434Tim Northover}
17572062f5744557e270a38192554c3126ea5f97434Tim Northover
17672062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64MCExpr::AddValueSymbols(MCAssembler *Asm) const {
17772062f5744557e270a38192554c3126ea5f97434Tim Northover  AddValueSymbolsImpl(getSubExpr(), Asm);
17872062f5744557e270a38192554c3126ea5f97434Tim Northover}
179