Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/z/codegen/J9TreeEvaluator.hpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2022 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
#ifndef J9_Z_TREE_EVALUATOR_INCL
24
#define J9_Z_TREE_EVALUATOR_INCL
25
26
/*
27
* The following #define and typedef must appear before any #includes in this file
28
*/
29
#ifndef J9_TREE_EVALUATOR_CONNECTOR
30
#define J9_TREE_EVALUATOR_CONNECTOR
31
namespace J9 { namespace Z { class TreeEvaluator; } }
32
namespace J9 { typedef J9::Z::TreeEvaluator TreeEvaluatorConnector; }
33
#else
34
#error J9::Z::TreeEvaluator expected to be a primary connector, but a J9 connector is already defined
35
#endif
36
37
#include "codegen/Snippet.hpp"
38
#include "compiler/codegen/J9TreeEvaluator.hpp" // include parent
39
#include "il/MethodSymbol.hpp"
40
41
#define INSN_HEAP cg->trHeapMemory()
42
43
namespace J9
44
{
45
46
namespace Z
47
{
48
49
class OMR_EXTENSIBLE TreeEvaluator: public J9::TreeEvaluator
50
{
51
public:
52
53
static void inlineEncodeASCII(TR::Node *node, TR::CodeGenerator *cg);
54
55
/** \brief
56
* Evaluates a sequence of instructions which generate the current time in terms of 1/2048 of micro-seconds.
57
*
58
* \param cg
59
* The code generator used to generate the instructions.
60
*
61
* \param node
62
* The node with which to associate the generated instructions with.
63
*
64
* \return
65
* A register (or register pair for 31-bit) containing the current time in terms of 1/2048 of micro-seconds.
66
*/
67
static TR::Register *inlineCurrentTimeMaxPrecision(TR::CodeGenerator *cg, TR::Node *node);
68
/**
69
* generate a single precision sqrt instruction
70
*/
71
static TR::Register *inlineSinglePrecisionSQRT(TR::Node *node, TR::CodeGenerator *cg);
72
/*
73
* Inline Java's (Java 11 onwards) StringLatin1.inflate([BI[CII)V
74
*/
75
static TR::Register *inlineStringLatin1Inflate(TR::Node *node, TR::CodeGenerator *cg);
76
static TR::Register *VMinlineCompareAndSwap( TR::Node *node, TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic casOp, bool isObj);
77
static TR::Register *inlineAtomicOps(TR::Node *node, TR::CodeGenerator *cg, int8_t size, TR::MethodSymbol *method, bool isArray = false);
78
static TR::Register *inlineAtomicFieldUpdater(TR::Node *node, TR::CodeGenerator *cg, TR::MethodSymbol *method);
79
static TR::Register *inlineKeepAlive(TR::Node *node, TR::CodeGenerator *cg);
80
static TR::Register *inlineConcurrentLinkedQueueTMOffer(TR::Node *node, TR::CodeGenerator *cg);
81
static TR::Register *inlineConcurrentLinkedQueueTMPoll(TR::Node *node, TR::CodeGenerator *cg);
82
static TR::Register *toUpperIntrinsic(TR::Node *node, TR::CodeGenerator *cg, bool isCompressedString);
83
static TR::Register *toLowerIntrinsic(TR::Node *node, TR::CodeGenerator *cg, bool isCompressedString);
84
85
/**
86
* \brief
87
*
88
* Use vector instructions to find the index of a sub-string inside
89
* a string assuming both strings have the same element size. Each element
90
* is 1-byte for compact strings and 2-bytes for non-compressed strings.
91
*
92
* \details
93
*
94
* The vector sequence searches for the first character of the sub-string
95
* inside the source/main string. If the first character is located, it'll
96
* perform iterative vector binary compares to match the rest of the sub-string
97
* starting from the first character position.
98
*
99
* This evaluator inlines the following Java intrinsic methods:
100
*
101
* <verbatim>
102
* For Java 9 and above:
103
*
104
* StringLatin1.indexOf(s1Value, s1Length, s2Value, s2Length, fromIndex);
105
* StringUTF16.indexOf(s1Value, s1Length, s2Value, s2Length, fromIndex);
106
*
107
* For Java 8:
108
* com.ibm.jit.JITHelpers.intrinsicIndexOfStringLatin1(Object s1Value, int s1len, Object s2Value, int s2len, int start);
109
* com.ibm.jit.JITHelpers.intrinsicIndexOfStringUTF16(Object s1Value, int s1len, Object s2Value, int s2len, int start);
110
*
111
* Assumptions:
112
*
113
* -# 0 <= fromIndex < s1Length
114
* -# s1Length could be anything: positive, negative or 0.
115
* -# s2Length > 0
116
* -# s1Value and s2Value are non-null arrays and are interpreted as byte arrays.
117
* -# s1Length and s2Length are not related. i.e. s1Length could be smallers than s2Length.
118
*
119
* <\verbatim>
120
*
121
* \param node the intrinsic function call node
122
* \param cg the code generator
123
* \param isUTF16 true if the string is a decompressed string.
124
*
125
* \return a register for that contains the indexOf() result.
126
*/
127
static TR::Register *inlineVectorizedStringIndexOf(TR::Node *node, TR::CodeGenerator *cg, bool isCompressed);
128
static TR::Register *inlineIntrinsicIndexOf(TR::Node *node, TR::CodeGenerator *cg, bool isLatin1);
129
static TR::Register *inlineDoubleMax(TR::Node *node, TR::CodeGenerator *cg);
130
static TR::Register *inlineDoubleMin(TR::Node *node, TR::CodeGenerator *cg);
131
static TR::Register *inlineMathFma(TR::Node *node, TR::CodeGenerator *cg);
132
133
/* This Evaluator generates the SIMD routine for methods
134
* java/lang/String.hashCodeImplCompressed and
135
* java/lang/String.hashCodeImplDecompressed depending on the "isCompressed"
136
* parameter passed to it.
137
*/
138
static TR::Register *inlineStringHashCode(TR::Node *node, TR::CodeGenerator *cg, bool isCompressed);
139
static TR::Register *inlineUTF16BEEncodeSIMD(TR::Node *node, TR::CodeGenerator *cg);
140
static TR::Register* inlineUTF16BEEncode (TR::Node *node, TR::CodeGenerator *cg);
141
142
static TR::Register *zdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
143
static TR::Register *zdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
144
static TR::Register *zdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
145
static TR::Register *zdstoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
146
static TR::Register *zdsleLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
147
static TR::Register *zdslsLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
148
static TR::Register *zdstsLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
149
static TR::Register *zdsleLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
150
static TR::Register *zdslsLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
151
static TR::Register *zdstsLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
152
static TR::Register *zdsleStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
153
static TR::Register *zdslsStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
154
static TR::Register *zdstsStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
155
static TR::Register *zdsleStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
156
static TR::Register *zdslsStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
157
static TR::Register *zdstsStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
158
static TR::Register *zd2zdsleEvaluator(TR::Node *node, TR::CodeGenerator *cg);
159
static TR::Register *zd2zdstsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
160
static TR::Register *zdsle2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
161
static TR::Register *zdsts2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
162
static TR::Register *zdsts2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
163
static TR::Register *pd2zdslsSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);
164
static TR::Register *pd2zdstsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
165
static TR::Register *pd2zdstsSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);
166
static TR::Register *udLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
167
static TR::Register *udslLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
168
static TR::Register *udstLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
169
static TR::Register *udLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
170
static TR::Register *udslLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
171
static TR::Register *udstLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
172
static TR::Register *udStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
173
static TR::Register *udslStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
174
static TR::Register *udstStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
175
static TR::Register *udStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
176
static TR::Register *udslStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
177
static TR::Register *udstStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
178
static TR::Register *pd2udstEvaluator(TR::Node *node, TR::CodeGenerator *cg);
179
static TR::Register *udsl2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);
180
static TR::Register *udst2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);
181
static TR::Register *udst2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
182
static TR::Register *pdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
183
static TR::Register *pdstoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
184
static TR::Register *pddivEvaluator(TR::Node *node, TR::CodeGenerator *cg);
185
static TR::Register *pdremEvaluator(TR::Node *node, TR::CodeGenerator *cg);
186
static TR::Register *pdabsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
187
static TR::Register *pdshrSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);
188
static TR::Register *pdshlSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);
189
static TR::Register *pdshlOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);
190
static TR::Register *pd2iOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);
191
static TR::Register *pd2iuEvaluator(TR::Node *node, TR::CodeGenerator *cg);
192
static TR::Register *iu2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
193
static TR::Register *pd2lOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);
194
static TR::Register *pd2luEvaluator(TR::Node *node, TR::CodeGenerator *cg);
195
static TR::Register *lu2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
196
static TR::Register *pd2fEvaluator(TR::Node *node, TR::CodeGenerator *cg);
197
static TR::Register *pd2dEvaluator(TR::Node *node, TR::CodeGenerator *cg);
198
static TR::Register *f2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
199
static TR::Register *d2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
200
static TR::Register *pdcleanEvaluator(TR::Node *node, TR::CodeGenerator *cg);
201
static TR::Register *pdclearSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);
202
203
static TR::Register *monentEvaluator(TR::Node *node, TR::CodeGenerator *cg);
204
static TR::Register *monexitEvaluator(TR::Node *node, TR::CodeGenerator *cg);
205
static TR::Register *asynccheckEvaluator(TR::Node *node, TR::CodeGenerator *cg);
206
static TR::Register *instanceofEvaluator(TR::Node *node, TR::CodeGenerator *cg);
207
static TR::Register *checkcastEvaluator(TR::Node *node, TR::CodeGenerator *cg);
208
static TR::Register *checkcastAndNULLCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
209
static TR::Register *generateHelperCallForVMNewEvaluators(TR::Node *node, TR::CodeGenerator *cg, bool doInlineAllocation = false, TR::Register *resReg = NULL);
210
static TR::Register *newObjectEvaluator(TR::Node *node, TR::CodeGenerator *cg);
211
static TR::Register *newArrayEvaluator(TR::Node *node, TR::CodeGenerator *cg);
212
static TR::Register *anewArrayEvaluator(TR::Node *node, TR::CodeGenerator *cg);
213
static TR::Register *multianewArrayEvaluator(TR::Node *node, TR::CodeGenerator *cg);
214
static TR::Register *arraylengthEvaluator(TR::Node *node, TR::CodeGenerator *cg);
215
static TR::Register *DIVCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
216
static TR::Register *BNDCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
217
static TR::Register *ArrayCopyBNDCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
218
static TR::Register *BNDCHKwithSpineCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
219
static TR::Register *ArrayStoreCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
220
static TR::Register *ArrayCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
221
static TR::Register *conditionalHelperEvaluator(TR::Node *node, TR::CodeGenerator *cg);
222
static TR::Register *NULLCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
223
static TR::Register *resolveAndNULLCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
224
static TR::Register *evaluateNULLCHKWithPossibleResolve(TR::Node *node, bool needResolution, TR::CodeGenerator *cg);
225
static float interpreterProfilingInstanceOfOrCheckCastTopProb(TR::CodeGenerator * cg, TR::Node * node);
226
227
/**
228
* \brief
229
* In concurrent scavenge (CS) mode, this is used to evaluate ardbari nodes and inlined-compare-and-swap to
230
* generate a guarded load software sequence that is functionally equivalent to LGG/LLGFSG instructions on z.
231
*
232
* \param node
233
* the read barrier node to evaluate
234
*
235
* \param cg
236
* the code generator object
237
*
238
* \param resultReg
239
* the read barrier's result register
240
*
241
* \param memRef
242
* a memory reference to the reference field to load from
243
*
244
* \param deps
245
* A register dependency condition pointer used when the software read barrier, which itself is an internal
246
* control flow (ICF), is built inside another ICF. This is the outer ICF's dependency conditions.
247
* When the deps parameter is not NULL, this evaluator helper does not build its own dependencies. Instead,
248
* it builds on top of this outer deps.
249
*
250
* \param produceUnshiftedValue
251
* A flag to make this evaluator produce unshifted reference loads for compressed reference Java.
252
* For compressed reference builds, a guarded reference field load normally produces a
253
* reference (64-bit value).
254
* However, for compressed reference array copy, it is faster to do 32-bit load, 32-bit range check,
255
* and 32-bit stores. Hence, eliminating the need for shift instructions (compression and decompression).
256
*
257
* \return
258
* returns a register that contains the reference field.
259
*/
260
static TR::Register *generateSoftwareReadBarrier(TR::Node* node,
261
TR::CodeGenerator* cg,
262
TR::Register* resultReg,
263
TR::MemoryReference* memRef,
264
TR::RegisterDependencyConditions* deps = NULL,
265
bool produceUnshiftedValue = false);
266
267
/** \brief
268
* Evaluates a reference arraycopy node. If software concurrent scavenge is not enabled, it generates an
269
* MVC memory-memory copy for a forward arraycopy and a
270
* loop based on the reference size for a backward arraycopy. For runtimes which support it, this function will
271
* also generate write barrier checks on \p byteSrcObjNode and \p byteDstObjNode.
272
*
273
* When software concurrent scavenge is enabled, it generates a internal control flow that first checks if the current
274
* execution is in the GC cycle and performs either a loop-based array copy or a helper call.
275
*
276
* \param node
277
* The reference arraycopy node.
278
*
279
* \param cg
280
* The code generator used to generate the instructions.
281
*/
282
static TR::Register *referenceArraycopyEvaluator(TR::Node *node, TR::CodeGenerator *cg);
283
static TR::Register *arraycopyEvaluator(TR::Node *node, TR::CodeGenerator *cg);
284
285
static TR::Register *generateConstantLengthReferenceArrayCopy(TR::Node *node, TR::CodeGenerator *cg);
286
287
static void generateLoadAndStoreForArrayCopy(TR::Node *node, TR::CodeGenerator *cg, TR::MemoryReference *srcMemRef,
288
TR::MemoryReference *dstMemRef,
289
TR_S390ScratchRegisterManager *srm,
290
TR::DataType elenmentType,
291
bool needsGuardedLoad,
292
TR::RegisterDependencyConditions* deps = NULL);
293
294
static void forwardArrayCopySequenceGenerator(TR::Node *node, TR::CodeGenerator *cg,
295
TR::Register *byteSrcReg, TR::Register *byteDstReg,
296
TR::Register *byteLenReg, TR::Node *byteLenNode,
297
TR_S390ScratchRegisterManager *srm, TR::LabelSymbol *mergeLabel);
298
static TR::RegisterDependencyConditions * backwardArrayCopySequenceGenerator(TR::Node *node, TR::CodeGenerator *cg,
299
TR::Register *byteSrcReg, TR::Register *byteDstReg,
300
TR::Register *byteLenReg, TR::Node *byteLenNode,
301
TR_S390ScratchRegisterManager *srm, TR::LabelSymbol *mergeLabel);
302
303
304
/* START BCD Evaluators */
305
// Used for VPSOP in vector setSign operations
306
enum SignOperationType
307
{
308
maintain, // maintain sign
309
complement, // complement sign
310
setSign // force positive or negative
311
};
312
313
static TR::Register *zdsls2zdEvaluator(TR::Node * node, TR::CodeGenerator * cg);
314
static TR::Register *zd2zdslsEvaluator(TR::Node * node, TR::CodeGenerator * cg);
315
static TR::Register *pd2zdslsEvaluator(TR::Node * node, TR::CodeGenerator * cg);
316
static TR::Register *zdsls2pdEvaluator(TR::Node * node, TR::CodeGenerator * cg);
317
static void zonedToZonedSeparateSignHelper(TR::Node *node, TR_PseudoRegister *srcReg, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR::MemoryReference *destMR, TR::CodeGenerator * cg);
318
static TR::MemoryReference *packedToZonedHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR_PseudoRegister *childReg, TR::CodeGenerator * cg);
319
static void pd2zdSignFixup(TR::Node *node, TR::MemoryReference *destMR, TR::CodeGenerator * cg, bool useLeftAlignedMR);
320
static TR::Register *zdstoreiVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
321
322
static void zonedSeparateSignToPackedOrZonedHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR::MemoryReference *destMR, TR::CodeGenerator * cg);
323
static TR::Register *zdsle2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
324
static TR::MemoryReference *zonedToPackedHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR_PseudoRegister *childReg, TR::CodeGenerator * cg);
325
static TR::MemoryReference *packedToUnicodeHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR_PseudoRegister *childReg, bool isSeparateSign, TR::CodeGenerator * cg, TR_StorageReference* srcStorageReference);
326
static TR::MemoryReference *asciiAndUnicodeToPackedHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR_PseudoRegister *childReg, TR::CodeGenerator * cg);
327
328
/* PD -> UD/ZD */
329
static TR::Register *pd2udslEvaluator(TR::Node *node, TR::CodeGenerator *cg);
330
static TR::Register *pd2udslEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
331
static TR::Register *pd2udslVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
332
static TR::Register *pd2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);
333
static TR::Register *pd2udEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
334
static TR::Register *pd2udVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
335
static TR::Register *pd2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
336
static TR::Register *pd2zdVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
337
338
/* PD <- UD/ZD */
339
static TR::Register *ud2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
340
static TR::Register *ud2pdVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
341
static TR::Register *udsl2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
342
static TR::Register *zd2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
343
static TR::Register *zd2pdVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
344
345
static bool isZonedOperationAnEffectiveNop(TR::Node * node, int32_t shiftAmount, bool isTruncation, TR_PseudoRegister *srcReg, bool isSetSign, int32_t sign,TR::CodeGenerator * cg);
346
347
348
static TR::Register *BCDCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);
349
static TR::Register *BCDCHKEvaluatorImpl(TR::Node * node,
350
TR::CodeGenerator * cg,
351
uint32_t numCallParam,
352
uint32_t callChildStartIndex,
353
bool isResultPD,
354
bool isUseVector,
355
bool isVariableParam);
356
357
static TR::Register *pd2iEvaluator(TR::Node *node, TR::CodeGenerator *cg);
358
static TR::Register *pd2lEvaluator(TR::Node *node, TR::CodeGenerator *cg);
359
static TR::Register *i2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
360
static TR::Register *l2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);
361
static TR::Register* pd2lVariableEvaluator(TR::Node* node, TR::CodeGenerator* cg, bool isUseVectorBCD);
362
static TR::Register *generatePackedToBinaryConversion(TR::Node * node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator * cg);
363
static TR::Register *generateVectorPackedToBinaryConversion(TR::Node * node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator * cg);
364
static TR::Register *generateBinaryToPackedConversion(TR::Node * node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator * cg);
365
static TR::Register *generateVectorBinaryToPackedConversion(TR::Node * node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator * cg);
366
367
static void correctPackedArithmeticPrecision(TR::Node *node, int32_t op1EncodingSize, TR_PseudoRegister *targetReg, int32_t computedResultPrecision, TR::CodeGenerator * cg);
368
369
static TR::Register *pdaddEvaluator(TR::Node *node, TR::CodeGenerator *cg);
370
static TR::Register *pdsubEvaluator(TR::Node *node, TR::CodeGenerator *cg);
371
static TR::Register *pdaddsubEvaluatorHelper(TR::Node *node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator *cg);
372
static TR::Register *pdArithmeticVectorEvaluatorHelper(TR::Node *node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator *cg);
373
374
static TR::Register *pdmulEvaluator(TR::Node *node, TR::CodeGenerator *cg);
375
static TR::Register *pdmulEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
376
377
static TR::Register *pddivremEvaluator(TR::Node *node, TR::CodeGenerator *cg);
378
static TR::Register *pddivremEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
379
static TR::Register *pddivremVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
380
381
static TR::Register *pdnegEvaluator(TR::Node *node, TR::CodeGenerator *cg);
382
383
static void clearAndSetSign(TR::Node *node,
384
TR_PseudoRegister *targetReg,
385
int32_t leftMostByteForClear,
386
int32_t digitsToClear,
387
TR::MemoryReference *destMR,
388
TR_PseudoRegister *srcReg,
389
TR::MemoryReference *sourceMR,
390
bool isSetSign,
391
int32_t sign,
392
bool signCodeIsInitialized,
393
TR::CodeGenerator *cg);
394
395
static TR_PseudoRegister *simpleWideningOrTruncation(TR::Node *node,
396
TR_PseudoRegister *srcReg,
397
bool isSetSign,
398
int32_t sign,
399
TR::CodeGenerator *cg);
400
401
static TR::Register *pdshrEvaluator(TR::Node *node, TR::CodeGenerator *cg);
402
static TR::Register *pdshrEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
403
static TR::Register *pdshrVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
404
405
static TR::Register *pdshlEvaluator(TR::Node *node, TR::CodeGenerator *cg);
406
static TR::Register *pdshiftEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isRightShift);
407
408
static TR::Register *pdModifyPrecisionEvaluator(TR::Node * node, TR::CodeGenerator * cg);
409
static TR::Register *pdshlVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
410
411
/** \brief
412
* Helper to generate a VPSOP instruction.
413
*
414
* \param node
415
* The node to which the instruction is associated.
416
* \param cg
417
* The codegen object.
418
* \param setPrecision
419
* Determines whether the VPSOP instruction will set precision.
420
* \param precision
421
* The new precision value.
422
* \param signedStatus
423
* Determines whether positive results will carry the preferred positive sign 0xC if true or 0xF if false.
424
* \param soType
425
* See enum SignOperationType.
426
* \param signValidityCheck
427
* Checks if originalSignCode is a valid sign.
428
* \param digitValidityCheck
429
* Validate the input digits
430
* \param sign
431
* The new sign. Used if signOpType is SignOperationType::setSign. Possible values include:
432
* - positive: 0xA, 0xC
433
* - negative: 0xB, 0xD
434
* - unsigned: 0xF
435
* \param setConditionCode
436
* Determines if this instruction sets ConditionCode or not.
437
* \param ignoreDecimalOverflow
438
* Turns on the Instruction Overflow Mask (IOM) so no decimal overflow is triggered
439
*/
440
static TR::Register *vectorPerformSignOperationHelper(TR::Node *node,
441
TR::CodeGenerator *cg,
442
bool setPrecision,
443
uint32_t precision,
444
bool signedStatus,
445
SignOperationType soType,
446
bool signValidityCheck = false,
447
bool digitValidityCheck = true,
448
int32_t sign = 0,
449
bool setConditionCode = true,
450
bool ignoreDecimalOverflow = false);
451
452
static TR::Register *pdchkEvaluator(TR::Node *node, TR::CodeGenerator *cg);
453
454
static TR::Register *pdcmpeqEvaluator(TR::Node *node, TR::CodeGenerator *cg);
455
static TR::Register *pdcmpneEvaluator(TR::Node *node, TR::CodeGenerator *cg);
456
static TR::Register *pdcmpltEvaluator(TR::Node *node, TR::CodeGenerator *cg);
457
static TR::Register *pdcmpgeEvaluator(TR::Node *node, TR::CodeGenerator *cg);
458
static TR::Register *pdcmpgtEvaluator(TR::Node *node, TR::CodeGenerator *cg);
459
static TR::Register *pdcmpleEvaluator(TR::Node *node, TR::CodeGenerator *cg);
460
static TR::Register *pdcmpVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
461
462
static TR::Register *zdabsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
463
static TR::Register *pdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
464
static TR::Register *pdloadEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
465
static TR::Register *pdloadVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
466
static TR::Register *pdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
467
static TR::Register *pdstoreEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
468
static TR::Register *pdstoreVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);
469
static TR_OpaquePseudoRegister *evaluateValueModifyingOperand(TR::Node * node, bool initTarget, TR::MemoryReference *sourceMR, TR::CodeGenerator * cg, bool trackSignState=false, int32_t srcSize=0, bool alwaysLegalToCleanSign=false);
470
static TR_PseudoRegister *evaluateBCDValueModifyingOperand(TR::Node * node, bool initTarget, TR::MemoryReference *sourceMR, TR::CodeGenerator * cg, bool trackSignState=false, int32_t srcSize=0, bool alwaysLegalToCleanSign=false);
471
static TR_OpaquePseudoRegister *evaluateSignModifyingOperand(TR::Node *node, bool isEffectiveNop, bool isNondestructiveNop, bool initTarget, TR::MemoryReference *sourceMR, TR::CodeGenerator *cg);
472
static TR_PseudoRegister *evaluateBCDSignModifyingOperand(TR::Node *node, bool isEffectiveNop, bool isNondestructiveNop, bool initTarget, TR::MemoryReference *sourceMR, TR::CodeGenerator *cg);
473
474
static TR::Register *pdclearEvaluator(TR::Node *node, TR::CodeGenerator *cg);
475
static TR::Register *pdSetSignHelper(TR::Node *node, int32_t sign, TR::CodeGenerator *cg);
476
static TR::Register *pdSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);
477
/* END BCD Evaluators */
478
479
static TR::Register *countDigitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);
480
static void countDigitsHelper(TR::Node * node, TR::CodeGenerator * cg,
481
int32_t memRefIndex, TR::MemoryReference * memRef,
482
TR::Register* inputReg, TR::Register* countReg,
483
TR::LabelSymbol *doneLabel, bool isLong);
484
485
static TR::Register *tstartEvaluator(TR::Node *node, TR::CodeGenerator *cg);
486
static TR::Register *tfinishEvaluator(TR::Node *node, TR::CodeGenerator *cg);
487
static TR::Register *tabortEvaluator(TR::Node *node, TR::CodeGenerator *cg);
488
489
static TR::Instruction *generateRuntimeInstrumentationOnOffSequence(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, TR::Node *node, TR::Instruction *preced = NULL, bool postRA = false);
490
static TR::Instruction* genLoadForObjectHeaders (TR::CodeGenerator *cg, TR::Node *node, TR::Register *reg, TR::MemoryReference *tempMR, TR::Instruction *iCursor);
491
static TR::Instruction* genLoadForObjectHeadersMasked(TR::CodeGenerator *cg, TR::Node *node, TR::Register *reg, TR::MemoryReference *tempMR, TR::Instruction *iCursor);
492
static TR::Instruction *generateVFTMaskInstruction(TR::Node *node, TR::Register *reg, TR::CodeGenerator *cg, TR::Instruction *preced = NULL);
493
static TR::Register *VMifInstanceOfEvaluator(TR::Node *node, TR::CodeGenerator *cg);
494
static bool VMinlineCallEvaluator(TR::Node *node, bool, TR::CodeGenerator *cg);
495
496
/** \brief
497
* Generates Sequence to check and use Guarded Load for ArrayCopy
498
*
499
* \param node
500
* The arraycopy node.
501
*
502
* \param cg
503
* The code generator used to generate the instructions.
504
*
505
* \param byteSrcReg
506
* Register holding starting address of source
507
*
508
* \param byteDstReg
509
* Register holding starting address of destination
510
*
511
* \param byteLenReg
512
* Register holding number of bytes to copy
513
*
514
* \param mergeLabel
515
* Label Symbol to merge from generated OOL sequence
516
*
517
* \param srm
518
* Scratch Register Manager providing pool of scratch registers to use
519
*
520
* \param isForward
521
* Boolean specifying if we need to copy elements in forward direction
522
*
523
*/
524
static void genGuardedLoadOOL(TR::Node *node, TR::CodeGenerator *cg, TR::Register *byteSrcReg, TR::Register *byteDstReg, TR::Register *byteLenReg, TR::LabelSymbol *mergeLabel, TR_S390ScratchRegisterManager *srm, bool isForward);
525
static void genArrayCopyWithArrayStoreCHK(TR::Node *node, TR::Register *srcObjReg, TR::Register *dstObjReg, TR::Register *srcAddrReg, TR::Register *dstAddrReg, TR::Register *lengthReg, TR::CodeGenerator *cg);
526
static void genWrtbarForArrayCopy(TR::Node *node, TR::Register *srcObjReg, TR::Register *dstObjReg, bool srcNonNull, TR::CodeGenerator *cg);
527
static TR::Register *VMgenCoreInstanceofEvaluator(TR::Node *node, TR::CodeGenerator *cg, TR::LabelSymbol * trueLabel, TR::LabelSymbol * falseLabel, bool initialResult, bool needResult, TR::RegisterDependencyConditions * conditions, bool ifInstanceOf=false);
528
static TR::Register *VMmonentEvaluator(TR::Node *node, TR::CodeGenerator *cg);
529
static TR::Register *VMmonexitEvaluator(TR::Node *node, TR::CodeGenerator *cg);
530
static TR::Register *VMnewEvaluator(TR::Node *node, TR::CodeGenerator *cg);
531
static TR::Register *VMarrayCheckEvaluator(TR::Node *node, TR::CodeGenerator *cg);
532
static void restoreGPR7(TR::Node *node, TR::CodeGenerator *cg);
533
534
/*
535
* Generate instructions for static/instance field access report.
536
* @param dataSnippetRegister: Optional, can be used to pass the address of the snippet inside the register.
537
*/
538
static void generateTestAndReportFieldWatchInstructions(TR::CodeGenerator *cg, TR::Node *node, TR::Snippet *dataSnippet, bool isWrite, TR::Register *sideEffectRegister, TR::Register *valueReg, TR::Register *dataSnippetRegister);
539
540
541
/*
542
* Generate instructions to fill in the J9JITWatchedStaticFieldData.fieldAddress, J9JITWatchedStaticFieldData.fieldClass for static fields,
543
* and J9JITWatchedInstanceFieldData.offset for instance fields at runtime. Used for fieldwatch support.
544
* @param dataSnippetRegister: Optional, can be used to pass the address of the snippet inside the register.
545
*/
546
static void generateFillInDataBlockSequenceForUnresolvedField (TR::CodeGenerator *cg, TR::Node *node, TR::Snippet *dataSnippet, bool isWrite, TR::Register *sideEffectRegister, TR::Register *dataSnippetRegister);
547
static TR::Register *irdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);
548
static TR::Register *irdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);
549
static TR::Register *ardbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);
550
static TR::Register *ardbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);
551
static TR::Register *fwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);
552
static TR::Register *fwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);
553
static TR::Register *dwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);
554
static TR::Register *dwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);
555
static TR::Register *awrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);
556
static TR::Register *awrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);
557
558
static TR::Register *inlineIntegerStringSize(TR::Node *node, TR::CodeGenerator *cg);
559
static TR::Register *inlineIntegerToCharsForLatin1Strings(TR::Node *node, TR::CodeGenerator *cg);
560
static TR::Register *inlineIntegerToCharsForUTF16Strings(TR::Node *node, TR::CodeGenerator *cg);
561
};
562
}
563
564
}
565
566
#endif
567
568