LLVM API Documentation

PPCMCExpr.cpp
Go to the documentation of this file.
00001 //===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "PPCFixupKinds.h"
00011 #include "PPCMCExpr.h"
00012 #include "llvm/MC/MCAsmInfo.h"
00013 #include "llvm/MC/MCAssembler.h"
00014 #include "llvm/MC/MCContext.h"
00015 #include "llvm/MC/MCObjectStreamer.h"
00016 
00017 using namespace llvm;
00018 
00019 #define DEBUG_TYPE "ppcmcexpr"
00020 
00021 const PPCMCExpr*
00022 PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
00023                   bool isDarwin, MCContext &Ctx) {
00024   return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin);
00025 }
00026 
00027 void PPCMCExpr::PrintImpl(raw_ostream &OS) const {
00028   if (isDarwinSyntax()) {
00029     switch (Kind) {
00030     default: llvm_unreachable("Invalid kind!");
00031     case VK_PPC_LO: OS << "lo16"; break;
00032     case VK_PPC_HI: OS << "hi16"; break;
00033     case VK_PPC_HA: OS << "ha16"; break;
00034     }
00035 
00036     OS << '(';
00037     getSubExpr()->print(OS);
00038     OS << ')';
00039   } else {
00040     getSubExpr()->print(OS);
00041 
00042     switch (Kind) {
00043     default: llvm_unreachable("Invalid kind!");
00044     case VK_PPC_LO: OS << "@l"; break;
00045     case VK_PPC_HI: OS << "@h"; break;
00046     case VK_PPC_HA: OS << "@ha"; break;
00047     case VK_PPC_HIGHER: OS << "@higher"; break;
00048     case VK_PPC_HIGHERA: OS << "@highera"; break;
00049     case VK_PPC_HIGHEST: OS << "@highest"; break;
00050     case VK_PPC_HIGHESTA: OS << "@highesta"; break;
00051     }
00052   }
00053 }
00054 
00055 bool
00056 PPCMCExpr::EvaluateAsConstant(int64_t &Res) const {
00057   MCValue Value;
00058 
00059   if (!getSubExpr()->EvaluateAsRelocatable(Value, nullptr, nullptr))
00060     return false;
00061 
00062   if (!Value.isAbsolute())
00063     return false;
00064 
00065   Res = EvaluateAsInt64(Value.getConstant());
00066   return true;
00067 }
00068 
00069 int64_t
00070 PPCMCExpr::EvaluateAsInt64(int64_t Value) const {
00071   switch (Kind) {
00072     case VK_PPC_LO:
00073       return Value & 0xffff;
00074     case VK_PPC_HI:
00075       return (Value >> 16) & 0xffff;
00076     case VK_PPC_HA:
00077       return ((Value + 0x8000) >> 16) & 0xffff;
00078     case VK_PPC_HIGHER:
00079       return (Value >> 32) & 0xffff;
00080     case VK_PPC_HIGHERA:
00081       return ((Value + 0x8000) >> 32) & 0xffff;
00082     case VK_PPC_HIGHEST:
00083       return (Value >> 48) & 0xffff;
00084     case VK_PPC_HIGHESTA:
00085       return ((Value + 0x8000) >> 48) & 0xffff;
00086     case VK_PPC_None:
00087       break;
00088   }
00089   llvm_unreachable("Invalid kind!");
00090 }
00091 
00092 bool
00093 PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
00094                                      const MCAsmLayout *Layout,
00095                                      const MCFixup *Fixup) const {
00096   MCValue Value;
00097 
00098   if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout, Fixup))
00099     return false;
00100 
00101   if (Value.isAbsolute()) {
00102     int64_t Result = EvaluateAsInt64(Value.getConstant());
00103     if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) &&
00104         (Result >= 0x8000))
00105       return false;
00106     Res = MCValue::get(Result);
00107   } else {
00108     if (!Layout)
00109       return false;
00110 
00111     MCContext &Context = Layout->getAssembler().getContext();
00112     const MCSymbolRefExpr *Sym = Value.getSymA();
00113     MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
00114     if (Modifier != MCSymbolRefExpr::VK_None)
00115       return false;
00116     switch (Kind) {
00117       default:
00118         llvm_unreachable("Invalid kind!");
00119       case VK_PPC_LO:
00120         Modifier = MCSymbolRefExpr::VK_PPC_LO;
00121         break;
00122       case VK_PPC_HI:
00123         Modifier = MCSymbolRefExpr::VK_PPC_HI;
00124         break;
00125       case VK_PPC_HA:
00126         Modifier = MCSymbolRefExpr::VK_PPC_HA;
00127         break;
00128       case VK_PPC_HIGHERA:
00129         Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
00130         break;
00131       case VK_PPC_HIGHER:
00132         Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
00133         break;
00134       case VK_PPC_HIGHEST:
00135         Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
00136         break;
00137       case VK_PPC_HIGHESTA:
00138         Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
00139         break;
00140     }
00141     Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context);
00142     Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
00143   }
00144 
00145   return true;
00146 }
00147 
00148 void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
00149   Streamer.visitUsedExpr(*getSubExpr());
00150 }