MipsMCExpr.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis//===-- MipsMCExpr.cpp - Mips specific MC expression classes --------------===// 2c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis// 3c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 4c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis// 5c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 6c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 7c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis// 8c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 9c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis 10c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis#define DEBUG_TYPE "mipsmcexpr" 11c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis#include "MipsMCExpr.h" 12c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis#include "llvm/MC/MCAsmInfo.h" 13c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis#include "llvm/MC/MCAssembler.h" 14c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis#include "llvm/MC/MCContext.h" 15c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis 16c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidisusing namespace llvm; 17674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak 18674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszakbool MipsMCExpr::isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK, 19c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis const MCBinaryExpr *BE) { 201f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer switch (VK) { 210c8ae782cb966068f8317f8225633e2f4720ccb7Douglas Gregor case MCSymbolRefExpr::VK_Mips_ABS_LO: 22c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis case MCSymbolRefExpr::VK_Mips_ABS_HI: 23c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis case MCSymbolRefExpr::VK_Mips_HIGHER: 24c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis case MCSymbolRefExpr::VK_Mips_HIGHEST: 25c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis break; 26c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis default: 27c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis return false; 28c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis } 29c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // We support expressions of the form "(sym1 binop1 sym2) binop2 const", 31c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis // where "binop2 const" is optional. 32c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis if (isa<MCBinaryExpr>(BE->getLHS())) { 33c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis if (!isa<MCConstantExpr>(BE->getRHS())) 34c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis return false; 35c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis BE = cast<MCBinaryExpr>(BE->getLHS()); 36c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis } 37c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis return (isa<MCSymbolRefExpr>(BE->getLHS()) 38c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis && isa<MCSymbolRefExpr>(BE->getRHS())); 39c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis} 40c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis 41c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidisconst MipsMCExpr* 42c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios KyrtzidisMipsMCExpr::Create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr, 43c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis MCContext &Ctx) { 44c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis VariantKind Kind; 45c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis switch (VK) { 46c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis case MCSymbolRefExpr::VK_Mips_ABS_LO: 47c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis Kind = VK_Mips_LO; 48c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis break; 49c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis case MCSymbolRefExpr::VK_Mips_ABS_HI: 50c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis Kind = VK_Mips_HI; 51c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis break; 52c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis case MCSymbolRefExpr::VK_Mips_HIGHER: 53c1a45f60c7aaf21e4a5adebf0fc9700f62d08ee6Argyrios Kyrtzidis Kind = VK_Mips_HIGHER; 54 break; 55 case MCSymbolRefExpr::VK_Mips_HIGHEST: 56 Kind = VK_Mips_HIGHEST; 57 break; 58 default: 59 llvm_unreachable("Invalid kind!"); 60 } 61 62 return new (Ctx) MipsMCExpr(Kind, Expr); 63} 64 65void MipsMCExpr::PrintImpl(raw_ostream &OS) const { 66 switch (Kind) { 67 default: llvm_unreachable("Invalid kind!"); 68 case VK_Mips_LO: OS << "%lo"; break; 69 case VK_Mips_HI: OS << "%hi"; break; 70 case VK_Mips_HIGHER: OS << "%higher"; break; 71 case VK_Mips_HIGHEST: OS << "%highest"; break; 72 } 73 74 OS << '('; 75 Expr->print(OS); 76 OS << ')'; 77} 78 79bool 80MipsMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 81 const MCAsmLayout *Layout) const { 82 return getSubExpr()->EvaluateAsRelocatable(Res, Layout); 83} 84 85// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps 86// that method should be made public? 87static void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) { 88 switch (Value->getKind()) { 89 case MCExpr::Target: 90 llvm_unreachable("Can't handle nested target expr!"); 91 92 case MCExpr::Constant: 93 break; 94 95 case MCExpr::Binary: { 96 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 97 AddValueSymbolsImpl(BE->getLHS(), Asm); 98 AddValueSymbolsImpl(BE->getRHS(), Asm); 99 break; 100 } 101 102 case MCExpr::SymbolRef: 103 Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 104 break; 105 106 case MCExpr::Unary: 107 AddValueSymbolsImpl(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm); 108 break; 109 } 110} 111 112void MipsMCExpr::AddValueSymbols(MCAssembler *Asm) const { 113 AddValueSymbolsImpl(getSubExpr(), Asm); 114} 115