Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/il/J9ILOps.hpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2021 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 J9ILOPS_INCL
24
#define J9ILOPS_INCL
25
26
#include "il/OMRILOps.hpp"
27
28
namespace J9 {
29
30
class ILOpCode : public OMR::ILOpCode
31
{
32
33
public:
34
35
ILOpCode() : OMR::ILOpCode() {}
36
ILOpCode(TR::ILOpCodes opCode) : OMR::ILOpCode(opCode) {}
37
38
/**
39
* ILTypeProp, ILProp1, ILProp2, ILProp3
40
*/
41
bool isFloatingPoint() const { return typeProperties().testAny(ILTypeProp::Floating_Point); }
42
bool isBCDLoadVar() const { return isLoadVar() && getType().isBCD(); }
43
bool isBCDLoad() const { return isLoad() && getType().isBCD(); }
44
bool isBCDStore() const { return isStore() && getType().isBCD(); }
45
bool isPackedConst() const { return isLoadConst() && getType().isAnyPacked(); }
46
bool isPackedStore() const { return isStore() && getType().isAnyPacked(); }
47
bool isPackedAdd() const { return isAdd() && getType().isAnyPacked(); }
48
bool isPackedSubtract() const { return isSub() && getType().isAnyPacked(); }
49
bool isPackedMultiply() const { return isMul() && getType().isAnyPacked(); }
50
bool isPackedDivide() const { return isDiv() && getType().isAnyPacked(); }
51
bool isPackedRemainder() const { return isRem() && getType().isAnyPacked(); }
52
bool isPackedShift() const { return isShift() && getType().isAnyPacked(); }
53
bool isPackedRightShift() const { return isRightShift() && getType().isAnyPacked(); }
54
bool isPackedLeftShift() const { return isLeftShift() && getType().isAnyPacked(); }
55
bool isBasicPackedArithmetic() const { return (isAdd() || isSub() || isMul() || isDiv() || isRem()) && getType().isAnyPacked(); }
56
57
/**
58
* ILProp4
59
*/
60
bool isSetSign() const { return properties4().testAny(ILProp4::SetSign); }
61
bool isSetSignOnNode() const { return properties4().testAny(ILProp4::SetSignOnNode); }
62
bool isModifyPrecision() const { return properties4().testAny(ILProp4::ModifyPrecision); }
63
bool isPackedModifyPrecision() const { return isModifyPrecision() && getType().isAnyPacked(); }
64
bool isConversionWithFraction() const { return properties4().testAny(ILProp4::ConversionHasFraction); }
65
bool isBinaryCodedDecimalOp() const { return properties4().testAny(ILProp4::BinaryCodedDecimalOp); }
66
bool isAnyBCDCompareOp() const { return isBinaryCodedDecimalOp() && isBooleanCompare(); } // isAnyBCDCompareOp is true for all BCD nodes that do some type of compare e.g. pdcmpxx
67
bool isBCDToNonBCDConversion() const { return isConversion() && isBinaryCodedDecimalOp() && !getType().isBCD(); }
68
bool isPackedArithmeticOverflowMessage() const { return properties4().testAny(ILProp4::PackedArithmeticOverflowMessage); }
69
bool isBasicOrSpecialPackedArithmetic() const { return isBasicPackedArithmetic() || isPackedArithmeticOverflowMessage(); }
70
bool isAnyBCDArithmetic() const { return isBasicOrSpecialPackedArithmetic(); }
71
bool trackLineNo() const { return properties4().testAny(ILProp4::TrackLineNo); }
72
bool canHavePaddingAddress() const { return properties4().testAny(ILProp4::CanHavePaddingAddress); }
73
bool canHaveStorageReferenceHint() const { return properties4().testAny(ILProp4::CanHaveStorageReferenceHint); }
74
bool canUseStoreAsAnAccumulator() const { return properties4().testAny(ILProp4::CanUseStoreAsAnAccumulator); }
75
76
77
bool isSignlessBCDType() const {return (getDataType() == TR::UnicodeDecimal); }
78
79
// i.e. a clean with no other side-effects
80
bool isSimpleBCDClean() const {return _opCode == TR::pdclean; }
81
82
bool isSqrt()
83
{
84
return OMR::ILOpCode::isSqrt();
85
}
86
87
static TR::ILOpCodes setSignOpCode(TR::DataType type)
88
{
89
switch (type)
90
{
91
case TR::PackedDecimal: return TR::pdSetSign;
92
default: TR_ASSERT(0, "no setSign opcode for this datatype");
93
}
94
return TR::BadILOp;
95
}
96
97
// returns the index (0->numChild-1) for the sign value to be set or retrieved
98
static int32_t getSetSignValueIndex(TR::ILOpCodes op)
99
{
100
int32_t index = 0;
101
switch (op)
102
{
103
case TR::pdSetSign:
104
case TR::pd2zdslsSetSign:
105
case TR::pd2zdstsSetSign:
106
index = 1; // child 2
107
break;
108
case TR::pdshlSetSign:
109
index = 2; // child 3
110
break;
111
case TR::pdshrSetSign:
112
index = 3; // child 4
113
break;
114
default:
115
TR_ASSERT(false,"op is not a setSign operation\n");
116
}
117
return index;
118
}
119
120
static TR::ILOpCodes setSignVersionOfOpCode(TR::ILOpCodes op)
121
{
122
switch(op)
123
{
124
case TR::pdshr: return TR::pdshrSetSign;
125
case TR::pdshl: return TR::pdshlSetSign;
126
case TR::pd2zdsls: return TR::pd2zdslsSetSign;
127
case TR::pd2zdsts: return TR::pd2zdstsSetSign;
128
default: return TR::BadILOp;
129
}
130
return TR::BadILOp;
131
}
132
133
static TR::ILOpCodes reverseSetSignOpCode(TR::ILOpCodes op)
134
{
135
switch(op)
136
{
137
case TR::pdshrSetSign: return TR::pdshr;
138
case TR::pdshlSetSign: return TR::pdshl;
139
case TR::pd2zdslsSetSign: return TR::pd2zdsls;
140
case TR::pd2zdstsSetSign: return TR::pd2zdsts;
141
default: return TR::BadILOp;
142
}
143
return TR::BadILOp;
144
}
145
146
static bool isZonedToZonedConversion(TR::ILOpCodes op)
147
{
148
switch (op)
149
{
150
case TR::zd2zdsle:
151
case TR::zdsle2zd:
152
return true;
153
default:
154
return false;
155
}
156
}
157
158
static bool isPackedConversionToWiderType(TR::ILOpCodes op)
159
{
160
switch(op)
161
{
162
case TR::pd2zd:
163
case TR::pd2zdslsSetSign:
164
case TR::pd2zdstsSetSign:
165
return true;
166
default:
167
return false;
168
}
169
170
}
171
172
static TR::ILOpCodes getProperConversion(TR::DataType sourceDataType, TR::DataType targetDataType, bool needUnsignedConversion)
173
{
174
TR::ILOpCodes op = TR::DataType::getDataTypeConversion(sourceDataType, targetDataType);
175
if (!needUnsignedConversion) return op;
176
177
switch (op)
178
{
179
case TR::i2pd: return TR::iu2pd;
180
case TR::l2pd: return TR::lu2pd;
181
case TR::pd2i: return TR::pd2iu;
182
case TR::pd2l: return TR::pd2lu;
183
184
default: return OMR::ILOpCode::getProperConversion(sourceDataType, targetDataType, needUnsignedConversion);
185
}
186
}
187
188
static bool isStrictlyLessThanCmp(TR::ILOpCodes op)
189
{
190
return OMR::ILOpCode::isStrictlyLessThanCmp(op);
191
}
192
193
static bool isStrictlyGreaterThanCmp(TR::ILOpCodes op)
194
{
195
return OMR::ILOpCode::isStrictlyGreaterThanCmp(op);
196
}
197
198
static bool isLessCmp(TR::ILOpCodes op)
199
{
200
return OMR::ILOpCode::isLessCmp(op);
201
}
202
203
static bool isGreaterCmp(TR::ILOpCodes op)
204
{
205
return OMR::ILOpCode::isGreaterCmp(op);
206
}
207
208
static bool isEqualCmp(TR::ILOpCodes op)
209
{
210
return OMR::ILOpCode::isEqualCmp(op);
211
}
212
213
static bool isNotEqualCmp(TR::ILOpCodes op)
214
{
215
return OMR::ILOpCode::isNotEqualCmp(op);
216
}
217
218
static TR::ILOpCodes cleanOpCode(TR::DataType type)
219
{
220
switch(type)
221
{
222
case TR::PackedDecimal: return TR::pdclean;
223
default: TR_ASSERT(0, "no clean opcode for this datatype");
224
}
225
return TR::BadILOp;
226
}
227
228
static TR::ILOpCodes absOpCode(TR::DataType type)
229
{
230
switch(type)
231
{
232
case TR::PackedDecimal: return TR::pdabs;
233
default: return OMR::ILOpCode::absOpCode(type);
234
}
235
return TR::BadILOp;
236
}
237
238
static TR::ILOpCodes addOpCode(TR::DataType type, bool is64Bit)
239
{
240
switch(type)
241
{
242
case TR::PackedDecimal: return TR::pdadd;
243
default: return OMR::ILOpCode::addOpCode(type, is64Bit);
244
}
245
return TR::BadILOp;
246
}
247
248
static TR::ILOpCodes subtractOpCode(TR::DataType type)
249
{
250
switch(type)
251
{
252
case TR::PackedDecimal: return TR::pdsub;
253
default: return OMR::ILOpCode::subtractOpCode(type);
254
}
255
return TR::BadILOp;
256
}
257
258
static TR::ILOpCodes multiplyOpCode(TR::DataType type)
259
{
260
switch(type)
261
{
262
case TR::PackedDecimal: return TR::pdmul;
263
default: return OMR::ILOpCode::multiplyOpCode(type);
264
}
265
return TR::BadILOp;
266
}
267
268
static TR::ILOpCodes divideOpCode(TR::DataType type)
269
{
270
switch(type)
271
{
272
case TR::PackedDecimal: return TR::pddiv;
273
default: return OMR::ILOpCode::divideOpCode(type);
274
}
275
return TR::BadILOp;
276
}
277
278
static TR::ILOpCodes remainderOpCode(TR::DataType type)
279
{
280
switch(type)
281
{
282
case TR::PackedDecimal: return TR::pdrem;
283
default: return OMR::ILOpCode::remainderOpCode(type);
284
}
285
return TR::BadILOp;
286
}
287
288
static TR::ILOpCodes negateOpCode(TR::DataType type)
289
{
290
switch(type)
291
{
292
case TR::PackedDecimal: return TR::pdneg;
293
default: return OMR::ILOpCode::negateOpCode(type);
294
}
295
return TR::BadILOp;
296
}
297
298
static TR::ILOpCodes modifyPrecisionOpCode(TR::DataType type)
299
{
300
switch (type)
301
{
302
case TR::PackedDecimal: return TR::pdModifyPrecision;
303
default: TR_ASSERT(0, "no modifyPrecision opcode for this datatype");
304
}
305
return TR::BadILOp;
306
}
307
308
static TR::ILOpCodes shiftLeftOpCode(TR::DataType type)
309
{
310
return OMR::ILOpCode::shiftLeftOpCode(type);
311
}
312
313
static TR::ILOpCodes shiftRightOpCode(TR::DataType type)
314
{
315
return OMR::ILOpCode::shiftRightOpCode(type);
316
}
317
318
static TR::ILOpCodes ifcmpgeOpCode(TR::DataType type, bool isUnsigned)
319
{
320
return OMR::ILOpCode::ifcmpgeOpCode(type, isUnsigned);
321
}
322
323
static TR::ILOpCodes ifcmpleOpCode(TR::DataType type, bool isUnsigned)
324
{
325
return OMR::ILOpCode::ifcmpleOpCode(type, isUnsigned);
326
}
327
328
static TR::ILOpCodes ifcmpgtOpCode(TR::DataType type, bool isUnsigned)
329
{
330
return OMR::ILOpCode::ifcmpgtOpCode(type, isUnsigned);
331
}
332
333
static TR::ILOpCodes ifcmpltOpCode(TR::DataType type, bool isUnsigned)
334
{
335
return OMR::ILOpCode::ifcmpltOpCode(type, isUnsigned);
336
}
337
338
static TR::ILOpCodes ifcmpeqOpCode(TR::DataType type)
339
{
340
return OMR::ILOpCode::ifcmpeqOpCode(type);
341
}
342
343
static TR::ILOpCodes ifcmpneOpCode(TR::DataType type)
344
{
345
return OMR::ILOpCode::ifcmpneOpCode(type);
346
}
347
348
static TR::ILOpCodes cmpeqOpCode(TR::DataType type)
349
{
350
return OMR::ILOpCode::cmpeqOpCode(type);
351
}
352
353
static TR::ILOpCodes constOpCode(TR::DataType type)
354
{
355
return OMR::ILOpCode::constOpCode(type);
356
}
357
358
static TR::ILOpCodes returnOpCode(TR::DataType type)
359
{
360
return OMR::ILOpCode::returnOpCode(type);
361
}
362
363
};
364
365
}
366
367
#endif
368
369
370