| 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. |
| 4 | |
| 5 | // clang-format off |
| 6 | /*****************************************************************************/ |
| 7 | #ifndef GTNODE |
| 8 | #error Define GTNODE before including this file. |
| 9 | #endif |
| 10 | /*****************************************************************************/ |
| 11 | // |
| 12 | // Node enum |
| 13 | // , GenTree struct flavor |
| 14 | // ,commutative |
| 15 | // ,operKind |
| 16 | |
| 17 | GTNODE(NONE , char ,0,GTK_SPECIAL) |
| 18 | |
| 19 | //----------------------------------------------------------------------------- |
| 20 | // Leaf nodes (i.e. these nodes have no sub-operands): |
| 21 | //----------------------------------------------------------------------------- |
| 22 | |
| 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 |
| 33 | |
| 34 | //----------------------------------------------------------------------------- |
| 35 | // Constant nodes: |
| 36 | //----------------------------------------------------------------------------- |
| 37 | |
| 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) |
| 42 | |
| 43 | //----------------------------------------------------------------------------- |
| 44 | // Unary operators (1 operand): |
| 45 | //----------------------------------------------------------------------------- |
| 46 | |
| 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) |
| 53 | GTNODE(ARR_LENGTH , GenTreeArrLen ,0,GTK_UNOP|GTK_EXOP) // array-length |
| 54 | GTNODE(INTRINSIC , GenTreeIntrinsic ,0,GTK_BINOP|GTK_EXOP) // intrinsics |
| 55 | |
| 56 | GTNODE(LOCKADD , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) |
| 57 | GTNODE(XADD , GenTreeOp ,0,GTK_BINOP) |
| 58 | GTNODE(XCHG , GenTreeOp ,0,GTK_BINOP) |
| 59 | GTNODE(CMPXCHG , GenTreeCmpXchg ,0,GTK_SPECIAL) |
| 60 | GTNODE(MEMORYBARRIER , GenTree ,0,GTK_LEAF|GTK_NOVALUE) |
| 61 | |
| 62 | GTNODE(CAST , GenTreeCast ,0,GTK_UNOP|GTK_EXOP) // conversion to another type |
| 63 | #if defined(_TARGET_ARM_) |
| 64 | GTNODE(BITCAST , GenTreeMultiRegOp ,0,GTK_UNOP) // reinterpretation of bits as another type |
| 65 | #else |
| 66 | GTNODE(BITCAST , GenTreeOp ,0,GTK_UNOP) // reinterpretation of bits as another type |
| 67 | #endif |
| 68 | GTNODE(CKFINITE , GenTreeOp ,0,GTK_UNOP|GTK_NOCONTAIN) // Check for NaN |
| 69 | GTNODE(LCLHEAP , GenTreeOp ,0,GTK_UNOP|GTK_NOCONTAIN) // alloca() |
| 70 | GTNODE(JMP , GenTreeVal ,0,GTK_LEAF|GTK_NOVALUE) // Jump to another function |
| 71 | |
| 72 | GTNODE(ADDR , GenTreeOp ,0,GTK_UNOP) // address of |
| 73 | GTNODE(IND , GenTreeOp ,0,GTK_UNOP) // load indirection |
| 74 | GTNODE(STOREIND , GenTreeStoreInd ,0,GTK_BINOP|GTK_NOVALUE) // store indirection |
| 75 | |
| 76 | // TODO-Cleanup: GT_ARR_BOUNDS_CHECK should be made a GTK_BINOP now that it has only two child nodes |
| 77 | GTNODE(ARR_BOUNDS_CHECK , GenTreeBoundsChk ,0,GTK_SPECIAL|GTK_NOVALUE)// array bounds check |
| 78 | GTNODE(OBJ , GenTreeObj ,0,GTK_UNOP|GTK_EXOP) // Object that MAY have gc pointers, and thus includes the relevant gc layout info. |
| 79 | 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. |
| 80 | 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) |
| 81 | 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) |
| 82 | GTNODE(DYN_BLK , GenTreeBlk ,0,GTK_SPECIAL) // Dynamically sized block object |
| 83 | GTNODE(STORE_DYN_BLK , GenTreeBlk ,0,GTK_SPECIAL|GTK_NOVALUE)// Dynamically sized block object |
| 84 | GTNODE(BOX , GenTreeBox ,0,GTK_UNOP|GTK_EXOP|GTK_NOTLIR) |
| 85 | |
| 86 | #ifdef FEATURE_SIMD |
| 87 | 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. |
| 88 | // TODO-CQ: In future may want to add a field that specifies different exceptions but we'll |
| 89 | // need VM assistance for that. |
| 90 | // TODO-CQ: It would actually be very nice to make this an unconditional throw, and expose the control flow that |
| 91 | // does the compare, so that it can be more easily optimized. But that involves generating qmarks at import time... |
| 92 | #endif // FEATURE_SIMD |
| 93 | |
| 94 | #ifdef FEATURE_HW_INTRINSICS |
| 95 | 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. |
| 96 | #endif |
| 97 | |
| 98 | GTNODE(ALLOCOBJ , GenTreeAllocObj ,0,GTK_UNOP|GTK_EXOP) // object allocator |
| 99 | |
| 100 | GTNODE(INIT_VAL , GenTreeOp ,0,GTK_UNOP) // Initialization value for an initBlk |
| 101 | |
| 102 | GTNODE(RUNTIMELOOKUP , GenTreeRuntimeLookup, 0,GTK_UNOP|GTK_EXOP) // Runtime handle lookup |
| 103 | |
| 104 | GTNODE(BSWAP , GenTreeOp ,0,GTK_UNOP) // Byte swap (32-bit or 64-bit) |
| 105 | GTNODE(BSWAP16 , GenTreeOp ,0,GTK_UNOP) // Byte swap (16-bit) |
| 106 | |
| 107 | //----------------------------------------------------------------------------- |
| 108 | // Binary operators (2 operands): |
| 109 | //----------------------------------------------------------------------------- |
| 110 | |
| 111 | GTNODE(ADD , GenTreeOp ,1,GTK_BINOP) |
| 112 | GTNODE(SUB , GenTreeOp ,0,GTK_BINOP) |
| 113 | GTNODE(MUL , GenTreeOp ,1,GTK_BINOP) |
| 114 | GTNODE(DIV , GenTreeOp ,0,GTK_BINOP) |
| 115 | GTNODE(MOD , GenTreeOp ,0,GTK_BINOP) |
| 116 | |
| 117 | GTNODE(UDIV , GenTreeOp ,0,GTK_BINOP) |
| 118 | GTNODE(UMOD , GenTreeOp ,0,GTK_BINOP) |
| 119 | |
| 120 | GTNODE(OR , GenTreeOp ,1,GTK_BINOP|GTK_LOGOP) |
| 121 | GTNODE(XOR , GenTreeOp ,1,GTK_BINOP|GTK_LOGOP) |
| 122 | GTNODE(AND , GenTreeOp ,1,GTK_BINOP|GTK_LOGOP) |
| 123 | |
| 124 | GTNODE(LSH , GenTreeOp ,0,GTK_BINOP) |
| 125 | GTNODE(RSH , GenTreeOp ,0,GTK_BINOP) |
| 126 | GTNODE(RSZ , GenTreeOp ,0,GTK_BINOP) |
| 127 | GTNODE(ROL , GenTreeOp ,0,GTK_BINOP) |
| 128 | GTNODE(ROR , GenTreeOp ,0,GTK_BINOP) |
| 129 | GTNODE(MULHI , GenTreeOp ,1,GTK_BINOP) // returns high bits (top N bits of the 2N bit result of an NxN multiply) |
| 130 | // GT_MULHI is used in division by a constant (fgMorphDivByConst). We turn |
| 131 | // the div into a MULHI + some adjustments. In codegen, we only use the |
| 132 | // results of the high register, and we drop the low results. |
| 133 | |
| 134 | GTNODE(ASG , GenTreeOp ,0,GTK_BINOP|GTK_NOTLIR) |
| 135 | GTNODE(EQ , GenTreeOp ,0,GTK_BINOP|GTK_RELOP) |
| 136 | GTNODE(NE , GenTreeOp ,0,GTK_BINOP|GTK_RELOP) |
| 137 | GTNODE(LT , GenTreeOp ,0,GTK_BINOP|GTK_RELOP) |
| 138 | GTNODE(LE , GenTreeOp ,0,GTK_BINOP|GTK_RELOP) |
| 139 | GTNODE(GE , GenTreeOp ,0,GTK_BINOP|GTK_RELOP) |
| 140 | GTNODE(GT , GenTreeOp ,0,GTK_BINOP|GTK_RELOP) |
| 141 | |
| 142 | // These are similar to GT_EQ/GT_NE but they generate "test" instead of "cmp" instructions. |
| 143 | // Currently these are generated during lowering for code like ((x & y) eq|ne 0) only on |
| 144 | // XArch but ARM could too use these for the same purpose as there is a "tst" instruction. |
| 145 | // Note that the general case of comparing a register against 0 is handled directly by |
| 146 | // codegen which emits a "test reg, reg" instruction, that would be more difficult to do |
| 147 | // during lowering because the source operand is used twice so it has to be a lclvar. |
| 148 | // Because of this there is no need to also add GT_TEST_LT/LE/GE/GT opers. |
| 149 | GTNODE(TEST_EQ , GenTreeOp ,0,GTK_BINOP|GTK_RELOP) |
| 150 | GTNODE(TEST_NE , GenTreeOp ,0,GTK_BINOP|GTK_RELOP) |
| 151 | |
| 152 | GTNODE(COMMA , GenTreeOp ,0,GTK_BINOP|GTK_NOTLIR) |
| 153 | |
| 154 | GTNODE(QMARK , GenTreeQmark ,0,GTK_BINOP|GTK_EXOP|GTK_NOTLIR) |
| 155 | GTNODE(COLON , GenTreeColon ,0,GTK_BINOP|GTK_NOTLIR) |
| 156 | |
| 157 | GTNODE(INDEX , GenTreeIndex ,0,GTK_BINOP|GTK_EXOP|GTK_NOTLIR) // SZ-array-element |
| 158 | GTNODE(INDEX_ADDR , GenTreeIndex ,0,GTK_BINOP|GTK_EXOP) // addr of SZ-array-element; used when |
| 159 | // aiming to minimize compile times. |
| 160 | |
| 161 | GTNODE(MKREFANY , GenTreeOp ,0,GTK_BINOP) |
| 162 | |
| 163 | GTNODE(LEA , GenTreeAddrMode ,0,GTK_BINOP|GTK_EXOP) |
| 164 | |
| 165 | #if !defined(_TARGET_64BIT_) |
| 166 | // A GT_LONG node simply represents the long value produced by the concatenation |
| 167 | // of its two (lower and upper half) operands. Some GT_LONG nodes are transient, |
| 168 | // during the decomposing of longs; others are handled by codegen as operands of |
| 169 | // nodes such as calls, returns and stores of long lclVars. |
| 170 | GTNODE(LONG , GenTreeOp ,0,GTK_BINOP) |
| 171 | |
| 172 | // The following are nodes representing x86/arm32 specific long operators, including |
| 173 | // high operators of a 64-bit operations that requires a carry/borrow, which are |
| 174 | // named GT_XXX_HI for consistency, low operators of 64-bit operations that need |
| 175 | // to not be modified in phases post-decompose, and operators that return 64-bit |
| 176 | // results in one instruction. |
| 177 | GTNODE(ADD_LO , GenTreeOp ,1,GTK_BINOP) |
| 178 | GTNODE(ADD_HI , GenTreeOp ,1,GTK_BINOP) |
| 179 | GTNODE(SUB_LO , GenTreeOp ,0,GTK_BINOP) |
| 180 | GTNODE(SUB_HI , GenTreeOp ,0,GTK_BINOP) |
| 181 | |
| 182 | // A mul that returns the 2N bit result of an NxN multiply. This op is used for |
| 183 | // multiplies that take two ints and return a long result. All other multiplies |
| 184 | // with long results are morphed into helper calls. It is similar to GT_MULHI, |
| 185 | // the difference being that GT_MULHI drops the lo part of the result, whereas |
| 186 | // GT_MUL_LONG keeps both parts of the result. |
| 187 | #if !defined(_TARGET_64BIT_) |
| 188 | GTNODE(MUL_LONG , GenTreeMultiRegOp ,1,GTK_BINOP) |
| 189 | #endif |
| 190 | |
| 191 | // The following are nodes that specify shifts that take a GT_LONG op1. The GT_LONG |
| 192 | // contains the hi and lo parts of three operand shift form where one op will be |
| 193 | // shifted into the other op as part of the operation (LSH_HI will shift |
| 194 | // the high bits of the lo operand into the high operand as it shifts left. RSH_LO |
| 195 | // will shift the lo bits of the high operand into the lo operand). LSH_HI |
| 196 | // represents the high operation of a 64-bit left shift by a constant int, and |
| 197 | // RSH_LO represents the lo operation of a 64-bit right shift by a constant int. |
| 198 | GTNODE(LSH_HI , GenTreeOp ,0,GTK_BINOP) |
| 199 | GTNODE(RSH_LO , GenTreeOp ,0,GTK_BINOP) |
| 200 | #endif // !defined(_TARGET_64BIT_) |
| 201 | |
| 202 | #ifdef FEATURE_SIMD |
| 203 | GTNODE(SIMD , GenTreeSIMD ,0,GTK_BINOP|GTK_EXOP) // SIMD functions/operators/intrinsics |
| 204 | #endif // FEATURE_SIMD |
| 205 | |
| 206 | #ifdef FEATURE_HW_INTRINSICS |
| 207 | GTNODE(HWIntrinsic , GenTreeHWIntrinsic ,0,GTK_BINOP|GTK_EXOP) // hardware intrinsics |
| 208 | #endif // FEATURE_HW_INTRINSICS |
| 209 | |
| 210 | //----------------------------------------------------------------------------- |
| 211 | // LIR specific compare and conditional branch/set nodes: |
| 212 | //----------------------------------------------------------------------------- |
| 213 | |
| 214 | GTNODE(CMP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // Sets the condition flags according to the compare result. |
| 215 | // N.B. Not a relop, it does not produce a value and it cannot be reversed. |
| 216 | GTNODE(JCMP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // Makes a comparison and jump if the condition specified. Does not set flags |
| 217 | GTNODE(JCC , GenTreeCC ,0,GTK_LEAF|GTK_NOVALUE) // Checks the condition flags and branch if the condition specified |
| 218 | // by GenTreeCC::gtCondition is true. |
| 219 | GTNODE(SETCC , GenTreeCC ,0,GTK_LEAF) // Checks the condition flags and produces 1 if the condition specified |
| 220 | // by GenTreeCC::gtCondition is true and 0 otherwise. |
| 221 | #ifdef _TARGET_XARCH_ |
| 222 | GTNODE(BT , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // The XARCH BT instruction. Like CMP, this sets the condition flags (CF |
| 223 | // to be precise) and does not produce a value. |
| 224 | #endif |
| 225 | //----------------------------------------------------------------------------- |
| 226 | // Other nodes that look like unary/binary operators: |
| 227 | //----------------------------------------------------------------------------- |
| 228 | |
| 229 | GTNODE(JTRUE , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) |
| 230 | |
| 231 | GTNODE(LIST , GenTreeArgList ,0,GTK_BINOP|GTK_NOVALUE) |
| 232 | GTNODE(FIELD_LIST , GenTreeFieldList ,0,GTK_BINOP) // List of fields of a struct, when passed as an argument |
| 233 | |
| 234 | //----------------------------------------------------------------------------- |
| 235 | // Other nodes that have special structure: |
| 236 | //----------------------------------------------------------------------------- |
| 237 | |
| 238 | GTNODE(FIELD , GenTreeField ,0,GTK_SPECIAL) // Member-field |
| 239 | GTNODE(ARR_ELEM , GenTreeArrElem ,0,GTK_SPECIAL) // Multi-dimensional array-element address |
| 240 | GTNODE(ARR_INDEX , GenTreeArrIndex ,0,GTK_BINOP|GTK_EXOP) // Effective, bounds-checked index for one dimension of a multi-dimensional array element |
| 241 | GTNODE(ARR_OFFSET , GenTreeArrOffs ,0,GTK_SPECIAL) // Flattened offset of multi-dimensional array element |
| 242 | GTNODE(CALL , GenTreeCall ,0,GTK_SPECIAL|GTK_NOCONTAIN) |
| 243 | |
| 244 | //----------------------------------------------------------------------------- |
| 245 | // Statement operator nodes: |
| 246 | //----------------------------------------------------------------------------- |
| 247 | |
| 248 | GTNODE(BEG_STMTS , GenTree ,0,GTK_SPECIAL|GTK_NOVALUE)// used only temporarily in importer by impBegin/EndTreeList() |
| 249 | GTNODE(STMT , GenTreeStmt ,0,GTK_SPECIAL|GTK_NOVALUE)// top-level list nodes in bbTreeList |
| 250 | |
| 251 | GTNODE(RETURN , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // return from current function |
| 252 | GTNODE(SWITCH , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // switch |
| 253 | |
| 254 | GTNODE(NO_OP , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // nop! |
| 255 | |
| 256 | GTNODE(START_NONGC , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // starts a new instruction group that will be non-gc interruptible |
| 257 | |
| 258 | GTNODE(PROF_HOOK , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // profiler Enter/Leave/TailCall hook |
| 259 | |
| 260 | GTNODE(RETFILT , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // end filter with TYP_I_IMPL return value |
| 261 | #if !FEATURE_EH_FUNCLETS |
| 262 | GTNODE(END_LFIN , GenTreeVal ,0,GTK_LEAF|GTK_NOVALUE) // end locally-invoked finally |
| 263 | #endif // !FEATURE_EH_FUNCLETS |
| 264 | |
| 265 | //----------------------------------------------------------------------------- |
| 266 | // Nodes used for optimizations. |
| 267 | //----------------------------------------------------------------------------- |
| 268 | |
| 269 | GTNODE(PHI , GenTreeOp ,0,GTK_UNOP) // phi node for ssa. |
| 270 | GTNODE(PHI_ARG , GenTreePhiArg ,0,GTK_LEAF|GTK_LOCAL) // phi(phiarg, phiarg, phiarg) |
| 271 | |
| 272 | //----------------------------------------------------------------------------- |
| 273 | // Nodes used by Lower to generate a closer CPU representation of other nodes |
| 274 | //----------------------------------------------------------------------------- |
| 275 | |
| 276 | GTNODE(JMPTABLE , GenTreeJumpTable ,0, GTK_LEAF|GTK_NOCONTAIN) // Generates the jump table for switches |
| 277 | GTNODE(SWITCH_TABLE , GenTreeOp ,0, GTK_BINOP|GTK_NOVALUE) // Jump Table based switch construct |
| 278 | |
| 279 | //----------------------------------------------------------------------------- |
| 280 | // Nodes used only within the code generator: |
| 281 | //----------------------------------------------------------------------------- |
| 282 | |
| 283 | GTNODE(CLS_VAR , GenTreeClsVar ,0,GTK_LEAF) // static data member |
| 284 | GTNODE(CLS_VAR_ADDR , GenTreeClsVar ,0,GTK_LEAF) // static data member address |
| 285 | GTNODE(ARGPLACE , GenTreeArgPlace ,0,GTK_LEAF|GTK_NOVALUE|GTK_NOTLIR) // placeholder for a register arg |
| 286 | GTNODE(NULLCHECK , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // null checks the source |
| 287 | GTNODE(PHYSREG , GenTreePhysReg ,0,GTK_LEAF) // read from a physical register |
| 288 | GTNODE(EMITNOP , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // emitter-placed nop |
| 289 | GTNODE(PINVOKE_PROLOG , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // pinvoke prolog seq |
| 290 | GTNODE(PINVOKE_EPILOG , GenTree ,0,GTK_LEAF|GTK_NOVALUE) // pinvoke epilog seq |
| 291 | #if defined(_TARGET_ARM_) |
| 292 | GTNODE(PUTARG_REG , GenTreeMultiRegOp ,0,GTK_UNOP) // operator that places outgoing arg in register |
| 293 | #else |
| 294 | GTNODE(PUTARG_REG , GenTreeOp ,0,GTK_UNOP) // operator that places outgoing arg in register |
| 295 | #endif |
| 296 | GTNODE(PUTARG_STK , GenTreePutArgStk ,0,GTK_UNOP|GTK_NOVALUE) // operator that places outgoing arg in stack |
| 297 | #if FEATURE_ARG_SPLIT |
| 298 | GTNODE(PUTARG_SPLIT , GenTreePutArgSplit ,0,GTK_UNOP) // operator that places outgoing arg in registers with stack (split struct in ARM32) |
| 299 | #endif // FEATURE_ARG_SPLIT |
| 300 | GTNODE(RETURNTRAP , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // a conditional call to wait on gc |
| 301 | GTNODE(SWAP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // op1 and op2 swap (registers) |
| 302 | GTNODE(IL_OFFSET , GenTreeStmt ,0,GTK_LEAF|GTK_NOVALUE) // marks an IL offset for debugging purposes |
| 303 | |
| 304 | /*****************************************************************************/ |
| 305 | #undef GTNODE |
| 306 | /*****************************************************************************/ |
| 307 | // clang-format on |
| 308 | |