summaryrefslogtreecommitdiff
path: root/lib/Target/R600/SIInstrInfo.td
blob: cf0d5b936ae8b40c224c644cad7e7628c6a01c35 (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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// SI DAG Nodes
//===----------------------------------------------------------------------===//

// SMRD takes a 64bit memory address and can only add an 32bit offset
def SIadd64bit32bit : SDNode<"ISD::ADD",
  SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVT<0, i64>, SDTCisVT<2, i32>]>
>;

// Transformation function, extract the lower 32bit of a 64bit immediate
def LO32 : SDNodeXForm<imm, [{
  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
}]>;

// Transformation function, extract the upper 32bit of a 64bit immediate
def HI32 : SDNodeXForm<imm, [{
  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
}]>;

def IMM8bitDWORD : ImmLeaf <
  i32, [{
    return (Imm & ~0x3FC) == 0;
  }], SDNodeXForm<imm, [{
    return CurDAG->getTargetConstant(
      N->getZExtValue() >> 2, MVT::i32);
  }]>
>;

def IMM12bit : ImmLeaf <
  i16,
  [{return isUInt<12>(Imm);}]
>;

class InlineImm <ValueType vt> : ImmLeaf <vt, [{
  return -16 <= Imm && Imm <= 64;
}]>;


//===----------------------------------------------------------------------===//
// SI assembler operands
//===----------------------------------------------------------------------===//

class SIOperand <ValueType vt, dag opInfo>: Operand <vt> {
  let EncoderMethod = "encodeOperand";
  let MIOperandInfo = opInfo;
}

class GPR4Align <RegisterClass rc> : Operand <vAny> {
  let EncoderMethod = "GPR4AlignEncode";
  let MIOperandInfo = (ops rc:$reg); 
}

class GPR2Align <RegisterClass rc> : Operand <iPTR> {
  let EncoderMethod = "GPR2AlignEncode";
  let MIOperandInfo = (ops rc:$reg);
}

include "SIInstrFormats.td"

//===----------------------------------------------------------------------===//
//
// SI Instruction multiclass helpers.
//
// Instructions with _32 take 32-bit operands.
// Instructions with _64 take 64-bit operands.
//
// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
// encoding is the standard encoding, but instruction that make use of
// any of the instruction modifiers must use the 64-bit encoding.
//
// Instructions with _e32 use the 32-bit encoding.
// Instructions with _e64 use the 64-bit encoding.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Scalar classes
//===----------------------------------------------------------------------===//

class SOP1_32 <bits<8> op, string opName, list<dag> pattern>
  : SOP1 <op, (outs SReg_32:$dst), (ins SSrc_32:$src0), opName, pattern>;

class SOP1_64 <bits<8> op, string opName, list<dag> pattern>
  : SOP1 <op, (outs SReg_64:$dst), (ins SSrc_64:$src0), opName, pattern>;

class SOP2_32 <bits<7> op, string opName, list<dag> pattern>
  : SOP2 <op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), opName, pattern>;

class SOP2_64 <bits<7> op, string opName, list<dag> pattern>
  : SOP2 <op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), opName, pattern>;

class SOPC_32 <bits<7> op, string opName, list<dag> pattern>
  : SOPC <op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1), opName, pattern>;

class SOPC_64 <bits<7> op, string opName, list<dag> pattern>
  : SOPC <op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1), opName, pattern>;

class SOPK_32 <bits<5> op, string opName, list<dag> pattern>
  : SOPK <op, (outs SReg_32:$dst), (ins i16imm:$src0), opName, pattern>;

class SOPK_64 <bits<5> op, string opName, list<dag> pattern>
  : SOPK <op, (outs SReg_64:$dst), (ins i16imm:$src0), opName, pattern>;

multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass dstClass> {
  def _IMM : SMRD <
    op, 1, (outs dstClass:$dst),
    (ins GPR2Align<SReg_64>:$sbase, i32imm:$offset),
    asm, []
  >;

  def _SGPR : SMRD <
    op, 0, (outs dstClass:$dst),
    (ins GPR2Align<SReg_64>:$sbase, SReg_32:$soff),
    asm, []
  >;
}

//===----------------------------------------------------------------------===//
// Vector ALU classes
//===----------------------------------------------------------------------===//

class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
  op, (outs VReg_32:$dst),
  (ins VSrc_32:$src0, VReg_32:$src1, VReg_32:$src2, i32imm:$src3,
   i32imm:$src4, i32imm:$src5, i32imm:$src6),
  opName, pattern
>;

class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
  op, (outs VReg_64:$dst),
  (ins VSrc_64:$src0, VReg_64:$src1, VReg_64:$src2,
   i32imm:$src3, i32imm:$src4, i32imm:$src5, i32imm:$src6),
  opName, pattern
>;

class VOP1_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
                   string opName, list<dag> pattern> : 
  VOP1 <
    op, (outs vrc:$dst), (ins arc:$src0), opName, pattern
  >;

multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern> {
  def _e32: VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
  def _e64 : VOP3_32 <{1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
                      opName, []
  >;
}

multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern> {

  def _e32 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;

  def _e64 : VOP3_64 <
    {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    opName, []
  >;
}

class VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
                   string opName, list<dag> pattern> :
  VOP2 <
    op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1), opName, pattern
  >;

multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern> {

  def _e32 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern>;

  def _e64 : VOP3_32 <{1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
                      opName, []
  >;
}

multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern> {
  def _e32: VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern>;

  def _e64 : VOP3_64 <
    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    opName, []
  >;
}

multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
                        string opName, list<dag> pattern> {

  def _e32 : VOPC <op, (ins arc:$src0, vrc:$src1), opName, pattern>;
  def _e64 : VOP3 <
    {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
    (outs SReg_64:$dst),
    (ins arc:$src0, vrc:$src1,
         InstFlag:$abs, InstFlag:$clamp,
         InstFlag:$omod, InstFlag:$neg),
    opName, pattern
  > {
    let SRC2 = 0x80;
  }
}

multiclass VOPC_32 <bits<8> op, string opName, list<dag> pattern>
  : VOPC_Helper <op, VReg_32, VSrc_32, opName, pattern>;

multiclass VOPC_64 <bits<8> op, string opName, list<dag> pattern>
  : VOPC_Helper <op, VReg_64, VSrc_64, opName, pattern>;

//===----------------------------------------------------------------------===//
// Vector I/O classes
//===----------------------------------------------------------------------===//

class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
  op,
  (outs),
  (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
   GPR4Align<SReg_128>:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
  asm,
  []> {
  let mayStore = 1;
  let mayLoad = 0;
}

class MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> : MUBUF <
  op,
  (outs regClass:$dst),
  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
       i1imm:$lds, VReg_32:$vaddr, GPR4Align<SReg_128>:$srsrc, i1imm:$slc,
       i1imm:$tfe, SSrc_32:$soffset),
  asm,
  []> {
  let mayLoad = 1;
  let mayStore = 0;
}

class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
  op,
  (outs regClass:$dst),
  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
       i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, GPR4Align<SReg_128>:$srsrc,
       i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
  asm,
  []> {
  let mayLoad = 1;
  let mayStore = 0;
}

class MIMG_Load_Helper <bits<7> op, string asm> : MIMG <
  op,
  (outs VReg_128:$vdata),
  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, VReg_32:$vaddr,
       GPR4Align<SReg_256>:$srsrc, GPR4Align<SReg_128>:$ssamp),
  asm,
  []> {
  let mayLoad = 1;
  let mayStore = 0;
}

include "SIInstructions.td"