diff options
Diffstat (limited to 'include/llvm/Target/GenericOpcodes.td')
-rw-r--r-- | include/llvm/Target/GenericOpcodes.td | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td index 45718327b4a7..4b49dfd4dd18 100644 --- a/include/llvm/Target/GenericOpcodes.td +++ b/include/llvm/Target/GenericOpcodes.td @@ -15,7 +15,9 @@ // Unary ops. //------------------------------------------------------------------------------ -class GenericInstruction : StandardPseudoInstruction; +class GenericInstruction : StandardPseudoInstruction { + let isPreISelOpcode = 1; +} // Extend the underlying scalar type of an operation, leaving the high bits // unspecified. @@ -33,6 +35,20 @@ def G_SEXT : GenericInstruction { let hasSideEffects = 0; } +// Sign extend the a value from an arbitrary bit position, copying the sign bit +// into all bits above it. This is equivalent to a shl + ashr pair with an +// appropriate shift amount. $sz is an immediate (MachineOperand::isImm() +// returns true) to allow targets to have some bitwidths legal and others +// lowered. This opcode is particularly useful if the target has sign-extension +// instructions that are cheaper than the constituent shifts as the optimizer is +// able to make decisions on whether it's better to hang on to the G_SEXT_INREG +// or to lower it and optimize the individual shifts. +def G_SEXT_INREG : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src, untyped_imm_0:$sz); + let hasSideEffects = 0; +} + // Zero extend the underlying scalar type of an operation, putting zero bits // into the newly-created space. def G_ZEXT : GenericInstruction { @@ -157,6 +173,12 @@ def G_BSWAP : GenericInstruction { let hasSideEffects = 0; } +def G_BITREVERSE : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src); + let hasSideEffects = 0; +} + def G_ADDRSPACE_CAST : GenericInstruction { let OutOperandList = (outs type0:$dst); let InOperandList = (ins type1:$src); @@ -175,6 +197,12 @@ def G_JUMP_TABLE : GenericInstruction { let hasSideEffects = 0; } +def G_DYN_STACKALLOC : GenericInstruction { + let OutOperandList = (outs ptype0:$dst); + let InOperandList = (ins type1:$size, i32imm:$align); + let hasSideEffects = 1; +} + //------------------------------------------------------------------------------ // Binary ops. //------------------------------------------------------------------------------ @@ -598,6 +626,15 @@ def G_FMA : GenericInstruction { let isCommutable = 0; } +/// Generic FP multiply and add. Perform a * b + c, while getting the +/// same result as the separately rounded operations, unlike G_FMA. +def G_FMAD : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3); + let hasSideEffects = 0; + let isCommutable = 0; +} + // Generic FP division. def G_FDIV : GenericInstruction { let OutOperandList = (outs type0:$dst); @@ -725,7 +762,11 @@ def G_INTRINSIC_ROUND : GenericInstruction { // Memory ops //------------------------------------------------------------------------------ -// Generic load. Expects a MachineMemOperand in addition to explicit operands. +// Generic load. Expects a MachineMemOperand in addition to explicit +// operands. If the result size is larger than the memory size, the +// high bits are undefined. If the result is a vector type and larger +// than the memory size, the high elements are undefined (i.e. this is +// not a per-element, vector anyextload) def G_LOAD : GenericInstruction { let OutOperandList = (outs type0:$dst); let InOperandList = (ins ptype1:$addr); @@ -749,6 +790,32 @@ def G_ZEXTLOAD : GenericInstruction { let mayLoad = 1; } +// Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset. +// If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed) +// then the value is loaded from $newaddr. +def G_INDEXED_LOAD : GenericInstruction { + let OutOperandList = (outs type0:$dst, ptype1:$newaddr); + let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am); + let hasSideEffects = 0; + let mayLoad = 1; +} + +// Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD. +def G_INDEXED_SEXTLOAD : GenericInstruction { + let OutOperandList = (outs type0:$dst, ptype1:$newaddr); + let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am); + let hasSideEffects = 0; + let mayLoad = 1; +} + +// Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD. +def G_INDEXED_ZEXTLOAD : GenericInstruction { + let OutOperandList = (outs type0:$dst, ptype1:$newaddr); + let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am); + let hasSideEffects = 0; + let mayLoad = 1; +} + // Generic store. Expects a MachineMemOperand in addition to explicit operands. def G_STORE : GenericInstruction { let OutOperandList = (outs); @@ -757,6 +824,15 @@ def G_STORE : GenericInstruction { let mayStore = 1; } +// Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour. +def G_INDEXED_STORE : GenericInstruction { + let OutOperandList = (outs ptype0:$newaddr); + let InOperandList = (ins type1:$src, ptype0:$base, ptype2:$offset, + unknown:$am); + let hasSideEffects = 0; + let mayStore = 1; +} + // Generic atomic cmpxchg with internal success check. Expects a // MachineMemOperand in addition to explicit operands. def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction { @@ -798,6 +874,8 @@ def G_ATOMICRMW_MAX : G_ATOMICRMW_OP; def G_ATOMICRMW_MIN : G_ATOMICRMW_OP; def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP; def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP; +def G_ATOMICRMW_FADD : G_ATOMICRMW_OP; +def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP; def G_FENCE : GenericInstruction { let OutOperandList = (outs); @@ -947,9 +1025,12 @@ def G_EXTRACT_VECTOR_ELT : GenericInstruction { } // Generic shufflevector. +// +// The mask operand should be an IR Constant which exactly matches the +// corresponding mask for the IR shufflevector instruction. def G_SHUFFLE_VECTOR: GenericInstruction { let OutOperandList = (outs type0:$dst); - let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask); + let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask); let hasSideEffects = 0; } |