1//===-- PPCMCExpr.cpp - PPC 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#include "PPCMCExpr.h" 11#include "llvm/MC/MCAsmInfo.h" 12#include "llvm/MC/MCAssembler.h" 13#include "llvm/MC/MCContext.h" 14#include "llvm/MC/MCObjectStreamer.h" 15 16using namespace llvm; 17 18#define DEBUG_TYPE "ppcmcexpr" 19 20const PPCMCExpr* 21PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr, 22 bool isDarwin, MCContext &Ctx) { 23 return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin); 24} 25 26void PPCMCExpr::PrintImpl(raw_ostream &OS) const { 27 if (isDarwinSyntax()) { 28 switch (Kind) { 29 default: llvm_unreachable("Invalid kind!"); 30 case VK_PPC_LO: OS << "lo16"; break; 31 case VK_PPC_HI: OS << "hi16"; break; 32 case VK_PPC_HA: OS << "ha16"; break; 33 } 34 35 OS << '('; 36 getSubExpr()->print(OS); 37 OS << ')'; 38 } else { 39 getSubExpr()->print(OS); 40 41 switch (Kind) { 42 default: llvm_unreachable("Invalid kind!"); 43 case VK_PPC_LO: OS << "@l"; break; 44 case VK_PPC_HI: OS << "@h"; break; 45 case VK_PPC_HA: OS << "@ha"; break; 46 case VK_PPC_HIGHER: OS << "@higher"; break; 47 case VK_PPC_HIGHERA: OS << "@highera"; break; 48 case VK_PPC_HIGHEST: OS << "@highest"; break; 49 case VK_PPC_HIGHESTA: OS << "@highesta"; break; 50 } 51 } 52} 53 54bool 55PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 56 const MCAsmLayout *Layout) const { 57 MCValue Value; 58 59 if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout)) 60 return false; 61 62 if (Value.isAbsolute()) { 63 int64_t Result = Value.getConstant(); 64 switch (Kind) { 65 default: 66 llvm_unreachable("Invalid kind!"); 67 case VK_PPC_LO: 68 Result = Result & 0xffff; 69 break; 70 case VK_PPC_HI: 71 Result = (Result >> 16) & 0xffff; 72 break; 73 case VK_PPC_HA: 74 Result = ((Result + 0x8000) >> 16) & 0xffff; 75 break; 76 case VK_PPC_HIGHER: 77 Result = (Result >> 32) & 0xffff; 78 break; 79 case VK_PPC_HIGHERA: 80 Result = ((Result + 0x8000) >> 32) & 0xffff; 81 break; 82 case VK_PPC_HIGHEST: 83 Result = (Result >> 48) & 0xffff; 84 break; 85 case VK_PPC_HIGHESTA: 86 Result = ((Result + 0x8000) >> 48) & 0xffff; 87 break; 88 } 89 Res = MCValue::get(Result); 90 } else { 91 if (!Layout) 92 return false; 93 94 MCContext &Context = Layout->getAssembler().getContext(); 95 const MCSymbolRefExpr *Sym = Value.getSymA(); 96 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind(); 97 if (Modifier != MCSymbolRefExpr::VK_None) 98 return false; 99 switch (Kind) { 100 default: 101 llvm_unreachable("Invalid kind!"); 102 case VK_PPC_LO: 103 Modifier = MCSymbolRefExpr::VK_PPC_LO; 104 break; 105 case VK_PPC_HI: 106 Modifier = MCSymbolRefExpr::VK_PPC_HI; 107 break; 108 case VK_PPC_HA: 109 Modifier = MCSymbolRefExpr::VK_PPC_HA; 110 break; 111 case VK_PPC_HIGHERA: 112 Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA; 113 break; 114 case VK_PPC_HIGHER: 115 Modifier = MCSymbolRefExpr::VK_PPC_HIGHER; 116 break; 117 case VK_PPC_HIGHEST: 118 Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST; 119 break; 120 case VK_PPC_HIGHESTA: 121 Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA; 122 break; 123 } 124 Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context); 125 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant()); 126 } 127 128 return true; 129} 130 131void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 132 Streamer.visitUsedExpr(*getSubExpr()); 133} 134