Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/p/codegen/J9PPCInstruction.cpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2020 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include "p/codegen/PPCInstruction.hpp"
24
25
#include "codegen/CodeGenerator.hpp"
26
#include "codegen/Relocation.hpp"
27
#include "compile/ResolvedMethod.hpp"
28
#include "env/CompilerEnv.hpp"
29
#include "env/jittypes.h"
30
#include "env/VMJ9.h"
31
#include "il/Node.hpp"
32
#include "il/Node_inlines.hpp"
33
#include "il/SymbolReference.hpp"
34
#include "infra/Assert.hpp"
35
#include "p/codegen/CallSnippet.hpp"
36
#include "runtime/CodeCacheManager.hpp"
37
#include "runtime/Runtime.hpp"
38
39
uint8_t *TR::PPCDepImmSymInstruction::generateBinaryEncoding()
40
{
41
TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg()->fe());
42
TR::Compilation *comp = cg()->comp();
43
uint8_t *instructionStart = cg()->getBinaryBufferCursor();
44
uint8_t *cursor = getOpCode().copyBinaryToBuffer(instructionStart);
45
intptr_t imm = getAddrImmediate();
46
47
if (getOpCodeValue() == TR::InstOpCode::bl || getOpCodeValue() == TR::InstOpCode::b)
48
{
49
int32_t refNum = getSymbolReference()->getReferenceNumber();
50
TR::ResolvedMethodSymbol *sym = getSymbolReference()->getSymbol()->getResolvedMethodSymbol();
51
TR_ResolvedMethod *resolvedMethod = sym == NULL ? NULL : sym->getResolvedMethod();
52
TR::LabelSymbol *label = getSymbolReference()->getSymbol()->getLabelSymbol();
53
bool callToSelf = comp->isRecursiveMethodTarget(resolvedMethod);
54
55
if (cg()->hasCodeCacheSwitched())
56
{
57
TR::SymbolReference *calleeSymRef = NULL;
58
59
if (label == NULL)
60
{
61
calleeSymRef = getSymbolReference();
62
}
63
else
64
{
65
if (label->getSnippet() != NULL)
66
{
67
TR::Snippet *snippet = label->getSnippet();
68
if (snippet->getKind() == TR::Snippet::IsCall)
69
{
70
calleeSymRef = ((TR::PPCCallSnippet *)snippet)->getRealMethodSymbolReference();
71
}
72
}
73
74
if (calleeSymRef == NULL && getNode() != NULL)
75
{
76
calleeSymRef = getNode()->getSymbolReference();
77
}
78
}
79
80
if (calleeSymRef != NULL)
81
{
82
if (calleeSymRef->getReferenceNumber() >= TR_PPCnumRuntimeHelpers &&
83
(calleeSymRef->getReferenceNumber() < cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::firstPerCodeCacheHelperSymbol) ||
84
calleeSymRef->getReferenceNumber() > cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::lastPerCodeCacheHelperSymbol)))
85
{
86
fej9->reserveTrampolineIfNecessary(comp, calleeSymRef, true);
87
}
88
}
89
else
90
{
91
TR_ASSERT(false, "Missing possible re-reservation for trampolines.");
92
}
93
}
94
95
if (callToSelf)
96
{
97
intptr_t jitToJitStart = cg()->getLinkage()->entryPointFromCompiledMethod();
98
*(int32_t *)cursor |= (reinterpret_cast<uint8_t *>(jitToJitStart) - cursor) & 0x03fffffc;
99
}
100
else if (label != NULL)
101
{
102
cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative24BitRelocation(cursor, label));
103
((TR::PPCCallSnippet *)getCallSnippet())->setCallRA(cursor + 4);
104
}
105
else
106
{
107
if (comp->target().cpu.isTargetWithinIFormBranchRange(imm, (intptr_t)cursor))
108
{
109
*(int32_t *)cursor |= (imm - (intptr_t)cursor) & 0x03fffffc;
110
}
111
else
112
{
113
intptr_t targetAddress;
114
if (refNum < TR_PPCnumRuntimeHelpers)
115
{
116
targetAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(refNum, (void *)cursor);
117
}
118
else if (refNum >= cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::firstPerCodeCacheHelperSymbol) &&
119
refNum <= cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::lastPerCodeCacheHelperSymbol))
120
{
121
TR_ASSERT(cg()->hasCodeCacheSwitched(), "Expecting per-codecache helper to be unreachable only when codecache was switched");
122
TR_CCPreLoadedCode helper = (TR_CCPreLoadedCode)(refNum - cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::firstPerCodeCacheHelperSymbol));
123
_addrImmediate = (uintptr_t)fej9->getCCPreLoadedCodeAddress(cg()->getCodeCache(), helper, cg());
124
targetAddress = (intptr_t)_addrImmediate;
125
}
126
else
127
{
128
// Must use the trampoline as the target and not the label
129
//
130
targetAddress = (intptr_t)fej9->methodTrampolineLookup(comp, getSymbolReference(), (void *)cursor);
131
}
132
133
TR_ASSERT_FATAL(comp->target().cpu.isTargetWithinIFormBranchRange(targetAddress, (intptr_t)cursor),
134
"Call target address is out of range");
135
*(int32_t *)cursor |= (targetAddress - (intptr_t)cursor) & 0x03fffffc;
136
}
137
}
138
139
if ((comp->compileRelocatableCode()
140
#ifdef J9VM_OPT_JITSERVER
141
|| comp->isOutOfProcessCompilation()
142
#endif
143
) &&
144
label == NULL &&
145
!callToSelf)
146
{
147
bool callIsJ2ITransition = runtimeHelperValue(TR_j2iTransition) == getSymbolReference()->getMethodAddress();
148
if (sym && !sym->isHelper() && resolvedMethod && !callIsJ2ITransition)
149
{
150
cg()->addProjectSpecializedRelocation(cursor, (uint8_t *)getSymbolReference()->getMethodAddress(), NULL, TR_MethodCallAddress,
151
__FILE__, __LINE__, getNode());
152
}
153
else
154
{
155
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor,(uint8_t *)getSymbolReference(),TR_HelperAddress, cg()),
156
__FILE__, __LINE__, getNode());
157
}
158
}
159
}
160
else
161
{
162
intptr_t distance = imm - (intptr_t)cursor;
163
// Place holder only: non-TR::InstOpCode::b[l] usage of this instruction doesn't
164
// exist at this moment.
165
*(int32_t *)cursor |= distance & 0x03fffffc;
166
}
167
168
cursor += 4;
169
setBinaryLength(cursor - instructionStart);
170
setBinaryEncoding(instructionStart);
171
cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength());
172
return cursor;
173
}
174
175