Home | History | Annotate | Download | only in MCTargetDesc
      1 //===-- AArch64MCExpr.cpp - AArch64 specific MC expression classes --------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the implementation of the assembly expression modifiers
     11 // accepted by the AArch64 architecture (e.g. ":lo12:", ":gottprel_g1:", ...).
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #define DEBUG_TYPE "aarch64mcexpr"
     16 #include "AArch64MCExpr.h"
     17 #include "llvm/MC/MCContext.h"
     18 #include "llvm/MC/MCAssembler.h"
     19 #include "llvm/MC/MCELF.h"
     20 #include "llvm/Object/ELF.h"
     21 
     22 using namespace llvm;
     23 
     24 const AArch64MCExpr*
     25 AArch64MCExpr::Create(VariantKind Kind, const MCExpr *Expr,
     26                       MCContext &Ctx) {
     27   return new (Ctx) AArch64MCExpr(Kind, Expr);
     28 }
     29 
     30 void AArch64MCExpr::PrintImpl(raw_ostream &OS) const {
     31   switch (Kind) {
     32   default: llvm_unreachable("Invalid kind!");
     33   case VK_AARCH64_GOT:              OS << ":got:"; break;
     34   case VK_AARCH64_GOT_LO12:         OS << ":got_lo12:"; break;
     35   case VK_AARCH64_LO12:             OS << ":lo12:"; break;
     36   case VK_AARCH64_ABS_G0:           OS << ":abs_g0:"; break;
     37   case VK_AARCH64_ABS_G0_NC:        OS << ":abs_g0_nc:"; break;
     38   case VK_AARCH64_ABS_G1:           OS << ":abs_g1:"; break;
     39   case VK_AARCH64_ABS_G1_NC:        OS << ":abs_g1_nc:"; break;
     40   case VK_AARCH64_ABS_G2:           OS << ":abs_g2:"; break;
     41   case VK_AARCH64_ABS_G2_NC:        OS << ":abs_g2_nc:"; break;
     42   case VK_AARCH64_ABS_G3:           OS << ":abs_g3:"; break;
     43   case VK_AARCH64_SABS_G0:          OS << ":abs_g0_s:"; break;
     44   case VK_AARCH64_SABS_G1:          OS << ":abs_g1_s:"; break;
     45   case VK_AARCH64_SABS_G2:          OS << ":abs_g2_s:"; break;
     46   case VK_AARCH64_DTPREL_G2:        OS << ":dtprel_g2:"; break;
     47   case VK_AARCH64_DTPREL_G1:        OS << ":dtprel_g1:"; break;
     48   case VK_AARCH64_DTPREL_G1_NC:     OS << ":dtprel_g1_nc:"; break;
     49   case VK_AARCH64_DTPREL_G0:        OS << ":dtprel_g0:"; break;
     50   case VK_AARCH64_DTPREL_G0_NC:     OS << ":dtprel_g0_nc:"; break;
     51   case VK_AARCH64_DTPREL_HI12:      OS << ":dtprel_hi12:"; break;
     52   case VK_AARCH64_DTPREL_LO12:      OS << ":dtprel_lo12:"; break;
     53   case VK_AARCH64_DTPREL_LO12_NC:   OS << ":dtprel_lo12_nc:"; break;
     54   case VK_AARCH64_GOTTPREL_G1:      OS << ":gottprel_g1:"; break;
     55   case VK_AARCH64_GOTTPREL_G0_NC:   OS << ":gottprel_g0_nc:"; break;
     56   case VK_AARCH64_GOTTPREL:         OS << ":gottprel:"; break;
     57   case VK_AARCH64_GOTTPREL_LO12:    OS << ":gottprel_lo12:"; break;
     58   case VK_AARCH64_TPREL_G2:         OS << ":tprel_g2:"; break;
     59   case VK_AARCH64_TPREL_G1:         OS << ":tprel_g1:"; break;
     60   case VK_AARCH64_TPREL_G1_NC:      OS << ":tprel_g1_nc:"; break;
     61   case VK_AARCH64_TPREL_G0:         OS << ":tprel_g0:"; break;
     62   case VK_AARCH64_TPREL_G0_NC:      OS << ":tprel_g0_nc:"; break;
     63   case VK_AARCH64_TPREL_HI12:       OS << ":tprel_hi12:"; break;
     64   case VK_AARCH64_TPREL_LO12:       OS << ":tprel_lo12:"; break;
     65   case VK_AARCH64_TPREL_LO12_NC:    OS << ":tprel_lo12_nc:"; break;
     66   case VK_AARCH64_TLSDESC:          OS << ":tlsdesc:"; break;
     67   case VK_AARCH64_TLSDESC_LO12:     OS << ":tlsdesc_lo12:"; break;
     68 
     69   }
     70 
     71   const MCExpr *Expr = getSubExpr();
     72   if (Expr->getKind() != MCExpr::SymbolRef)
     73     OS << '(';
     74   Expr->print(OS);
     75   if (Expr->getKind() != MCExpr::SymbolRef)
     76     OS << ')';
     77 }
     78 
     79 bool
     80 AArch64MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
     81                                          const MCAsmLayout *Layout) const {
     82   return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
     83 }
     84 
     85 static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
     86   switch (Expr->getKind()) {
     87   case MCExpr::Target:
     88     llvm_unreachable("Can't handle nested target expression");
     89     break;
     90   case MCExpr::Constant:
     91     break;
     92 
     93   case MCExpr::Binary: {
     94     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
     95     fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
     96     fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
     97     break;
     98   }
     99 
    100   case MCExpr::SymbolRef: {
    101     // We're known to be under a TLS fixup, so any symbol should be
    102     // modified. There should be only one.
    103     const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
    104     MCSymbolData &SD = Asm.getOrCreateSymbolData(SymRef.getSymbol());
    105     MCELF::SetType(SD, ELF::STT_TLS);
    106     break;
    107   }
    108 
    109   case MCExpr::Unary:
    110     fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
    111     break;
    112   }
    113 }
    114 
    115 void AArch64MCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
    116   switch (getKind()) {
    117   default:
    118     return;
    119   case VK_AARCH64_DTPREL_G2:
    120   case VK_AARCH64_DTPREL_G1:
    121   case VK_AARCH64_DTPREL_G1_NC:
    122   case VK_AARCH64_DTPREL_G0:
    123   case VK_AARCH64_DTPREL_G0_NC:
    124   case VK_AARCH64_DTPREL_HI12:
    125   case VK_AARCH64_DTPREL_LO12:
    126   case VK_AARCH64_DTPREL_LO12_NC:
    127   case VK_AARCH64_GOTTPREL_G1:
    128   case VK_AARCH64_GOTTPREL_G0_NC:
    129   case VK_AARCH64_GOTTPREL:
    130   case VK_AARCH64_GOTTPREL_LO12:
    131   case VK_AARCH64_TPREL_G2:
    132   case VK_AARCH64_TPREL_G1:
    133   case VK_AARCH64_TPREL_G1_NC:
    134   case VK_AARCH64_TPREL_G0:
    135   case VK_AARCH64_TPREL_G0_NC:
    136   case VK_AARCH64_TPREL_HI12:
    137   case VK_AARCH64_TPREL_LO12:
    138   case VK_AARCH64_TPREL_LO12_NC:
    139   case VK_AARCH64_TLSDESC:
    140   case VK_AARCH64_TLSDESC_LO12:
    141     break;
    142   }
    143 
    144   fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
    145 }
    146 
    147 // FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps
    148 // that method should be made public?
    149 // FIXME: really do above: now that two backends are using it.
    150 static void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) {
    151   switch (Value->getKind()) {
    152   case MCExpr::Target:
    153     llvm_unreachable("Can't handle nested target expr!");
    154     break;
    155 
    156   case MCExpr::Constant:
    157     break;
    158 
    159   case MCExpr::Binary: {
    160     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
    161     AddValueSymbolsImpl(BE->getLHS(), Asm);
    162     AddValueSymbolsImpl(BE->getRHS(), Asm);
    163     break;
    164   }
    165 
    166   case MCExpr::SymbolRef:
    167     Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
    168     break;
    169 
    170   case MCExpr::Unary:
    171     AddValueSymbolsImpl(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm);
    172     break;
    173   }
    174 }
    175 
    176 void AArch64MCExpr::AddValueSymbols(MCAssembler *Asm) const {
    177   AddValueSymbolsImpl(getSubExpr(), Asm);
    178 }
    179