1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 /*****************************************************************************/
8 #error Define GTNODE before including this file.
10 /*****************************************************************************/
13 // , GenTree struct flavor
17 GTNODE(NONE , char ,0,GTK_SPECIAL)
19 //-----------------------------------------------------------------------------
20 // Leaf nodes (i.e. these nodes have no sub-operands):
21 //-----------------------------------------------------------------------------
23 GTNODE(LCL_VAR , GenTreeLclVar ,0,GTK_LEAF|GTK_LOCAL) // local variable
24 GTNODE(LCL_FLD , GenTreeLclFld ,0,GTK_LEAF|GTK_LOCAL) // field in a non-primitive variable
25 GTNODE(LCL_VAR_ADDR , GenTreeLclVar ,0,GTK_LEAF) // address of local variable
26 GTNODE(LCL_FLD_ADDR , GenTreeLclFld ,0,GTK_LEAF) // address of field in a non-primitive variable
27 GTNODE(STORE_LCL_VAR , GenTreeLclVar ,0,GTK_UNOP|GTK_LOCAL|GTK_NOVALUE) // store to local variable
28 GTNODE(STORE_LCL_FLD , GenTreeLclFld ,0,GTK_UNOP|GTK_LOCAL|GTK_NOVALUE) // store to field in a non-primitive variable
29 GTNODE(CATCH_ARG , GenTree ,0,GTK_LEAF) // Exception object in a catch block
30 GTNODE(LABEL , GenTreeLabel ,0,GTK_LEAF) // Jump-target
31 GTNODE(FTN_ADDR , GenTreeFptrVal ,0,GTK_LEAF) // Address of a function
32 GTNODE(RET_EXPR , GenTreeRetExpr ,0,GTK_LEAF) // Place holder for the return expression from an inline candidate
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
38 GTNODE(CNS_INT , GenTreeIntCon ,0,GTK_LEAF|GTK_CONST)
39 GTNODE(CNS_LNG , GenTreeLngCon ,0,GTK_LEAF|GTK_CONST)
40 GTNODE(CNS_DBL , GenTreeDblCon ,0,GTK_LEAF|GTK_CONST)
41 GTNODE(CNS_STR , GenTreeStrCon ,0,GTK_LEAF|GTK_CONST)
43 //-----------------------------------------------------------------------------
44 // Unary operators (1 operand):
45 //-----------------------------------------------------------------------------
47 GTNODE(NOT , GenTreeOp ,0,GTK_UNOP)
48 GTNODE(NOP , GenTree ,0,GTK_UNOP|GTK_NOCONTAIN)
49 GTNODE(NEG , GenTreeOp ,0,GTK_UNOP)
50 GTNODE(COPY , GenTreeCopyOrReload,0,GTK_UNOP) // Copies a variable from its current location to a register that satisfies
51 // code generation constraints. The child is the actual lclVar node.
52 GTNODE(RELOAD , GenTreeCopyOrReload,0,GTK_UNOP)
54 GTNODE(CHS , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR) // GT_CHS is actually unary -- op2 is ignored.
55 // Changing to unary presently causes problems, though -- take a little work to fix.
58 GTNODE(ARR_LENGTH , GenTreeArrLen ,0,GTK_UNOP|GTK_EXOP) // array-length
60 GTNODE(INTRINSIC , GenTreeIntrinsic ,0,GTK_BINOP|GTK_EXOP) // intrinsics
62 GTNODE(LOCKADD , GenTreeOp ,0,GTK_BINOP)
63 GTNODE(XADD , GenTreeOp ,0,GTK_BINOP)
64 GTNODE(XCHG , GenTreeOp ,0,GTK_BINOP)
65 GTNODE(CMPXCHG , GenTreeCmpXchg ,0,GTK_SPECIAL)
66 GTNODE(MEMORYBARRIER , GenTree ,0,GTK_LEAF|GTK_NOVALUE)
68 GTNODE(CAST , GenTreeCast ,0,GTK_UNOP|GTK_EXOP) // conversion to another type
69 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
70 GTNODE(BITCAST , GenTreeMultiRegOp ,0,GTK_UNOP) // reinterpretation of bits as another type
72 GTNODE(BITCAST , GenTreeOp ,0,GTK_UNOP) // reinterpretation of bits as another type
74 GTNODE(CKFINITE , GenTreeOp ,0,GTK_UNOP|GTK_NOCONTAIN) // Check for NaN
75 GTNODE(LCLHEAP , GenTreeOp ,0,GTK_UNOP|GTK_NOCONTAIN) // alloca()
76 GTNODE(JMP , GenTreeVal ,0,GTK_LEAF|GTK_NOVALUE) // Jump to another function
78 GTNODE(ADDR , GenTreeOp ,0,GTK_UNOP) // address of
79 GTNODE(IND , GenTreeOp ,0,GTK_UNOP) // load indirection
80 GTNODE(STOREIND , GenTreeStoreInd ,0,GTK_BINOP|GTK_NOVALUE) // store indirection
82 // TODO-Cleanup: GT_ARR_BOUNDS_CHECK should be made a GTK_BINOP now that it has only two child nodes
83 GTNODE(ARR_BOUNDS_CHECK , GenTreeBoundsChk ,0,GTK_SPECIAL|GTK_NOVALUE)// array bounds check
84 GTNODE(OBJ , GenTreeObj ,0,GTK_UNOP|GTK_EXOP) // Object that MAY have gc pointers, and thus includes the relevant gc layout info.
85 GTNODE(STORE_OBJ , GenTreeBlk ,0,GTK_BINOP|GTK_EXOP|GTK_NOVALUE) // Object that MAY have gc pointers, and thus includes the relevant gc layout info.
86 GTNODE(BLK , GenTreeBlk ,0,GTK_UNOP) // Block/object with no gc pointers, and with a known size (e.g. a struct with no gc fields)
87 GTNODE(STORE_BLK , GenTreeBlk ,0,GTK_BINOP|GTK_NOVALUE) // Block/object with no gc pointers, and with a known size (e.g. a struct with no gc fields)
88 GTNODE(DYN_BLK , GenTreeBlk ,0,GTK_SPECIAL) // Dynamically sized block object
89 GTNODE(STORE_DYN_BLK , GenTreeBlk ,0,GTK_SPECIAL|GTK_NOVALUE)// Dynamically sized block object
90 GTNODE(BOX , GenTreeBox ,0,GTK_UNOP|GTK_EXOP|GTK_NOTLIR)
93 GTNODE(SIMD_CHK , GenTreeBoundsChk ,0,GTK_SPECIAL|GTK_NOVALUE)// Compare whether an index is less than the given SIMD vector length, and call CORINFO_HELP_RNGCHKFAIL if not.
94 // TODO-CQ: In future may want to add a field that specifies different exceptions but we'll
95 // need VM assistance for that.
96 // TODO-CQ: It would actually be very nice to make this an unconditional throw, and expose the control flow that
97 // does the compare, so that it can be more easily optimized. But that involves generating qmarks at import time...
98 #endif // FEATURE_SIMD
100 #ifdef FEATURE_HW_INTRINSICS
101 GTNODE(HW_INTRINSIC_CHK , GenTreeBoundsChk ,0,GTK_SPECIAL|GTK_NOVALUE)// Compare whether an imm8 argument is in the valid range, and throw ArgumentOutOfRangeException if not.
104 GTNODE(ALLOCOBJ , GenTreeAllocObj ,0,GTK_UNOP|GTK_EXOP) // object allocator
106 GTNODE(INIT_VAL , GenTreeOp ,0,GTK_UNOP) // Initialization value for an initBlk
108 GTNODE(RUNTIMELOOKUP , GenTreeRuntimeLookup, 0,GTK_UNOP|GTK_EXOP) // Runtime handle lookup
110 //-----------------------------------------------------------------------------
111 // Binary operators (2 operands):
112 //-----------------------------------------------------------------------------
114 GTNODE(ADD , GenTreeOp ,1,GTK_BINOP)
115 GTNODE(SUB , GenTreeOp ,0,GTK_BINOP)
116 GTNODE(MUL , GenTreeOp ,1,GTK_BINOP)
117 GTNODE(DIV , GenTreeOp ,0,GTK_BINOP)
118 GTNODE(MOD , GenTreeOp ,0,GTK_BINOP)
120 GTNODE(UDIV , GenTreeOp ,0,GTK_BINOP)
121 GTNODE(UMOD , GenTreeOp ,0,GTK_BINOP)
123 GTNODE(OR , GenTreeOp ,1,GTK_BINOP|GTK_LOGOP)
124 GTNODE(XOR , GenTreeOp ,1,GTK_BINOP|GTK_LOGOP)
125 GTNODE(AND , GenTreeOp ,1,GTK_BINOP|GTK_LOGOP)
127 GTNODE(LSH , GenTreeOp ,0,GTK_BINOP)
128 GTNODE(RSH , GenTreeOp ,0,GTK_BINOP)
129 GTNODE(RSZ , GenTreeOp ,0,GTK_BINOP)
130 GTNODE(ROL , GenTreeOp ,0,GTK_BINOP)
131 GTNODE(ROR , GenTreeOp ,0,GTK_BINOP)
132 GTNODE(MULHI , GenTreeOp ,1,GTK_BINOP) // returns high bits (top N bits of the 2N bit result of an NxN multiply)
133 // GT_MULHI is used in division by a constant (fgMorphDivByConst). We turn
134 // the div into a MULHI + some adjustments. In codegen, we only use the
135 // results of the high register, and we drop the low results.
137 #ifndef LEGACY_BACKEND
138 GTNODE(ASG , GenTreeOp ,0,GTK_BINOP|GTK_NOTLIR)
140 GTNODE(ASG , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
141 GTNODE(ASG_ADD , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
142 GTNODE(ASG_SUB , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
143 GTNODE(ASG_MUL , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
144 GTNODE(ASG_DIV , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
145 GTNODE(ASG_MOD , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
147 GTNODE(ASG_UDIV , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
148 GTNODE(ASG_UMOD , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
150 GTNODE(ASG_OR , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
151 GTNODE(ASG_XOR , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
152 GTNODE(ASG_AND , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
153 GTNODE(ASG_LSH , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
154 GTNODE(ASG_RSH , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
155 GTNODE(ASG_RSZ , GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
157 GTNODE(EQ , GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
158 GTNODE(NE , GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
159 GTNODE(LT , GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
160 GTNODE(LE , GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
161 GTNODE(GE , GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
162 GTNODE(GT , GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
163 #ifndef LEGACY_BACKEND
164 // These are similar to GT_EQ/GT_NE but they generate "test" instead of "cmp" instructions.
165 // Currently these are generated during lowering for code like ((x & y) eq|ne 0) only on
166 // XArch but ARM could too use these for the same purpose as there is a "tst" instruction.
167 // Note that the general case of comparing a register against 0 is handled directly by
168 // codegen which emits a "test reg, reg" instruction, that would be more difficult to do
169 // during lowering because the source operand is used twice so it has to be a lclvar.
170 // Because of this there is no need to also add GT_TEST_LT/LE/GE/GT opers.
171 GTNODE(TEST_EQ , GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
172 GTNODE(TEST_NE , GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
175 GTNODE(COMMA , GenTreeOp ,0,GTK_BINOP|GTK_NOTLIR)
177 GTNODE(QMARK , GenTreeQmark ,0,GTK_BINOP|GTK_EXOP|GTK_NOTLIR)
178 GTNODE(COLON , GenTreeColon ,0,GTK_BINOP|GTK_NOTLIR)
180 GTNODE(INDEX , GenTreeIndex ,0,GTK_BINOP|GTK_EXOP|GTK_NOTLIR) // SZ-array-element
181 GTNODE(INDEX_ADDR , GenTreeIndex ,0,GTK_BINOP|GTK_EXOP) // addr of SZ-array-element; used when
182 // aiming to minimize compile times.
184 GTNODE(MKREFANY , GenTreeOp ,0,GTK_BINOP)
186 GTNODE(LEA , GenTreeAddrMode ,0,GTK_BINOP|GTK_EXOP)
188 #if !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
189 // A GT_LONG node simply represents the long value produced by the concatenation
190 // of its two (lower and upper half) operands. Some GT_LONG nodes are transient,
191 // during the decomposing of longs; others are handled by codegen as operands of
192 // nodes such as calls, returns and stores of long lclVars.
193 GTNODE(LONG , GenTreeOp ,0,GTK_BINOP)
195 // The following are nodes representing x86/arm32 specific long operators, including
196 // high operators of a 64-bit operations that requires a carry/borrow, which are
197 // named GT_XXX_HI for consistency, low operators of 64-bit operations that need
198 // to not be modified in phases post-decompose, and operators that return 64-bit
199 // results in one instruction.
200 GTNODE(ADD_LO , GenTreeOp ,1,GTK_BINOP)
201 GTNODE(ADD_HI , GenTreeOp ,1,GTK_BINOP)
202 GTNODE(SUB_LO , GenTreeOp ,0,GTK_BINOP)
203 GTNODE(SUB_HI , GenTreeOp ,0,GTK_BINOP)
205 // A mul that returns the 2N bit result of an NxN multiply. This op is used for
206 // multiplies that take two ints and return a long result. All other multiplies
207 // with long results are morphed into helper calls. It is similar to GT_MULHI,
208 // the difference being that GT_MULHI drops the lo part of the result, whereas
209 // GT_MUL_LONG keeps both parts of the result.
210 #if defined(_TARGET_X86_)
211 GTNODE(MUL_LONG , GenTreeOp ,1,GTK_BINOP)
212 #elif defined (_TARGET_ARM_)
213 GTNODE(MUL_LONG , GenTreeMultiRegOp ,1,GTK_BINOP)
216 // The following are nodes that specify shifts that take a GT_LONG op1. The GT_LONG
217 // contains the hi and lo parts of three operand shift form where one op will be
218 // shifted into the other op as part of the operation (LSH_HI will shift
219 // the high bits of the lo operand into the high operand as it shifts left. RSH_LO
220 // will shift the lo bits of the high operand into the lo operand). LSH_HI
221 // represents the high operation of a 64-bit left shift by a constant int, and
222 // RSH_LO represents the lo operation of a 64-bit right shift by a constant int.
223 GTNODE(LSH_HI , GenTreeOp ,0,GTK_BINOP)
224 GTNODE(RSH_LO , GenTreeOp ,0,GTK_BINOP)
225 #endif // !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
228 GTNODE(SIMD , GenTreeSIMD ,0,GTK_BINOP|GTK_EXOP) // SIMD functions/operators/intrinsics
229 #endif // FEATURE_SIMD
231 #ifdef FEATURE_HW_INTRINSICS
232 GTNODE(HWIntrinsic , GenTreeHWIntrinsic ,0,GTK_BINOP|GTK_EXOP) // hardware intrinsics
233 #endif // FEATURE_HW_INTRINSICS
235 //-----------------------------------------------------------------------------
236 // LIR specific compare and conditional branch/set nodes:
237 //-----------------------------------------------------------------------------
239 GTNODE(CMP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // Sets the condition flags according to the compare result.
240 // N.B. Not a relop, it does not produce a value and it cannot be reversed.
241 GTNODE(JCMP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // Makes a comparison and jump if the condition specified. Does not set flags
242 GTNODE(JCC , GenTreeCC ,0,GTK_LEAF|GTK_NOVALUE) // Checks the condition flags and branch if the condition specified
243 // by GenTreeCC::gtCondition is true.
244 GTNODE(SETCC , GenTreeCC ,0,GTK_LEAF) // Checks the condition flags and produces 1 if the condition specified
245 // by GenTreeCC::gtCondition is true and 0 otherwise.
246 #ifdef _TARGET_XARCH_
247 GTNODE(BT , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // The XARCH BT instruction. Like CMP, this sets the condition flags (CF
248 // to be precise) and does not produce a value.
250 //-----------------------------------------------------------------------------
251 // Other nodes that look like unary/binary operators:
252 //-----------------------------------------------------------------------------
254 GTNODE(JTRUE , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE)
256 GTNODE(LIST , GenTreeArgList ,0,GTK_BINOP|GTK_NOVALUE)
257 GTNODE(FIELD_LIST , GenTreeFieldList ,0,GTK_BINOP) // List of fields of a struct, when passed as an argument
259 //-----------------------------------------------------------------------------
260 // Other nodes that have special structure:
261 //-----------------------------------------------------------------------------
263 GTNODE(FIELD , GenTreeField ,0,GTK_SPECIAL) // Member-field
264 GTNODE(ARR_ELEM , GenTreeArrElem ,0,GTK_SPECIAL) // Multi-dimensional array-element address
265 GTNODE(ARR_INDEX , GenTreeArrIndex ,0,GTK_BINOP|GTK_EXOP) // Effective, bounds-checked index for one dimension of a multi-dimensional array element
266 GTNODE(ARR_OFFSET , GenTreeArrOffs ,0,GTK_SPECIAL) // Flattened offset of multi-dimensional array element
267 GTNODE(CALL , GenTreeCall ,0,GTK_SPECIAL|GTK_NOCONTAIN)
269 //-----------------------------------------------------------------------------
270 // Statement operator nodes:
271 //-----------------------------------------------------------------------------
273 GTNODE(BEG_STMTS , GenTree ,0,GTK_SPECIAL|GTK_NOVALUE)// used only temporarily in importer by impBegin/EndTreeList()
274 GTNODE(STMT , GenTreeStmt ,0,GTK_SPECIAL|GTK_NOVALUE)// top-level list nodes in bbTreeList
276 GTNODE(RETURN , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // return from current function
277 GTNODE(SWITCH , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // switch
279 GTNODE(NO_OP , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // nop!
281 GTNODE(START_NONGC , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // starts a new instruction group that will be non-gc interruptible
283 GTNODE(PROF_HOOK , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // profiler Enter/Leave/TailCall hook
285 GTNODE(RETFILT , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // end filter with TYP_I_IMPL return value
286 #if !FEATURE_EH_FUNCLETS
287 GTNODE(END_LFIN , GenTreeVal ,0,GTK_LEAF|GTK_NOVALUE) // end locally-invoked finally
288 #endif // !FEATURE_EH_FUNCLETS
290 //-----------------------------------------------------------------------------
291 // Nodes used for optimizations.
292 //-----------------------------------------------------------------------------
294 GTNODE(PHI , GenTreeOp ,0,GTK_UNOP) // phi node for ssa.
295 GTNODE(PHI_ARG , GenTreePhiArg ,0,GTK_LEAF|GTK_LOCAL) // phi(phiarg, phiarg, phiarg)
297 //-----------------------------------------------------------------------------
298 // Nodes used by Lower to generate a closer CPU representation of other nodes
299 //-----------------------------------------------------------------------------
301 #ifndef LEGACY_BACKEND
302 GTNODE(JMPTABLE , GenTreeJumpTable ,0, GTK_LEAF|GTK_NOCONTAIN) // Generates the jump table for switches
304 GTNODE(SWITCH_TABLE , GenTreeOp ,0, GTK_BINOP|GTK_NOVALUE) // Jump Table based switch construct
306 //-----------------------------------------------------------------------------
307 // Nodes used only within the code generator:
308 //-----------------------------------------------------------------------------
310 GTNODE(REG_VAR , GenTreeLclVar ,0,GTK_LEAF|GTK_LOCAL) // register variable
311 GTNODE(CLS_VAR , GenTreeClsVar ,0,GTK_LEAF) // static data member
312 GTNODE(CLS_VAR_ADDR , GenTreeClsVar ,0,GTK_LEAF) // static data member address
313 GTNODE(ARGPLACE , GenTreeArgPlace ,0,GTK_LEAF|GTK_NOVALUE|GTK_NOTLIR) // placeholder for a register arg
314 GTNODE(NULLCHECK , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // null checks the source
315 GTNODE(PHYSREG , GenTreePhysReg ,0,GTK_LEAF) // read from a physical register
316 GTNODE(EMITNOP , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // emitter-placed nop
317 GTNODE(PINVOKE_PROLOG , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // pinvoke prolog seq
318 GTNODE(PINVOKE_EPILOG , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // pinvoke epilog seq
319 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
320 GTNODE(PUTARG_REG , GenTreeMultiRegOp ,0,GTK_UNOP) // operator that places outgoing arg in register
322 GTNODE(PUTARG_REG , GenTreeOp ,0,GTK_UNOP) // operator that places outgoing arg in register
324 GTNODE(PUTARG_STK , GenTreePutArgStk ,0,GTK_UNOP|GTK_NOVALUE) // operator that places outgoing arg in stack
325 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
326 GTNODE(PUTARG_SPLIT , GenTreePutArgSplit ,0,GTK_UNOP) // operator that places outgoing arg in registers with stack (split struct in ARM32)
327 #endif // !LEGACY_BACKEND && _TARGET_ARM_
328 GTNODE(RETURNTRAP , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // a conditional call to wait on gc
329 GTNODE(SWAP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // op1 and op2 swap (registers)
330 GTNODE(IL_OFFSET , GenTreeStmt ,0,GTK_LEAF|GTK_NOVALUE) // marks an IL offset for debugging purposes
332 /*****************************************************************************/
334 /*****************************************************************************/