Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/p/codegen/ForceRecompilationSnippet.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/ForceRecompilationSnippet.hpp"
24
25
#include <stdint.h>
26
#include "codegen/CodeGenerator.hpp"
27
#include "codegen/Machine.hpp"
28
#include "codegen/Relocation.hpp"
29
#include "env/CompilerEnv.hpp"
30
#include "env/IO.hpp"
31
#include "env/jittypes.h"
32
#include "env/VMJ9.h"
33
#include "il/LabelSymbol.hpp"
34
#include "il/MethodSymbol.hpp"
35
#include "il/Node.hpp"
36
#include "il/Node_inlines.hpp"
37
#include "il/RegisterMappedSymbol.hpp"
38
#include "il/ResolvedMethodSymbol.hpp"
39
#include "il/StaticSymbol.hpp"
40
#include "il/Symbol.hpp"
41
#include "p/codegen/PPCInstruction.hpp"
42
#include "p/codegen/PPCRecompilation.hpp"
43
#include "runtime/CodeCacheManager.hpp"
44
45
uint8_t *TR::PPCForceRecompilationSnippet::emitSnippetBody()
46
{
47
uint8_t *buffer = cg()->getBinaryBufferCursor();
48
TR::SymbolReference *induceRecompilationSymRef = cg()->symRefTab()->findOrCreateRuntimeHelper(TR_PPCinduceRecompilation);
49
intptr_t startPC = (intptr_t)((uint8_t*)cg()->getCodeStart());
50
51
getSnippetLabel()->setCodeLocation(buffer);
52
53
TR::RegisterDependencyConditions *deps = _doneLabel->getInstruction()->getDependencyConditions();
54
TR::RealRegister *startPCReg = cg()->machine()->getRealRegister(deps->getPostConditions()->getRegisterDependency(0)->getRealRegister());
55
56
TR::InstOpCode opcode;
57
58
if (cg()->comp()->target().is64Bit())
59
{
60
// put jit entry point address in startPCReg
61
uint32_t hhval, hlval, lhval, llval;
62
hhval = startPC >> 48 & 0xffff;
63
hlval = (startPC >>32) & 0xffff;
64
lhval = (startPC >>16) & 0xffff;
65
llval = startPC & 0xffff;
66
67
opcode.setOpCodeValue(TR::InstOpCode::lis);
68
buffer = opcode.copyBinaryToBuffer(buffer);
69
startPCReg->setRegisterFieldRS((uint32_t *)buffer);
70
*(uint32_t *)buffer |= hhval;
71
buffer += PPC_INSTRUCTION_LENGTH;
72
73
opcode.setOpCodeValue(TR::InstOpCode::ori);
74
buffer = opcode.copyBinaryToBuffer(buffer);
75
startPCReg->setRegisterFieldRT((uint32_t *)buffer);
76
startPCReg->setRegisterFieldRA((uint32_t *)buffer);
77
*(uint32_t *)buffer |= hlval;
78
buffer += PPC_INSTRUCTION_LENGTH;
79
80
opcode.setOpCodeValue(TR::InstOpCode::rldicr);
81
buffer = opcode.copyBinaryToBuffer(buffer);
82
startPCReg->setRegisterFieldRA((uint32_t *)buffer);
83
startPCReg->setRegisterFieldRS((uint32_t *)buffer);
84
// SH = 32;
85
*(uint32_t *)buffer |= ((32 & 0x1f) << 11) | ((32 & 0x20) >> 4);
86
// ME = 32
87
*(uint32_t *)buffer |= 0x3e << 5;
88
buffer += PPC_INSTRUCTION_LENGTH;
89
90
opcode.setOpCodeValue(TR::InstOpCode::oris);
91
buffer = opcode.copyBinaryToBuffer(buffer);
92
startPCReg->setRegisterFieldRA((uint32_t *)buffer);
93
startPCReg->setRegisterFieldRS((uint32_t *)buffer);
94
*(uint32_t *)buffer |= lhval;
95
buffer += PPC_INSTRUCTION_LENGTH;
96
97
opcode.setOpCodeValue(TR::InstOpCode::ori);
98
buffer = opcode.copyBinaryToBuffer(buffer);
99
startPCReg->setRegisterFieldRA((uint32_t *)buffer);
100
startPCReg->setRegisterFieldRS((uint32_t *)buffer);
101
*(uint32_t *)buffer |= llval;
102
buffer += PPC_INSTRUCTION_LENGTH;
103
}
104
else
105
{
106
// put jit entry point address in startPCReg
107
opcode.setOpCodeValue(TR::InstOpCode::lis);
108
buffer = opcode.copyBinaryToBuffer(buffer);
109
startPCReg->setRegisterFieldRS((uint32_t *)buffer);
110
*(uint32_t *)buffer |= (uint32_t) (startPC >> 16 & 0xffff);
111
buffer += PPC_INSTRUCTION_LENGTH;
112
113
opcode.setOpCodeValue(TR::InstOpCode::ori);
114
buffer = opcode.copyBinaryToBuffer(buffer);
115
startPCReg->setRegisterFieldRT((uint32_t *)buffer);
116
startPCReg->setRegisterFieldRA((uint32_t *)buffer);
117
*(uint32_t *)buffer |= (uint32_t) (startPC & 0xffff);
118
buffer += PPC_INSTRUCTION_LENGTH;
119
}
120
121
intptr_t helperAddress = (intptr_t)induceRecompilationSymRef->getMethodAddress();
122
if (cg()->directCallRequiresTrampoline(helperAddress, (intptr_t)buffer))
123
{
124
helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(induceRecompilationSymRef->getReferenceNumber(), (void *)buffer);
125
TR_ASSERT_FATAL(cg()->comp()->target().cpu.isTargetWithinIFormBranchRange(helperAddress, (intptr_t)buffer),
126
"Helper address is out of range");
127
}
128
129
// b distance
130
*(int32_t *)buffer = 0x48000000 | ((helperAddress - (intptr_t)buffer) & 0x03ffffff);
131
132
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(buffer,(uint8_t *)induceRecompilationSymRef,TR_HelperAddress, cg()),
133
__FILE__,
134
__LINE__,
135
getNode());
136
137
buffer += PPC_INSTRUCTION_LENGTH;
138
139
return buffer;
140
}
141
142
void
143
TR_Debug::print(TR::FILE *pOutFile, TR::PPCForceRecompilationSnippet * snippet)
144
{
145
uint8_t *cursor = snippet->getSnippetLabel()->getCodeLocation();
146
147
TR::RegisterDependencyConditions *deps = snippet->getDoneLabel()->getInstruction()->getDependencyConditions();
148
TR::RealRegister *startPCReg = _cg->machine()->getRealRegister(deps->getPostConditions()->getRegisterDependency(0)->getRealRegister());
149
150
printSnippetLabel(pOutFile, snippet->getSnippetLabel(), cursor, "EDO Recompilation Snippet");
151
152
int32_t value;
153
154
if (_comp->target().is64Bit())
155
{
156
printPrefix(pOutFile, NULL, cursor, 4);
157
value = *((int32_t *) cursor) & 0x0ffff;
158
trfprintf(pOutFile, "lis \t%s, 0x%p\t; Load jit entry point address", getName(startPCReg),value );
159
cursor += 4;
160
161
printPrefix(pOutFile, NULL, cursor, 4);
162
value = *((int32_t *) cursor) & 0x0ffff;
163
trfprintf(pOutFile, "ori \t%s, %s, 0x%p\t;", getName(startPCReg), getName(startPCReg), value);
164
cursor += 4;
165
166
printPrefix(pOutFile, NULL, cursor, 4);
167
trfprintf(pOutFile, "rldicr \t%s, %s, 32, 31\t;", getName(startPCReg), getName(startPCReg));
168
cursor += 4;
169
170
printPrefix(pOutFile, NULL, cursor, 4);
171
value = *((int32_t *) cursor) & 0x0ffff;
172
trfprintf(pOutFile, "oris \t%s, %s, 0x%p\t;", getName(startPCReg),getName(startPCReg), value );
173
cursor += 4;
174
175
printPrefix(pOutFile, NULL, cursor, 4);
176
value = *((int32_t *) cursor) & 0x0ffff;
177
trfprintf(pOutFile, "ori \t%s, %s, 0x%p\t;", getName(startPCReg), getName(startPCReg), value);
178
cursor += 4;
179
}
180
else
181
{
182
printPrefix(pOutFile, NULL, cursor, 4);
183
value = *((int32_t *) cursor) & 0x0ffff;
184
trfprintf(pOutFile, "lis \t%s, 0x%p\t; Load jit entry point address", getName(startPCReg),value );
185
cursor += 4;
186
187
printPrefix(pOutFile, NULL, cursor, 4);
188
value = *((int32_t *) cursor) & 0x0ffff;
189
trfprintf(pOutFile, "ori \t%s, %s, 0x%p\t;", getName(startPCReg), getName(startPCReg), value);
190
cursor += 4;
191
}
192
193
char *info = "";
194
if (isBranchToTrampoline(_cg->getSymRef(TR_PPCinduceRecompilation), cursor, value))
195
info = " Through trampoline";
196
197
printPrefix(pOutFile, NULL, cursor, 4);
198
value = *((int32_t *) cursor) & 0x03fffffc;
199
value = (value << 6) >> 6; // sign extend
200
trfprintf(pOutFile, "b \t" POINTER_PRINTF_FORMAT "\t; %s%s", (intptr_t)cursor + value, getName(_cg->getSymRef(TR_PPCinduceRecompilation)), info);
201
cursor += 4;
202
}
203
204
uint32_t TR::PPCForceRecompilationSnippet::getLength(int32_t estimatedSnippetStart)
205
{
206
return(cg()->comp()->target().is64Bit() ? 6*PPC_INSTRUCTION_LENGTH : 3*PPC_INSTRUCTION_LENGTH);
207
}
208
209