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