blob: d467f5c4a43921a1eb7ad5e60c8e4f6d01d7f43b [file] [log] [blame]
Ulrich Weigand41789de2013-05-23 22:26:41 +00001//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Ulrich Weigand41789de2013-05-23 22:26:41 +00006//
7//===----------------------------------------------------------------------===//
8
Ulrich Weigand41789de2013-05-23 22:26:41 +00009#include "PPCMCExpr.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000010#include "PPCFixupKinds.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*
Jim Grosbach13760bd2015-05-30 01:25:56 +000021PPCMCExpr::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
Matt Arsenault8b643552015-06-09 00:31:39 +000026void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) 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 << '(';
Matt Arsenault8b643552015-06-09 00:31:39 +000036 getSubExpr()->print(OS, MAI);
Ulrich Weigand96e65782013-06-20 16:23:52 +000037 OS << ')';
38 } else {
Matt Arsenault8b643552015-06-09 00:31:39 +000039 getSubExpr()->print(OS, MAI);
Ulrich Weigand96e65782013-06-20 16:23:52 +000040
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;
Sean Fertile80b8f822018-06-15 19:47:11 +000046 case VK_PPC_HIGH: OS << "@high"; break;
47 case VK_PPC_HIGHA: OS << "@higha"; break;
Ulrich Weigande9126f52013-06-21 14:43:42 +000048 case VK_PPC_HIGHER: OS << "@higher"; break;
49 case VK_PPC_HIGHERA: OS << "@highera"; break;
50 case VK_PPC_HIGHEST: OS << "@highest"; break;
51 case VK_PPC_HIGHESTA: OS << "@highesta"; break;
Ulrich Weigand96e65782013-06-20 16:23:52 +000052 }
53 }
Ulrich Weigand41789de2013-05-23 22:26:41 +000054}
55
56bool
Jim Grosbach13760bd2015-05-30 01:25:56 +000057PPCMCExpr::evaluateAsConstant(int64_t &Res) const {
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000058 MCValue Value;
59
Jim Grosbach13760bd2015-05-30 01:25:56 +000060 if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr))
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000061 return false;
62
63 if (!Value.isAbsolute())
64 return false;
65
Jim Grosbach13760bd2015-05-30 01:25:56 +000066 Res = evaluateAsInt64(Value.getConstant());
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000067 return true;
68}
69
70int64_t
Jim Grosbach13760bd2015-05-30 01:25:56 +000071PPCMCExpr::evaluateAsInt64(int64_t Value) const {
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000072 switch (Kind) {
73 case VK_PPC_LO:
74 return Value & 0xffff;
75 case VK_PPC_HI:
76 return (Value >> 16) & 0xffff;
77 case VK_PPC_HA:
78 return ((Value + 0x8000) >> 16) & 0xffff;
Sean Fertile80b8f822018-06-15 19:47:11 +000079 case VK_PPC_HIGH:
80 return (Value >> 16) & 0xffff;
81 case VK_PPC_HIGHA:
82 return ((Value + 0x8000) >> 16) & 0xffff;
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +000083 case VK_PPC_HIGHER:
84 return (Value >> 32) & 0xffff;
85 case VK_PPC_HIGHERA:
86 return ((Value + 0x8000) >> 32) & 0xffff;
87 case VK_PPC_HIGHEST:
88 return (Value >> 48) & 0xffff;
89 case VK_PPC_HIGHESTA:
90 return ((Value + 0x8000) >> 48) & 0xffff;
91 case VK_PPC_None:
92 break;
93 }
94 llvm_unreachable("Invalid kind!");
95}
96
97bool
Jim Grosbach13760bd2015-05-30 01:25:56 +000098PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
Joerg Sonnenberger752b91b2014-08-10 11:35:12 +000099 const MCAsmLayout *Layout,
100 const MCFixup *Fixup) const {
Ulrich Weigand41789de2013-05-23 22:26:41 +0000101 MCValue Value;
102
Jim Grosbach13760bd2015-05-30 01:25:56 +0000103 if (!getSubExpr()->evaluateAsRelocatable(Value, Layout, Fixup))
Ulrich Weigand41789de2013-05-23 22:26:41 +0000104 return false;
105
106 if (Value.isAbsolute()) {
Jim Grosbach13760bd2015-05-30 01:25:56 +0000107 int64_t Result = evaluateAsInt64(Value.getConstant());
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000108 if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) &&
109 (Result >= 0x8000))
110 return false;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000111 Res = MCValue::get(Result);
Alexey Samsonova3a037d2013-08-28 08:30:47 +0000112 } else {
Rafael Espindola3d5d4642014-03-12 16:55:59 +0000113 if (!Layout)
114 return false;
115
Ulrich Weigand41789de2013-05-23 22:26:41 +0000116 MCContext &Context = Layout->getAssembler().getContext();
117 const MCSymbolRefExpr *Sym = Value.getSymA();
118 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
119 if (Modifier != MCSymbolRefExpr::VK_None)
120 return false;
121 switch (Kind) {
122 default:
123 llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +0000124 case VK_PPC_LO:
125 Modifier = MCSymbolRefExpr::VK_PPC_LO;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000126 break;
Ulrich Weigande67c5652013-06-21 14:42:49 +0000127 case VK_PPC_HI:
128 Modifier = MCSymbolRefExpr::VK_PPC_HI;
129 break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +0000130 case VK_PPC_HA:
131 Modifier = MCSymbolRefExpr::VK_PPC_HA;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000132 break;
Sean Fertile80b8f822018-06-15 19:47:11 +0000133 case VK_PPC_HIGH:
134 Modifier = MCSymbolRefExpr::VK_PPC_HIGH;
135 break;
136 case VK_PPC_HIGHA:
137 Modifier = MCSymbolRefExpr::VK_PPC_HIGHA;
138 break;
Ulrich Weigande9126f52013-06-21 14:43:42 +0000139 case VK_PPC_HIGHERA:
140 Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
141 break;
142 case VK_PPC_HIGHER:
143 Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
144 break;
145 case VK_PPC_HIGHEST:
146 Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
147 break;
148 case VK_PPC_HIGHESTA:
149 Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
150 break;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000151 }
Jim Grosbach13760bd2015-05-30 01:25:56 +0000152 Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
Ulrich Weigand41789de2013-05-23 22:26:41 +0000153 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
Alexey Samsonova3a037d2013-08-28 08:30:47 +0000154 }
Ulrich Weigand41789de2013-05-23 22:26:41 +0000155
156 return true;
157}
158
Rafael Espindolae2c66242014-06-25 15:45:33 +0000159void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
Rafael Espindola2be12812014-06-25 15:29:54 +0000160 Streamer.visitUsedExpr(*getSubExpr());
Ulrich Weigand41789de2013-05-23 22:26:41 +0000161}