summaryrefslogtreecommitdiff
path: root/src/jit/codegenlinear.h
blob: 851ee7ab6ba3da05933616aebc38d74fea0a23f9 (plain)
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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more 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);

#ifdef _TARGET_XARCH_
    unsigned            getFirstArgWithStackSlot();
#endif // !_TARGET_XARCH_

    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);

    bool                genStoreRegisterReturnInLclVar(GenTreePtr treeNode);

    // Deals with codegen for muti-register struct returns.
    bool                isStructReturn(GenTreePtr treeNode);
    void                genStructReturn(GenTreePtr treeNode);

    // Codegen for GT_RETURN.
    void                genReturn(GenTreePtr treeNode);

#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
    void                getStructTypeOffset(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& structDesc,
                                            var_types* type0,
                                            var_types* type1,
                                            unsigned __int8* offset0,
                                            unsigned __int8* offset1);

    void                getStructReturnRegisters(var_types type0,
                                                 var_types type1,
                                                 regNumber* retRegPtr0,
                                                 regNumber* retRegPtr1);
#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