blob: 32e6a0bdd65fe9b9e3c0bb29f5c4c4be05881b5c [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 Carruth6bda14b2017-06-06 11:49:48 +000011#include "PPCFixupKinds.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000012#include "llvm/MC/MCAsmInfo.h"
Ulrich Weigand41789de2013-05-23 22:26:41 +000013#include "llvm/MC/MCAssembler.h"
14#include "llvm/MC/MCContext.h"
Rafael Espindola2be12812014-06-25 15:29:54 +000015#include "llvm/MC/MCObjectStreamer.h"
Ulrich Weigand41789de2013-05-23 22:26:41 +000016
17using namespace llvm;
18
Chandler Carruth84e68b22014-04-22 02:41:26 +000019#define DEBUG_TYPE "ppcmcexpr"
20
Ulrich Weigand41789de2013-05-23 22:26:41 +000021const PPCMCExpr*
Jim Grosbach13760bd2015-05-30 01:25:56 +000022PPCMCExpr::create(VariantKind Kind, const MCExpr *Expr,
Ulrich Weigand266db7f2013-07-08 20:20:51 +000023 bool isDarwin, MCContext &Ctx) {
24 return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin);
Ulrich Weigand41789de2013-05-23 22:26:41 +000025}
26
Matt Arsenault8b643552015-06-09 00:31:39 +000027void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
Ulrich Weigand96e65782013-06-20 16:23:52 +000028 if (isDarwinSyntax()) {
29 switch (Kind) {
30 default: llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000031 case VK_PPC_LO: OS << "lo16"; break;
Ulrich Weigande67c5652013-06-21 14:42:49 +000032 case VK_PPC_HI: OS << "hi16"; break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000033 case VK_PPC_HA: OS << "ha16"; break;
Ulrich Weigand96e65782013-06-20 16:23:52 +000034 }
Ulrich Weigand41789de2013-05-23 22:26:41 +000035
Ulrich Weigand96e65782013-06-20 16:23:52 +000036 OS << '(';
Matt Arsenault8b643552015-06-09 00:31:39 +000037 getSubExpr()->print(OS, MAI);
Ulrich Weigand96e65782013-06-20 16:23:52 +000038 OS << ')';
39 } else {
Matt Arsenault8b643552015-06-09 00:31:39 +000040 getSubExpr()->print(OS, MAI);
Ulrich Weigand96e65782013-06-20 16:23:52 +000041
42 switch (Kind) {
43 default: llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000044 case VK_PPC_LO: OS << "@l"; break;
Ulrich Weigande67c5652013-06-21 14:42:49 +000045 case VK_PPC_HI: OS << "@h"; break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000046 case VK_PPC_HA: OS << "@ha"; break;
Sean Fertile80b8f822018-06-15 19:47:11 +000047 case VK_PPC_HIGH: OS << "@high"; break;
48 case VK_PPC_HIGHA: OS << "@higha"; break;
Ulrich Weigande9126f52013-06-21 14:43:42 +000049 case VK_PPC_HIGHER: OS << "@higher"; break;
50 case VK_PPC_HIGHERA: OS << "@highera"; break;
51 case VK_PPC_HIGHEST: OS << "@highest"; break;
52 case VK_PPC_HIGHESTA: OS << "@highesta"; break;
Ulrich Weigand96e65782013-06-20 16:23:52 +000053 }
54 }
Ulrich Weigand41789de2013-05-23 22:26:41 +000055}
56
57bool
Jim Grosbach13760bd2015-05-30 01:25:56 +000058PPCMCExpr::evaluateAsConstant(int64_t &Res) const {
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000059 MCValue Value;
60
Jim Grosbach13760bd2015-05-30 01:25:56 +000061 if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr))
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000062 return false;
63
64 if (!Value.isAbsolute())
65 return false;
66
Jim Grosbach13760bd2015-05-30 01:25:56 +000067 Res = evaluateAsInt64(Value.getConstant());
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000068 return true;
69}
70
71int64_t
Jim Grosbach13760bd2015-05-30 01:25:56 +000072PPCMCExpr::evaluateAsInt64(int64_t Value) const {
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000073 switch (Kind) {
74 case VK_PPC_LO:
75 return Value & 0xffff;
76 case VK_PPC_HI:
77 return (Value >> 16) & 0xffff;
78 case VK_PPC_HA:
79 return ((Value + 0x8000) >> 16) & 0xffff;
Sean Fertile80b8f822018-06-15 19:47:11 +000080 case VK_PPC_HIGH:
81 return (Value >> 16) & 0xffff;
82 case VK_PPC_HIGHA:
83 return ((Value + 0x8000) >> 16) & 0xffff;
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000084 case VK_PPC_HIGHER:
85 return (Value >> 32) & 0xffff;
86 case VK_PPC_HIGHERA:
87 return ((Value + 0x8000) >> 32) & 0xffff;
88 case VK_PPC_HIGHEST:
89 return (Value >> 48) & 0xffff;
90 case VK_PPC_HIGHESTA:
91 return ((Value + 0x8000) >> 48) & 0xffff;
92 case VK_PPC_None:
93 break;
94 }
95 llvm_unreachable("Invalid kind!");
96}
97
98bool
Jim Grosbach13760bd2015-05-30 01:25:56 +000099PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
Joerg Sonnenberger752b91b2014-08-10 11:35:12 +0000100 const MCAsmLayout *Layout,
101 const MCFixup *Fixup) const {
Ulrich Weigand41789de2013-05-23 22:26:41 +0000102 MCValue Value;
103
Jim Grosbach13760bd2015-05-30 01:25:56 +0000104 if (!getSubExpr()->evaluateAsRelocatable(Value, Layout, Fixup))
Ulrich Weigand41789de2013-05-23 22:26:41 +0000105 return false;
106
107 if (Value.isAbsolute()) {
Jim Grosbach13760bd2015-05-30 01:25:56 +0000108 int64_t Result = evaluateAsInt64(Value.getConstant());
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000109 if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) &&
110 (Result >= 0x8000))
111 return false;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000112 Res = MCValue::get(Result);
Alexey Samsonova3a037d2013-08-28 08:30:47 +0000113 } else {
Rafael Espindola3d5d4642014-03-12 16:55:59 +0000114 if (!Layout)
115 return false;
116
Ulrich Weigand41789de2013-05-23 22:26:41 +0000117 MCContext &Context = Layout->getAssembler().getContext();
118 const MCSymbolRefExpr *Sym = Value.getSymA();
119 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
120 if (Modifier != MCSymbolRefExpr::VK_None)
121 return false;
122 switch (Kind) {
123 default:
124 llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +0000125 case VK_PPC_LO:
126 Modifier = MCSymbolRefExpr::VK_PPC_LO;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000127 break;
Ulrich Weigande67c5652013-06-21 14:42:49 +0000128 case VK_PPC_HI:
129 Modifier = MCSymbolRefExpr::VK_PPC_HI;
130 break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +0000131 case VK_PPC_HA:
132 Modifier = MCSymbolRefExpr::VK_PPC_HA;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000133 break;
Sean Fertile80b8f822018-06-15 19:47:11 +0000134 case VK_PPC_HIGH:
135 Modifier = MCSymbolRefExpr::VK_PPC_HIGH;
136 break;
137 case VK_PPC_HIGHA:
138 Modifier = MCSymbolRefExpr::VK_PPC_HIGHA;
139 break;
Ulrich Weigande9126f52013-06-21 14:43:42 +0000140 case VK_PPC_HIGHERA:
141 Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
142 break;
143 case VK_PPC_HIGHER:
144 Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
145 break;
146 case VK_PPC_HIGHEST:
147 Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
148 break;
149 case VK_PPC_HIGHESTA:
150 Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
151 break;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000152 }
Jim Grosbach13760bd2015-05-30 01:25:56 +0000153 Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
Ulrich Weigand41789de2013-05-23 22:26:41 +0000154 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
Alexey Samsonova3a037d2013-08-28 08:30:47 +0000155 }
Ulrich Weigand41789de2013-05-23 22:26:41 +0000156
157 return true;
158}
159
Rafael Espindolae2c66242014-06-25 15:45:33 +0000160void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
Rafael Espindola2be12812014-06-25 15:29:54 +0000161 Streamer.visitUsedExpr(*getSubExpr());
Ulrich Weigand41789de2013-05-23 22:26:41 +0000162}