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
|
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
//
// This file contains the members of CodeGen that are defined and used
// only by the RyuJIT backend. It is included by CodeGen.h in the
// definition of the CodeGen class.
//
#ifndef LEGACY_BACKEND // Not necessary (it's this way in the #include location), but helpful to IntelliSense
void genSetRegToConst(regNumber targetReg, var_types targetType, GenTreePtr tree);
void genCodeForTreeNode(GenTreePtr treeNode);
void genCodeForBinary(GenTreePtr treeNode);
void genCodeForDivMod(GenTreeOp* treeNode);
void genCodeForMulHi(GenTreeOp* treeNode);
void genCodeForPow2Div(GenTreeOp* treeNode);
void genLeaInstruction(GenTreeAddrMode *lea);
void genSetRegToCond(regNumber dstReg, GenTreePtr tree);
void genIntToIntCast(GenTreePtr treeNode);
void genFloatToFloatCast(GenTreePtr treeNode);
void genFloatToIntCast(GenTreePtr treeNode);
void genIntToFloatCast(GenTreePtr treeNode);
void genCkfinite(GenTreePtr treeNode);
void genIntrinsic(GenTreePtr treeNode);
void genPutArgStk(GenTreePtr treeNode);
unsigned getBaseVarForPutArgStk(GenTreePtr treeNode);
void genCompareFloat(GenTreePtr treeNode);
void genCompareInt(GenTreePtr treeNode);
#if !defined(_TARGET_64BIT_)
void genCompareLong(GenTreePtr treeNode);
#endif
#ifdef _TARGET_ARM64_
void genCodeForLdObj(GenTreeOp* treeNode);
#endif
#ifdef FEATURE_SIMD
instruction getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_types baseType, unsigned *ival = nullptr);
void genSIMDScalarMove(var_types type, regNumber target, regNumber src, bool zeroInit);
void genSIMDIntrinsicInit(GenTreeSIMD* simdNode);
void genSIMDIntrinsicInitN(GenTreeSIMD* simdNode);
void genSIMDIntrinsicInitArray(GenTreeSIMD* simdNode);
void genSIMDIntrinsicUnOp(GenTreeSIMD* simdNode);
void genSIMDIntrinsicBinOp(GenTreeSIMD* simdNode);
void genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode);
void genSIMDIntrinsicDotProduct(GenTreeSIMD* simdNode);
void genSIMDIntrinsicSetItem(GenTreeSIMD* simdNode);
void genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode);
void genSIMDIntrinsicShuffleSSE2(GenTreeSIMD* simdNode);
void genSIMDIntrinsicUpperSave(GenTreeSIMD* simdNode);
void genSIMDIntrinsicUpperRestore(GenTreeSIMD* simdNode);
void genSIMDIntrinsic(GenTreeSIMD* simdNode);
void genSIMDCheck(GenTree* treeNode);
// TYP_SIMD12 (i.e Vector3 of size 12 bytes) is not a hardware supported size and requires
// two reads/writes on 64-bit targets. These routines abstract reading/writing of Vector3
// values through an indirection. Note that Vector3 locals allocated on stack would have
// their size rounded to TARGET_POINTER_SIZE (which is 8 bytes on 64-bit targets) and hence
// Vector3 locals could be treated as TYP_SIMD16 while reading/writing.
void genStoreIndTypeSIMD12(GenTree* treeNode);
void genStoreLclFldTypeSIMD12(GenTree* treeNode);
void genLoadIndTypeSIMD12(GenTree* treeNode);
void genLoadLclFldTypeSIMD12(GenTree* treeNode);
#endif // FEATURE_SIMD
#if !defined(_TARGET_64BIT_)
// CodeGen for Long Ints
void genStoreLongLclVar(GenTree* treeNode);
#endif // !defined(_TARGET_64BIT_)
void genProduceReg(GenTree *tree);
void genUnspillRegIfNeeded(GenTree* tree);
regNumber genConsumeReg(GenTree *tree);
void genConsumeRegAndCopy(GenTree *tree, regNumber needReg);
void genConsumeIfReg(GenTreePtr tree)
{
if (!tree->isContained())
(void) genConsumeReg(tree);
}
void genRegCopy(GenTreePtr tree);
void genTransferRegGCState(regNumber dst, regNumber src);
void genConsumeAddress(GenTree* addr);
void genConsumeAddrMode(GenTreeAddrMode *mode);
void genConsumeBlockOp(GenTreeBlkOp* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg);
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
void genConsumePutStructArgStk(GenTreePutArgStk* putArgStkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg, unsigned baseVarNum);
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
void genConsumeRegs(GenTree* tree);
void genConsumeOperands(GenTreeOp* tree);
void genEmitGSCookieCheck(bool pushReg);
void genSetRegToIcon (regNumber reg,
ssize_t val,
var_types type = TYP_INT,
insFlags flags = INS_FLAGS_DONT_CARE);
void genCodeForShift (GenTreePtr dst,
GenTreePtr src,
GenTreePtr treeNode);
void genCodeForCpObj (GenTreeCpObj* cpObjNode);
void genCodeForCpBlk (GenTreeCpBlk* cpBlkNode);
void genCodeForCpBlkRepMovs (GenTreeCpBlk* cpBlkNode);
void genCodeForCpBlkUnroll (GenTreeCpBlk* cpBlkNode);
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
void genPutStructArgStk(GenTreePtr treeNode, unsigned baseVarNum);
void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode, unsigned baseVarNum);
void genStructPutArgUnroll(GenTreePutArgStk* putArgStkNode, unsigned baseVarNum);
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
void genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset);
void genCodeForStoreOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset);
void genCodeForInitBlk (GenTreeInitBlk* initBlkNode);
void genCodeForInitBlkRepStos (GenTreeInitBlk* initBlkNode);
void genCodeForInitBlkUnroll (GenTreeInitBlk* initBlkNode);
void genJumpTable(GenTree* tree);
void genTableBasedSwitch(GenTree* tree);
void genCodeForArrIndex (GenTreeArrIndex* treeNode);
void genCodeForArrOffset (GenTreeArrOffs* treeNode);
instruction genGetInsForOper (genTreeOps oper, var_types type);
void genStoreInd(GenTreePtr node);
bool genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data);
void genCallInstruction(GenTreePtr call);
void genJmpMethod(GenTreePtr jmp);
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
void genGetStructTypeSizeOffset(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& structDesc,
var_types* type0,
var_types* type1,
emitAttr* size0,
emitAttr* size1,
unsigned __int8* offset0,
unsigned __int8* offset1);
bool genStoreRegisterReturnInLclVar(GenTreePtr treeNode);
#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
void genLclHeap(GenTreePtr tree);
bool genIsRegCandidateLocal (GenTreePtr tree)
{
if (!tree->IsLocal()) return false;
const LclVarDsc * varDsc = &compiler->lvaTable[tree->gtLclVarCommon.gtLclNum];
return(varDsc->lvIsRegCandidate());
}
#ifdef DEBUG
GenTree* lastConsumedNode;
void genCheckConsumeNode(GenTree* treeNode);
#else // !DEBUG
inline void genCheckConsumeNode(GenTree* treeNode) {}
#endif // DEBUG
#endif // !LEGACY_BACKEND
|