LLVM 20.0.0git
PPCMCExpr.cpp
Go to the documentation of this file.
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"
15
16using namespace llvm;
17
18#define DEBUG_TYPE "ppcmcexpr"
19
21 MCContext &Ctx) {
22 return new (Ctx) PPCMCExpr(Kind, Expr);
23}
24
25void 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
61bool
62PPCMCExpr::evaluateAsConstant(int64_t &Res) const {
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
75int64_t
76PPCMCExpr::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
103 const MCFixup *Fixup) const {
105
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:
138 break;
139 case VK_PPC_HI:
141 break;
142 case VK_PPC_HA:
144 break;
145 case VK_PPC_HIGH:
147 break;
148 case VK_PPC_HIGHA:
150 break;
151 case VK_PPC_HIGHERA:
153 break;
154 case VK_PPC_HIGHER:
156 break;
157 case VK_PPC_HIGHEST:
159 break;
160 case 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
172 Streamer.visitUsedExpr(*getSubExpr());
173}
Symbol * Sym
Definition: ELF_riscv.cpp:479
PowerPC TLS Dynamic Call Fixup
raw_pwrite_stream & OS
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
Context object for machine code objects.
Definition: MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:788
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:40
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
Streaming machine code generation interface.
Definition: MCStreamer.h:213
void visitUsedExpr(const MCExpr &Expr)
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:188
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:393
This represents an "assembler immediate".
Definition: MCValue.h:36
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)
Definition: MCValue.h:59
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const override
Definition: PPCMCExpr.cpp:102
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override
Definition: PPCMCExpr.cpp:25
static const PPCMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: PPCMCExpr.cpp:20
const MCExpr * getSubExpr() const
getSubExpr - Get the child of this expression.
Definition: PPCMCExpr.h:68
void visitUsedExpr(MCStreamer &Streamer) const override
Definition: PPCMCExpr.cpp:171
bool evaluateAsConstant(int64_t &Res) const
Definition: PPCMCExpr.cpp:62
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ fixup_ppc_half16
A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like 'li' or 'addis'.
Definition: PPCFixupKinds.h:37
@ fixup_ppc_half16dq
A 16-bit fixup corresponding to lo16(_foo) with implied 3 zero bits for instrs like 'lxv'.
Definition: PPCFixupKinds.h:57
@ fixup_ppc_half16ds
A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for instrs like 'std'.
Definition: PPCFixupKinds.h:41
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18