diff options
| author | vvvv <[email protected]> | 2024-02-06 20:01:22 +0300 |
|---|---|---|
| committer | vvvv <[email protected]> | 2024-02-06 20:22:16 +0300 |
| commit | 0203b7a9a40828bb2bd4c32029b79ff0ea3d1f8f (patch) | |
| tree | e630d0d5bd0bd29fc8c2d2842ed2cfde781b993a /contrib/libs/llvm16/include/llvm/CodeGen/ISDOpcodes.h | |
| parent | ba27db76d99d12a4f1c06960b5449423218614c4 (diff) | |
llvm16 targets
Diffstat (limited to 'contrib/libs/llvm16/include/llvm/CodeGen/ISDOpcodes.h')
| -rw-r--r-- | contrib/libs/llvm16/include/llvm/CodeGen/ISDOpcodes.h | 1537 |
1 files changed, 1537 insertions, 0 deletions
diff --git a/contrib/libs/llvm16/include/llvm/CodeGen/ISDOpcodes.h b/contrib/libs/llvm16/include/llvm/CodeGen/ISDOpcodes.h new file mode 100644 index 00000000000..d39b2d03421 --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/CodeGen/ISDOpcodes.h @@ -0,0 +1,1537 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-- llvm/CodeGen/ISDOpcodes.h - CodeGen opcodes -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares codegen opcodes and related utilities. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_ISDOPCODES_H +#define LLVM_CODEGEN_ISDOPCODES_H + +#include "llvm/CodeGen/ValueTypes.h" + +namespace llvm { + +/// ISD namespace - This namespace contains an enum which represents all of the +/// SelectionDAG node types and value types. +/// +namespace ISD { + +//===--------------------------------------------------------------------===// +/// ISD::NodeType enum - This enum defines the target-independent operators +/// for a SelectionDAG. +/// +/// Targets may also define target-dependent operator codes for SDNodes. For +/// example, on x86, these are the enum values in the X86ISD namespace. +/// Targets should aim to use target-independent operators to model their +/// instruction sets as much as possible, and only use target-dependent +/// operators when they have special requirements. +/// +/// Finally, during and after selection proper, SNodes may use special +/// operator codes that correspond directly with MachineInstr opcodes. These +/// are used to represent selected instructions. See the isMachineOpcode() +/// and getMachineOpcode() member functions of SDNode. +/// +enum NodeType { + + /// DELETED_NODE - This is an illegal value that is used to catch + /// errors. This opcode is not a legal opcode for any node. + DELETED_NODE, + + /// EntryToken - This is the marker used to indicate the start of a region. + EntryToken, + + /// TokenFactor - This node takes multiple tokens as input and produces a + /// single token result. This is used to represent the fact that the operand + /// operators are independent of each other. + TokenFactor, + + /// AssertSext, AssertZext - These nodes record if a register contains a + /// value that has already been zero or sign extended from a narrower type. + /// These nodes take two operands. The first is the node that has already + /// been extended, and the second is a value type node indicating the width + /// of the extension. + /// NOTE: In case of the source value (or any vector element value) is + /// poisoned the assertion will not be true for that value. + AssertSext, + AssertZext, + + /// AssertAlign - These nodes record if a register contains a value that + /// has a known alignment and the trailing bits are known to be zero. + /// NOTE: In case of the source value (or any vector element value) is + /// poisoned the assertion will not be true for that value. + AssertAlign, + + /// Various leaf nodes. + BasicBlock, + VALUETYPE, + CONDCODE, + Register, + RegisterMask, + Constant, + ConstantFP, + GlobalAddress, + GlobalTLSAddress, + FrameIndex, + JumpTable, + ConstantPool, + ExternalSymbol, + BlockAddress, + + /// The address of the GOT + GLOBAL_OFFSET_TABLE, + + /// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and + /// llvm.returnaddress on the DAG. These nodes take one operand, the index + /// of the frame or return address to return. An index of zero corresponds + /// to the current function's frame or return address, an index of one to + /// the parent's frame or return address, and so on. + FRAMEADDR, + RETURNADDR, + + /// ADDROFRETURNADDR - Represents the llvm.addressofreturnaddress intrinsic. + /// This node takes no operand, returns a target-specific pointer to the + /// place in the stack frame where the return address of the current + /// function is stored. + ADDROFRETURNADDR, + + /// SPONENTRY - Represents the llvm.sponentry intrinsic. Takes no argument + /// and returns the stack pointer value at the entry of the current + /// function calling this intrinsic. + SPONENTRY, + + /// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic. + /// Materializes the offset from the local object pointer of another + /// function to a particular local object passed to llvm.localescape. The + /// operand is the MCSymbol label used to represent this offset, since + /// typically the offset is not known until after code generation of the + /// parent. + LOCAL_RECOVER, + + /// READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on + /// the DAG, which implements the named register global variables extension. + READ_REGISTER, + WRITE_REGISTER, + + /// FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to + /// first (possible) on-stack argument. This is needed for correct stack + /// adjustment during unwind. + FRAME_TO_ARGS_OFFSET, + + /// EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical + /// Frame Address (CFA), generally the value of the stack pointer at the + /// call site in the previous frame. + EH_DWARF_CFA, + + /// OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents + /// 'eh_return' gcc dwarf builtin, which is used to return from + /// exception. The general meaning is: adjust stack by OFFSET and pass + /// execution to HANDLER. Many platform-related details also :) + EH_RETURN, + + /// RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) + /// This corresponds to the eh.sjlj.setjmp intrinsic. + /// It takes an input chain and a pointer to the jump buffer as inputs + /// and returns an outchain. + EH_SJLJ_SETJMP, + + /// OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) + /// This corresponds to the eh.sjlj.longjmp intrinsic. + /// It takes an input chain and a pointer to the jump buffer as inputs + /// and returns an outchain. + EH_SJLJ_LONGJMP, + + /// OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) + /// The target initializes the dispatch table here. + EH_SJLJ_SETUP_DISPATCH, + + /// TargetConstant* - Like Constant*, but the DAG does not do any folding, + /// simplification, or lowering of the constant. They are used for constants + /// which are known to fit in the immediate fields of their users, or for + /// carrying magic numbers which are not values which need to be + /// materialized in registers. + TargetConstant, + TargetConstantFP, + + /// TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or + /// anything else with this node, and this is valid in the target-specific + /// dag, turning into a GlobalAddress operand. + TargetGlobalAddress, + TargetGlobalTLSAddress, + TargetFrameIndex, + TargetJumpTable, + TargetConstantPool, + TargetExternalSymbol, + TargetBlockAddress, + + MCSymbol, + + /// TargetIndex - Like a constant pool entry, but with completely + /// target-dependent semantics. Holds target flags, a 32-bit index, and a + /// 64-bit index. Targets can use this however they like. + TargetIndex, + + /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) + /// This node represents a target intrinsic function with no side effects. + /// The first operand is the ID number of the intrinsic from the + /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The + /// node returns the result of the intrinsic. + INTRINSIC_WO_CHAIN, + + /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) + /// This node represents a target intrinsic function with side effects that + /// returns a result. The first operand is a chain pointer. The second is + /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The + /// operands to the intrinsic follow. The node has two results, the result + /// of the intrinsic and an output chain. + INTRINSIC_W_CHAIN, + + /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) + /// This node represents a target intrinsic function with side effects that + /// does not return a result. The first operand is a chain pointer. The + /// second is the ID number of the intrinsic from the llvm::Intrinsic + /// namespace. The operands to the intrinsic follow. + INTRINSIC_VOID, + + /// CopyToReg - This node has three operands: a chain, a register number to + /// set to this value, and a value. + CopyToReg, + + /// CopyFromReg - This node indicates that the input value is a virtual or + /// physical register that is defined outside of the scope of this + /// SelectionDAG. The register is available from the RegisterSDNode object. + CopyFromReg, + + /// UNDEF - An undefined node. + UNDEF, + + // FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or + // is evaluated to UNDEF), or returns VAL otherwise. Note that each + // read of UNDEF can yield different value, but FREEZE(UNDEF) cannot. + FREEZE, + + /// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by + /// a Constant, which is required to be operand #1) half of the integer or + /// float value specified as operand #0. This is only for use before + /// legalization, for values that will be broken into multiple registers. + EXTRACT_ELEMENT, + + /// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. + /// Given two values of the same integer value type, this produces a value + /// twice as big. Like EXTRACT_ELEMENT, this can only be used before + /// legalization. The lower part of the composite value should be in + /// element 0 and the upper part should be in element 1. + BUILD_PAIR, + + /// MERGE_VALUES - This node takes multiple discrete operands and returns + /// them all as its individual results. This nodes has exactly the same + /// number of inputs and outputs. This node is useful for some pieces of the + /// code generator that want to think about a single node with multiple + /// results, not multiple nodes. + MERGE_VALUES, + + /// Simple integer binary arithmetic operators. + ADD, + SUB, + MUL, + SDIV, + UDIV, + SREM, + UREM, + + /// SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing + /// a signed/unsigned value of type i[2*N], and return the full value as + /// two results, each of type iN. + SMUL_LOHI, + UMUL_LOHI, + + /// SDIVREM/UDIVREM - Divide two integers and produce both a quotient and + /// remainder result. + SDIVREM, + UDIVREM, + + /// CARRY_FALSE - This node is used when folding other nodes, + /// like ADDC/SUBC, which indicate the carry result is always false. + CARRY_FALSE, + + /// Carry-setting nodes for multiple precision addition and subtraction. + /// These nodes take two operands of the same value type, and produce two + /// results. The first result is the normal add or sub result, the second + /// result is the carry flag result. + /// FIXME: These nodes are deprecated in favor of ADDCARRY and SUBCARRY. + /// They are kept around for now to provide a smooth transition path + /// toward the use of ADDCARRY/SUBCARRY and will eventually be removed. + ADDC, + SUBC, + + /// Carry-using nodes for multiple precision addition and subtraction. These + /// nodes take three operands: The first two are the normal lhs and rhs to + /// the add or sub, and the third is the input carry flag. These nodes + /// produce two results; the normal result of the add or sub, and the output + /// carry flag. These nodes both read and write a carry flag to allow them + /// to them to be chained together for add and sub of arbitrarily large + /// values. + ADDE, + SUBE, + + /// Carry-using nodes for multiple precision addition and subtraction. + /// These nodes take three operands: The first two are the normal lhs and + /// rhs to the add or sub, and the third is a boolean value that is 1 if and + /// only if there is an incoming carry/borrow. These nodes produce two + /// results: the normal result of the add or sub, and a boolean value that is + /// 1 if and only if there is an outgoing carry/borrow. + /// + /// Care must be taken if these opcodes are lowered to hardware instructions + /// that use the inverse logic -- 0 if and only if there is an + /// incoming/outgoing carry/borrow. In such cases, you must preserve the + /// semantics of these opcodes by inverting the incoming carry/borrow, feeding + /// it to the add/sub hardware instruction, and then inverting the outgoing + /// carry/borrow. + /// + /// The use of these opcodes is preferable to adde/sube if the target supports + /// it, as the carry is a regular value rather than a glue, which allows + /// further optimisation. + /// + /// These opcodes are different from [US]{ADD,SUB}O in that ADDCARRY/SUBCARRY + /// consume and produce a carry/borrow, whereas [US]{ADD,SUB}O produce an + /// overflow. + ADDCARRY, + SUBCARRY, + + /// Carry-using overflow-aware nodes for multiple precision addition and + /// subtraction. These nodes take three operands: The first two are normal lhs + /// and rhs to the add or sub, and the third is a boolean indicating if there + /// is an incoming carry. They produce two results: the normal result of the + /// add or sub, and a boolean that indicates if an overflow occurred (*not* + /// flag, because it may be a store to memory, etc.). If the type of the + /// boolean is not i1 then the high bits conform to getBooleanContents. + SADDO_CARRY, + SSUBO_CARRY, + + /// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition. + /// These nodes take two operands: the normal LHS and RHS to the add. They + /// produce two results: the normal result of the add, and a boolean that + /// indicates if an overflow occurred (*not* a flag, because it may be store + /// to memory, etc.). If the type of the boolean is not i1 then the high + /// bits conform to getBooleanContents. + /// These nodes are generated from llvm.[su]add.with.overflow intrinsics. + SADDO, + UADDO, + + /// Same for subtraction. + SSUBO, + USUBO, + + /// Same for multiplication. + SMULO, + UMULO, + + /// RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 + /// integers with the same bit width (W). If the true value of LHS + RHS + /// exceeds the largest value that can be represented by W bits, the + /// resulting value is this maximum value. Otherwise, if this value is less + /// than the smallest value that can be represented by W bits, the + /// resulting value is this minimum value. + SADDSAT, + UADDSAT, + + /// RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 + /// integers with the same bit width (W). If the true value of LHS - RHS + /// exceeds the largest value that can be represented by W bits, the + /// resulting value is this maximum value. Otherwise, if this value is less + /// than the smallest value that can be represented by W bits, the + /// resulting value is this minimum value. + SSUBSAT, + USUBSAT, + + /// RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift. The first + /// operand is the value to be shifted, and the second argument is the amount + /// to shift by. Both must be integers of the same bit width (W). If the true + /// value of LHS << RHS exceeds the largest value that can be represented by + /// W bits, the resulting value is this maximum value, Otherwise, if this + /// value is less than the smallest value that can be represented by W bits, + /// the resulting value is this minimum value. + SSHLSAT, + USHLSAT, + + /// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication + /// on 2 integers with the same width and scale. SCALE represents the scale + /// of both operands as fixed point numbers. This SCALE parameter must be a + /// constant integer. A scale of zero is effectively performing + /// multiplication on 2 integers. + SMULFIX, + UMULFIX, + + /// Same as the corresponding unsaturated fixed point instructions, but the + /// result is clamped between the min and max values representable by the + /// bits of the first 2 operands. + SMULFIXSAT, + UMULFIXSAT, + + /// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on + /// 2 integers with the same width and scale. SCALE represents the scale + /// of both operands as fixed point numbers. This SCALE parameter must be a + /// constant integer. + SDIVFIX, + UDIVFIX, + + /// Same as the corresponding unsaturated fixed point instructions, but the + /// result is clamped between the min and max values representable by the + /// bits of the first 2 operands. + SDIVFIXSAT, + UDIVFIXSAT, + + /// Simple binary floating point operators. + FADD, + FSUB, + FMUL, + FDIV, + FREM, + + /// Constrained versions of the binary floating point operators. + /// These will be lowered to the simple operators before final selection. + /// They are used to limit optimizations while the DAG is being + /// optimized. + STRICT_FADD, + STRICT_FSUB, + STRICT_FMUL, + STRICT_FDIV, + STRICT_FREM, + STRICT_FMA, + + /// Constrained versions of libm-equivalent floating point intrinsics. + /// These will be lowered to the equivalent non-constrained pseudo-op + /// (or expanded to the equivalent library call) before final selection. + /// They are used to limit optimizations while the DAG is being optimized. + STRICT_FSQRT, + STRICT_FPOW, + STRICT_FPOWI, + STRICT_FSIN, + STRICT_FCOS, + STRICT_FEXP, + STRICT_FEXP2, + STRICT_FLOG, + STRICT_FLOG10, + STRICT_FLOG2, + STRICT_FRINT, + STRICT_FNEARBYINT, + STRICT_FMAXNUM, + STRICT_FMINNUM, + STRICT_FCEIL, + STRICT_FFLOOR, + STRICT_FROUND, + STRICT_FROUNDEVEN, + STRICT_FTRUNC, + STRICT_LROUND, + STRICT_LLROUND, + STRICT_LRINT, + STRICT_LLRINT, + STRICT_FMAXIMUM, + STRICT_FMINIMUM, + + /// STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or + /// unsigned integer. These have the same semantics as fptosi and fptoui + /// in IR. + /// They are used to limit optimizations while the DAG is being optimized. + STRICT_FP_TO_SINT, + STRICT_FP_TO_UINT, + + /// STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to + /// a floating point value. These have the same semantics as sitofp and + /// uitofp in IR. + /// They are used to limit optimizations while the DAG is being optimized. + STRICT_SINT_TO_FP, + STRICT_UINT_TO_FP, + + /// X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating + /// point type down to the precision of the destination VT. TRUNC is a + /// flag, which is always an integer that is zero or one. If TRUNC is 0, + /// this is a normal rounding, if it is 1, this FP_ROUND is known to not + /// change the value of Y. + /// + /// The TRUNC = 1 case is used in cases where we know that the value will + /// not be modified by the node, because Y is not using any of the extra + /// precision of source type. This allows certain transformations like + /// STRICT_FP_EXTEND(STRICT_FP_ROUND(X,1)) -> X which are not safe for + /// STRICT_FP_EXTEND(STRICT_FP_ROUND(X,0)) because the extra bits aren't + /// removed. + /// It is used to limit optimizations while the DAG is being optimized. + STRICT_FP_ROUND, + + /// X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP + /// type. + /// It is used to limit optimizations while the DAG is being optimized. + STRICT_FP_EXTEND, + + /// STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used + /// for floating-point operands only. STRICT_FSETCC performs a quiet + /// comparison operation, while STRICT_FSETCCS performs a signaling + /// comparison operation. + STRICT_FSETCC, + STRICT_FSETCCS, + + // FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic. + FPTRUNC_ROUND, + + /// FMA - Perform a * b + c with no intermediate rounding step. + FMA, + + /// FMAD - Perform a * b + c, while getting the same result as the + /// separately rounded operations. + FMAD, + + /// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This + /// DAG node does not require that X and Y have the same type, just that + /// they are both floating point. X and the result must have the same type. + /// FCOPYSIGN(f32, f64) is allowed. + FCOPYSIGN, + + /// INT = FGETSIGN(FP) - Return the sign bit of the specified floating point + /// value as an integer 0/1 value. + FGETSIGN, + + /// Returns platform specific canonical encoding of a floating point number. + FCANONICALIZE, + + /// Performs a check of floating point class property, defined by IEEE-754. + /// The first operand is the floating point value to check. The second operand + /// specifies the checked property and is a TargetConstant which specifies + /// test in the same way as intrinsic 'is_fpclass'. + /// Returns boolean value. + IS_FPCLASS, + + /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector + /// with the specified, possibly variable, elements. The types of the + /// operands must match the vector element type, except that integer types + /// are allowed to be larger than the element type, in which case the + /// operands are implicitly truncated. The types of the operands must all + /// be the same. + BUILD_VECTOR, + + /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element + /// at IDX replaced with VAL. If the type of VAL is larger than the vector + /// element type then VAL is truncated before replacement. + /// + /// If VECTOR is a scalable vector, then IDX may be larger than the minimum + /// vector width. IDX is not first scaled by the runtime scaling factor of + /// VECTOR. + INSERT_VECTOR_ELT, + + /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR + /// identified by the (potentially variable) element number IDX. If the return + /// type is an integer type larger than the element type of the vector, the + /// result is extended to the width of the return type. In that case, the high + /// bits are undefined. + /// + /// If VECTOR is a scalable vector, then IDX may be larger than the minimum + /// vector width. IDX is not first scaled by the runtime scaling factor of + /// VECTOR. + EXTRACT_VECTOR_ELT, + + /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of + /// vector type with the same length and element type, this produces a + /// concatenated vector result value, with length equal to the sum of the + /// lengths of the input vectors. If VECTOR0 is a fixed-width vector, then + /// VECTOR1..VECTORN must all be fixed-width vectors. Similarly, if VECTOR0 + /// is a scalable vector, then VECTOR1..VECTORN must all be scalable vectors. + CONCAT_VECTORS, + + /// INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 + /// inserted into VECTOR1. IDX represents the starting element number at which + /// VECTOR2 will be inserted. IDX must be a constant multiple of T's known + /// minimum vector length. Let the type of VECTOR2 be T, then if T is a + /// scalable vector, IDX is first scaled by the runtime scaling factor of T. + /// The elements of VECTOR1 starting at IDX are overwritten with VECTOR2. + /// Elements IDX through (IDX + num_elements(T) - 1) must be valid VECTOR1 + /// indices. If this condition cannot be determined statically but is false at + /// runtime, then the result vector is undefined. The IDX parameter must be a + /// vector index constant type, which for most targets will be an integer + /// pointer type. + /// + /// This operation supports inserting a fixed-width vector into a scalable + /// vector, but not the other way around. + INSERT_SUBVECTOR, + + /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR. + /// Let the result type be T, then IDX represents the starting element number + /// from which a subvector of type T is extracted. IDX must be a constant + /// multiple of T's known minimum vector length. If T is a scalable vector, + /// IDX is first scaled by the runtime scaling factor of T. Elements IDX + /// through (IDX + num_elements(T) - 1) must be valid VECTOR indices. If this + /// condition cannot be determined statically but is false at runtime, then + /// the result vector is undefined. The IDX parameter must be a vector index + /// constant type, which for most targets will be an integer pointer type. + /// + /// This operation supports extracting a fixed-width vector from a scalable + /// vector, but not the other way around. + EXTRACT_SUBVECTOR, + + /// VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, + /// whose elements are shuffled using the following algorithm: + /// RESULT[i] = VECTOR[VECTOR.ElementCount - 1 - i] + VECTOR_REVERSE, + + /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as + /// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int + /// values that indicate which value (or undef) each result element will + /// get. These constant ints are accessible through the + /// ShuffleVectorSDNode class. This is quite similar to the Altivec + /// 'vperm' instruction, except that the indices must be constants and are + /// in terms of the element size of VEC1/VEC2, not in terms of bytes. + VECTOR_SHUFFLE, + + /// VECTOR_SPLICE(VEC1, VEC2, IMM) - Returns a subvector of the same type as + /// VEC1/VEC2 from CONCAT_VECTORS(VEC1, VEC2), based on the IMM in two ways. + /// Let the result type be T, if IMM is positive it represents the starting + /// element number (an index) from which a subvector of type T is extracted + /// from CONCAT_VECTORS(VEC1, VEC2). If IMM is negative it represents a count + /// specifying the number of trailing elements to extract from VEC1, where the + /// elements of T are selected using the following algorithm: + /// RESULT[i] = CONCAT_VECTORS(VEC1,VEC2)[VEC1.ElementCount - ABS(IMM) + i] + /// If IMM is not in the range [-VL, VL-1] the result vector is undefined. IMM + /// is a constant integer. + VECTOR_SPLICE, + + /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a + /// scalar value into element 0 of the resultant vector type. The top + /// elements 1 to N-1 of the N-element vector are undefined. The type + /// of the operand must match the vector element type, except when they + /// are integer types. In this case the operand is allowed to be wider + /// than the vector element type, and is implicitly truncated to it. + SCALAR_TO_VECTOR, + + /// SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL + /// duplicated in all lanes. The type of the operand must match the vector + /// element type, except when they are integer types. In this case the + /// operand is allowed to be wider than the vector element type, and is + /// implicitly truncated to it. + SPLAT_VECTOR, + + /// SPLAT_VECTOR_PARTS(SCALAR1, SCALAR2, ...) - Returns a vector with the + /// scalar values joined together and then duplicated in all lanes. This + /// represents a SPLAT_VECTOR that has had its scalar operand expanded. This + /// allows representing a 64-bit splat on a target with 32-bit integers. The + /// total width of the scalars must cover the element width. SCALAR1 contains + /// the least significant bits of the value regardless of endianness and all + /// scalars should have the same type. + SPLAT_VECTOR_PARTS, + + /// STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised + /// of a linear sequence of unsigned values starting from 0 with a step of + /// IMM, where IMM must be a TargetConstant with type equal to the vector + /// element type. The arithmetic is performed modulo the bitwidth of the + /// element. + /// + /// The operation does not support returning fixed-width vectors or + /// non-constant operands. + STEP_VECTOR, + + /// MULHU/MULHS - Multiply high - Multiply two integers of type iN, + /// producing an unsigned/signed value of type i[2*N], then return the top + /// part. + MULHU, + MULHS, + + /// AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of + /// type i[N+1], halving the result by shifting it one bit right. + /// shr(add(ext(X), ext(Y)), 1) + AVGFLOORS, + AVGFLOORU, + /// AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an + /// integer of type i[N+2], add 1 and halve the result by shifting it one bit + /// right. shr(add(ext(X), ext(Y), 1), 1) + AVGCEILS, + AVGCEILU, + + // ABDS/ABDU - Absolute difference - Return the absolute difference between + // two numbers interpreted as signed/unsigned. + // i.e trunc(abs(sext(Op0) - sext(Op1))) becomes abds(Op0, Op1) + // or trunc(abs(zext(Op0) - zext(Op1))) becomes abdu(Op0, Op1) + ABDS, + ABDU, + + /// [US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned + /// integers. + SMIN, + SMAX, + UMIN, + UMAX, + + /// Bitwise operators - logical and, logical or, logical xor. + AND, + OR, + XOR, + + /// ABS - Determine the unsigned absolute value of a signed integer value of + /// the same bitwidth. + /// Note: A value of INT_MIN will return INT_MIN, no saturation or overflow + /// is performed. + ABS, + + /// Shift and rotation operations. After legalization, the type of the + /// shift amount is known to be TLI.getShiftAmountTy(). Before legalization + /// the shift amount can be any type, but care must be taken to ensure it is + /// large enough. TLI.getShiftAmountTy() is i8 on some targets, but before + /// legalization, types like i1024 can occur and i8 doesn't have enough bits + /// to represent the shift amount. + /// When the 1st operand is a vector, the shift amount must be in the same + /// type. (TLI.getShiftAmountTy() will return the same type when the input + /// type is a vector.) + /// For rotates and funnel shifts, the shift amount is treated as an unsigned + /// amount modulo the element size of the first operand. + /// + /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount. + /// fshl(X,Y,Z): (X << (Z % BW)) | (Y >> (BW - (Z % BW))) + /// fshr(X,Y,Z): (X << (BW - (Z % BW))) | (Y >> (Z % BW)) + SHL, + SRA, + SRL, + ROTL, + ROTR, + FSHL, + FSHR, + + /// Byte Swap and Counting operators. + BSWAP, + CTTZ, + CTLZ, + CTPOP, + BITREVERSE, + PARITY, + + /// Bit counting operators with an undefined result for zero inputs. + CTTZ_ZERO_UNDEF, + CTLZ_ZERO_UNDEF, + + /// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not + /// i1 then the high bits must conform to getBooleanContents. + SELECT, + + /// Select with a vector condition (op #0) and two vector operands (ops #1 + /// and #2), returning a vector result. All vectors have the same length. + /// Much like the scalar select and setcc, each bit in the condition selects + /// whether the corresponding result element is taken from op #1 or op #2. + /// At first, the VSELECT condition is of vXi1 type. Later, targets may + /// change the condition type in order to match the VSELECT node using a + /// pattern. The condition follows the BooleanContent format of the target. + VSELECT, + + /// Select with condition operator - This selects between a true value and + /// a false value (ops #2 and #3) based on the boolean result of comparing + /// the lhs and rhs (ops #0 and #1) of a conditional expression with the + /// condition code in op #4, a CondCodeSDNode. + SELECT_CC, + + /// SetCC operator - This evaluates to a true value iff the condition is + /// true. If the result value type is not i1 then the high bits conform + /// to getBooleanContents. The operands to this are the left and right + /// operands to compare (ops #0, and #1) and the condition code to compare + /// them with (op #2) as a CondCodeSDNode. If the operands are vector types + /// then the result type must also be a vector type. + SETCC, + + /// Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but + /// op #2 is a boolean indicating if there is an incoming carry. This + /// operator checks the result of "LHS - RHS - Carry", and can be used to + /// compare two wide integers: + /// (setcccarry lhshi rhshi (subcarry lhslo rhslo) cc). + /// Only valid for integers. + SETCCCARRY, + + /// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded + /// integer shift operations. The operation ordering is: + /// [Lo,Hi] = op [LoLHS,HiLHS], Amt + SHL_PARTS, + SRA_PARTS, + SRL_PARTS, + + /// Conversion operators. These are all single input single output + /// operations. For all of these, the result type must be strictly + /// wider or narrower (depending on the operation) than the source + /// type. + + /// SIGN_EXTEND - Used for integer types, replicating the sign bit + /// into new bits. + SIGN_EXTEND, + + /// ZERO_EXTEND - Used for integer types, zeroing the new bits. + ZERO_EXTEND, + + /// ANY_EXTEND - Used for integer types. The high bits are undefined. + ANY_EXTEND, + + /// TRUNCATE - Completely drop the high bits. + TRUNCATE, + + /// [SU]INT_TO_FP - These operators convert integers (whose interpreted sign + /// depends on the first letter) to floating point. + SINT_TO_FP, + UINT_TO_FP, + + /// SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to + /// sign extend a small value in a large integer register (e.g. sign + /// extending the low 8 bits of a 32-bit register to fill the top 24 bits + /// with the 7th bit). The size of the smaller type is indicated by the 1th + /// operand, a ValueType node. + SIGN_EXTEND_INREG, + + /// ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an + /// in-register any-extension of the low lanes of an integer vector. The + /// result type must have fewer elements than the operand type, and those + /// elements must be larger integer types such that the total size of the + /// operand type is less than or equal to the size of the result type. Each + /// of the low operand elements is any-extended into the corresponding, + /// wider result elements with the high bits becoming undef. + /// NOTE: The type legalizer prefers to make the operand and result size + /// the same to allow expansion to shuffle vector during op legalization. + ANY_EXTEND_VECTOR_INREG, + + /// SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an + /// in-register sign-extension of the low lanes of an integer vector. The + /// result type must have fewer elements than the operand type, and those + /// elements must be larger integer types such that the total size of the + /// operand type is less than or equal to the size of the result type. Each + /// of the low operand elements is sign-extended into the corresponding, + /// wider result elements. + /// NOTE: The type legalizer prefers to make the operand and result size + /// the same to allow expansion to shuffle vector during op legalization. + SIGN_EXTEND_VECTOR_INREG, + + /// ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an + /// in-register zero-extension of the low lanes of an integer vector. The + /// result type must have fewer elements than the operand type, and those + /// elements must be larger integer types such that the total size of the + /// operand type is less than or equal to the size of the result type. Each + /// of the low operand elements is zero-extended into the corresponding, + /// wider result elements. + /// NOTE: The type legalizer prefers to make the operand and result size + /// the same to allow expansion to shuffle vector during op legalization. + ZERO_EXTEND_VECTOR_INREG, + + /// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned + /// integer. These have the same semantics as fptosi and fptoui in IR. If + /// the FP value cannot fit in the integer type, the results are undefined. + FP_TO_SINT, + FP_TO_UINT, + + /// FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a + /// signed or unsigned scalar integer type given in operand 1 with the + /// following semantics: + /// + /// * If the value is NaN, zero is returned. + /// * If the value is larger/smaller than the largest/smallest integer, + /// the largest/smallest integer is returned (saturation). + /// * Otherwise the result of rounding the value towards zero is returned. + /// + /// The scalar width of the type given in operand 1 must be equal to, or + /// smaller than, the scalar result type width. It may end up being smaller + /// than the result width as a result of integer type legalization. + /// + /// After converting to the scalar integer type in operand 1, the value is + /// extended to the result VT. FP_TO_SINT_SAT sign extends and FP_TO_UINT_SAT + /// zero extends. + FP_TO_SINT_SAT, + FP_TO_UINT_SAT, + + /// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type + /// down to the precision of the destination VT. TRUNC is a flag, which is + /// always an integer that is zero or one. If TRUNC is 0, this is a + /// normal rounding, if it is 1, this FP_ROUND is known to not change the + /// value of Y. + /// + /// The TRUNC = 1 case is used in cases where we know that the value will + /// not be modified by the node, because Y is not using any of the extra + /// precision of source type. This allows certain transformations like + /// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for + /// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed. + FP_ROUND, + + /// Returns current rounding mode: + /// -1 Undefined + /// 0 Round to 0 + /// 1 Round to nearest, ties to even + /// 2 Round to +inf + /// 3 Round to -inf + /// 4 Round to nearest, ties to zero + /// Result is rounding mode and chain. Input is a chain. + GET_ROUNDING, + + /// Set rounding mode. + /// The first operand is a chain pointer. The second specifies the required + /// rounding mode, encoded in the same way as used in '``GET_ROUNDING``'. + SET_ROUNDING, + + /// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type. + FP_EXTEND, + + /// BITCAST - This operator converts between integer, vector and FP + /// values, as if the value was stored to memory with one type and loaded + /// from the same address with the other type (or equivalently for vector + /// format conversions, etc). The source and result are required to have + /// the same bit size (e.g. f32 <-> i32). This can also be used for + /// int-to-int or fp-to-fp conversions, but that is a noop, deleted by + /// getNode(). + /// + /// This operator is subtly different from the bitcast instruction from + /// LLVM-IR since this node may change the bits in the register. For + /// example, this occurs on big-endian NEON and big-endian MSA where the + /// layout of the bits in the register depends on the vector type and this + /// operator acts as a shuffle operation for some vector type combinations. + BITCAST, + + /// ADDRSPACECAST - This operator converts between pointers of different + /// address spaces. + ADDRSPACECAST, + + /// FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions + /// and truncation for half-precision (16 bit) floating numbers. These nodes + /// form a semi-softened interface for dealing with f16 (as an i16), which + /// is often a storage-only type but has native conversions. + FP16_TO_FP, + FP_TO_FP16, + STRICT_FP16_TO_FP, + STRICT_FP_TO_FP16, + + /// BF16_TO_FP, FP_TO_BF16 - These operators are used to perform promotions + /// and truncation for bfloat16. These nodes form a semi-softened interface + /// for dealing with bf16 (as an i16), which is often a storage-only type but + /// has native conversions. + BF16_TO_FP, + FP_TO_BF16, + + /// Perform various unary floating-point operations inspired by libm. For + /// FPOWI, the result is undefined if if the integer operand doesn't fit into + /// sizeof(int). + FNEG, + FABS, + FSQRT, + FCBRT, + FSIN, + FCOS, + FPOWI, + FPOW, + FLOG, + FLOG2, + FLOG10, + FEXP, + FEXP2, + FCEIL, + FTRUNC, + FRINT, + FNEARBYINT, + FROUND, + FROUNDEVEN, + FFLOOR, + LROUND, + LLROUND, + LRINT, + LLRINT, + + /// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two + /// values. + // + /// In the case where a single input is a NaN (either signaling or quiet), + /// the non-NaN input is returned. + /// + /// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0. + FMINNUM, + FMAXNUM, + + /// FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on + /// two values, following the IEEE-754 2008 definition. This differs from + /// FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a + /// signaling NaN, returns a quiet NaN. + FMINNUM_IEEE, + FMAXNUM_IEEE, + + /// FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 + /// as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008 + /// semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics. + FMINIMUM, + FMAXIMUM, + + /// FSINCOS - Compute both fsin and fcos as a single operation. + FSINCOS, + + /// LOAD and STORE have token chains as their first operand, then the same + /// operands as an LLVM load/store instruction, then an offset node that + /// is added / subtracted from the base pointer to form the address (for + /// indexed memory ops). + LOAD, + STORE, + + /// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned + /// to a specified boundary. This node always has two return values: a new + /// stack pointer value and a chain. The first operand is the token chain, + /// the second is the number of bytes to allocate, and the third is the + /// alignment boundary. The size is guaranteed to be a multiple of the + /// stack alignment, and the alignment is guaranteed to be bigger than the + /// stack alignment (if required) or 0 to get standard stack alignment. + DYNAMIC_STACKALLOC, + + /// Control flow instructions. These all have token chains. + + /// BR - Unconditional branch. The first operand is the chain + /// operand, the second is the MBB to branch to. + BR, + + /// BRIND - Indirect branch. The first operand is the chain, the second + /// is the value to branch to, which must be of the same type as the + /// target's pointer type. + BRIND, + + /// BR_JT - Jumptable branch. The first operand is the chain, the second + /// is the jumptable index, the last one is the jumptable entry index. + BR_JT, + + /// BRCOND - Conditional branch. The first operand is the chain, the + /// second is the condition, the third is the block to branch to if the + /// condition is true. If the type of the condition is not i1, then the + /// high bits must conform to getBooleanContents. If the condition is undef, + /// it nondeterministically jumps to the block. + /// TODO: Its semantics w.r.t undef requires further discussion; we need to + /// make it sure that it is consistent with optimizations in MIR & the + /// meaning of IMPLICIT_DEF. See https://reviews.llvm.org/D92015 + BRCOND, + + /// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in + /// that the condition is represented as condition code, and two nodes to + /// compare, rather than as a combined SetCC node. The operands in order + /// are chain, cc, lhs, rhs, block to branch to if condition is true. If + /// condition is undef, it nondeterministically jumps to the block. + BR_CC, + + /// INLINEASM - Represents an inline asm block. This node always has two + /// return values: a chain and a flag result. The inputs are as follows: + /// Operand #0 : Input chain. + /// Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string. + /// Operand #2 : a MDNodeSDNode with the !srcloc metadata. + /// Operand #3 : HasSideEffect, IsAlignStack bits. + /// After this, it is followed by a list of operands with this format: + /// ConstantSDNode: Flags that encode whether it is a mem or not, the + /// of operands that follow, etc. See InlineAsm.h. + /// ... however many operands ... + /// Operand #last: Optional, an incoming flag. + /// + /// The variable width operands are required to represent target addressing + /// modes as a single "operand", even though they may have multiple + /// SDOperands. + INLINEASM, + + /// INLINEASM_BR - Branching version of inline asm. Used by asm-goto. + INLINEASM_BR, + + /// EH_LABEL - Represents a label in mid basic block used to track + /// locations needed for debug and exception handling tables. These nodes + /// take a chain as input and return a chain. + EH_LABEL, + + /// ANNOTATION_LABEL - Represents a mid basic block label used by + /// annotations. This should remain within the basic block and be ordered + /// with respect to other call instructions, but loads and stores may float + /// past it. + ANNOTATION_LABEL, + + /// CATCHRET - Represents a return from a catch block funclet. Used for + /// MSVC compatible exception handling. Takes a chain operand and a + /// destination basic block operand. + CATCHRET, + + /// CLEANUPRET - Represents a return from a cleanup block funclet. Used for + /// MSVC compatible exception handling. Takes only a chain operand. + CLEANUPRET, + + /// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a + /// value, the same type as the pointer type for the system, and an output + /// chain. + STACKSAVE, + + /// STACKRESTORE has two operands, an input chain and a pointer to restore + /// to it returns an output chain. + STACKRESTORE, + + /// CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end + /// of a call sequence, and carry arbitrary information that target might + /// want to know. The first operand is a chain, the rest are specified by + /// the target and not touched by the DAG optimizers. + /// Targets that may use stack to pass call arguments define additional + /// operands: + /// - size of the call frame part that must be set up within the + /// CALLSEQ_START..CALLSEQ_END pair, + /// - part of the call frame prepared prior to CALLSEQ_START. + /// Both these parameters must be constants, their sum is the total call + /// frame size. + /// CALLSEQ_START..CALLSEQ_END pairs may not be nested. + CALLSEQ_START, // Beginning of a call sequence + CALLSEQ_END, // End of a call sequence + + /// VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, + /// and the alignment. It returns a pair of values: the vaarg value and a + /// new chain. + VAARG, + + /// VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, + /// a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the + /// source. + VACOPY, + + /// VAEND, VASTART - VAEND and VASTART have three operands: an input chain, + /// pointer, and a SRCVALUE. + VAEND, + VASTART, + + // PREALLOCATED_SETUP - This has 2 operands: an input chain and a SRCVALUE + // with the preallocated call Value. + PREALLOCATED_SETUP, + // PREALLOCATED_ARG - This has 3 operands: an input chain, a SRCVALUE + // with the preallocated call Value, and a constant int. + PREALLOCATED_ARG, + + /// SRCVALUE - This is a node type that holds a Value* that is used to + /// make reference to a value in the LLVM IR. + SRCVALUE, + + /// MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to + /// reference metadata in the IR. + MDNODE_SDNODE, + + /// PCMARKER - This corresponds to the pcmarker intrinsic. + PCMARKER, + + /// READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic. + /// It produces a chain and one i64 value. The only operand is a chain. + /// If i64 is not legal, the result will be expanded into smaller values. + /// Still, it returns an i64, so targets should set legality for i64. + /// The result is the content of the architecture-specific cycle + /// counter-like register (or other high accuracy low latency clock source). + READCYCLECOUNTER, + + /// HANDLENODE node - Used as a handle for various purposes. + HANDLENODE, + + /// INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It + /// takes as input a token chain, the pointer to the trampoline, the pointer + /// to the nested function, the pointer to pass for the 'nest' parameter, a + /// SRCVALUE for the trampoline and another for the nested function + /// (allowing targets to access the original Function*). + /// It produces a token chain as output. + INIT_TRAMPOLINE, + + /// ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic. + /// It takes a pointer to the trampoline and produces a (possibly) new + /// pointer to the same trampoline with platform-specific adjustments + /// applied. The pointer it returns points to an executable block of code. + ADJUST_TRAMPOLINE, + + /// TRAP - Trapping instruction + TRAP, + + /// DEBUGTRAP - Trap intended to get the attention of a debugger. + DEBUGTRAP, + + /// UBSANTRAP - Trap with an immediate describing the kind of sanitizer + /// failure. + UBSANTRAP, + + /// PREFETCH - This corresponds to a prefetch intrinsic. The first operand + /// is the chain. The other operands are the address to prefetch, + /// read / write specifier, locality specifier and instruction / data cache + /// specifier. + PREFETCH, + + /// ARITH_FENCE - This corresponds to a arithmetic fence intrinsic. Both its + /// operand and output are the same floating type. + ARITH_FENCE, + + /// MEMBARRIER - Compiler barrier only; generate a no-op. + MEMBARRIER, + + /// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) + /// This corresponds to the fence instruction. It takes an input chain, and + /// two integer constants: an AtomicOrdering and a SynchronizationScope. + ATOMIC_FENCE, + + /// Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) + /// This corresponds to "load atomic" instruction. + ATOMIC_LOAD, + + /// OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) + /// This corresponds to "store atomic" instruction. + ATOMIC_STORE, + + /// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) + /// For double-word atomic operations: + /// ValLo, ValHi, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmpLo, cmpHi, + /// swapLo, swapHi) + /// This corresponds to the cmpxchg instruction. + ATOMIC_CMP_SWAP, + + /// Val, Success, OUTCHAIN + /// = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) + /// N.b. this is still a strong cmpxchg operation, so + /// Success == "Val == cmp". + ATOMIC_CMP_SWAP_WITH_SUCCESS, + + /// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) + /// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) + /// For double-word atomic operations: + /// ValLo, ValHi, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amtLo, amtHi) + /// ValLo, ValHi, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amtLo, amtHi) + /// These correspond to the atomicrmw instruction. + ATOMIC_SWAP, + ATOMIC_LOAD_ADD, + ATOMIC_LOAD_SUB, + ATOMIC_LOAD_AND, + ATOMIC_LOAD_CLR, + ATOMIC_LOAD_OR, + ATOMIC_LOAD_XOR, + ATOMIC_LOAD_NAND, + ATOMIC_LOAD_MIN, + ATOMIC_LOAD_MAX, + ATOMIC_LOAD_UMIN, + ATOMIC_LOAD_UMAX, + ATOMIC_LOAD_FADD, + ATOMIC_LOAD_FSUB, + ATOMIC_LOAD_FMAX, + ATOMIC_LOAD_FMIN, + ATOMIC_LOAD_UINC_WRAP, + ATOMIC_LOAD_UDEC_WRAP, + + // Masked load and store - consecutive vector load and store operations + // with additional mask operand that prevents memory accesses to the + // masked-off lanes. + // + // Val, OutChain = MLOAD(BasePtr, Mask, PassThru) + // OutChain = MSTORE(Value, BasePtr, Mask) + MLOAD, + MSTORE, + + // Masked gather and scatter - load and store operations for a vector of + // random addresses with additional mask operand that prevents memory + // accesses to the masked-off lanes. + // + // Val, OutChain = GATHER(InChain, PassThru, Mask, BasePtr, Index, Scale) + // OutChain = SCATTER(InChain, Value, Mask, BasePtr, Index, Scale) + // + // The Index operand can have more vector elements than the other operands + // due to type legalization. The extra elements are ignored. + MGATHER, + MSCATTER, + + /// This corresponds to the llvm.lifetime.* intrinsics. The first operand + /// is the chain and the second operand is the alloca pointer. + LIFETIME_START, + LIFETIME_END, + + /// GC_TRANSITION_START/GC_TRANSITION_END - These operators mark the + /// beginning and end of GC transition sequence, and carry arbitrary + /// information that target might need for lowering. The first operand is + /// a chain, the rest are specified by the target and not touched by the DAG + /// optimizers. GC_TRANSITION_START..GC_TRANSITION_END pairs may not be + /// nested. + GC_TRANSITION_START, + GC_TRANSITION_END, + + /// GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of + /// the most recent dynamic alloca. For most targets that would be 0, but + /// for some others (e.g. PowerPC, PowerPC64) that would be compile-time + /// known nonzero constant. The only operand here is the chain. + GET_DYNAMIC_AREA_OFFSET, + + /// Pseudo probe for AutoFDO, as a place holder in a basic block to improve + /// the sample counts quality. + PSEUDO_PROBE, + + /// VSCALE(IMM) - Returns the runtime scaling factor used to calculate the + /// number of elements within a scalable vector. IMM is a constant integer + /// multiplier that is applied to the runtime value. + VSCALE, + + /// Generic reduction nodes. These nodes represent horizontal vector + /// reduction operations, producing a scalar result. + /// The SEQ variants perform reductions in sequential order. The first + /// operand is an initial scalar accumulator value, and the second operand + /// is the vector to reduce. + /// E.g. RES = VECREDUCE_SEQ_FADD f32 ACC, <4 x f32> SRC_VEC + /// ... is equivalent to + /// RES = (((ACC + SRC_VEC[0]) + SRC_VEC[1]) + SRC_VEC[2]) + SRC_VEC[3] + VECREDUCE_SEQ_FADD, + VECREDUCE_SEQ_FMUL, + + /// These reductions have relaxed evaluation order semantics, and have a + /// single vector operand. The order of evaluation is unspecified. For + /// pow-of-2 vectors, one valid legalizer expansion is to use a tree + /// reduction, i.e.: + /// For RES = VECREDUCE_FADD <8 x f16> SRC_VEC + /// PART_RDX = FADD SRC_VEC[0:3], SRC_VEC[4:7] + /// PART_RDX2 = FADD PART_RDX[0:1], PART_RDX[2:3] + /// RES = FADD PART_RDX2[0], PART_RDX2[1] + /// For non-pow-2 vectors, this can be computed by extracting each element + /// and performing the operation as if it were scalarized. + VECREDUCE_FADD, + VECREDUCE_FMUL, + /// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants. + VECREDUCE_FMAX, + VECREDUCE_FMIN, + /// Integer reductions may have a result type larger than the vector element + /// type. However, the reduction is performed using the vector element type + /// and the value in the top bits is unspecified. + VECREDUCE_ADD, + VECREDUCE_MUL, + VECREDUCE_AND, + VECREDUCE_OR, + VECREDUCE_XOR, + VECREDUCE_SMAX, + VECREDUCE_SMIN, + VECREDUCE_UMAX, + VECREDUCE_UMIN, + + // The `llvm.experimental.stackmap` intrinsic. + // Operands: input chain, glue, <id>, <numShadowBytes>, [live0[, live1...]] + // Outputs: output chain, glue + STACKMAP, + + // The `llvm.experimental.patchpoint.*` intrinsic. + // Operands: input chain, [glue], reg-mask, <id>, <numShadowBytes>, callee, + // <numArgs>, cc, ... + // Outputs: [rv], output chain, glue + PATCHPOINT, + +// Vector Predication +#define BEGIN_REGISTER_VP_SDNODE(VPSDID, ...) VPSDID, +#include "llvm/IR/VPIntrinsics.def" + + /// BUILTIN_OP_END - This must be the last enum value in this list. + /// The target-specific pre-isel opcode values start here. + BUILTIN_OP_END +}; + +/// FIRST_TARGET_STRICTFP_OPCODE - Target-specific pre-isel operations +/// which cannot raise FP exceptions should be less than this value. +/// Those that do must not be less than this value. +static const int FIRST_TARGET_STRICTFP_OPCODE = BUILTIN_OP_END + 400; + +/// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations +/// which do not reference a specific memory location should be less than +/// this value. Those that do must not be less than this value, and can +/// be used with SelectionDAG::getMemIntrinsicNode. +static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END + 500; + +/// Whether this is bitwise logic opcode. +inline bool isBitwiseLogicOp(unsigned Opcode) { + return Opcode == ISD::AND || Opcode == ISD::OR || Opcode == ISD::XOR; +} + +/// Get underlying scalar opcode for VECREDUCE opcode. +/// For example ISD::AND for ISD::VECREDUCE_AND. +NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode); + +/// Whether this is a vector-predicated Opcode. +bool isVPOpcode(unsigned Opcode); + +/// Whether this is a vector-predicated binary operation opcode. +bool isVPBinaryOp(unsigned Opcode); + +/// Whether this is a vector-predicated reduction opcode. +bool isVPReduction(unsigned Opcode); + +/// The operand position of the vector mask. +std::optional<unsigned> getVPMaskIdx(unsigned Opcode); + +/// The operand position of the explicit vector length parameter. +std::optional<unsigned> getVPExplicitVectorLengthIdx(unsigned Opcode); + +//===--------------------------------------------------------------------===// +/// MemIndexedMode enum - This enum defines the load / store indexed +/// addressing modes. +/// +/// UNINDEXED "Normal" load / store. The effective address is already +/// computed and is available in the base pointer. The offset +/// operand is always undefined. In addition to producing a +/// chain, an unindexed load produces one value (result of the +/// load); an unindexed store does not produce a value. +/// +/// PRE_INC Similar to the unindexed mode where the effective address is +/// PRE_DEC the value of the base pointer add / subtract the offset. +/// It considers the computation as being folded into the load / +/// store operation (i.e. the load / store does the address +/// computation as well as performing the memory transaction). +/// The base operand is always undefined. In addition to +/// producing a chain, pre-indexed load produces two values +/// (result of the load and the result of the address +/// computation); a pre-indexed store produces one value (result +/// of the address computation). +/// +/// POST_INC The effective address is the value of the base pointer. The +/// POST_DEC value of the offset operand is then added to / subtracted +/// from the base after memory transaction. In addition to +/// producing a chain, post-indexed load produces two values +/// (the result of the load and the result of the base +/- offset +/// computation); a post-indexed store produces one value (the +/// the result of the base +/- offset computation). +enum MemIndexedMode { UNINDEXED = 0, PRE_INC, PRE_DEC, POST_INC, POST_DEC }; + +static const int LAST_INDEXED_MODE = POST_DEC + 1; + +//===--------------------------------------------------------------------===// +/// MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's +/// index parameter when calculating addresses. +/// +/// SIGNED_SCALED Addr = Base + ((signed)Index * Scale) +/// UNSIGNED_SCALED Addr = Base + ((unsigned)Index * Scale) +/// +/// NOTE: The value of Scale is typically only known to the node owning the +/// IndexType, with a value of 1 the equivalent of being unscaled. +enum MemIndexType { SIGNED_SCALED = 0, UNSIGNED_SCALED }; + +static const int LAST_MEM_INDEX_TYPE = UNSIGNED_SCALED + 1; + +inline bool isIndexTypeSigned(MemIndexType IndexType) { + return IndexType == SIGNED_SCALED; +} + +//===--------------------------------------------------------------------===// +/// LoadExtType enum - This enum defines the three variants of LOADEXT +/// (load with extension). +/// +/// SEXTLOAD loads the integer operand and sign extends it to a larger +/// integer result type. +/// ZEXTLOAD loads the integer operand and zero extends it to a larger +/// integer result type. +/// EXTLOAD is used for two things: floating point extending loads and +/// integer extending loads [the top bits are undefined]. +enum LoadExtType { NON_EXTLOAD = 0, EXTLOAD, SEXTLOAD, ZEXTLOAD }; + +static const int LAST_LOADEXT_TYPE = ZEXTLOAD + 1; + +NodeType getExtForLoadExtType(bool IsFP, LoadExtType); + +//===--------------------------------------------------------------------===// +/// ISD::CondCode enum - These are ordered carefully to make the bitfields +/// below work out, when considering SETFALSE (something that never exists +/// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered +/// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal +/// to. If the "N" column is 1, the result of the comparison is undefined if +/// the input is a NAN. +/// +/// All of these (except for the 'always folded ops') should be handled for +/// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT, +/// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used. +/// +/// Note that these are laid out in a specific order to allow bit-twiddling +/// to transform conditions. +enum CondCode { + // Opcode N U L G E Intuitive operation + SETFALSE, // 0 0 0 0 Always false (always folded) + SETOEQ, // 0 0 0 1 True if ordered and equal + SETOGT, // 0 0 1 0 True if ordered and greater than + SETOGE, // 0 0 1 1 True if ordered and greater than or equal + SETOLT, // 0 1 0 0 True if ordered and less than + SETOLE, // 0 1 0 1 True if ordered and less than or equal + SETONE, // 0 1 1 0 True if ordered and operands are unequal + SETO, // 0 1 1 1 True if ordered (no nans) + SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y) + SETUEQ, // 1 0 0 1 True if unordered or equal + SETUGT, // 1 0 1 0 True if unordered or greater than + SETUGE, // 1 0 1 1 True if unordered, greater than, or equal + SETULT, // 1 1 0 0 True if unordered or less than + SETULE, // 1 1 0 1 True if unordered, less than, or equal + SETUNE, // 1 1 1 0 True if unordered or not equal + SETTRUE, // 1 1 1 1 Always true (always folded) + // Don't care operations: undefined if the input is a nan. + SETFALSE2, // 1 X 0 0 0 Always false (always folded) + SETEQ, // 1 X 0 0 1 True if equal + SETGT, // 1 X 0 1 0 True if greater than + SETGE, // 1 X 0 1 1 True if greater than or equal + SETLT, // 1 X 1 0 0 True if less than + SETLE, // 1 X 1 0 1 True if less than or equal + SETNE, // 1 X 1 1 0 True if not equal + SETTRUE2, // 1 X 1 1 1 Always true (always folded) + + SETCC_INVALID // Marker value. +}; + +/// Return true if this is a setcc instruction that performs a signed +/// comparison when used with integer operands. +inline bool isSignedIntSetCC(CondCode Code) { + return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE; +} + +/// Return true if this is a setcc instruction that performs an unsigned +/// comparison when used with integer operands. +inline bool isUnsignedIntSetCC(CondCode Code) { + return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE; +} + +/// Return true if this is a setcc instruction that performs an equality +/// comparison when used with integer operands. +inline bool isIntEqualitySetCC(CondCode Code) { + return Code == SETEQ || Code == SETNE; +} + +/// Return true if the specified condition returns true if the two operands to +/// the condition are equal. Note that if one of the two operands is a NaN, +/// this value is meaningless. +inline bool isTrueWhenEqual(CondCode Cond) { return ((int)Cond & 1) != 0; } + +/// This function returns 0 if the condition is always false if an operand is +/// a NaN, 1 if the condition is always true if the operand is a NaN, and 2 if +/// the condition is undefined if the operand is a NaN. +inline unsigned getUnorderedFlavor(CondCode Cond) { + return ((int)Cond >> 3) & 3; +} + +/// Return the operation corresponding to !(X op Y), where 'op' is a valid +/// SetCC operation. +CondCode getSetCCInverse(CondCode Operation, EVT Type); + +inline bool isExtOpcode(unsigned Opcode) { + return Opcode == ISD::ANY_EXTEND || Opcode == ISD::ZERO_EXTEND || + Opcode == ISD::SIGN_EXTEND; +} + +namespace GlobalISel { +/// Return the operation corresponding to !(X op Y), where 'op' is a valid +/// SetCC operation. The U bit of the condition code has different meanings +/// between floating point and integer comparisons and LLT's don't provide +/// this distinction. As such we need to be told whether the comparison is +/// floating point or integer-like. Pointers should use integer-like +/// comparisons. +CondCode getSetCCInverse(CondCode Operation, bool isIntegerLike); +} // end namespace GlobalISel + +/// Return the operation corresponding to (Y op X) when given the operation +/// for (X op Y). +CondCode getSetCCSwappedOperands(CondCode Operation); + +/// Return the result of a logical OR between different comparisons of +/// identical values: ((X op1 Y) | (X op2 Y)). This function returns +/// SETCC_INVALID if it is not possible to represent the resultant comparison. +CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, EVT Type); + +/// Return the result of a logical AND between different comparisons of +/// identical values: ((X op1 Y) & (X op2 Y)). This function returns +/// SETCC_INVALID if it is not possible to represent the resultant comparison. +CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, EVT Type); + +} // namespace ISD + +} // namespace llvm + +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |
