blob: e4740c240da7508f9f23456ac3a50837c053e8f8 [file] [log] [blame]
Ulrich Weigand41789de2013-05-23 22:26:41 +00001//===-- PPCMCExpr.cpp - PPC 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
Ulrich Weigand41789de2013-05-23 22:26:41 +000010#include "PPCMCExpr.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000011#include "llvm/MC/MCAsmInfo.h"
Ulrich Weigand41789de2013-05-23 22:26:41 +000012#include "llvm/MC/MCAssembler.h"
13#include "llvm/MC/MCContext.h"
Rafael Espindola2be12812014-06-25 15:29:54 +000014#include "llvm/MC/MCObjectStreamer.h"
Ulrich Weigand41789de2013-05-23 22:26:41 +000015
16using namespace llvm;
17
Chandler Carruth84e68b22014-04-22 02:41:26 +000018#define DEBUG_TYPE "ppcmcexpr"
19
Ulrich Weigand41789de2013-05-23 22:26:41 +000020const PPCMCExpr*
21PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
Ulrich Weigand266db7f2013-07-08 20:20:51 +000022 bool isDarwin, MCContext &Ctx) {
23 return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin);
Ulrich Weigand41789de2013-05-23 22:26:41 +000024}
25
26void PPCMCExpr::PrintImpl(raw_ostream &OS) const {
Ulrich Weigand96e65782013-06-20 16:23:52 +000027 if (isDarwinSyntax()) {
28 switch (Kind) {
29 default: llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000030 case VK_PPC_LO: OS << "lo16"; break;
Ulrich Weigande67c5652013-06-21 14:42:49 +000031 case VK_PPC_HI: OS << "hi16"; break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000032 case VK_PPC_HA: OS << "ha16"; break;
Ulrich Weigand96e65782013-06-20 16:23:52 +000033 }
Ulrich Weigand41789de2013-05-23 22:26:41 +000034
Ulrich Weigand96e65782013-06-20 16:23:52 +000035 OS << '(';
36 getSubExpr()->print(OS);
37 OS << ')';
38 } else {
39 getSubExpr()->print(OS);
40
41 switch (Kind) {
42 default: llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000043 case VK_PPC_LO: OS << "@l"; break;
Ulrich Weigande67c5652013-06-21 14:42:49 +000044 case VK_PPC_HI: OS << "@h"; break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000045 case VK_PPC_HA: OS << "@ha"; break;
Ulrich Weigande9126f52013-06-21 14:43:42 +000046 case VK_PPC_HIGHER: OS << "@higher"; break;
47 case VK_PPC_HIGHERA: OS << "@highera"; break;
48 case VK_PPC_HIGHEST: OS << "@highest"; break;
49 case VK_PPC_HIGHESTA: OS << "@highesta"; break;
Ulrich Weigand96e65782013-06-20 16:23:52 +000050 }
51 }
Ulrich Weigand41789de2013-05-23 22:26:41 +000052}
53
54bool
55PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
56 const MCAsmLayout *Layout) const {
57 MCValue Value;
58
Rafael Espindola3d5d4642014-03-12 16:55:59 +000059 if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout))
Ulrich Weigand41789de2013-05-23 22:26:41 +000060 return false;
61
62 if (Value.isAbsolute()) {
63 int64_t Result = Value.getConstant();
64 switch (Kind) {
65 default:
66 llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000067 case VK_PPC_LO:
Ulrich Weigand41789de2013-05-23 22:26:41 +000068 Result = Result & 0xffff;
69 break;
Ulrich Weigande67c5652013-06-21 14:42:49 +000070 case VK_PPC_HI:
71 Result = (Result >> 16) & 0xffff;
72 break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000073 case VK_PPC_HA:
Ulrich Weigande9126f52013-06-21 14:43:42 +000074 Result = ((Result + 0x8000) >> 16) & 0xffff;
75 break;
76 case VK_PPC_HIGHER:
77 Result = (Result >> 32) & 0xffff;
78 break;
79 case VK_PPC_HIGHERA:
80 Result = ((Result + 0x8000) >> 32) & 0xffff;
81 break;
82 case VK_PPC_HIGHEST:
83 Result = (Result >> 48) & 0xffff;
84 break;
85 case VK_PPC_HIGHESTA:
86 Result = ((Result + 0x8000) >> 48) & 0xffff;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000087 break;
Ulrich Weigand41789de2013-05-23 22:26:41 +000088 }
89 Res = MCValue::get(Result);
Alexey Samsonova3a037d2013-08-28 08:30:47 +000090 } else {
Rafael Espindola3d5d4642014-03-12 16:55:59 +000091 if (!Layout)
92 return false;
93
Ulrich Weigand41789de2013-05-23 22:26:41 +000094 MCContext &Context = Layout->getAssembler().getContext();
95 const MCSymbolRefExpr *Sym = Value.getSymA();
96 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
97 if (Modifier != MCSymbolRefExpr::VK_None)
98 return false;
99 switch (Kind) {
100 default:
101 llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +0000102 case VK_PPC_LO:
103 Modifier = MCSymbolRefExpr::VK_PPC_LO;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000104 break;
Ulrich Weigande67c5652013-06-21 14:42:49 +0000105 case VK_PPC_HI:
106 Modifier = MCSymbolRefExpr::VK_PPC_HI;
107 break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +0000108 case VK_PPC_HA:
109 Modifier = MCSymbolRefExpr::VK_PPC_HA;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000110 break;
Ulrich Weigande9126f52013-06-21 14:43:42 +0000111 case VK_PPC_HIGHERA:
112 Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
113 break;
114 case VK_PPC_HIGHER:
115 Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
116 break;
117 case VK_PPC_HIGHEST:
118 Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
119 break;
120 case VK_PPC_HIGHESTA:
121 Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
122 break;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000123 }
124 Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context);
125 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
Alexey Samsonova3a037d2013-08-28 08:30:47 +0000126 }
Ulrich Weigand41789de2013-05-23 22:26:41 +0000127
128 return true;
129}
130
Rafael Espindola2be12812014-06-25 15:29:54 +0000131void PPCMCExpr::visitUsedExpr(MCObjectStreamer &Streamer) const {
132 Streamer.visitUsedExpr(*getSubExpr());
Ulrich Weigand41789de2013-05-23 22:26:41 +0000133}