Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/z/codegen/J9S390Snippet.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 "z/codegen/J9S390Snippet.hpp"
24
25
#include <stdint.h>
26
#include "j9.h"
27
#include "thrdsup.h"
28
#include "thrtypes.h"
29
#include "codegen/CodeGenerator.hpp"
30
#include "codegen/GCStackMap.hpp"
31
#include "codegen/Machine.hpp"
32
#include "codegen/S390PrivateLinkage.hpp"
33
#include "codegen/SnippetGCMap.hpp"
34
#include "env/CompilerEnv.hpp"
35
#include "env/IO.hpp"
36
#include "env/jittypes.h"
37
#include "env/VMJ9.h"
38
#include "il/Node.hpp"
39
#include "il/Node_inlines.hpp"
40
#include "env/VMJ9.h"
41
#include "runtime/CodeCacheManager.hpp"
42
#include "z/codegen/S390Instruction.hpp"
43
#include "z/codegen/S390Snippets.hpp"
44
45
TR::S390HeapAllocSnippet::S390HeapAllocSnippet(
46
TR::CodeGenerator *codeGen,
47
TR::Node *node,
48
TR::LabelSymbol *callLabel,
49
TR::SymbolReference *destination,
50
TR::LabelSymbol *restartLabel)
51
: _restartLabel(restartLabel), _destination(destination), _isLongBranch(false), _length(0),
52
TR::Snippet(codeGen, node, callLabel, destination->canCauseGC())
53
{
54
if (destination->canCauseGC())
55
{
56
// Helper call, preserves all registers
57
//
58
gcMap().setGCRegisterMask(0x0000FFFF);
59
}
60
}
61
62
63
uint8_t *
64
TR::S390HeapAllocSnippet::emitSnippetBody()
65
{
66
TR::CodeGenerator * codeGen = cg();
67
TR::Compilation *comp = codeGen->comp();
68
TR_J9VMBase *fej9 = (TR_J9VMBase *)(codeGen->fe());
69
uint8_t * buffer = codeGen->getBinaryBufferCursor();
70
int32_t distance;
71
int32_t jumpToCallDistance = -1;
72
intptr_t branchToCallLocation = -1;
73
74
TR::Machine *machine = codeGen->machine();
75
TR::RegisterDependencyConditions *deps = getRestartLabel()->getInstruction()->getDependencyConditions();
76
TR::RealRegister * resReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(2)->getRealRegister());
77
uint32_t resRegEncoding = resReg->getRegisterNumber() - 1;
78
bool is64BitTarget = comp->target().is64Bit();
79
80
getSnippetLabel()->setCodeLocation(buffer);
81
82
TR_ASSERT(jumpToCallDistance == -1 || jumpToCallDistance == (((intptr_t)buffer) - branchToCallLocation), "Jump in Heap Alloc Misaligned.");
83
84
// The code for the none-G5 32bit snippet looks like:
85
// BRASL gr14, jitNewXXXX;
86
// LR/LGR resReg, gr2;
87
// BRC[L] restartLabel;
88
89
*(uint16_t *) buffer = 0xc0e5;
90
buffer += 2;
91
92
intptr_t destAddr = (intptr_t) getDestination()->getSymbol()->castToMethodSymbol()->getMethodAddress();
93
94
#if defined(TR_TARGET_64BIT)
95
#if defined(J9ZOS390)
96
if (comp->getOption(TR_EnableRMODE64))
97
#endif
98
{
99
if (NEEDS_TRAMPOLINE(destAddr, buffer, cg()))
100
{
101
uint32_t rEP = (uint32_t) cg()->getEntryPointRegister() - 1;
102
// Destination is beyond our reachable jump distance, we'll find the
103
// trampoline.
104
destAddr = TR::CodeCacheManager::instance()->findHelperTrampoline(getDestination()->getReferenceNumber(), (void *)buffer);
105
this->setUsedTrampoline(true);
106
107
// We clobber rEP if we take a trampoline. Update our register map if necessary.
108
if (gcMap().getStackMap() != NULL)
109
{
110
gcMap().getStackMap()->maskRegisters(~(0x1 << (rEP)));
111
}
112
}
113
}
114
#endif
115
116
TR_ASSERT(CHECK_32BIT_TRAMPOLINE_RANGE(destAddr, buffer), "Helper Call is not reachable.");
117
this->setSnippetDestAddr(destAddr);
118
119
*(int32_t *) buffer = (int32_t)((destAddr - (intptr_t)(buffer - 2)) / 2);
120
if (comp->compileRelocatableCode() || comp->isOutOfProcessCompilation())
121
{
122
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(buffer, (uint8_t*) getDestination(), TR_HelperAddress, cg()),
123
__FILE__, __LINE__, getNode());
124
}
125
126
buffer += sizeof(int32_t);
127
128
if (gcMap().getStackMap() != NULL)
129
{
130
gcMap().getStackMap()->resetRegistersBits(codeGen->registerBitMask(resReg->getRegisterNumber()));
131
}
132
133
gcMap().registerStackMap(buffer, cg());
134
135
if (is64BitTarget)
136
{
137
*(uint32_t *) buffer = 0xb9040002 | (resRegEncoding << 4);
138
buffer += 4;
139
}
140
else
141
{
142
*(uint16_t *) buffer = 0x1802 | (resRegEncoding << 4);
143
buffer += 2;
144
}
145
146
distance = (intptr_t) getRestartLabel()->getCodeLocation() - (intptr_t) buffer;
147
distance >>= 1;
148
if (!isLongBranch())
149
{
150
*(int32_t *) buffer = 0xa7f40000 | (distance & 0x0000ffff);
151
buffer += 4;
152
}
153
else
154
{
155
*(uint16_t *) buffer = 0xc0f4;
156
buffer += 2;
157
*(int32_t *) buffer = distance;
158
buffer += 4;
159
}
160
161
return buffer;
162
}
163
164
uint32_t
165
TR::S390HeapAllocSnippet::getLength(int32_t estimatedCodeStart)
166
{
167
TR::CodeGenerator * codeGen = cg();
168
TR::Compilation *comp = codeGen->comp();
169
int32_t distance;
170
uint32_t length = getMyLength();
171
172
if (length != 0)
173
{
174
return length;
175
}
176
177
distance = estimatedCodeStart +
178
(comp->target().is64Bit() ? 10 : 8) -
179
getRestartLabel()->getEstimatedCodeLocation();
180
181
// to be conservative: we use the byte count as half-word count, accounting for length estimation deviation
182
if (distance<MIN_IMMEDIATE_VAL || distance>MAX_IMMEDIATE_VAL)
183
{
184
setIsLongBranch(true);
185
}
186
if (comp->target().is64Bit())
187
{
188
if (isLongBranch())
189
length = 16;
190
else
191
length = 14;
192
}
193
else
194
{
195
if (isLongBranch())
196
length = 14;
197
else
198
length = 12;
199
}
200
201
setMyLength(length);
202
203
return length;
204
}
205
206
void
207
TR::S390HeapAllocSnippet::print(TR::FILE *pOutFile, TR_Debug *debug)
208
{
209
if (pOutFile == NULL)
210
{
211
return;
212
}
213
214
TR::Compilation *comp = cg()->comp();
215
TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());
216
uint8_t * buffer = getSnippetLabel()->getCodeLocation();
217
int32_t distance;
218
bool is64BitTarget = comp->target().is64Bit();
219
220
TR::Machine *machine = cg()->machine();
221
TR::RegisterDependencyConditions *deps = getRestartLabel()->getInstruction()->getDependencyConditions();
222
TR::RealRegister * resReg = machine->getRealRegister(deps->getPostConditions()->getRegisterDependency(2)->getRealRegister());
223
224
debug->printSnippetLabel(pOutFile, getSnippetLabel(), buffer, "HeapAlloc Snippet", debug->getName(getDestination()));
225
226
227
// The code for the snippet looks like:
228
// BRASL gr14, jitNewXXXX;
229
// LR/LGR resReg, gr2;
230
// BRC[L] restartLabel;
231
232
distance = (intptr_t) getDestination()->getSymbol()->castToMethodSymbol()->getMethodAddress() - (intptr_t) buffer;
233
234
debug->printPrefix(pOutFile, NULL, buffer, 6);
235
trfprintf(pOutFile, "BRASL \tGPR14, 0x%8x", distance >> 1);
236
buffer += 6;
237
238
if (comp->target().is64Bit())
239
{
240
debug->printPrefix(pOutFile, NULL, buffer, 4);
241
trfprintf(pOutFile, "LGR \t%s,GPR2", debug->getName(resReg));
242
buffer += 4;
243
}
244
else
245
{
246
debug->printPrefix(pOutFile, NULL, buffer, 2);
247
trfprintf(pOutFile, "LR \t%s, GPR2", debug->getName(resReg));
248
buffer += 2;
249
}
250
251
distance = (intptr_t) getRestartLabel()->getCodeLocation() - (intptr_t) buffer;
252
distance >>= 1;
253
if (!isLongBranch())
254
{
255
debug->printPrefix(pOutFile, NULL, buffer, 4);
256
trfprintf(pOutFile, "BRC \t");
257
debug->print(pOutFile, getRestartLabel());
258
buffer += 4;
259
}
260
else
261
{
262
debug->printPrefix(pOutFile, NULL, buffer, 6);
263
trfprintf(pOutFile, "BRCL \t");
264
debug->print(pOutFile, getRestartLabel());
265
buffer += 6;
266
}
267
}
268
269
uint32_t
270
TR::S390RestoreGPR7Snippet::getLength(int32_t estimatedSnippetStart)
271
{
272
273
if (cg()->comp()->target().is64Bit())
274
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
275
return 6*3 + 6 + 4;
276
#else
277
return 6*1 + 6 + 4;
278
#endif
279
else
280
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
281
return 4*3 + 6 + 4;
282
#else
283
return 4*1 + 6 + 4;
284
#endif
285
}
286
287
uint8_t *
288
TR::S390RestoreGPR7Snippet::emitSnippetBody()
289
{
290
uint8_t * cursor = cg()->getBinaryBufferCursor();
291
uint8_t * startPointCursor = cg()->getBinaryBufferCursor();
292
getSnippetLabel()->setCodeLocation(cursor);
293
TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg()->fe());
294
295
int32_t tempOffset = fej9->thisThreadGetTempSlotOffset();
296
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
297
int32_t returnOffset = fej9->thisThreadGetReturnValueOffset();
298
int32_t sspOffset = fej9->thisThreadGetSystemSPOffset();
299
#endif
300
301
302
//E370DXXX0058
303
if (cg()->comp()->target().is64Bit())//generate LG
304
{
305
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
306
*(int32_t *) cursor = 0xE340D000|sspOffset;
307
cursor += sizeof(int32_t);
308
*(int16_t *) cursor = 0x0024;
309
cursor += sizeof(int16_t);
310
#endif
311
312
//restore gpr7 from tempslot, 6bytes
313
*(int32_t *) cursor = 0xE370D000|tempOffset;
314
cursor += sizeof(int32_t);
315
*(int16_t *) cursor = 0x0004;
316
cursor += sizeof(int16_t);
317
318
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
319
//restore gpr4 from returnValue, 6 bytes
320
*(int32_t *) cursor = 0xE340D000|returnOffset;
321
cursor += sizeof(int32_t);
322
*(int16_t *) cursor = 0x0004;
323
cursor += sizeof(int16_t);
324
#endif
325
}
326
else
327
{ //generate L
328
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
329
TR_ASSERT(tempOffset < 4096 && returnOffset < 4096, "if > 4k then must use LY, not L.");
330
#else
331
TR_ASSERT(tempOffset < 4096, "if > 4k then must use LY, not L.");
332
#endif
333
334
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
335
//store GPR4 onto vmThread->ssp
336
*(int32_t *) cursor = 0x5040D000|(sspOffset & 0x0FFF);
337
cursor += sizeof(int32_t);
338
#endif
339
340
//gpr7, 4bytes
341
*(int32_t *) cursor = 0x5870D000|(tempOffset & 0x0FFF);
342
cursor += sizeof(int32_t);
343
344
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
345
//gpr4, 4bytes
346
*(int32_t *) cursor = 0x5840D000|(returnOffset & 0x0FFF);
347
cursor += sizeof(int32_t);
348
#endif
349
}
350
351
352
cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative32BitRelocation(cursor, getTargetLabel()));
353
// 6 bytes
354
// BRCL 0xf, <target>
355
*(int16_t *) cursor = 0xC0F4;
356
cursor += sizeof(int16_t);
357
358
// BRCL - Add Relocation the data constants to this LARL.
359
*(int32_t *) cursor = 0xDEADBEEF;
360
cursor += sizeof(int32_t);
361
362
#if defined(J9VM_JIT_FREE_SYSTEM_STACK_POINTER)
363
if (cg()->comp()->target().is64Bit())
364
TR_ASSERT(((U_8*)cursor) - startPointCursor == 24,
365
"for 64bit, DAA eyecatcher should be generated at offset 24 bytes");
366
else
367
TR_ASSERT(((U_8*)cursor) - startPointCursor == 18,
368
"for 31bit, DAA eyecatcher should be generated at offset 18 bytes");
369
#endif
370
371
*(int32_t *) cursor = 0xDAA0CA11;
372
cursor += sizeof(int32_t);
373
374
return cursor;
375
}
376
377
void
378
TR_Debug::print(TR::FILE *pOutFile, TR::S390RestoreGPR7Snippet *snippet)
379
{
380
uint8_t * buffer = snippet->getSnippetLabel()->getCodeLocation();
381
printSnippetLabel(pOutFile, snippet->getSnippetLabel(), buffer, "Restore GPR 7 after signal handler");
382
383
#ifdef J9VM_JIT_FREE_SYSTEM_STACK_POINTER
384
//save GPR4 to
385
if (_comp->target().is64Bit())
386
{
387
printPrefix(pOutFile, NULL, buffer, 6);
388
trfprintf(pOutFile, "STG GPR7, SSP(GPR13)", snippet->getTargetLabel()->getCodeLocation());
389
buffer += 6;
390
}
391
else
392
{
393
printPrefix(pOutFile, NULL, buffer, 4);
394
trfprintf(pOutFile, "ST GPR7, SSP(GPR13)", snippet->getTargetLabel()->getCodeLocation());
395
buffer += 4;
396
}
397
#endif
398
399
//0x4a2af68a (???) e370d0980058 LY R7,152(,R13)
400
if (_comp->target().is64Bit())
401
{
402
printPrefix(pOutFile, NULL, buffer, 6);
403
trfprintf(pOutFile, "LG GPR7, 152(GPR13)", snippet->getTargetLabel()->getCodeLocation());
404
buffer += 6;
405
}
406
else
407
{
408
printPrefix(pOutFile, NULL, buffer, 4);
409
trfprintf(pOutFile, "L GPR7, 144(GPR13)", snippet->getTargetLabel()->getCodeLocation());
410
buffer += 4;
411
}
412
413
#ifdef J9VM_JIT_FREE_SYSTEM_STACK_POINTER
414
// L R4,136(,R13)
415
if (_comp->target().is64Bit())
416
{
417
printPrefix(pOutFile, NULL, buffer, 6);
418
trfprintf(pOutFile, "LG GPR4, 136(GPR13)", snippet->getTargetLabel()->getCodeLocation());
419
buffer += 6;
420
}
421
else
422
{
423
printPrefix(pOutFile, NULL, buffer, 4);
424
trfprintf(pOutFile, "L GPR4, 136(GPR13)", snippet->getTargetLabel()->getCodeLocation());
425
buffer += 4;
426
}
427
#endif
428
429
//0x4a2af690 (???) c0f4fff1bb80 BRCL 15,*-1870080
430
printPrefix(pOutFile, NULL, buffer, 6);
431
trfprintf(pOutFile, "BRCL 0xF, targetLabel(%p)", snippet->getTargetLabel()->getCodeLocation());
432
buffer += 6;
433
434
printPrefix(pOutFile, NULL, buffer, 4);
435
trfprintf(pOutFile, "Eye Catcher = 0xDAA0CA11", snippet->getTargetLabel()->getCodeLocation());
436
buffer += 4;
437
}
438
439
440