LLVM API Documentation
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 }