Scott Michel | 564427e | 2007-12-05 01:24:05 +0000 | [diff] [blame^] | 1 | //=- SPUNodes.h - Specialized SelectionDAG nodes used for CellSPU -*- C++ -*-=// |
| 2 | // |
| 3 | // This file was developed by a team from the Computer Systems Research |
| 4 | // Department at The Aerospace Corporation. |
| 5 | // |
| 6 | // See README.txt for details. |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // Type profiles and SelectionDAG nodes used by CellSPU |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | // Type profile for a call sequence |
| 14 | def SDT_SPUCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; |
| 15 | |
| 16 | // SPU_GenControl: Type profile for generating control words for insertions |
| 17 | def SPU_GenControl : SDTypeProfile<1, 1, []>; |
| 18 | def SPUvecinsmask : SDNode<"SPUISD::INSERT_MASK", SPU_GenControl, []>; |
| 19 | |
| 20 | def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPUCallSeq, |
| 21 | [SDNPHasChain, SDNPOutFlag]>; |
| 22 | def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPUCallSeq, |
| 23 | [SDNPHasChain, SDNPOutFlag]>; |
| 24 | //===----------------------------------------------------------------------===// |
| 25 | // Operand constraints: |
| 26 | //===----------------------------------------------------------------------===// |
| 27 | |
| 28 | def SDT_SPUCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; |
| 29 | def SPUcall : SDNode<"SPUISD::CALL", SDT_SPUCall, |
| 30 | [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; |
| 31 | |
| 32 | // Operand type constraints for vector shuffle/permute operations |
| 33 | def SDT_SPUshuffle : SDTypeProfile<1, 3, [ |
| 34 | SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2> |
| 35 | ]>; |
| 36 | |
| 37 | // Unary, binary v16i8 operator type constraints: |
| 38 | def SPUv16i8_unop: SDTypeProfile<1, 1, [ |
| 39 | SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>]>; |
| 40 | |
| 41 | def SPUv16i8_binop: SDTypeProfile<1, 2, [ |
| 42 | SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; |
| 43 | |
| 44 | // Binary v8i16 operator type constraints: |
| 45 | def SPUv8i16_unop: SDTypeProfile<1, 1, [ |
| 46 | SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>]>; |
| 47 | |
| 48 | def SPUv8i16_binop: SDTypeProfile<1, 2, [ |
| 49 | SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; |
| 50 | |
| 51 | // Binary v4i32 operator type constraints: |
| 52 | def SPUv4i32_unop: SDTypeProfile<1, 1, [ |
| 53 | SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>]>; |
| 54 | |
| 55 | def SPUv4i32_binop: SDTypeProfile<1, 2, [ |
| 56 | SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; |
| 57 | |
| 58 | // FSMBI type constraints: There are several variations for the various |
| 59 | // vector types (this avoids having to bit_convert all over the place.) |
| 60 | def SPUfsmbi_type_v16i8: SDTypeProfile<1, 1, [ |
| 61 | SDTCisVT<0, v16i8>, SDTCisVT<1, i32>]>; |
| 62 | |
| 63 | def SPUfsmbi_type_v8i16: SDTypeProfile<1, 1, [ |
| 64 | SDTCisVT<0, v8i16>, SDTCisVT<1, i32>]>; |
| 65 | |
| 66 | def SPUfsmbi_type_v4i32: SDTypeProfile<1, 1, [ |
| 67 | SDTCisVT<0, v4i32>, SDTCisVT<1, i32>]>; |
| 68 | |
| 69 | // SELB type constraints: |
| 70 | def SPUselb_type_v16i8: SDTypeProfile<1, 3, [ |
| 71 | SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, |
| 72 | SDTCisSameAs<0, 3> ]>; |
| 73 | |
| 74 | def SPUselb_type_v8i16: SDTypeProfile<1, 3, [ |
| 75 | SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, |
| 76 | SDTCisSameAs<0, 3> ]>; |
| 77 | |
| 78 | def SPUselb_type_v4i32: SDTypeProfile<1, 3, [ |
| 79 | SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, |
| 80 | SDTCisSameAs<0, 3> ]>; |
| 81 | |
| 82 | // SPU Vector shift pseudo-instruction type constraints |
| 83 | def SPUvecshift_type_v16i8: SDTypeProfile<1, 2, [ |
| 84 | SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>; |
| 85 | |
| 86 | def SPUvecshift_type_v8i16: SDTypeProfile<1, 2, [ |
| 87 | SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>; |
| 88 | |
| 89 | def SPUvecshift_type_v4i32: SDTypeProfile<1, 2, [ |
| 90 | SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>; |
| 91 | |
| 92 | //===----------------------------------------------------------------------===// |
| 93 | // Synthetic/pseudo-instructions |
| 94 | //===----------------------------------------------------------------------===// |
| 95 | |
| 96 | // SPU CNTB: |
| 97 | def SPUcntb_v16i8: SDNode<"SPUISD::CNTB", SPUv16i8_unop, []>; |
| 98 | def SPUcntb_v8i16: SDNode<"SPUISD::CNTB", SPUv8i16_unop, []>; |
| 99 | def SPUcntb_v4i32: SDNode<"SPUISD::CNTB", SPUv4i32_unop, []>; |
| 100 | |
| 101 | // SPU vector shuffle node, matched by the SPUISD::SHUFB enum (see |
| 102 | // SPUISelLowering.h): |
| 103 | def SPUshuffle: SDNode<"SPUISD::SHUFB", SDT_SPUshuffle, []>; |
| 104 | |
| 105 | // SPU 16-bit multiply |
| 106 | def SPUmpy_v16i8: SDNode<"SPUISD::MPY", SPUv16i8_binop, []>; |
| 107 | def SPUmpy_v8i16: SDNode<"SPUISD::MPY", SPUv8i16_binop, []>; |
| 108 | def SPUmpy_v4i32: SDNode<"SPUISD::MPY", SPUv4i32_binop, []>; |
| 109 | |
| 110 | // SPU multiply unsigned, used in instruction lowering for v4i32 |
| 111 | // multiplies: |
| 112 | def SPUmpyu_v4i32: SDNode<"SPUISD::MPYU", SPUv4i32_binop, []>; |
| 113 | def SPUmpyu_i32: SDNode<"SPUISD::MPYU", SDTIntBinOp, []>; |
| 114 | |
| 115 | // SPU 16-bit multiply high x low, shift result 16-bits |
| 116 | // Used to compute intermediate products for 32-bit multiplies |
| 117 | def SPUmpyh_v4i32: SDNode<"SPUISD::MPYH", SPUv4i32_binop, []>; |
| 118 | def SPUmpyh_i32: SDNode<"SPUISD::MPYH", SDTIntBinOp, []>; |
| 119 | |
| 120 | // SPU 16-bit multiply high x high, 32-bit product |
| 121 | // Used to compute intermediate products for 16-bit multiplies |
| 122 | def SPUmpyhh_v8i16: SDNode<"SPUISD::MPYHH", SPUv8i16_binop, []>; |
| 123 | |
| 124 | // Vector shifts (ISD::SHL,SRL,SRA are for _integers_ only): |
| 125 | def SPUvec_shl_v8i16: SDNode<"SPUISD::VEC_SHL", SPUvecshift_type_v8i16, []>; |
| 126 | def SPUvec_srl_v8i16: SDNode<"SPUISD::VEC_SRL", SPUvecshift_type_v8i16, []>; |
| 127 | def SPUvec_sra_v8i16: SDNode<"SPUISD::VEC_SRA", SPUvecshift_type_v8i16, []>; |
| 128 | |
| 129 | def SPUvec_shl_v4i32: SDNode<"SPUISD::VEC_SHL", SPUvecshift_type_v4i32, []>; |
| 130 | def SPUvec_srl_v4i32: SDNode<"SPUISD::VEC_SRL", SPUvecshift_type_v4i32, []>; |
| 131 | def SPUvec_sra_v4i32: SDNode<"SPUISD::VEC_SRA", SPUvecshift_type_v4i32, []>; |
| 132 | |
| 133 | def SPUvec_rotl_v8i16: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type_v8i16, []>; |
| 134 | def SPUvec_rotl_v4i32: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type_v4i32, []>; |
| 135 | |
| 136 | def SPUvec_rotr_v8i16: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v8i16, []>; |
| 137 | def SPUvec_rotr_v4i32: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v4i32, []>; |
| 138 | |
| 139 | def SPUrotbytes_right_zfill: SDNode<"SPUISD::ROTBYTES_RIGHT_Z", |
| 140 | SPUvecshift_type_v16i8, []>; |
| 141 | def SPUrotbytes_right_sfill: SDNode<"SPUISD::ROTBYTES_RIGHT_S", |
| 142 | SPUvecshift_type_v16i8, []>; |
| 143 | def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT", |
| 144 | SPUvecshift_type_v16i8, []>; |
| 145 | |
| 146 | def SPUrotbytes_left_chained : SDNode<"SPUISD::ROTBYTES_LEFT_CHAINED", |
| 147 | SPUvecshift_type_v16i8, [SDNPHasChain]>; |
| 148 | |
| 149 | // SPU form select mask for bytes, immediate |
| 150 | def SPUfsmbi_v16i8: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v16i8, []>; |
| 151 | def SPUfsmbi_v8i16: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v8i16, []>; |
| 152 | def SPUfsmbi_v4i32: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v4i32, []>; |
| 153 | |
| 154 | // SPU select bits instruction |
| 155 | def SPUselb_v16i8: SDNode<"SPUISD::SELB", SPUselb_type_v16i8, []>; |
| 156 | def SPUselb_v8i16: SDNode<"SPUISD::SELB", SPUselb_type_v8i16, []>; |
| 157 | def SPUselb_v4i32: SDNode<"SPUISD::SELB", SPUselb_type_v4i32, []>; |
| 158 | |
| 159 | // SPU single precision floating point constant load |
| 160 | def SPUFPconstant: SDNode<"SPUISD::SFPConstant", SDTFPUnaryOp, []>; |
| 161 | |
| 162 | // SPU floating point interpolate |
| 163 | def SPUinterpolate : SDNode<"SPUISD::FPInterp", SDTFPBinOp, []>; |
| 164 | |
| 165 | // SPU floating point reciprocal estimate (used for fdiv) |
| 166 | def SPUreciprocalEst: SDNode<"SPUISD::FPRecipEst", SDTFPUnaryOp, []>; |
| 167 | |
| 168 | def SDT_vec_promote : SDTypeProfile<1, 1, []>; |
| 169 | def SPUpromote_scalar: SDNode<"SPUISD::PROMOTE_SCALAR", SDT_vec_promote, []>; |
| 170 | |
| 171 | def SPU_vec_demote : SDTypeProfile<1, 1, []>; |
| 172 | def SPUextract_elt0: SDNode<"SPUISD::EXTRACT_ELT0", SPU_vec_demote, []>; |
| 173 | def SPU_vec_demote_chained : SDTypeProfile<1, 2, []>; |
| 174 | def SPUextract_elt0_chained: SDNode<"SPUISD::EXTRACT_ELT0_CHAINED", |
| 175 | SPU_vec_demote_chained, [SDNPHasChain]>; |
| 176 | def SPUextract_i1_sext: SDNode<"SPUISD::EXTRACT_I1_SEXT", SPU_vec_demote, []>; |
| 177 | def SPUextract_i1_zext: SDNode<"SPUISD::EXTRACT_I1_ZEXT", SPU_vec_demote, []>; |
| 178 | def SPUextract_i8_sext: SDNode<"SPUISD::EXTRACT_I8_SEXT", SPU_vec_demote, []>; |
| 179 | def SPUextract_i8_zext: SDNode<"SPUISD::EXTRACT_I8_ZEXT", SPU_vec_demote, []>; |
| 180 | |
| 181 | // Address high and low components, used for [r+r] type addressing |
| 182 | def SPUhi : SDNode<"SPUISD::Hi", SDTIntBinOp, []>; |
| 183 | def SPUlo : SDNode<"SPUISD::Lo", SDTIntBinOp, []>; |
| 184 | |
| 185 | // PC-relative address |
| 186 | def SPUpcrel : SDNode<"SPUISD::PCRelAddr", SDTIntBinOp, []>; |
| 187 | |
| 188 | // D-Form "imm($reg)" addresses |
| 189 | def SPUdform : SDNode<"SPUISD::DFormAddr", SDTIntBinOp, []>; |
| 190 | |
| 191 | // SPU 32-bit sign-extension to 64-bits |
| 192 | def SPUsext32_to_64: SDNode<"SPUISD::SEXT32TO64", SDTIntExtendOp, []>; |
| 193 | |
| 194 | // Branches: |
| 195 | |
| 196 | def SPUbrnz : SDNode<"SPUISD::BR_NOTZERO", SDTBrcond, [SDNPHasChain]>; |
| 197 | def SPUbrz : SDNode<"SPUISD::BR_ZERO", SDTBrcond, [SDNPHasChain]>; |
| 198 | /* def SPUbinz : SDNode<"SPUISD::BR_NOTZERO", SDTBrind, [SDNPHasChain]>; |
| 199 | def SPUbiz : SDNode<"SPUISD::BR_ZERO", SPUBrind, [SDNPHasChain]>; */ |
| 200 | |
| 201 | //===----------------------------------------------------------------------===// |
| 202 | // Constraints: (taken from PPCInstrInfo.td) |
| 203 | //===----------------------------------------------------------------------===// |
| 204 | |
| 205 | class RegConstraint<string C> { |
| 206 | string Constraints = C; |
| 207 | } |
| 208 | |
| 209 | class NoEncode<string E> { |
| 210 | string DisableEncoding = E; |
| 211 | } |
| 212 | |
| 213 | //===----------------------------------------------------------------------===// |
| 214 | // Return (flag isn't quite what it means: the operations are flagged so that |
| 215 | // instruction scheduling doesn't disassociate them.) |
| 216 | //===----------------------------------------------------------------------===// |
| 217 | |
| 218 | def retflag : SDNode<"SPUISD::RET_FLAG", SDTRet, |
| 219 | [SDNPHasChain, SDNPOptInFlag]>; |