//===-- llvm/Support/TargetOpcodes.def - Target Indep Opcodes ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the target independent instruction opcodes.
//
//===----------------------------------------------------------------------===//

// NOTE: NO INCLUDE GUARD DESIRED!

/// HANDLE_TARGET_OPCODE defines an opcode and its associated enum value.
///
#ifndef HANDLE_TARGET_OPCODE
#define HANDLE_TARGET_OPCODE(OPC, NUM)
#endif

/// HANDLE_TARGET_OPCODE_MARKER defines an alternative identifier for an opcode.
///
#ifndef HANDLE_TARGET_OPCODE_MARKER
#define HANDLE_TARGET_OPCODE_MARKER(IDENT, OPC)
#endif

/// Every instruction defined here must also appear in Target.td.
///
HANDLE_TARGET_OPCODE(PHI)
HANDLE_TARGET_OPCODE(INLINEASM)
HANDLE_TARGET_OPCODE(CFI_INSTRUCTION)
HANDLE_TARGET_OPCODE(EH_LABEL)
HANDLE_TARGET_OPCODE(GC_LABEL)
HANDLE_TARGET_OPCODE(ANNOTATION_LABEL)

/// KILL - This instruction is a noop that is used only to adjust the
/// liveness of registers. This can be useful when dealing with
/// sub-registers.
HANDLE_TARGET_OPCODE(KILL)

/// EXTRACT_SUBREG - This instruction takes two operands: a register
/// that has subregisters, and a subregister index. It returns the
/// extracted subregister value. This is commonly used to implement
/// truncation operations on target architectures which support it.
HANDLE_TARGET_OPCODE(EXTRACT_SUBREG)

/// INSERT_SUBREG - This instruction takes three operands: a register that
/// has subregisters, a register providing an insert value, and a
/// subregister index. It returns the value of the first register with the
/// value of the second register inserted. The first register is often
/// defined by an IMPLICIT_DEF, because it is commonly used to implement
/// anyext operations on target architectures which support it.
HANDLE_TARGET_OPCODE(INSERT_SUBREG)

/// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
HANDLE_TARGET_OPCODE(IMPLICIT_DEF)

/// SUBREG_TO_REG - Assert the value of bits in a super register.
/// The result of this instruction is the value of the second operand inserted
/// into the subregister specified by the third operand. All other bits are
/// assumed to be equal to the bits in the immediate integer constant in the
/// first operand. This instruction just communicates information; No code
/// should be generated.
/// This is typically used after an instruction where the write to a subregister
/// implicitly cleared the bits in the super registers.
HANDLE_TARGET_OPCODE(SUBREG_TO_REG)

/// COPY_TO_REGCLASS - This instruction is a placeholder for a plain
/// register-to-register copy into a specific register class. This is only
/// used between instruction selection and MachineInstr creation, before
/// virtual registers have been created for all the instructions, and it's
/// only needed in cases where the register classes implied by the
/// instructions are insufficient. It is emitted as a COPY MachineInstr.
  HANDLE_TARGET_OPCODE(COPY_TO_REGCLASS)

/// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
HANDLE_TARGET_OPCODE(DBG_VALUE)

/// DBG_LABEL - a mapping of the llvm.dbg.label intrinsic
HANDLE_TARGET_OPCODE(DBG_LABEL)

/// REG_SEQUENCE - This variadic instruction is used to form a register that
/// represents a consecutive sequence of sub-registers. It's used as a
/// register coalescing / allocation aid and must be eliminated before code
/// emission.
// In SDNode form, the first operand encodes the register class created by
// the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index
// pair.  Once it has been lowered to a MachineInstr, the regclass operand
// is no longer present.
/// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5
/// After register coalescing references of v1024 should be replace with
/// v1027:3, v1025 with v1027:4, etc.
  HANDLE_TARGET_OPCODE(REG_SEQUENCE)

/// COPY - Target-independent register copy. This instruction can also be
/// used to copy between subregisters of virtual registers.
  HANDLE_TARGET_OPCODE(COPY)

/// BUNDLE - This instruction represents an instruction bundle. Instructions
/// which immediately follow a BUNDLE instruction which are marked with
/// 'InsideBundle' flag are inside the bundle.
HANDLE_TARGET_OPCODE(BUNDLE)

/// Lifetime markers.
HANDLE_TARGET_OPCODE(LIFETIME_START)
HANDLE_TARGET_OPCODE(LIFETIME_END)

/// A Stackmap instruction captures the location of live variables at its
/// position in the instruction stream. It is followed by a shadow of bytes
/// that must lie within the function and not contain another stackmap.
HANDLE_TARGET_OPCODE(STACKMAP)

/// FEntry all - This is a marker instruction which gets translated into a raw fentry call.
HANDLE_TARGET_OPCODE(FENTRY_CALL)

/// Patchable call instruction - this instruction represents a call to a
/// constant address, followed by a series of NOPs. It is intended to
/// support optimizations for dynamic languages (such as javascript) that
/// rewrite calls to runtimes with more efficient code sequences.
/// This also implies a stack map.
HANDLE_TARGET_OPCODE(PATCHPOINT)

/// This pseudo-instruction loads the stack guard value. Targets which need
/// to prevent the stack guard value or address from being spilled to the
/// stack should override TargetLowering::emitLoadStackGuardNode and
/// additionally expand this pseudo after register allocation.
HANDLE_TARGET_OPCODE(LOAD_STACK_GUARD)

/// Call instruction with associated vm state for deoptimization and list
/// of live pointers for relocation by the garbage collector.  It is
/// intended to support garbage collection with fully precise relocating
/// collectors and deoptimizations in either the callee or caller.
HANDLE_TARGET_OPCODE(STATEPOINT)

/// Instruction that records the offset of a local stack allocation passed to
/// llvm.localescape. It has two arguments: the symbol for the label and the
/// frame index of the local stack allocation.
HANDLE_TARGET_OPCODE(LOCAL_ESCAPE)

/// Wraps a machine instruction which can fault, bundled with associated
/// information on how to handle such a fault.
/// For example loading instruction that may page fault, bundled with associated
/// information on how to handle such a page fault.  It is intended to support
/// "zero cost" null checks in managed languages by allowing LLVM to fold
/// comparisons into existing memory operations.
HANDLE_TARGET_OPCODE(FAULTING_OP)

/// Wraps a machine instruction to add patchability constraints.  An
/// instruction wrapped in PATCHABLE_OP has to either have a minimum
/// size or be preceded with a nop of that size.  The first operand is
/// an immediate denoting the minimum size of the instruction, the
/// second operand is an immediate denoting the opcode of the original
/// instruction.  The rest of the operands are the operands of the
/// original instruction.
HANDLE_TARGET_OPCODE(PATCHABLE_OP)

/// This is a marker instruction which gets translated into a nop sled, useful
/// for inserting instrumentation instructions at runtime.
HANDLE_TARGET_OPCODE(PATCHABLE_FUNCTION_ENTER)

/// Wraps a return instruction and its operands to enable adding nop sleds
/// either before or after the return. The nop sleds are useful for inserting
/// instrumentation instructions at runtime.
/// The patch here replaces the return instruction.
HANDLE_TARGET_OPCODE(PATCHABLE_RET)

/// This is a marker instruction which gets translated into a nop sled, useful
/// for inserting instrumentation instructions at runtime.
/// The patch here prepends the return instruction.
/// The same thing as in x86_64 is not possible for ARM because it has multiple
/// return instructions. Furthermore, CPU allows parametrized and even
/// conditional return instructions. In the current ARM implementation we are
/// making use of the fact that currently LLVM doesn't seem to generate
/// conditional return instructions.
/// On ARM, the same instruction can be used for popping multiple registers
/// from the stack and returning (it just pops pc register too), and LLVM
/// generates it sometimes. So we can't insert the sled between this stack
/// adjustment and the return without splitting the original instruction into 2
/// instructions. So on ARM, rather than jumping into the exit trampoline, we
/// call it, it does the tracing, preserves the stack and returns.
HANDLE_TARGET_OPCODE(PATCHABLE_FUNCTION_EXIT)

/// Wraps a tail call instruction and its operands to enable adding nop sleds
/// either before or after the tail exit. We use this as a disambiguation from
/// PATCHABLE_RET which specifically only works for return instructions.
HANDLE_TARGET_OPCODE(PATCHABLE_TAIL_CALL)

/// Wraps a logging call and its arguments with nop sleds. At runtime, this can
/// be patched to insert instrumentation instructions.
HANDLE_TARGET_OPCODE(PATCHABLE_EVENT_CALL)

/// Wraps a typed logging call and its argument with nop sleds. At runtime, this
/// can be patched to insert instrumentation instructions.
HANDLE_TARGET_OPCODE(PATCHABLE_TYPED_EVENT_CALL)

HANDLE_TARGET_OPCODE(ICALL_BRANCH_FUNNEL)

/// The following generic opcodes are not supposed to appear after ISel.
/// This is something we might want to relax, but for now, this is convenient
/// to produce diagnostics.

/// Generic ADD instruction. This is an integer add.
HANDLE_TARGET_OPCODE(G_ADD)
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_START, G_ADD)

/// Generic SUB instruction. This is an integer sub.
HANDLE_TARGET_OPCODE(G_SUB)

// Generic multiply instruction.
HANDLE_TARGET_OPCODE(G_MUL)

// Generic signed division instruction.
HANDLE_TARGET_OPCODE(G_SDIV)

// Generic unsigned division instruction.
HANDLE_TARGET_OPCODE(G_UDIV)

// Generic signed remainder instruction.
HANDLE_TARGET_OPCODE(G_SREM)

// Generic unsigned remainder instruction.
HANDLE_TARGET_OPCODE(G_UREM)

/// Generic bitwise and instruction.
HANDLE_TARGET_OPCODE(G_AND)

/// Generic bitwise or instruction.
HANDLE_TARGET_OPCODE(G_OR)

/// Generic bitwise exclusive-or instruction.
HANDLE_TARGET_OPCODE(G_XOR)


HANDLE_TARGET_OPCODE(G_IMPLICIT_DEF)

/// Generic PHI instruction with types.
HANDLE_TARGET_OPCODE(G_PHI)

/// Generic instruction to materialize the address of an alloca or other
/// stack-based object.
HANDLE_TARGET_OPCODE(G_FRAME_INDEX)

/// Generic reference to global value.
HANDLE_TARGET_OPCODE(G_GLOBAL_VALUE)

/// Generic instruction to extract blocks of bits from the register given
/// (typically a sub-register COPY after instruction selection).
HANDLE_TARGET_OPCODE(G_EXTRACT)

HANDLE_TARGET_OPCODE(G_UNMERGE_VALUES)

/// Generic instruction to insert blocks of bits from the registers given into
/// the source.
HANDLE_TARGET_OPCODE(G_INSERT)

/// Generic instruction to paste a variable number of components together into a
/// larger register.
HANDLE_TARGET_OPCODE(G_MERGE_VALUES)

/// Generic pointer to int conversion.
HANDLE_TARGET_OPCODE(G_PTRTOINT)

/// Generic int to pointer conversion.
HANDLE_TARGET_OPCODE(G_INTTOPTR)

/// Generic bitcast. The source and destination types must be different, or a
/// COPY is the relevant instruction.
HANDLE_TARGET_OPCODE(G_BITCAST)

/// INTRINSIC trunc intrinsic.
HANDLE_TARGET_OPCODE(G_INTRINSIC_TRUNC)

/// INTRINSIC round intrinsic.
HANDLE_TARGET_OPCODE(G_INTRINSIC_ROUND)

/// Generic load (including anyext load)
HANDLE_TARGET_OPCODE(G_LOAD)

/// Generic signext load
HANDLE_TARGET_OPCODE(G_SEXTLOAD)

/// Generic zeroext load
HANDLE_TARGET_OPCODE(G_ZEXTLOAD)

/// Generic store.
HANDLE_TARGET_OPCODE(G_STORE)

/// Generic atomic cmpxchg with internal success check.
HANDLE_TARGET_OPCODE(G_ATOMIC_CMPXCHG_WITH_SUCCESS)

/// Generic atomic cmpxchg.
HANDLE_TARGET_OPCODE(G_ATOMIC_CMPXCHG)

/// Generic atomicrmw.
HANDLE_TARGET_OPCODE(G_ATOMICRMW_XCHG)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_ADD)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_SUB)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_AND)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_NAND)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_OR)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_XOR)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_MAX)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_MIN)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMAX)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMIN)

/// Generic conditional branch instruction.
HANDLE_TARGET_OPCODE(G_BRCOND)

/// Generic indirect branch instruction.
HANDLE_TARGET_OPCODE(G_BRINDIRECT)

/// Generic intrinsic use (without side effects).
HANDLE_TARGET_OPCODE(G_INTRINSIC)

/// Generic intrinsic use (with side effects).
HANDLE_TARGET_OPCODE(G_INTRINSIC_W_SIDE_EFFECTS)

/// Generic extension allowing rubbish in high bits.
HANDLE_TARGET_OPCODE(G_ANYEXT)

/// Generic instruction to discard the high bits of a register. This differs
/// from (G_EXTRACT val, 0) on its action on vectors: G_TRUNC will truncate
/// each element individually, G_EXTRACT will typically discard the high
/// elements of the vector.
HANDLE_TARGET_OPCODE(G_TRUNC)

/// Generic integer constant.
HANDLE_TARGET_OPCODE(G_CONSTANT)

/// Generic floating constant.
HANDLE_TARGET_OPCODE(G_FCONSTANT)

/// Generic va_start instruction. Stores to its one pointer operand.
HANDLE_TARGET_OPCODE(G_VASTART)

/// Generic va_start instruction. Stores to its one pointer operand.
HANDLE_TARGET_OPCODE(G_VAARG)

// Generic sign extend
HANDLE_TARGET_OPCODE(G_SEXT)

// Generic zero extend
HANDLE_TARGET_OPCODE(G_ZEXT)

// Generic left-shift
HANDLE_TARGET_OPCODE(G_SHL)

// Generic logical right-shift
HANDLE_TARGET_OPCODE(G_LSHR)

// Generic arithmetic right-shift
HANDLE_TARGET_OPCODE(G_ASHR)

/// Generic integer-base comparison, also applicable to vectors of integers.
HANDLE_TARGET_OPCODE(G_ICMP)

/// Generic floating-point comparison, also applicable to vectors.
HANDLE_TARGET_OPCODE(G_FCMP)

/// Generic select.
HANDLE_TARGET_OPCODE(G_SELECT)

/// Generic unsigned add instruction, consuming the normal operands and
/// producing the result and a carry flag.
HANDLE_TARGET_OPCODE(G_UADDO)

/// Generic unsigned add instruction, consuming the normal operands plus a carry
/// flag, and similarly producing the result and a carry flag.
HANDLE_TARGET_OPCODE(G_UADDE)

/// Generic unsigned sub instruction, consuming the normal operands and
/// producing the result and a carry flag.
HANDLE_TARGET_OPCODE(G_USUBO)

/// Generic unsigned subtract instruction, consuming the normal operands plus a
/// carry flag, and similarly producing the result and a carry flag.
HANDLE_TARGET_OPCODE(G_USUBE)

/// Generic signed add instruction, producing the result and a signed overflow
/// flag.
HANDLE_TARGET_OPCODE(G_SADDO)

/// Generic signed add instruction, consuming the normal operands plus a carry
/// flag, and similarly producing the result and a carry flag.
HANDLE_TARGET_OPCODE(G_SADDE)

/// Generic signed subtract instruction, producing the result and a signed
/// overflow flag.
HANDLE_TARGET_OPCODE(G_SSUBO)

/// Generic signed sub instruction, consuming the normal operands plus a carry
/// flag, and similarly producing the result and a carry flag.
HANDLE_TARGET_OPCODE(G_SSUBE)

/// Generic unsigned multiply instruction, producing the result and a signed
/// overflow flag.
HANDLE_TARGET_OPCODE(G_UMULO)

/// Generic signed multiply instruction, producing the result and a signed
/// overflow flag.
HANDLE_TARGET_OPCODE(G_SMULO)

// Multiply two numbers at twice the incoming bit width (unsigned) and return
// the high half of the result.
HANDLE_TARGET_OPCODE(G_UMULH)

// Multiply two numbers at twice the incoming bit width (signed) and return
// the high half of the result.
HANDLE_TARGET_OPCODE(G_SMULH)

/// Generic FP addition.
HANDLE_TARGET_OPCODE(G_FADD)

/// Generic FP subtraction.
HANDLE_TARGET_OPCODE(G_FSUB)

/// Generic FP multiplication.
HANDLE_TARGET_OPCODE(G_FMUL)

/// Generic FMA multiplication. Behaves like llvm fma intrinsic
HANDLE_TARGET_OPCODE(G_FMA)

/// Generic FP division.
HANDLE_TARGET_OPCODE(G_FDIV)

/// Generic FP remainder.
HANDLE_TARGET_OPCODE(G_FREM)

/// Generic FP exponentiation.
HANDLE_TARGET_OPCODE(G_FPOW)

/// Generic base-e exponential of a value.
HANDLE_TARGET_OPCODE(G_FEXP)

/// Generic base-2 exponential of a value.
HANDLE_TARGET_OPCODE(G_FEXP2)

/// Floating point base-e logarithm of a value.
HANDLE_TARGET_OPCODE(G_FLOG)

/// Floating point base-2 logarithm of a value.
HANDLE_TARGET_OPCODE(G_FLOG2)

/// Generic FP negation.
HANDLE_TARGET_OPCODE(G_FNEG)

/// Generic FP extension.
HANDLE_TARGET_OPCODE(G_FPEXT)

/// Generic float to signed-int conversion
HANDLE_TARGET_OPCODE(G_FPTRUNC)

/// Generic float to signed-int conversion
HANDLE_TARGET_OPCODE(G_FPTOSI)

/// Generic float to unsigned-int conversion
HANDLE_TARGET_OPCODE(G_FPTOUI)

/// Generic signed-int to float conversion
HANDLE_TARGET_OPCODE(G_SITOFP)

/// Generic unsigned-int to float conversion
HANDLE_TARGET_OPCODE(G_UITOFP)

/// Generic FP absolute value.
HANDLE_TARGET_OPCODE(G_FABS)

/// Generic pointer offset
HANDLE_TARGET_OPCODE(G_GEP)

/// Clear the specified number of low bits in a pointer. This rounds the value
/// *down* to the given alignment.
HANDLE_TARGET_OPCODE(G_PTR_MASK)

/// Generic BRANCH instruction. This is an unconditional branch.
HANDLE_TARGET_OPCODE(G_BR)

/// Generic insertelement.
HANDLE_TARGET_OPCODE(G_INSERT_VECTOR_ELT)

/// Generic extractelement.
HANDLE_TARGET_OPCODE(G_EXTRACT_VECTOR_ELT)

/// Generic shufflevector.
HANDLE_TARGET_OPCODE(G_SHUFFLE_VECTOR)

/// Generic count trailing zeroes.
HANDLE_TARGET_OPCODE(G_CTTZ)

/// Same as above, undefined for zero inputs.
HANDLE_TARGET_OPCODE(G_CTTZ_ZERO_UNDEF)

/// Generic count leading zeroes.
HANDLE_TARGET_OPCODE(G_CTLZ)

/// Same as above, undefined for zero inputs.
HANDLE_TARGET_OPCODE(G_CTLZ_ZERO_UNDEF)

/// Generic count bits.
HANDLE_TARGET_OPCODE(G_CTPOP)

/// Generic byte swap.
HANDLE_TARGET_OPCODE(G_BSWAP)

/// Generic AddressSpaceCast.
HANDLE_TARGET_OPCODE(G_ADDRSPACE_CAST)

/// Generic block address
HANDLE_TARGET_OPCODE(G_BLOCK_ADDR)

// TODO: Add more generic opcodes as we move along.

/// Marker for the end of the generic opcode.
/// This is used to check if an opcode is in the range of the
/// generic opcodes.
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_BLOCK_ADDR)

/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific post-isel opcode values start here.
HANDLE_TARGET_OPCODE_MARKER(GENERIC_OP_END, PRE_ISEL_GENERIC_OPCODE_END)