1 //===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===//
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
7 //===----------------------------------------------------------------------===//
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"
18 #define DEBUG_TYPE "ppcmcexpr"
21 PPCMCExpr::create(VariantKind Kind
, const MCExpr
*Expr
,
22 bool IsDarwin
, MCContext
&Ctx
) {
23 return new (Ctx
) PPCMCExpr(Kind
, Expr
, IsDarwin
);
26 void PPCMCExpr::printImpl(raw_ostream
&OS
, const MCAsmInfo
*MAI
) const {
27 if (isDarwinSyntax()) {
29 default: llvm_unreachable("Invalid kind!");
30 case VK_PPC_LO
: OS
<< "lo16"; break;
31 case VK_PPC_HI
: OS
<< "hi16"; break;
32 case VK_PPC_HA
: OS
<< "ha16"; break;
36 getSubExpr()->print(OS
, MAI
);
39 getSubExpr()->print(OS
, MAI
);
42 default: llvm_unreachable("Invalid kind!");
43 case VK_PPC_LO
: OS
<< "@l"; break;
44 case VK_PPC_HI
: OS
<< "@h"; break;
45 case VK_PPC_HA
: OS
<< "@ha"; break;
46 case VK_PPC_HIGH
: OS
<< "@high"; break;
47 case VK_PPC_HIGHA
: OS
<< "@higha"; break;
48 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;
57 PPCMCExpr::evaluateAsConstant(int64_t &Res
) const {
60 if (!getSubExpr()->evaluateAsRelocatable(Value
, nullptr, nullptr))
63 if (!Value
.isAbsolute())
66 Res
= evaluateAsInt64(Value
.getConstant());
71 PPCMCExpr::evaluateAsInt64(int64_t Value
) const {
74 return Value
& 0xffff;
76 return (Value
>> 16) & 0xffff;
78 return ((Value
+ 0x8000) >> 16) & 0xffff;
80 return (Value
>> 16) & 0xffff;
82 return ((Value
+ 0x8000) >> 16) & 0xffff;
84 return (Value
>> 32) & 0xffff;
86 return ((Value
+ 0x8000) >> 32) & 0xffff;
88 return (Value
>> 48) & 0xffff;
90 return ((Value
+ 0x8000) >> 48) & 0xffff;
94 llvm_unreachable("Invalid kind!");
98 PPCMCExpr::evaluateAsRelocatableImpl(MCValue
&Res
,
99 const MCAsmLayout
*Layout
,
100 const MCFixup
*Fixup
) const {
103 if (!getSubExpr()->evaluateAsRelocatable(Value
, Layout
, Fixup
))
106 if (Value
.isAbsolute()) {
107 int64_t Result
= evaluateAsInt64(Value
.getConstant());
108 if ((Fixup
== nullptr || (unsigned)Fixup
->getKind() != PPC::fixup_ppc_half16
) &&
111 Res
= MCValue::get(Result
);
116 MCContext
&Context
= Layout
->getAssembler().getContext();
117 const MCSymbolRefExpr
*Sym
= Value
.getSymA();
118 MCSymbolRefExpr::VariantKind Modifier
= Sym
->getKind();
119 if (Modifier
!= MCSymbolRefExpr::VK_None
)
123 llvm_unreachable("Invalid kind!");
125 Modifier
= MCSymbolRefExpr::VK_PPC_LO
;
128 Modifier
= MCSymbolRefExpr::VK_PPC_HI
;
131 Modifier
= MCSymbolRefExpr::VK_PPC_HA
;
134 Modifier
= MCSymbolRefExpr::VK_PPC_HIGH
;
137 Modifier
= MCSymbolRefExpr::VK_PPC_HIGHA
;
140 Modifier
= MCSymbolRefExpr::VK_PPC_HIGHERA
;
143 Modifier
= MCSymbolRefExpr::VK_PPC_HIGHER
;
146 Modifier
= MCSymbolRefExpr::VK_PPC_HIGHEST
;
148 case VK_PPC_HIGHESTA
:
149 Modifier
= MCSymbolRefExpr::VK_PPC_HIGHESTA
;
152 Sym
= MCSymbolRefExpr::create(&Sym
->getSymbol(), Modifier
, Context
);
153 Res
= MCValue::get(Sym
, Value
.getSymB(), Value
.getConstant());
159 void PPCMCExpr::visitUsedExpr(MCStreamer
&Streamer
) const {
160 Streamer
.visitUsedExpr(*getSubExpr());