summaryrefslogtreecommitdiff
path: root/lib/Target/CellSPU/SPUNodes.td
blob: a6e621f36b35118a8f60f85bd367e35b1ad8e406 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//===- SPUNodes.td - Specialized SelectionDAG nodes used for CellSPU ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.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 SPUshufmask    : SDNode<"SPUISD::SHUFFLE_MASK", SPU_GenControl, []>;

def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPUCallSeq,
                           [SDNPHasChain, SDNPOutGlue]>;
def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_SPUCallSeq,
                           [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
//===----------------------------------------------------------------------===//
// Operand constraints:
//===----------------------------------------------------------------------===//

def SDT_SPUCall   : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
def SPUcall       : SDNode<"SPUISD::CALL", SDT_SPUCall,
                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
                            SDNPVariadic]>;

// Operand type constraints for vector shuffle/permute operations
def SDT_SPUshuffle   : SDTypeProfile<1, 3, [
  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
]>;

// Vector binary operator type constraints (needs a further constraint to
// ensure that operand 0 is a vector...):

def SPUVecBinop: SDTypeProfile<1, 2, [
  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>
]>;

// SELECT_MASK type constraints: There are several variations for the various
// vector types (this avoids having to bit_convert all over the place.)
def SPUselmask_type: SDTypeProfile<1, 1, [
  SDTCisInt<1>
]>;

// SELB type constraints:
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: SDTypeProfile<1, 2, [
  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 SPUmarker_type : SDTypeProfile<1, 3, [
  SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> ]>;

//===----------------------------------------------------------------------===//
// Synthetic/pseudo-instructions
//===----------------------------------------------------------------------===//

// SPU CNTB:
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, []>;

// Vector shifts (ISD::SHL,SRL,SRA are for _integers_ only):
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_rotl: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type, []>;
def SPUvec_rotr: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type, []>;

// Vector rotate left, bits shifted out of the left are rotated in on the right
def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT",
                             SPUvecshift_type, []>;

// 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 SPUselmask: SDNode<"SPUISD::SELECT_MASK", SPUselmask_type, []>;

// SPU select bits instruction
def SPUselb: SDNode<"SPUISD::SELB", SPUselb_type, []>;

def SDTprefslot2vec: SDTypeProfile<1, 1, []>;
def SPUprefslot2vec: SDNode<"SPUISD::PREFSLOT2VEC", SDTprefslot2vec, []>;

def SPU_vec_demote   : SDTypeProfile<1, 1, []>;
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, []>;
def SPUlo : SDNode<"SPUISD::Lo", SDTIntBinOp, []>;

// PC-relative address
def SPUpcrel : SDNode<"SPUISD::PCRelAddr", SDTIntBinOp, []>;

// A-Form local store addresses
def SPUaform : SDNode<"SPUISD::AFormAddr", SDTIntBinOp, []>;

// Indirect [D-Form "imm($reg)" and X-Form "$reg($reg)"] addresses
def SPUindirect : SDNode<"SPUISD::IndirectAddr", SDTIntBinOp, []>;

// 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)
//===----------------------------------------------------------------------===//

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", SDTNone,
                         [SDNPHasChain, SDNPOptInGlue]>;