aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Target/GenericOpcodes.td
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Target/GenericOpcodes.td')
-rw-r--r--include/llvm/Target/GenericOpcodes.td87
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;
}