Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
35294 views
1
//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===//
2
//
3
// 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
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "PPCMCExpr.h"
10
#include "PPCFixupKinds.h"
11
#include "llvm/MC/MCAsmInfo.h"
12
#include "llvm/MC/MCAssembler.h"
13
#include "llvm/MC/MCContext.h"
14
#include "llvm/MC/MCObjectStreamer.h"
15
16
using namespace llvm;
17
18
#define DEBUG_TYPE "ppcmcexpr"
19
20
const PPCMCExpr *PPCMCExpr::create(VariantKind Kind, const MCExpr *Expr,
21
MCContext &Ctx) {
22
return new (Ctx) PPCMCExpr(Kind, Expr);
23
}
24
25
void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
26
getSubExpr()->print(OS, MAI);
27
28
switch (Kind) {
29
default:
30
llvm_unreachable("Invalid kind!");
31
case VK_PPC_LO:
32
OS << "@l";
33
break;
34
case VK_PPC_HI:
35
OS << "@h";
36
break;
37
case VK_PPC_HA:
38
OS << "@ha";
39
break;
40
case VK_PPC_HIGH:
41
OS << "@high";
42
break;
43
case VK_PPC_HIGHA:
44
OS << "@higha";
45
break;
46
case VK_PPC_HIGHER:
47
OS << "@higher";
48
break;
49
case VK_PPC_HIGHERA:
50
OS << "@highera";
51
break;
52
case VK_PPC_HIGHEST:
53
OS << "@highest";
54
break;
55
case VK_PPC_HIGHESTA:
56
OS << "@highesta";
57
break;
58
}
59
}
60
61
bool
62
PPCMCExpr::evaluateAsConstant(int64_t &Res) const {
63
MCValue Value;
64
65
if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr))
66
return false;
67
68
if (!Value.isAbsolute())
69
return false;
70
71
Res = evaluateAsInt64(Value.getConstant());
72
return true;
73
}
74
75
int64_t
76
PPCMCExpr::evaluateAsInt64(int64_t Value) const {
77
switch (Kind) {
78
case VK_PPC_LO:
79
return Value & 0xffff;
80
case VK_PPC_HI:
81
return (Value >> 16) & 0xffff;
82
case VK_PPC_HA:
83
return ((Value + 0x8000) >> 16) & 0xffff;
84
case VK_PPC_HIGH:
85
return (Value >> 16) & 0xffff;
86
case VK_PPC_HIGHA:
87
return ((Value + 0x8000) >> 16) & 0xffff;
88
case VK_PPC_HIGHER:
89
return (Value >> 32) & 0xffff;
90
case VK_PPC_HIGHERA:
91
return ((Value + 0x8000) >> 32) & 0xffff;
92
case VK_PPC_HIGHEST:
93
return (Value >> 48) & 0xffff;
94
case VK_PPC_HIGHESTA:
95
return ((Value + 0x8000) >> 48) & 0xffff;
96
case VK_PPC_None:
97
break;
98
}
99
llvm_unreachable("Invalid kind!");
100
}
101
102
bool PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
103
const MCFixup *Fixup) const {
104
MCValue Value;
105
106
if (!getSubExpr()->evaluateAsRelocatable(Value, Asm, Fixup))
107
return false;
108
109
if (Value.isAbsolute()) {
110
int64_t Result = evaluateAsInt64(Value.getConstant());
111
bool IsHalf16 = Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16;
112
bool IsHalf16DS =
113
Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16ds;
114
bool IsHalf16DQ =
115
Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16dq;
116
bool IsHalf = IsHalf16 || IsHalf16DS || IsHalf16DQ;
117
118
if (!IsHalf && Result >= 0x8000)
119
return false;
120
if ((IsHalf16DS && (Result & 0x3)) || (IsHalf16DQ && (Result & 0xf)))
121
return false;
122
123
Res = MCValue::get(Result);
124
} else {
125
if (!Asm || !Asm->hasLayout())
126
return false;
127
128
MCContext &Context = Asm->getContext();
129
const MCSymbolRefExpr *Sym = Value.getSymA();
130
MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
131
if (Modifier != MCSymbolRefExpr::VK_None)
132
return false;
133
switch (Kind) {
134
default:
135
llvm_unreachable("Invalid kind!");
136
case VK_PPC_LO:
137
Modifier = MCSymbolRefExpr::VK_PPC_LO;
138
break;
139
case VK_PPC_HI:
140
Modifier = MCSymbolRefExpr::VK_PPC_HI;
141
break;
142
case VK_PPC_HA:
143
Modifier = MCSymbolRefExpr::VK_PPC_HA;
144
break;
145
case VK_PPC_HIGH:
146
Modifier = MCSymbolRefExpr::VK_PPC_HIGH;
147
break;
148
case VK_PPC_HIGHA:
149
Modifier = MCSymbolRefExpr::VK_PPC_HIGHA;
150
break;
151
case VK_PPC_HIGHERA:
152
Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
153
break;
154
case VK_PPC_HIGHER:
155
Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
156
break;
157
case VK_PPC_HIGHEST:
158
Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
159
break;
160
case VK_PPC_HIGHESTA:
161
Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
162
break;
163
}
164
Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
165
Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
166
}
167
168
return true;
169
}
170
171
void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
172
Streamer.visitUsedExpr(*getSubExpr());
173
}
174
175