2016-01-21 02:37:18 +01:00
|
|
|
//===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
|
|
|
|
//
|
|
|
|
// 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 generic opcodes used with GlobalISel.
|
|
|
|
// After instruction selection, these opcodes should not appear.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-08-11 23:01:10 +02:00
|
|
|
//------------------------------------------------------------------------------
|
2016-08-04 20:35:11 +02:00
|
|
|
// Unary ops.
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Extend the underlying scalar type of an operation, leaving the high bits
|
|
|
|
// unspecified.
|
2016-08-23 23:01:33 +02:00
|
|
|
def G_ANYEXT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-04 20:35:11 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-11 23:01:10 +02:00
|
|
|
// Sign extend the underlying scalar type of an operation, copying the sign bit
|
|
|
|
// into the newly-created space.
|
|
|
|
def G_SEXT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-11 23:01:10 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Zero extend the underlying scalar type of an operation, putting zero bits
|
|
|
|
// into the newly-created space.
|
|
|
|
def G_ZEXT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-11 23:01:10 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-04 20:35:11 +02:00
|
|
|
// Truncate the underlying scalar type of an operation. This is equivalent to
|
|
|
|
// G_EXTRACT for scalar types, but acts elementwise on vectors.
|
|
|
|
def G_TRUNC : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-04 20:35:11 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-07-22 18:59:52 +02:00
|
|
|
def G_FRAME_INDEX : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
2016-07-22 18:59:52 +02:00
|
|
|
let InOperandList = (ins unknown:$src2);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-09-12 14:10:41 +02:00
|
|
|
def G_GLOBAL_VALUE : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins unknown:$src);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-07-25 23:01:29 +02:00
|
|
|
def G_INTTOPTR : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-07-25 23:01:29 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
def G_PTRTOINT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-07-25 23:01:29 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
def G_BITCAST : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-07-25 23:01:29 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-04 22:54:13 +02:00
|
|
|
def G_CONSTANT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
2016-08-04 22:54:13 +02:00
|
|
|
let InOperandList = (ins unknown:$imm);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-19 22:09:15 +02:00
|
|
|
def G_FCONSTANT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
2016-08-19 22:09:15 +02:00
|
|
|
let InOperandList = (ins unknown:$imm);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2017-02-08 18:57:20 +01:00
|
|
|
def G_VASTART : Instruction {
|
|
|
|
let OutOperandList = (outs);
|
|
|
|
let InOperandList = (ins type0:$list);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
let mayStore = 1;
|
|
|
|
}
|
|
|
|
|
2017-02-16 00:22:33 +01:00
|
|
|
def G_VAARG : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$val);
|
|
|
|
let InOperandList = (ins type1:$list, unknown:$align);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
let mayLoad = 1;
|
|
|
|
let mayStore = 1;
|
|
|
|
}
|
|
|
|
|
2016-06-08 18:12:19 +02:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Binary ops.
|
|
|
|
//------------------------------------------------------------------------------
|
2016-07-26 22:23:26 +02:00
|
|
|
|
2016-01-21 02:37:18 +01:00
|
|
|
// Generic addition.
|
|
|
|
def G_ADD : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-01-21 02:37:18 +01:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
2016-03-11 18:27:38 +01:00
|
|
|
|
2016-07-21 19:26:50 +02:00
|
|
|
// Generic subtraction.
|
|
|
|
def G_SUB : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-07-21 19:26:50 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-16 16:37:43 +02:00
|
|
|
// Generic multiplication.
|
2016-08-04 23:39:44 +02:00
|
|
|
def G_MUL : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-04 23:39:44 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
2016-08-18 17:17:01 +02:00
|
|
|
// Generic signed division.
|
|
|
|
def G_SDIV : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 17:17:01 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic unsigned division.
|
|
|
|
def G_UDIV : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 17:17:01 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic signed remainder.
|
|
|
|
def G_SREM : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 17:17:01 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic unsigned remainder.
|
|
|
|
def G_UREM : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 17:17:01 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 0;
|
|
|
|
}
|
|
|
|
|
2016-07-21 17:50:42 +02:00
|
|
|
// Generic bitwise and.
|
|
|
|
def G_AND : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-07-21 17:50:42 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
2016-06-08 18:12:19 +02:00
|
|
|
// Generic bitwise or.
|
|
|
|
def G_OR : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-06-08 18:12:19 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
2016-07-29 18:56:20 +02:00
|
|
|
// Generic bitwise xor.
|
|
|
|
def G_XOR : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-07-29 18:56:20 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
2016-08-11 23:01:13 +02:00
|
|
|
// Generic left-shift.
|
|
|
|
def G_SHL : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-11 23:01:13 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic logical right-shift.
|
|
|
|
def G_LSHR : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-11 23:01:13 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic arithmetic right-shift.
|
|
|
|
def G_ASHR : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-11 23:01:13 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-19 22:48:16 +02:00
|
|
|
// Generic integer comparison.
|
2016-08-17 22:25:25 +02:00
|
|
|
def G_ICMP : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
|
2016-08-17 22:25:25 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-19 22:48:16 +02:00
|
|
|
// Generic floating-point comparison.
|
|
|
|
def G_FCMP : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
|
2016-08-19 22:48:16 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-19 22:09:07 +02:00
|
|
|
// Generic select
|
|
|
|
def G_SELECT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
|
2016-08-19 22:09:07 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2017-02-14 21:56:18 +01:00
|
|
|
// Generic pointer offset.
|
|
|
|
def G_GEP : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type1:$src2);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
def G_PTR_MASK : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src, unknown:$bits);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-19 19:17:06 +02:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Overflow ops
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Generic unsigned addition consuming and producing a carry flag.
|
|
|
|
def G_UADDE : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst, type1:$carry_out);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
|
2016-08-19 19:17:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic signed addition producing a carry flag.
|
|
|
|
def G_SADDO : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst, type1:$carry_out);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-19 19:17:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic unsigned subtraction consuming and producing a carry flag.
|
|
|
|
def G_USUBE : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst, type1:$carry_out);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
|
2016-08-19 19:17:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic unsigned subtraction producing a carry flag.
|
|
|
|
def G_SSUBO : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst, type1:$carry_out);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-19 19:17:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic unsigned multiplication producing a carry flag.
|
|
|
|
def G_UMULO : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst, type1:$carry_out);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-19 19:17:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic signed multiplication producing a carry flag.
|
|
|
|
def G_SMULO : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst, type1:$carry_out);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-19 19:17:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
2017-02-08 22:22:15 +01:00
|
|
|
// Multiply two numbers at twice the incoming bit width (unsigned) and return
|
|
|
|
// the high half of the result.
|
|
|
|
def G_UMULH : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Multiply two numbers at twice the incoming bit width (signed) and return
|
|
|
|
// the high half of the result.
|
|
|
|
def G_SMULH : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:05:06 +02:00
|
|
|
//------------------------------------------------------------------------------
|
2016-08-19 22:09:11 +02:00
|
|
|
// Floating Point Unary Ops.
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2017-03-07 19:03:28 +01:00
|
|
|
def G_FNEG : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-19 22:48:23 +02:00
|
|
|
def G_FPEXT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-19 22:48:23 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
def G_FPTRUNC : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-19 22:48:23 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-19 22:09:11 +02:00
|
|
|
def G_FPTOSI : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-19 22:09:11 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
def G_FPTOUI : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-19 22:09:11 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
def G_SITOFP : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-19 22:09:11 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
def G_UITOFP : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src);
|
2016-08-19 22:09:11 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2016-08-18 18:05:06 +02:00
|
|
|
// Floating Point Binary ops.
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Generic FP addition.
|
|
|
|
def G_FADD : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 18:05:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic FP subtraction.
|
|
|
|
def G_FSUB : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 18:05:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic FP multiplication.
|
|
|
|
def G_FMUL : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 18:05:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isCommutable = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic FP division.
|
|
|
|
def G_FDIV : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 18:05:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic FP remainder.
|
|
|
|
def G_FREM : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
2016-08-18 18:05:06 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2017-02-09 00:23:32 +01:00
|
|
|
// Floating point exponentiation.
|
|
|
|
def G_FPOW : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src1, type0:$src2);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-07-26 22:23:26 +02:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Memory ops
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Generic load. Expects a MachineMemOperand in addition to explicit operands.
|
|
|
|
def G_LOAD : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$addr);
|
2016-07-26 22:23:26 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let mayLoad = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic store. Expects a MachineMemOperand in addition to explicit operands.
|
|
|
|
def G_STORE : Instruction {
|
|
|
|
let OutOperandList = (outs);
|
2016-09-09 13:46:34 +02:00
|
|
|
let InOperandList = (ins type0:$src, type1:$addr);
|
2016-07-26 22:23:26 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let mayStore = 1;
|
|
|
|
}
|
|
|
|
|
2016-07-22 22:03:43 +02:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Variadic ops
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Extract multiple registers specified size, starting from blocks given by
|
|
|
|
// indexes. This will almost certainly be mapped to sub-register COPYs after
|
|
|
|
// register banks have been selected.
|
|
|
|
def G_EXTRACT : Instruction {
|
2017-03-07 00:50:28 +01:00
|
|
|
let OutOperandList = (outs type0:$res);
|
|
|
|
let InOperandList = (ins type1:$src, unknown:$offset);
|
2016-07-22 22:03:43 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2017-03-03 23:46:09 +01:00
|
|
|
// Extract multiple registers specified size, starting from blocks given by
|
|
|
|
// indexes. This will almost certainly be mapped to sub-register COPYs after
|
|
|
|
// register banks have been selected.
|
|
|
|
def G_UNMERGE_VALUES : Instruction {
|
|
|
|
let OutOperandList = (outs);
|
|
|
|
let InOperandList = (ins variable_ops);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2017-03-04 00:05:47 +01:00
|
|
|
// Insert a smaller register into a larger one at the specified bit-index.
|
2016-08-19 22:08:55 +02:00
|
|
|
def G_INSERT : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
2017-03-04 00:05:47 +01:00
|
|
|
let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
|
2016-08-19 22:08:55 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Combine a sequence of generic vregs into a single larger value (starting at
|
|
|
|
// bit 0). Essentially a G_INSERT where $src is an IMPLICIT_DEF, but it's so
|
|
|
|
// important to legalization it probably deserves its own instruction.
|
2016-07-22 22:03:43 +02:00
|
|
|
def G_SEQUENCE : Instruction {
|
2016-09-09 13:46:34 +02:00
|
|
|
let OutOperandList = (outs type0:$dst);
|
2016-07-22 22:03:43 +02:00
|
|
|
let InOperandList = (ins variable_ops);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2017-03-03 23:46:09 +01:00
|
|
|
def G_MERGE_VALUES : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins variable_ops);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-07-30 00:32:36 +02:00
|
|
|
// Intrinsic without side effects.
|
|
|
|
def G_INTRINSIC : Instruction {
|
|
|
|
let OutOperandList = (outs);
|
|
|
|
let InOperandList = (ins unknown:$intrin, variable_ops);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Intrinsic with side effects.
|
|
|
|
def G_INTRINSIC_W_SIDE_EFFECTS : Instruction {
|
|
|
|
let OutOperandList = (outs);
|
|
|
|
let InOperandList = (ins unknown:$intrin, variable_ops);
|
|
|
|
let hasSideEffects = 1;
|
|
|
|
let mayLoad = 1;
|
|
|
|
let mayStore = 1;
|
|
|
|
}
|
|
|
|
|
2016-06-08 18:12:19 +02:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Branches.
|
|
|
|
//------------------------------------------------------------------------------
|
2016-08-04 22:54:13 +02:00
|
|
|
|
2016-03-11 18:27:38 +01:00
|
|
|
// Generic unconditional branch.
|
|
|
|
def G_BR : Instruction {
|
|
|
|
let OutOperandList = (outs);
|
|
|
|
let InOperandList = (ins unknown:$src1);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isBranch = 1;
|
|
|
|
let isTerminator = 1;
|
2016-07-29 19:58:00 +02:00
|
|
|
let isBarrier = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic conditional branch.
|
|
|
|
def G_BRCOND : Instruction {
|
|
|
|
let OutOperandList = (outs);
|
2016-09-09 13:46:34 +02:00
|
|
|
let InOperandList = (ins type0:$tst, unknown:$truebb);
|
2016-07-29 19:58:00 +02:00
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isBranch = 1;
|
|
|
|
let isTerminator = 1;
|
2016-03-11 18:27:38 +01:00
|
|
|
}
|
|
|
|
|
2017-01-30 10:13:18 +01:00
|
|
|
// Generic indirect branch.
|
|
|
|
def G_BRINDIRECT : Instruction {
|
|
|
|
let OutOperandList = (outs);
|
|
|
|
let InOperandList = (ins type0:$src1);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
let isBranch = 1;
|
|
|
|
let isTerminator = 1;
|
|
|
|
}
|
|
|
|
|
2017-03-10 20:08:28 +01:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Vector ops
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Generic insertelement.
|
|
|
|
def G_INSERT_VECTOR_ELT : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic extractelement.
|
|
|
|
def G_EXTRACT_VECTOR_ELT : Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$src, type2:$idx);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:44:13 +01:00
|
|
|
// Generic shufflevector.
|
|
|
|
def G_SHUFFLE_VECTOR: Instruction {
|
|
|
|
let OutOperandList = (outs type0:$dst);
|
|
|
|
let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
|
|
|
|
let hasSideEffects = 0;
|
|
|
|
}
|
|
|
|
|
2016-01-21 02:37:18 +01:00
|
|
|
// TODO: Add the other generic opcodes.
|