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 #include "llvm/MC/MCObjectStreamer.h" 15 16 using namespace llvm; 17 18 #define DEBUG_TYPE "mipsmcexpr" 19 20 bool MipsMCExpr::isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK, 21 const MCBinaryExpr *BE) { 22 switch (VK) { 23 case MCSymbolRefExpr::VK_Mips_ABS_LO: 24 case MCSymbolRefExpr::VK_Mips_ABS_HI: 25 case MCSymbolRefExpr::VK_Mips_HIGHER: 26 case MCSymbolRefExpr::VK_Mips_HIGHEST: 27 break; 28 default: 29 return false; 30 } 31 32 // We support expressions of the form "(sym1 binop1 sym2) binop2 const", 33 // where "binop2 const" is optional. 34 if (isa<MCBinaryExpr>(BE->getLHS())) { 35 if (!isa<MCConstantExpr>(BE->getRHS())) 36 return false; 37 BE = cast<MCBinaryExpr>(BE->getLHS()); 38 } 39 return (isa<MCSymbolRefExpr>(BE->getLHS()) 40 && isa<MCSymbolRefExpr>(BE->getRHS())); 41 } 42 43 const MipsMCExpr* 44 MipsMCExpr::create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr, 45 MCContext &Ctx) { 46 VariantKind Kind; 47 switch (VK) { 48 case MCSymbolRefExpr::VK_Mips_ABS_LO: 49 Kind = VK_Mips_LO; 50 break; 51 case MCSymbolRefExpr::VK_Mips_ABS_HI: 52 Kind = VK_Mips_HI; 53 break; 54 case MCSymbolRefExpr::VK_Mips_HIGHER: 55 Kind = VK_Mips_HIGHER; 56 break; 57 case MCSymbolRefExpr::VK_Mips_HIGHEST: 58 Kind = VK_Mips_HIGHEST; 59 break; 60 default: 61 llvm_unreachable("Invalid kind!"); 62 } 63 64 return new (Ctx) MipsMCExpr(Kind, Expr); 65 } 66 67 void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { 68 switch (Kind) { 69 default: llvm_unreachable("Invalid kind!"); 70 case VK_Mips_LO: OS << "%lo"; break; 71 case VK_Mips_HI: OS << "%hi"; break; 72 case VK_Mips_HIGHER: OS << "%higher"; break; 73 case VK_Mips_HIGHEST: OS << "%highest"; break; 74 } 75 76 OS << '('; 77 Expr->print(OS, MAI); 78 OS << ')'; 79 } 80 81 bool 82 MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res, 83 const MCAsmLayout *Layout, 84 const MCFixup *Fixup) const { 85 return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup); 86 } 87 88 void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 89 Streamer.visitUsedExpr(*getSubExpr()); 90 } 91