1 //===-- MipsMCExpr.cpp - Mips 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 "MipsMCExpr.h" 11 #include "llvm/MC/MCAsmInfo.h" 12 #include "llvm/MC/MCAssembler.h" 13 #include "llvm/MC/MCContext.h" 14 15 using namespace llvm; 16 17 #define DEBUG_TYPE "mipsmcexpr" 18 19 bool MipsMCExpr::isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK, 20 const MCBinaryExpr *BE) { 21 switch (VK) { 22 case MCSymbolRefExpr::VK_Mips_ABS_LO: 23 case MCSymbolRefExpr::VK_Mips_ABS_HI: 24 case MCSymbolRefExpr::VK_Mips_HIGHER: 25 case MCSymbolRefExpr::VK_Mips_HIGHEST: 26 break; 27 default: 28 return false; 29 } 30 31 // We support expressions of the form "(sym1 binop1 sym2) binop2 const", 32 // where "binop2 const" is optional. 33 if (isa<MCBinaryExpr>(BE->getLHS())) { 34 if (!isa<MCConstantExpr>(BE->getRHS())) 35 return false; 36 BE = cast<MCBinaryExpr>(BE->getLHS()); 37 } 38 return (isa<MCSymbolRefExpr>(BE->getLHS()) 39 && isa<MCSymbolRefExpr>(BE->getRHS())); 40 } 41 42 const MipsMCExpr* 43 MipsMCExpr::Create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr, 44 MCContext &Ctx) { 45 VariantKind Kind; 46 switch (VK) { 47 case MCSymbolRefExpr::VK_Mips_ABS_LO: 48 Kind = VK_Mips_LO; 49 break; 50 case MCSymbolRefExpr::VK_Mips_ABS_HI: 51 Kind = VK_Mips_HI; 52 break; 53 case MCSymbolRefExpr::VK_Mips_HIGHER: 54 Kind = VK_Mips_HIGHER; 55 break; 56 case MCSymbolRefExpr::VK_Mips_HIGHEST: 57 Kind = VK_Mips_HIGHEST; 58 break; 59 default: 60 llvm_unreachable("Invalid kind!"); 61 } 62 63 return new (Ctx) MipsMCExpr(Kind, Expr); 64 } 65 66 void MipsMCExpr::PrintImpl(raw_ostream &OS) const { 67 switch (Kind) { 68 default: llvm_unreachable("Invalid kind!"); 69 case VK_Mips_LO: OS << "%lo"; break; 70 case VK_Mips_HI: OS << "%hi"; break; 71 case VK_Mips_HIGHER: OS << "%higher"; break; 72 case VK_Mips_HIGHEST: OS << "%highest"; break; 73 } 74 75 OS << '('; 76 Expr->print(OS); 77 OS << ')'; 78 } 79 80 bool 81 MipsMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 82 const MCAsmLayout *Layout) const { 83 return getSubExpr()->EvaluateAsRelocatable(Res, Layout); 84 } 85 86 // FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps 87 // that method should be made public? 88 static void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) { 89 switch (Value->getKind()) { 90 case MCExpr::Target: 91 llvm_unreachable("Can't handle nested target expr!"); 92 93 case MCExpr::Constant: 94 break; 95 96 case MCExpr::Binary: { 97 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 98 AddValueSymbolsImpl(BE->getLHS(), Asm); 99 AddValueSymbolsImpl(BE->getRHS(), Asm); 100 break; 101 } 102 103 case MCExpr::SymbolRef: 104 Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 105 break; 106 107 case MCExpr::Unary: 108 AddValueSymbolsImpl(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm); 109 break; 110 } 111 } 112 113 void MipsMCExpr::AddValueSymbols(MCAssembler *Asm) const { 114 AddValueSymbolsImpl(getSubExpr(), Asm); 115 } 116