[C++11] Add 'override' keywords and remove 'virtual'. Additionally add 'final' and...
[oota-llvm.git] / lib / Target / Mips / MCTargetDesc / MipsMCExpr.cpp
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 }