LLVM 19.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
102bool
104 const MCAsmLayout *Layout,
105 const MCFixup *Fixup) const {
107
109 return false;
110
111 if (Value.isAbsolute()) {
112 int64_t Result = evaluateAsInt64(Value.getConstant());
113 bool IsHalf16 = Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16;
114 bool IsHalf16DS =
115 Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16ds;
116 bool IsHalf16DQ =
117 Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16dq;
118 bool IsHalf = IsHalf16 || IsHalf16DS || IsHalf16DQ;
119
120 if (!IsHalf && Result >= 0x8000)
121 return false;
122 if ((IsHalf16DS && (Result & 0x3)) || (IsHalf16DQ && (Result & 0xf)))
123 return false;
124
125 Res = MCValue::get(Result);
126 } else {
127 if (!Layout)
128 return false;
129
131 const MCSymbolRefExpr *Sym = Value.getSymA();
132 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
133 if (Modifier != MCSymbolRefExpr::VK_None)
134 return false;
135 switch (Kind) {
136 default:
137 llvm_unreachable("Invalid kind!");
138 case VK_PPC_LO:
140 break;
141 case VK_PPC_HI:
143 break;
144 case VK_PPC_HA:
146 break;
147 case VK_PPC_HIGH:
149 break;
150 case VK_PPC_HIGHA:
152 break;
153 case VK_PPC_HIGHERA:
155 break;
156 case VK_PPC_HIGHER:
158 break;
159 case VK_PPC_HIGHEST:
161 break;
162 case VK_PPC_HIGHESTA:
164 break;
165 }
166 Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
167 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
168 }
169
170 return true;
171}
172
174 Streamer.visitUsedExpr(*getSubExpr());
175}
Symbol * Sym
Definition: ELF_riscv.cpp:479
LLVMContext & Context
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
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:50
MCContext & getContext() const
Definition: MCAssembler.h:326
Context object for machine code objects.
Definition: MCContext.h:81
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:814
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
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:212
void visitUsedExpr(const MCExpr &Expr)
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:397
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
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:69
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const override
Definition: PPCMCExpr.cpp:103
void visitUsedExpr(MCStreamer &Streamer) const override
Definition: PPCMCExpr.cpp:173
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