-
Notifications
You must be signed in to change notification settings - Fork 139
/
Copy pathOMRInstruction.hpp
221 lines (173 loc) · 8.83 KB
/
OMRInstruction.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*******************************************************************************
* Copyright IBM Corp. and others 2000
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
* or the Apache License, Version 2.0 which accompanies this distribution
* and is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception [1] and GNU General Public
* License, version 2 with the OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] https://openjdk.org/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
*******************************************************************************/
#ifndef OMR_ARM_INSTRUCTION_INCL
#define OMR_ARM_INSTRUCTION_INCL
/*
* The following #define and typedef must appear before any #includes in this file
*/
#ifndef OMR_INSTRUCTION_CONNECTOR
#define OMR_INSTRUCTION_CONNECTOR
namespace OMR { namespace ARM { class Instruction; } }
namespace OMR { typedef OMR::ARM::Instruction InstructionConnector; }
#else
#error OMR::ARM::Instruction expected to be a primary connector, but an OMR connector is already defined
#endif
#include "compiler/codegen/OMRInstruction.hpp"
#include "codegen/InstOpCode.hpp"
#include "codegen/InstOpCode.hpp"
#include "codegen/GCStackMap.hpp"
#include "codegen/RegisterConstants.hpp"
namespace TR { class ARMConditionalBranchInstruction; }
namespace TR { class ARMDepImmInstruction; }
namespace TR { class ARMImmInstruction; }
namespace TR { class CodeGenerator; }
namespace TR { class MemoryReference; }
namespace TR { class RegisterDependencyConditions; }
struct TR_RegisterPressureState;
namespace OMR
{
namespace ARM
{
class OMR_EXTENSIBLE Instruction : public OMR::Instruction
{
public:
Instruction(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, TR::Node *node = 0);
Instruction(TR::CodeGenerator *cg, TR::Instruction *precedingInstruction, TR::InstOpCode::Mnemonic op, TR::Node *node = 0);
Instruction(TR::Node *node, TR::CodeGenerator *cg);
Instruction(TR::InstOpCode::Mnemonic op, TR::Node *node, TR::CodeGenerator *cg);
Instruction(TR::Instruction *precedingInstruction,
TR::InstOpCode::Mnemonic op,
TR::Node *node,
TR::CodeGenerator *cg);
Instruction(TR::InstOpCode::Mnemonic op,
TR::Node *node,
TR::RegisterDependencyConditions *cond,
TR::CodeGenerator *cg);
Instruction(TR::Instruction *precedingInstruction,
TR::InstOpCode::Mnemonic op,
TR::Node *node,
TR::RegisterDependencyConditions *cond,
TR::CodeGenerator *cg);
virtual const char *description() { return "ARM"; }
virtual Kind getKind() { return IsNotExtended; }
TR::InstOpCode::Mnemonic getRecordFormOpCode() {return _opcode.getRecordFormOpCodeValue();}
void ARMNeedsGCMap(uint32_t mask);
TR_ARMConditionCode getConditionCode() {return _conditionCode;}
TR_ARMConditionCode setConditionCode(TR_ARMConditionCode conds) {return (_conditionCode = conds);}
virtual TR::Snippet *getSnippetForGC() {return NULL;}
virtual TR::Register *getMemoryDataRegister();
virtual uint8_t *generateBinaryEncoding();
void generateConditionBinaryEncoding(uint8_t *instructionStart);
virtual int32_t estimateBinaryLength(int32_t currentEstimate);
virtual bool setWriteBack() {return false;}
virtual bool isWriteBack() {return false;}
virtual bool isLabel() {return _opcode.getOpCodeValue() == TR::InstOpCode::label;}
virtual TR::RegisterDependencyConditions *getDependencyConditions()
{
return _conditions;
}
TR::RegisterDependencyConditions *setDependencyConditions(TR::RegisterDependencyConditions *cond)
{
return (_conditions = cond);
}
virtual void assignRegisters(TR_RegisterKinds kindToBeAssigned);
virtual bool refsRegister(TR::Register *reg);
virtual bool defsRegister(TR::Register *reg);
virtual bool usesRegister(TR::Register *reg);
virtual bool defsRealRegister(TR::Register *reg);
virtual bool dependencyRefsRegister(TR::Register *reg);
virtual TR::ARMConditionalBranchInstruction *getARMConditionalBranchInstruction();
virtual TR::Register *getPrimaryTargetRegister() {return NULL;}
// The following safe virtual downcast method is used under debug only
// for assertion checking
#if defined(DEBUG) || defined(PROD_WITH_ASSUMES)
virtual TR::ARMImmInstruction *getARMImmInstruction();
#endif
virtual TR::Register *getMemoryBase() {return NULL;}
virtual TR::Register *getMemoryIndex() {return NULL;}
virtual int32_t getOffset() {return 0;}
// @@ virtual bool usesCountRegister() {return _opcode.usesCountRegister();}
/* @@
virtual bool setsCountRegister()
{
if (_opcode.getOpCodeValue() == TR::InstOpCode::beql)
return true;
return isCall()|_opcode.setsCountRegister();
}
*/
bool isRecordForm() {return _opcode.isRecordForm();}
bool hasRecordForm() {return _opcode.hasRecordForm();}
bool singleFPOp() {return _opcode.singleFPOp();}
bool doubleFPOp() {return _opcode.doubleFPOp();}
bool gprOp() {return _opcode.gprOp();}
bool fprOp() {return _opcode.fprOp();}
// @@ bool useAlternateFormat() {return _opcode.useAlternateFormat();}
// @@ bool useAlternateFormatx() {return _opcode.useAlternateFormatx();}
bool readsCarryFlag() {return _opcode.readsCarryFlag();}
bool setsCarryFlag() {return _opcode.setsCarryFlag();}
bool setsOverflowFlag() {return _opcode.setsOverflowFlag();}
// @@ bool isUpdate() {return _opcode.isUpdate();}
// @@ bool isTrap() {return _opcode.isTrap();}
// @@ bool isTMAbort() {return _opcode.isTMAbort();}
// @@ bool isRegCopy() {return _opcode.isRegCopy();}
// @@ bool isDoubleWord() {return _opcode.isDoubleWord();}
// @@ bool isRotateOrShift() {return _opcode.isRotateOrShift();}
// @@ bool isCompare() {return _opcode.isCompare();}
// @@ bool isLongRunningFPOp() {return _opcode.isLongRunningFPOp();}
// @@ bool isFXMult() {return _opcode.isFXMult();}
// @@ virtual bool isLoad() {return _opcode.isLoad();}
// @@ virtual bool isStore() {return _opcode.isStore();}
virtual bool isBranchOp() {return _opcode.isBranchOp();}
virtual bool isExceptBranchOp() {return false; }
// @@ virtual bool isSync() {return _opcode.isSync();}
// @@ virtual bool isAdmin() {return _opcode.isAdmin();}
// @@ virtual bool is4ByteLoad() {return (getOpCodeValue() == TR::InstOpCode::lwz);}
virtual int32_t getMachineOpCode();
// @@ virtual bool isBeginBlock();
// @@ virtual bool isFloat() {return _opcode.isFloat();}
// @@ virtual bool isVMX() {return _opcode.isVMX();}
// @@ virtual bool isVSX() {return _opcode.isVSX();}
// @@ virtual bool isSyncSideEffectFree() {return _opcode.isSyncSideEffectFree();}
// @@ virtual bool isCall();
/*
* Maps to TIndex in Instruction. Here we set values specific to PPC CodeGen.
*
* A 32-bit field where the lower 24-bits contain an integer that represents an
* approximate ordering of instructions.
*
* The upper 8 bits are used for flags.
* Instruction flags encoded by their bit position. Subclasses may use any
* available bits between LastBaseFlag and MaxBaseFlag inclusive.
*/
enum
{
WillBePatched = 0x08000000
};
bool willBePatched() {return (_index & WillBePatched) != 0; }
void setWillBePatched(bool v = true) { v? _index |= WillBePatched : _index &= ~WillBePatched; }
private:
TR_ARMConditionCode _conditionCode;
TR::RegisterDependencyConditions *_conditions;
bool _asyncBranch;
};
}
}
#endif