diff options
Diffstat (limited to 'lib/Target/CellSPU/SPUNodes.td')
-rw-r--r-- | lib/Target/CellSPU/SPUNodes.td | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/lib/Target/CellSPU/SPUNodes.td b/lib/Target/CellSPU/SPUNodes.td new file mode 100644 index 0000000000..eaf2f49b23 --- /dev/null +++ b/lib/Target/CellSPU/SPUNodes.td @@ -0,0 +1,219 @@ +//=- SPUNodes.h - Specialized SelectionDAG nodes used for CellSPU -*- C++ -*-=// +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +//===----------------------------------------------------------------------===// +// +// Type profiles and SelectionDAG nodes used by CellSPU +// +//===----------------------------------------------------------------------===// + +// Type profile for a call sequence +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 callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPUCallSeq, + [SDNPHasChain, SDNPOutFlag]>; +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPUCallSeq, + [SDNPHasChain, SDNPOutFlag]>; +//===----------------------------------------------------------------------===// +// Operand constraints: +//===----------------------------------------------------------------------===// + +def SDT_SPUCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; +def SPUcall : SDNode<"SPUISD::CALL", SDT_SPUCall, + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + +// Operand type constraints for vector shuffle/permute operations +def SDT_SPUshuffle : SDTypeProfile<1, 3, [ + SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2> +]>; + +// Unary, binary v16i8 operator type constraints: +def SPUv16i8_unop: SDTypeProfile<1, 1, [ + SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>]>; + +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 SPUv4i32_binop: SDTypeProfile<1, 2, [ + SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; + +// FSMBI 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>]>; + +// 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> ]>; + +// 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_v8i16: SDTypeProfile<1, 2, [ + SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>; + +def SPUvecshift_type_v4i32: SDTypeProfile<1, 2, [ + SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisInt<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, []>; + +// 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_rotr_v8i16: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v8i16, []>; +def SPUvec_rotr_v4i32: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v4i32, []>; + +def SPUrotbytes_right_zfill: SDNode<"SPUISD::ROTBYTES_RIGHT_Z", + SPUvecshift_type_v16i8, []>; +def SPUrotbytes_right_sfill: SDNode<"SPUISD::ROTBYTES_RIGHT_S", + SPUvecshift_type_v16i8, []>; +def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT", + SPUvecshift_type_v16i8, []>; + +def SPUrotbytes_left_chained : SDNode<"SPUISD::ROTBYTES_LEFT_CHAINED", + SPUvecshift_type_v16i8, [SDNPHasChain]>; + +// 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, []>; + +// 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, []>; + +// 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 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, []>; + +// Address high and low components, used for [r+r] type addressing +def SPUhi : SDNode<"SPUISD::Hi", SDTIntBinOp, []>; +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, []>; + +// Branches: + +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]>; */ + +//===----------------------------------------------------------------------===// +// Constraints: (taken from PPCInstrInfo.td) +//===----------------------------------------------------------------------===// + +class RegConstraint<string C> { + string Constraints = C; +} + +class NoEncode<string E> { + string DisableEncoding = E; +} + +//===----------------------------------------------------------------------===// +// Return (flag isn't quite what it means: the operations are flagged so that +// instruction scheduling doesn't disassociate them.) +//===----------------------------------------------------------------------===// + +def retflag : SDNode<"SPUISD::RET_FLAG", SDTRet, + [SDNPHasChain, SDNPOptInFlag]>; |