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 16using namespace llvm; 17 18#define DEBUG_TYPE "mipsmcexpr" 19 20bool 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 43const MipsMCExpr* 44MipsMCExpr::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 67void MipsMCExpr::PrintImpl(raw_ostream &OS) 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); 78 OS << ')'; 79} 80 81bool 82MipsMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 83 const MCAsmLayout *Layout, 84 const MCFixup *Fixup) const { 85 return getSubExpr()->EvaluateAsRelocatable(Res, Layout, Fixup); 86} 87 88void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 89 Streamer.visitUsedExpr(*getSubExpr()); 90} 91