1edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===//
2edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand//
3edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand//                     The LLVM Compiler Infrastructure
4edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand//
5edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// This file is distributed under the University of Illinois Open Source
6edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// License. See LICENSE.TXT for details.
7edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand//
8edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand//===----------------------------------------------------------------------===//
9edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
10edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#define DEBUG_TYPE "ppcmcexpr"
11edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#include "PPCMCExpr.h"
12edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#include "llvm/MC/MCAssembler.h"
13edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#include "llvm/MC/MCContext.h"
14027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand#include "llvm/MC/MCAsmInfo.h"
15edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
16edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandusing namespace llvm;
17edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
18edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandconst PPCMCExpr*
19edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich WeigandPPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
20a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand                  bool isDarwin, MCContext &Ctx) {
21a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand  return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin);
22edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand}
23edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
24edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandvoid PPCMCExpr::PrintImpl(raw_ostream &OS) const {
25027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand  if (isDarwinSyntax()) {
26027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    switch (Kind) {
27027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    default: llvm_unreachable("Invalid kind!");
2892cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand    case VK_PPC_LO: OS << "lo16"; break;
29d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand    case VK_PPC_HI: OS << "hi16"; break;
3092cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand    case VK_PPC_HA: OS << "ha16"; break;
31027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    }
32027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand
33027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    OS << '(';
34027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    getSubExpr()->print(OS);
35027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    OS << ')';
36027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand  } else {
37027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    getSubExpr()->print(OS);
38edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
39027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    switch (Kind) {
40027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    default: llvm_unreachable("Invalid kind!");
4192cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand    case VK_PPC_LO: OS << "@l"; break;
42d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand    case VK_PPC_HI: OS << "@h"; break;
4392cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand    case VK_PPC_HA: OS << "@ha"; break;
44f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand    case VK_PPC_HIGHER: OS << "@higher"; break;
45f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand    case VK_PPC_HIGHERA: OS << "@highera"; break;
46f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand    case VK_PPC_HIGHEST: OS << "@highest"; break;
47f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand    case VK_PPC_HIGHESTA: OS << "@highesta"; break;
48027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand    }
49027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand  }
50edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand}
51edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
52edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandbool
53edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich WeigandPPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
54edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand                                     const MCAsmLayout *Layout) const {
55edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  MCValue Value;
56edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
57edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  if (!getSubExpr()->EvaluateAsRelocatable(Value, *Layout))
58edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    return false;
59edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
60edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  if (Value.isAbsolute()) {
61edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    int64_t Result = Value.getConstant();
62edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    switch (Kind) {
63edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand      default:
64edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        llvm_unreachable("Invalid kind!");
6592cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      case VK_PPC_LO:
66edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        Result = Result & 0xffff;
67edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        break;
68d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand      case VK_PPC_HI:
69d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand        Result = (Result >> 16) & 0xffff;
70d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand        break;
7192cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      case VK_PPC_HA:
72f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Result = ((Result + 0x8000) >> 16) & 0xffff;
73f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        break;
74f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand      case VK_PPC_HIGHER:
75f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Result = (Result >> 32) & 0xffff;
76f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        break;
77f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand      case VK_PPC_HIGHERA:
78f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Result = ((Result + 0x8000) >> 32) & 0xffff;
79f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        break;
80f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand      case VK_PPC_HIGHEST:
81f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Result = (Result >> 48) & 0xffff;
82f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        break;
83f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand      case VK_PPC_HIGHESTA:
84f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Result = ((Result + 0x8000) >> 48) & 0xffff;
8592cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand        break;
86edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    }
87edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    Res = MCValue::get(Result);
88edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  } else {
89edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    MCContext &Context = Layout->getAssembler().getContext();
90edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    const MCSymbolRefExpr *Sym = Value.getSymA();
91edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
92edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    if (Modifier != MCSymbolRefExpr::VK_None)
93edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand      return false;
94edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    switch (Kind) {
95edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand      default:
96edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        llvm_unreachable("Invalid kind!");
9792cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      case VK_PPC_LO:
9892cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand        Modifier = MCSymbolRefExpr::VK_PPC_LO;
99edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        break;
100d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand      case VK_PPC_HI:
101d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand        Modifier = MCSymbolRefExpr::VK_PPC_HI;
102d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand        break;
10392cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand      case VK_PPC_HA:
10492cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand        Modifier = MCSymbolRefExpr::VK_PPC_HA;
105edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand        break;
106f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand      case VK_PPC_HIGHERA:
107f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
108f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        break;
109f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand      case VK_PPC_HIGHER:
110f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
111f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        break;
112f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand      case VK_PPC_HIGHEST:
113f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
114f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        break;
115f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand      case VK_PPC_HIGHESTA:
116f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
117f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand        break;
118edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    }
119edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context);
120edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
121edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  }
122edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
123edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  return true;
124edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand}
125edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
126edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps
127edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// that method should be made public?
128edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandstatic void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) {
129edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  switch (Value->getKind()) {
130edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  case MCExpr::Target:
131edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    llvm_unreachable("Can't handle nested target expr!");
132edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
133edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  case MCExpr::Constant:
134edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    break;
135edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
136edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  case MCExpr::Binary: {
137edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
138edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    AddValueSymbols_(BE->getLHS(), Asm);
139edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    AddValueSymbols_(BE->getRHS(), Asm);
140edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    break;
141edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  }
142edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
143edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  case MCExpr::SymbolRef:
144edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
145edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    break;
146edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
147edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  case MCExpr::Unary:
148edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    AddValueSymbols_(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm);
149edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand    break;
150edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  }
151edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand}
152edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand
153edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandvoid PPCMCExpr::AddValueSymbols(MCAssembler *Asm) const {
154edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand  AddValueSymbols_(getSubExpr(), Asm);
155edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand}
156