PTX: support for select
[oota-llvm.git] / lib / Target / CellSPU / SPUNodes.td
index 4e78bee9550382865638915725f3e6889fe9aba2..a6e621f36b35118a8f60f85bd367e35b1ad8e406 100644 (file)
@@ -16,168 +16,108 @@ def SDT_SPUCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
 
 // SPU_GenControl: Type profile for generating control words for insertions
 def SPU_GenControl : SDTypeProfile<1, 1, []>;
-def SPUvecinsmask : SDNode<"SPUISD::INSERT_MASK", SPU_GenControl, []>;
+def SPUshufmask    : SDNode<"SPUISD::SHUFFLE_MASK", SPU_GenControl, []>;
 
 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPUCallSeq,
-                           [SDNPHasChain, SDNPOutFlag]>;
+                           [SDNPHasChain, SDNPOutGlue]>;
 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_SPUCallSeq,
-                           [SDNPHasChain, SDNPOutFlag]>;
+                           [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
 //===----------------------------------------------------------------------===//
 // Operand constraints:
 //===----------------------------------------------------------------------===//
 
-def SDT_SPUCall   : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
+def SDT_SPUCall   : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
 def SPUcall       : SDNode<"SPUISD::CALL", SDT_SPUCall,
-                           [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
+                            SDNPVariadic]>;
 
 // Operand type constraints for vector shuffle/permute operations
 def SDT_SPUshuffle   : SDTypeProfile<1, 3, [
-  SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>
+  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
 ]>;
 
-// Unary, binary v16i8 operator type constraints:
-def SPUv16i8_unop: SDTypeProfile<1, 1, [
-  SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>]>;
+// Vector binary operator type constraints (needs a further constraint to
+// ensure that operand 0 is a vector...):
 
-def SPUv16i8_binop: SDTypeProfile<1, 2, [
-  SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>;
-
-// Binary v8i16 operator type constraints:
-def SPUv8i16_unop: SDTypeProfile<1, 1, [
-  SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>]>;
-
-def SPUv8i16_binop: SDTypeProfile<1, 2, [
-  SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>;
-
-// Binary v4i32 operator type constraints:
-def SPUv4i32_unop: SDTypeProfile<1, 1, [
-  SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>]>;
+def SPUVecBinop: SDTypeProfile<1, 2, [
+  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
+]>;
 
-def SPUv4i32_binop: SDTypeProfile<1, 2, [
-  SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>;
+// Trinary operators, e.g., addx, carry generate
+def SPUIntTrinaryOp : SDTypeProfile<1, 3, [
+  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisInt<0>
+]>;
 
-// FSMBI type constraints: There are several variations for the various
+// SELECT_MASK type constraints: There are several variations for the various
 // vector types (this avoids having to bit_convert all over the place.)
-def SPUfsmbi_type_v16i8: SDTypeProfile<1, 1, [
-  SDTCisVT<0, v16i8>, SDTCisVT<1, i32>]>;
-
-def SPUfsmbi_type_v8i16: SDTypeProfile<1, 1, [
-  SDTCisVT<0, v8i16>, SDTCisVT<1, i32>]>;
-
-def SPUfsmbi_type_v4i32: SDTypeProfile<1, 1, [
-  SDTCisVT<0, v4i32>, SDTCisVT<1, i32>]>;
+def SPUselmask_type: SDTypeProfile<1, 1, [
+  SDTCisInt<1>
+]>;
 
 // SELB type constraints:
-def SPUselb_type_v16i8: SDTypeProfile<1, 3, [
-  SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
-  SDTCisSameAs<0, 3> ]>;
-
-def SPUselb_type_v8i16: SDTypeProfile<1, 3, [
-  SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
-  SDTCisSameAs<0, 3> ]>;
-
-def SPUselb_type_v4i32: SDTypeProfile<1, 3, [
-  SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
-  SDTCisSameAs<0, 3> ]>;
+def SPUselb_type: SDTypeProfile<1, 3, [
+  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisSameAs<0, 3> ]>;
 
 // SPU Vector shift pseudo-instruction type constraints
-def SPUvecshift_type_v16i8: SDTypeProfile<1, 2, [
-  SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
+def SPUvecshift_type: SDTypeProfile<1, 2, [
+  SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
 
-def SPUvecshift_type_v8i16: SDTypeProfile<1, 2, [
-  SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
+// "marker" type for i64 operators that need a shuffle mask
+// (i.e., uses cg or bg or another instruction that needs to
+// use shufb to get things in the right place.)
+// Op0: The result
+// Op1, 2: LHS, RHS
+// Op3: Carry-generate shuffle mask
 
-def SPUvecshift_type_v4i32: SDTypeProfile<1, 2, [
-  SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
+def SPUmarker_type : SDTypeProfile<1, 3, [
+  SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> ]>;
 
 //===----------------------------------------------------------------------===//
 // Synthetic/pseudo-instructions
 //===----------------------------------------------------------------------===//
 
 // SPU CNTB:
-def SPUcntb_v16i8: SDNode<"SPUISD::CNTB", SPUv16i8_unop, []>;
-def SPUcntb_v8i16: SDNode<"SPUISD::CNTB", SPUv8i16_unop, []>;
-def SPUcntb_v4i32: SDNode<"SPUISD::CNTB", SPUv4i32_unop, []>;
+def SPUcntb : SDNode<"SPUISD::CNTB", SDTIntUnaryOp>;
 
 // SPU vector shuffle node, matched by the SPUISD::SHUFB enum (see
 // SPUISelLowering.h):
 def SPUshuffle: SDNode<"SPUISD::SHUFB", SDT_SPUshuffle, []>;
 
-// SPU 16-bit multiply
-def SPUmpy_v16i8: SDNode<"SPUISD::MPY", SPUv16i8_binop, []>;
-def SPUmpy_v8i16: SDNode<"SPUISD::MPY", SPUv8i16_binop, []>;
-def SPUmpy_v4i32: SDNode<"SPUISD::MPY", SPUv4i32_binop, []>;
-
-// SPU multiply unsigned, used in instruction lowering for v4i32
-// multiplies:
-def SPUmpyu_v4i32: SDNode<"SPUISD::MPYU", SPUv4i32_binop, []>;
-def SPUmpyu_i32: SDNode<"SPUISD::MPYU", SDTIntBinOp, []>;
-
-// SPU 16-bit multiply high x low, shift result 16-bits
-// Used to compute intermediate products for 32-bit multiplies
-def SPUmpyh_v4i32: SDNode<"SPUISD::MPYH", SPUv4i32_binop, []>;
-def SPUmpyh_i32: SDNode<"SPUISD::MPYH", SDTIntBinOp, []>;
-
-// SPU 16-bit multiply high x high, 32-bit product
-// Used to compute intermediate products for 16-bit multiplies
-def SPUmpyhh_v8i16: SDNode<"SPUISD::MPYHH", SPUv8i16_binop, []>;
-
 // Vector shifts (ISD::SHL,SRL,SRA are for _integers_ only):
-def SPUvec_shl_v8i16: SDNode<"SPUISD::VEC_SHL", SPUvecshift_type_v8i16, []>;
-def SPUvec_srl_v8i16: SDNode<"SPUISD::VEC_SRL", SPUvecshift_type_v8i16, []>;
-def SPUvec_sra_v8i16: SDNode<"SPUISD::VEC_SRA", SPUvecshift_type_v8i16, []>;
-
-def SPUvec_shl_v4i32: SDNode<"SPUISD::VEC_SHL", SPUvecshift_type_v4i32, []>;
-def SPUvec_srl_v4i32: SDNode<"SPUISD::VEC_SRL", SPUvecshift_type_v4i32, []>;
-def SPUvec_sra_v4i32: SDNode<"SPUISD::VEC_SRA", SPUvecshift_type_v4i32, []>;
-
-def SPUvec_rotl_v8i16: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type_v8i16, []>;
-def SPUvec_rotl_v4i32: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type_v4i32, []>;
+def SPUvec_shl: SDNode<"ISD::SHL", SPUvecshift_type, []>;
+def SPUvec_srl: SDNode<"ISD::SRL", SPUvecshift_type, []>;
+def SPUvec_sra: SDNode<"ISD::SRA", SPUvecshift_type, []>;
 
-def SPUvec_rotr_v8i16: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v8i16, []>;
-def SPUvec_rotr_v4i32: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v4i32, []>;
+def SPUvec_rotl: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type, []>;
+def SPUvec_rotr: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type, []>;
 
-def SPUrotbytes_right_zfill: SDNode<"SPUISD::ROTBYTES_RIGHT_Z",
-                                    SPUvecshift_type_v16i8, []>;
-def SPUrotbytes_right_sfill: SDNode<"SPUISD::ROTBYTES_RIGHT_S",
-                                    SPUvecshift_type_v16i8, []>;
+// Vector rotate left, bits shifted out of the left are rotated in on the right
 def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT",
-                             SPUvecshift_type_v16i8, []>;
+                             SPUvecshift_type, []>;
 
-def SPUrotbytes_left_chained : SDNode<"SPUISD::ROTBYTES_LEFT_CHAINED",
-                                      SPUvecshift_type_v16i8, [SDNPHasChain]>;
+// Vector rotate left by bytes, but the count is given in bits and the SPU
+// internally converts it to bytes (saves an instruction to mask off lower
+// three bits)
+def SPUrotbytes_left_bits : SDNode<"SPUISD::ROTBYTES_LEFT_BITS",
+                                   SPUvecshift_type>;
+
+// Shift entire quad left by bytes/bits. Zeros are shifted in on the right
+// SHL_BITS the same as SHL for i128, but ISD::SHL is not implemented for i128
+def SPUshlquad_l_bytes: SDNode<"SPUISD::SHL_BYTES", SPUvecshift_type, []>;
+def SPUshlquad_l_bits: SDNode<"SPUISD::SHL_BITS", SPUvecshift_type, []>;
+def SPUsrl_bytes: SDNode<"SPUISD::SRL_BYTES", SPUvecshift_type, []>;
 
 // SPU form select mask for bytes, immediate
-def SPUfsmbi_v16i8: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v16i8, []>;
-def SPUfsmbi_v8i16: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v8i16, []>;
-def SPUfsmbi_v4i32: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v4i32, []>;
+def SPUselmask: SDNode<"SPUISD::SELECT_MASK", SPUselmask_type, []>;
 
 // SPU select bits instruction
-def SPUselb_v16i8: SDNode<"SPUISD::SELB", SPUselb_type_v16i8, []>;
-def SPUselb_v8i16: SDNode<"SPUISD::SELB", SPUselb_type_v8i16, []>;
-def SPUselb_v4i32: SDNode<"SPUISD::SELB", SPUselb_type_v4i32, []>;
-
-// SPU single precision floating point constant load
-def SPUFPconstant: SDNode<"SPUISD::SFPConstant", SDTFPUnaryOp, []>;
-
-// SPU floating point interpolate
-def SPUinterpolate : SDNode<"SPUISD::FPInterp", SDTFPBinOp, []>;
+def SPUselb: SDNode<"SPUISD::SELB", SPUselb_type, []>;
 
-// SPU floating point reciprocal estimate (used for fdiv)
-def SPUreciprocalEst: SDNode<"SPUISD::FPRecipEst", SDTFPUnaryOp, []>;
-
-def SDT_vec_promote   : SDTypeProfile<1, 1, []>;
-def SPUpromote_scalar: SDNode<"SPUISD::PROMOTE_SCALAR", SDT_vec_promote, []>;
+def SDTprefslot2vec: SDTypeProfile<1, 1, []>;
+def SPUprefslot2vec: SDNode<"SPUISD::PREFSLOT2VEC", SDTprefslot2vec, []>;
 
 def SPU_vec_demote   : SDTypeProfile<1, 1, []>;
-def SPUextract_elt0: SDNode<"SPUISD::EXTRACT_ELT0", SPU_vec_demote, []>;
-def SPU_vec_demote_chained : SDTypeProfile<1, 2, []>;
-def SPUextract_elt0_chained: SDNode<"SPUISD::EXTRACT_ELT0_CHAINED",
-                                    SPU_vec_demote_chained, [SDNPHasChain]>;
-def SPUextract_i1_sext: SDNode<"SPUISD::EXTRACT_I1_SEXT", SPU_vec_demote, []>;
-def SPUextract_i1_zext: SDNode<"SPUISD::EXTRACT_I1_ZEXT", SPU_vec_demote, []>;
-def SPUextract_i8_sext: SDNode<"SPUISD::EXTRACT_I8_SEXT", SPU_vec_demote, []>;
-def SPUextract_i8_zext: SDNode<"SPUISD::EXTRACT_I8_ZEXT", SPU_vec_demote, []>;
+def SPUvec2prefslot: SDNode<"SPUISD::VEC2PREFSLOT", SPU_vec_demote, []>;
 
 // Address high and low components, used for [r+r] type addressing
 def SPUhi : SDNode<"SPUISD::Hi", SDTIntBinOp, []>;
@@ -186,18 +126,17 @@ def SPUlo : SDNode<"SPUISD::Lo", SDTIntBinOp, []>;
 // PC-relative address
 def SPUpcrel : SDNode<"SPUISD::PCRelAddr", SDTIntBinOp, []>;
 
-// D-Form "imm($reg)" addresses
-def SPUdform : SDNode<"SPUISD::DFormAddr", SDTIntBinOp, []>;
-
-// SPU 32-bit sign-extension to 64-bits
-def SPUsext32_to_64: SDNode<"SPUISD::SEXT32TO64", SDTIntExtendOp, []>;
+// A-Form local store addresses
+def SPUaform : SDNode<"SPUISD::AFormAddr", SDTIntBinOp, []>;
 
-// Branches:
+// Indirect [D-Form "imm($reg)" and X-Form "$reg($reg)"] addresses
+def SPUindirect : SDNode<"SPUISD::IndirectAddr", SDTIntBinOp, []>;
 
-def SPUbrnz : SDNode<"SPUISD::BR_NOTZERO", SDTBrcond,  [SDNPHasChain]>;
-def SPUbrz  : SDNode<"SPUISD::BR_ZERO",    SDTBrcond,  [SDNPHasChain]>;
-/* def SPUbinz : SDNode<"SPUISD::BR_NOTZERO", SDTBrind,   [SDNPHasChain]>;
-def SPUbiz  : SDNode<"SPUISD::BR_ZERO",    SPUBrind,   [SDNPHasChain]>; */
+// i64 markers: supplies extra operands used to generate the i64 operator
+// instruction sequences
+def SPUadd64 : SDNode<"SPUISD::ADD64_MARKER", SPUmarker_type, []>;
+def SPUsub64 : SDNode<"SPUISD::SUB64_MARKER", SPUmarker_type, []>;
+def SPUmul64 : SDNode<"SPUISD::MUL64_MARKER", SPUmarker_type, []>;
 
 //===----------------------------------------------------------------------===//
 // Constraints: (taken from PPCInstrInfo.td)
@@ -216,5 +155,5 @@ class NoEncode<string E> {
 // instruction scheduling doesn't disassociate them.)
 //===----------------------------------------------------------------------===//
 
-def retflag     : SDNode<"SPUISD::RET_FLAG", SDTRet,
-                         [SDNPHasChain, SDNPOptInFlag]>;
+def retflag     : SDNode<"SPUISD::RET_FLAG", SDTNone,
+                         [SDNPHasChain, SDNPOptInGlue]>;