-
Notifications
You must be signed in to change notification settings - Fork 139
/
Copy pathOMRCodeGenerator.hpp
267 lines (210 loc) · 11.2 KB
/
OMRCodeGenerator.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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*******************************************************************************
* 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_CODEGENERATOR_INCL
#define OMR_ARM_CODEGENERATOR_INCL
/*
* The following #define and typedef must appear before any #includes in this file
*/
#ifndef OMR_CODEGENERATOR_CONNECTOR
#define OMR_CODEGENERATOR_CONNECTOR
namespace OMR { namespace ARM { class CodeGenerator; } }
namespace OMR { typedef OMR::ARM::CodeGenerator CodeGeneratorConnector; }
#else
#error OMR::ARM::CodeGenerator expected to be a primary connector, but a OMR connector is already defined
#endif
#include "compiler/codegen/OMRCodeGenerator.hpp"
#include <stdint.h>
#include "codegen/InstOpCode.hpp"
#include "codegen/RealRegister.hpp"
#include "codegen/ScratchRegisterManager.hpp"
#include "env/jittypes.h"
#include "optimizer/DataFlowAnalysis.hpp"
namespace TR { class Register; }
extern TR::Instruction *armLoadConstant(TR::Node *node,
int32_t value,
TR::Register *targetRegister,
TR::CodeGenerator *cg,
TR::Instruction *cursor=NULL);
extern TR::Instruction *loadAddressConstantInSnippet(TR::CodeGenerator *cg,
TR::Node *node,
intptr_t address,
TR::Register *targetRegister,
bool isUnloadablePicSite=false,
TR::Instruction *cursor=NULL);
extern TR::Instruction *loadAddressConstantFixed(TR::CodeGenerator *cg,
TR::Node *node,
intptr_t value,
TR::Register *targetRegister,
TR::Instruction *cursor=NULL,
uint8_t *targetAddress = NULL,
uint8_t *targetAddress2 = NULL,
int16_t typeAddress = -1,
bool doAOTRelocation = true);
extern TR::Instruction *loadAddressConstant(TR::CodeGenerator *cg,
TR::Node *node,
intptr_t value,
TR::Register *targetRegister,
TR::Instruction *cursor=NULL,
bool isPicSite=false,
int16_t typeAddress = -1,
uint8_t *targetAddress = NULL,
uint8_t *targetAddress2 = NULL);
extern int32_t findOrCreateARMHelperTrampoline(int32_t helperIndex);
uint32_t encodeBranchDistance(uint32_t from, uint32_t to);
uint32_t encodeHelperBranchAndLink(TR::SymbolReference *symRef, uint8_t *cursor, TR::Node *node, TR::CodeGenerator *cg);
uint32_t encodeHelperBranch(bool isBranchAndLink, TR::SymbolReference *symRef, uint8_t *cursor, TR_ARMConditionCode cc, TR::Node *node, TR::CodeGenerator *cg);
class TR_BackingStore;
namespace TR { class Machine; }
namespace TR { class CodeGenerator; }
namespace TR { struct ARMLinkageProperties; }
namespace TR { class ARMImmInstruction; }
namespace TR { class ARMConstantDataSnippet; }
class TR_ARMLoadLabelItem;
class TR_BitVector;
class TR_ARMScratchRegisterManager;
extern uint8_t *storeArgumentItem(TR::InstOpCode::Mnemonic op, uint8_t *buffer, TR::RealRegister *reg, int32_t offset, TR::CodeGenerator *cg);
extern uint8_t *loadArgumentItem(TR::InstOpCode::Mnemonic op, uint8_t *buffer, TR::RealRegister *reg, int32_t offset, TR::CodeGenerator *cg);
#include "il/Node.hpp"
#include "arm/codegen/ARMOutOfLineCodeSection.hpp"
namespace OMR
{
namespace ARM
{
class CodeGenerator;
class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator
{
protected:
CodeGenerator(TR::Compilation *comp);
public:
void initialize();
TR::Linkage *createLinkage(TR_LinkageConventions lc);
void beginInstructionSelection();
void endInstructionSelection();
void doBinaryEncoding();
void emitDataSnippets();
bool hasDataSnippets();
int32_t setEstimatedLocationsForDataSnippetLabels(int32_t estimatedSnippetStart);
#ifdef DEBUG
void dumpDataSnippets(TR::FILE *outFile);
#endif
TR::Instruction *generateSwitchToInterpreterPrePrologue(TR::Instruction *cursor, TR::Node *node);
int32_t findOrCreateAddressConstant(void *v, TR::DataType t,
TR::Instruction *n0, TR::Instruction *n1,
TR::Instruction *n2, TR::Instruction *n3,
TR::Instruction *n4,
TR::Node *node, bool isUnloadablePicSite);
TR::Register *gprClobberEvaluate(TR::Node *node);
const TR::ARMLinkageProperties &getProperties() { return *_linkageProperties; }
TR::RealRegister *getFrameRegister() {return _frameRegister;}
TR::RealRegister *setFrameRegister(TR::RealRegister *r) {return (_frameRegister = r);}
TR::RealRegister *getMethodMetaDataRegister() {return _methodMetaDataRegister;}
TR::RealRegister *setMethodMetaDataRegister(TR::RealRegister *r) {return (_methodMetaDataRegister = r);}
void buildRegisterMapForInstruction(TR_GCStackMap *map);
void apply24BitLabelRelativeRelocation(int32_t * cursor, TR::LabelSymbol *);
void apply8BitLabelRelativeRelocation(int32_t * cursor, TR::LabelSymbol *);
// ARM specific thresholds for constant re-materialization
int64_t getLargestNegConstThatMustBeMaterialized() {return -32769;} // minimum 16-bit signed int minus 1
int64_t getSmallestPosConstThatMustBeMaterialized() {return 32768;} // maximum 16-bit signed int plus 1
bool shouldValueBeInACommonedNode(int64_t);
// @@ bool canNullChkBeImplicit(TR::Node *node);
bool hasCall() {return _flags.testAny(HasCall);}
bool noStackFrame() {return _flags.testAny(NoStackFrame);}
bool canExceptByTrap() {return _flags.testAny(CanExceptByTrap);}
bool hasHardFloatReturn() {return _flags.testAny(HasHardFloatReturn);}
bool isOutOfLineHotPath() {return _flags.testAny(IsOutOfLineHotPath);}
void setHasHardFloatReturn() { _flags.set(HasHardFloatReturn);}
void setHasCall() { _flags.set(HasCall);}
void setNoStackFrame() { _flags.set(NoStackFrame);}
void setCanExceptByTrap() { _flags.set(CanExceptByTrap);}
void setIsOutOfLineHotPath(bool v) { _flags.set(IsOutOfLineHotPath, v);}
// This is needed by register simulation pickRegister in CodeGenRA common code.
TR_GlobalRegisterNumber pickRegister(TR::RegisterCandidate *, TR::Block * *, TR_BitVector & availableRegisters, TR_GlobalRegisterNumber & globalRegisterNumber, TR_LinkHead<TR::RegisterCandidate> *candidates);
bool allowGlobalRegisterAcrossBranch(TR::RegisterCandidate *, TR::Node * branchNode);
using OMR::CodeGenerator::getMaximumNumberOfGPRsAllowedAcrossEdge;
int32_t getMaximumNumberOfGPRsAllowedAcrossEdge(TR::Node *);
int32_t getMaximumNumberOfFPRsAllowedAcrossEdge(TR::Node *);
bool isGlobalRegisterAvailable(TR_GlobalRegisterNumber i, TR::DataType dt);
TR_BitVector _globalRegisterBitVectors[TR_numSpillKinds];
virtual TR_BitVector *getGlobalRegisters(TR_SpillKinds kind, TR_LinkageConventions lc){ return &_globalRegisterBitVectors[kind]; }
TR_GlobalRegisterNumber _gprLinkageGlobalRegisterNumbers[TR::RealRegister::NumRegisters], _fprLinkageGlobalRegisterNumbers[TR::RealRegister::NumRegisters]; // these could be smaller
TR_GlobalRegisterNumber getLinkageGlobalRegisterNumber(int8_t linkageRegisterIndex, TR::DataType type);
int32_t getMaximumNumbersOfAssignableGPRs();
int32_t getMaximumNumbersOfAssignableFPRs();
static uint32_t registerBitMask(int32_t reg)
{
return 1 << (reg - TR::RealRegister::FirstGPR);
}
// OutOfLineCodeSection List functions
List<TR_ARMOutOfLineCodeSection> &getARMOutOfLineCodeSectionList() {return _outOfLineCodeSectionList;}
TR_ARMOutOfLineCodeSection *findOutLinedInstructionsFromLabel(TR::LabelSymbol *label);
int32_t arrayTranslateMinimumNumberOfElements(bool isByteSource, bool isByteTarget) { return 8; } //FIXME
int32_t arrayTranslateAndTestMinimumNumberOfIterations() { return 8; } //FIXME
/**
* @brief Answers whether a trampoline is required for a direct call instruction to
* reach a target address.
*
* @param[in] targetAddress : the absolute address of the call target
* @param[in] sourceAddress : the absolute address of the call instruction
*
* @return : true if a trampoline is required; false otherwise.
*/
bool directCallRequiresTrampoline(intptr_t targetAddress, intptr_t sourceAddress);
/**
* @brief Answers whether fabs/dabs evaluators are available or not
* @return true if fabs/dabs evaluators are available
*/
bool supportsFPAbs()
{
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
return true;
#else
return false;
#endif
}
private:
enum // flags
{
HasCall = 0x00000200,
NoStackFrame = 0x00000400,
CanExceptByTrap = 0x00000800,
HasHardFloatReturn = 0x00001000,
IsOutOfLineColdPath = 0x00002000, // AVAILABLE
IsOutOfLineHotPath = 0x00004000,
DummyLastFlag
};
static TR_Processor _processor;
flags32_t _flags;
uint32_t _numGPR;
uint32_t _numFPR;
TR::RealRegister *_frameRegister;
TR::RealRegister *_methodMetaDataRegister;
TR::ARMConstantDataSnippet *_constantData;
TR::ARMLinkageProperties *_linkageProperties;
List<TR_ARMOutOfLineCodeSection> _outOfLineCodeSectionList;
// Internal Control Flow Depth Counters
int32_t _internalControlFlowNestingDepth;
int32_t _internalControlFlowSafeNestingDepth;
protected:
TR::ARMImmInstruction *_returnTypeInfoInstruction;
};
} // ARM
} // TR
#endif