1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2010 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "brw_cfg.h"
25*61046927SAndroid Build Coastguard Worker #include "brw_fs.h"
26*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker bool
brw_reg_saturate_immediate(brw_reg * reg)29*61046927SAndroid Build Coastguard Worker brw_reg_saturate_immediate(brw_reg *reg)
30*61046927SAndroid Build Coastguard Worker {
31*61046927SAndroid Build Coastguard Worker union {
32*61046927SAndroid Build Coastguard Worker unsigned ud;
33*61046927SAndroid Build Coastguard Worker int d;
34*61046927SAndroid Build Coastguard Worker float f;
35*61046927SAndroid Build Coastguard Worker double df;
36*61046927SAndroid Build Coastguard Worker } imm, sat_imm = { 0 };
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker const unsigned size = brw_type_size_bytes(reg->type);
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker /* We want to either do a 32-bit or 64-bit data copy, the type is otherwise
41*61046927SAndroid Build Coastguard Worker * irrelevant, so just check the size of the type and copy from/to an
42*61046927SAndroid Build Coastguard Worker * appropriately sized field.
43*61046927SAndroid Build Coastguard Worker */
44*61046927SAndroid Build Coastguard Worker if (size < 8)
45*61046927SAndroid Build Coastguard Worker imm.ud = reg->ud;
46*61046927SAndroid Build Coastguard Worker else
47*61046927SAndroid Build Coastguard Worker imm.df = reg->df;
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker switch (reg->type) {
50*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UD:
51*61046927SAndroid Build Coastguard Worker case BRW_TYPE_D:
52*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UW:
53*61046927SAndroid Build Coastguard Worker case BRW_TYPE_W:
54*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UQ:
55*61046927SAndroid Build Coastguard Worker case BRW_TYPE_Q:
56*61046927SAndroid Build Coastguard Worker /* Nothing to do. */
57*61046927SAndroid Build Coastguard Worker return false;
58*61046927SAndroid Build Coastguard Worker case BRW_TYPE_F:
59*61046927SAndroid Build Coastguard Worker sat_imm.f = SATURATE(imm.f);
60*61046927SAndroid Build Coastguard Worker break;
61*61046927SAndroid Build Coastguard Worker case BRW_TYPE_DF:
62*61046927SAndroid Build Coastguard Worker sat_imm.df = SATURATE(imm.df);
63*61046927SAndroid Build Coastguard Worker break;
64*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UB:
65*61046927SAndroid Build Coastguard Worker case BRW_TYPE_B:
66*61046927SAndroid Build Coastguard Worker unreachable("no UB/B immediates");
67*61046927SAndroid Build Coastguard Worker case BRW_TYPE_V:
68*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UV:
69*61046927SAndroid Build Coastguard Worker case BRW_TYPE_VF:
70*61046927SAndroid Build Coastguard Worker unreachable("unimplemented: saturate vector immediate");
71*61046927SAndroid Build Coastguard Worker case BRW_TYPE_HF:
72*61046927SAndroid Build Coastguard Worker unreachable("unimplemented: saturate HF immediate");
73*61046927SAndroid Build Coastguard Worker default:
74*61046927SAndroid Build Coastguard Worker unreachable("invalid type");
75*61046927SAndroid Build Coastguard Worker }
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker if (size < 8) {
78*61046927SAndroid Build Coastguard Worker if (imm.ud != sat_imm.ud) {
79*61046927SAndroid Build Coastguard Worker reg->ud = sat_imm.ud;
80*61046927SAndroid Build Coastguard Worker return true;
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker } else {
83*61046927SAndroid Build Coastguard Worker if (imm.df != sat_imm.df) {
84*61046927SAndroid Build Coastguard Worker reg->df = sat_imm.df;
85*61046927SAndroid Build Coastguard Worker return true;
86*61046927SAndroid Build Coastguard Worker }
87*61046927SAndroid Build Coastguard Worker }
88*61046927SAndroid Build Coastguard Worker return false;
89*61046927SAndroid Build Coastguard Worker }
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker bool
brw_reg_negate_immediate(brw_reg * reg)92*61046927SAndroid Build Coastguard Worker brw_reg_negate_immediate(brw_reg *reg)
93*61046927SAndroid Build Coastguard Worker {
94*61046927SAndroid Build Coastguard Worker switch (reg->type) {
95*61046927SAndroid Build Coastguard Worker case BRW_TYPE_D:
96*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UD:
97*61046927SAndroid Build Coastguard Worker reg->d = -reg->d;
98*61046927SAndroid Build Coastguard Worker return true;
99*61046927SAndroid Build Coastguard Worker case BRW_TYPE_W:
100*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UW: {
101*61046927SAndroid Build Coastguard Worker uint16_t value = -(int16_t)reg->ud;
102*61046927SAndroid Build Coastguard Worker reg->ud = value | (uint32_t)value << 16;
103*61046927SAndroid Build Coastguard Worker return true;
104*61046927SAndroid Build Coastguard Worker }
105*61046927SAndroid Build Coastguard Worker case BRW_TYPE_F:
106*61046927SAndroid Build Coastguard Worker reg->f = -reg->f;
107*61046927SAndroid Build Coastguard Worker return true;
108*61046927SAndroid Build Coastguard Worker case BRW_TYPE_VF:
109*61046927SAndroid Build Coastguard Worker reg->ud ^= 0x80808080;
110*61046927SAndroid Build Coastguard Worker return true;
111*61046927SAndroid Build Coastguard Worker case BRW_TYPE_DF:
112*61046927SAndroid Build Coastguard Worker reg->df = -reg->df;
113*61046927SAndroid Build Coastguard Worker return true;
114*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UQ:
115*61046927SAndroid Build Coastguard Worker case BRW_TYPE_Q:
116*61046927SAndroid Build Coastguard Worker reg->d64 = -reg->d64;
117*61046927SAndroid Build Coastguard Worker return true;
118*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UB:
119*61046927SAndroid Build Coastguard Worker case BRW_TYPE_B:
120*61046927SAndroid Build Coastguard Worker unreachable("no UB/B immediates");
121*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UV:
122*61046927SAndroid Build Coastguard Worker case BRW_TYPE_V:
123*61046927SAndroid Build Coastguard Worker assert(!"unimplemented: negate UV/V immediate");
124*61046927SAndroid Build Coastguard Worker case BRW_TYPE_HF:
125*61046927SAndroid Build Coastguard Worker reg->ud ^= 0x80008000;
126*61046927SAndroid Build Coastguard Worker return true;
127*61046927SAndroid Build Coastguard Worker default:
128*61046927SAndroid Build Coastguard Worker unreachable("invalid type");
129*61046927SAndroid Build Coastguard Worker }
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker return false;
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker bool
brw_reg_abs_immediate(brw_reg * reg)135*61046927SAndroid Build Coastguard Worker brw_reg_abs_immediate(brw_reg *reg)
136*61046927SAndroid Build Coastguard Worker {
137*61046927SAndroid Build Coastguard Worker switch (reg->type) {
138*61046927SAndroid Build Coastguard Worker case BRW_TYPE_D:
139*61046927SAndroid Build Coastguard Worker reg->d = abs(reg->d);
140*61046927SAndroid Build Coastguard Worker return true;
141*61046927SAndroid Build Coastguard Worker case BRW_TYPE_W: {
142*61046927SAndroid Build Coastguard Worker uint16_t value = abs((int16_t)reg->ud);
143*61046927SAndroid Build Coastguard Worker reg->ud = value | (uint32_t)value << 16;
144*61046927SAndroid Build Coastguard Worker return true;
145*61046927SAndroid Build Coastguard Worker }
146*61046927SAndroid Build Coastguard Worker case BRW_TYPE_F:
147*61046927SAndroid Build Coastguard Worker reg->f = fabsf(reg->f);
148*61046927SAndroid Build Coastguard Worker return true;
149*61046927SAndroid Build Coastguard Worker case BRW_TYPE_DF:
150*61046927SAndroid Build Coastguard Worker reg->df = fabs(reg->df);
151*61046927SAndroid Build Coastguard Worker return true;
152*61046927SAndroid Build Coastguard Worker case BRW_TYPE_VF:
153*61046927SAndroid Build Coastguard Worker reg->ud &= ~0x80808080;
154*61046927SAndroid Build Coastguard Worker return true;
155*61046927SAndroid Build Coastguard Worker case BRW_TYPE_Q:
156*61046927SAndroid Build Coastguard Worker reg->d64 = imaxabs(reg->d64);
157*61046927SAndroid Build Coastguard Worker return true;
158*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UB:
159*61046927SAndroid Build Coastguard Worker case BRW_TYPE_B:
160*61046927SAndroid Build Coastguard Worker unreachable("no UB/B immediates");
161*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UQ:
162*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UD:
163*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UW:
164*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UV:
165*61046927SAndroid Build Coastguard Worker /* Presumably the absolute value modifier on an unsigned source is a
166*61046927SAndroid Build Coastguard Worker * nop, but it would be nice to confirm.
167*61046927SAndroid Build Coastguard Worker */
168*61046927SAndroid Build Coastguard Worker assert(!"unimplemented: abs unsigned immediate");
169*61046927SAndroid Build Coastguard Worker case BRW_TYPE_V:
170*61046927SAndroid Build Coastguard Worker assert(!"unimplemented: abs V immediate");
171*61046927SAndroid Build Coastguard Worker case BRW_TYPE_HF:
172*61046927SAndroid Build Coastguard Worker reg->ud &= ~0x80008000;
173*61046927SAndroid Build Coastguard Worker return true;
174*61046927SAndroid Build Coastguard Worker default:
175*61046927SAndroid Build Coastguard Worker unreachable("invalid type");
176*61046927SAndroid Build Coastguard Worker }
177*61046927SAndroid Build Coastguard Worker
178*61046927SAndroid Build Coastguard Worker return false;
179*61046927SAndroid Build Coastguard Worker }
180*61046927SAndroid Build Coastguard Worker
181*61046927SAndroid Build Coastguard Worker bool
is_zero() const182*61046927SAndroid Build Coastguard Worker brw_reg::is_zero() const
183*61046927SAndroid Build Coastguard Worker {
184*61046927SAndroid Build Coastguard Worker if (file != IMM)
185*61046927SAndroid Build Coastguard Worker return false;
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard Worker assert(brw_type_size_bytes(type) > 1);
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker switch (type) {
190*61046927SAndroid Build Coastguard Worker case BRW_TYPE_HF:
191*61046927SAndroid Build Coastguard Worker assert((d & 0xffff) == ((d >> 16) & 0xffff));
192*61046927SAndroid Build Coastguard Worker return (d & 0xffff) == 0 || (d & 0xffff) == 0x8000;
193*61046927SAndroid Build Coastguard Worker case BRW_TYPE_F:
194*61046927SAndroid Build Coastguard Worker return f == 0;
195*61046927SAndroid Build Coastguard Worker case BRW_TYPE_DF:
196*61046927SAndroid Build Coastguard Worker return df == 0;
197*61046927SAndroid Build Coastguard Worker case BRW_TYPE_W:
198*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UW:
199*61046927SAndroid Build Coastguard Worker assert((d & 0xffff) == ((d >> 16) & 0xffff));
200*61046927SAndroid Build Coastguard Worker return (d & 0xffff) == 0;
201*61046927SAndroid Build Coastguard Worker case BRW_TYPE_D:
202*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UD:
203*61046927SAndroid Build Coastguard Worker return d == 0;
204*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UQ:
205*61046927SAndroid Build Coastguard Worker case BRW_TYPE_Q:
206*61046927SAndroid Build Coastguard Worker return u64 == 0;
207*61046927SAndroid Build Coastguard Worker default:
208*61046927SAndroid Build Coastguard Worker return false;
209*61046927SAndroid Build Coastguard Worker }
210*61046927SAndroid Build Coastguard Worker }
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker bool
is_one() const213*61046927SAndroid Build Coastguard Worker brw_reg::is_one() const
214*61046927SAndroid Build Coastguard Worker {
215*61046927SAndroid Build Coastguard Worker if (file != IMM)
216*61046927SAndroid Build Coastguard Worker return false;
217*61046927SAndroid Build Coastguard Worker
218*61046927SAndroid Build Coastguard Worker assert(brw_type_size_bytes(type) > 1);
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker switch (type) {
221*61046927SAndroid Build Coastguard Worker case BRW_TYPE_HF:
222*61046927SAndroid Build Coastguard Worker assert((d & 0xffff) == ((d >> 16) & 0xffff));
223*61046927SAndroid Build Coastguard Worker return (d & 0xffff) == 0x3c00;
224*61046927SAndroid Build Coastguard Worker case BRW_TYPE_F:
225*61046927SAndroid Build Coastguard Worker return f == 1.0f;
226*61046927SAndroid Build Coastguard Worker case BRW_TYPE_DF:
227*61046927SAndroid Build Coastguard Worker return df == 1.0;
228*61046927SAndroid Build Coastguard Worker case BRW_TYPE_W:
229*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UW:
230*61046927SAndroid Build Coastguard Worker assert((d & 0xffff) == ((d >> 16) & 0xffff));
231*61046927SAndroid Build Coastguard Worker return (d & 0xffff) == 1;
232*61046927SAndroid Build Coastguard Worker case BRW_TYPE_D:
233*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UD:
234*61046927SAndroid Build Coastguard Worker return d == 1;
235*61046927SAndroid Build Coastguard Worker case BRW_TYPE_UQ:
236*61046927SAndroid Build Coastguard Worker case BRW_TYPE_Q:
237*61046927SAndroid Build Coastguard Worker return u64 == 1;
238*61046927SAndroid Build Coastguard Worker default:
239*61046927SAndroid Build Coastguard Worker return false;
240*61046927SAndroid Build Coastguard Worker }
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker bool
is_negative_one() const244*61046927SAndroid Build Coastguard Worker brw_reg::is_negative_one() const
245*61046927SAndroid Build Coastguard Worker {
246*61046927SAndroid Build Coastguard Worker if (file != IMM)
247*61046927SAndroid Build Coastguard Worker return false;
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker assert(brw_type_size_bytes(type) > 1);
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker switch (type) {
252*61046927SAndroid Build Coastguard Worker case BRW_TYPE_HF:
253*61046927SAndroid Build Coastguard Worker assert((d & 0xffff) == ((d >> 16) & 0xffff));
254*61046927SAndroid Build Coastguard Worker return (d & 0xffff) == 0xbc00;
255*61046927SAndroid Build Coastguard Worker case BRW_TYPE_F:
256*61046927SAndroid Build Coastguard Worker return f == -1.0;
257*61046927SAndroid Build Coastguard Worker case BRW_TYPE_DF:
258*61046927SAndroid Build Coastguard Worker return df == -1.0;
259*61046927SAndroid Build Coastguard Worker case BRW_TYPE_W:
260*61046927SAndroid Build Coastguard Worker assert((d & 0xffff) == ((d >> 16) & 0xffff));
261*61046927SAndroid Build Coastguard Worker return (d & 0xffff) == 0xffff;
262*61046927SAndroid Build Coastguard Worker case BRW_TYPE_D:
263*61046927SAndroid Build Coastguard Worker return d == -1;
264*61046927SAndroid Build Coastguard Worker case BRW_TYPE_Q:
265*61046927SAndroid Build Coastguard Worker return d64 == -1;
266*61046927SAndroid Build Coastguard Worker default:
267*61046927SAndroid Build Coastguard Worker return false;
268*61046927SAndroid Build Coastguard Worker }
269*61046927SAndroid Build Coastguard Worker }
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker bool
is_null() const272*61046927SAndroid Build Coastguard Worker brw_reg::is_null() const
273*61046927SAndroid Build Coastguard Worker {
274*61046927SAndroid Build Coastguard Worker return file == ARF && nr == BRW_ARF_NULL;
275*61046927SAndroid Build Coastguard Worker }
276*61046927SAndroid Build Coastguard Worker
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker bool
is_accumulator() const279*61046927SAndroid Build Coastguard Worker brw_reg::is_accumulator() const
280*61046927SAndroid Build Coastguard Worker {
281*61046927SAndroid Build Coastguard Worker return file == ARF && (nr & 0xF0) == BRW_ARF_ACCUMULATOR;
282*61046927SAndroid Build Coastguard Worker }
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker bool
is_commutative() const285*61046927SAndroid Build Coastguard Worker fs_inst::is_commutative() const
286*61046927SAndroid Build Coastguard Worker {
287*61046927SAndroid Build Coastguard Worker switch (opcode) {
288*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_AND:
289*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_OR:
290*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_XOR:
291*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ADD:
292*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ADD3:
293*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_MULH:
294*61046927SAndroid Build Coastguard Worker return true;
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_MUL:
297*61046927SAndroid Build Coastguard Worker /* Integer multiplication of dword and word sources is not actually
298*61046927SAndroid Build Coastguard Worker * commutative. The DW source must be first.
299*61046927SAndroid Build Coastguard Worker */
300*61046927SAndroid Build Coastguard Worker return !brw_type_is_int(src[0].type) ||
301*61046927SAndroid Build Coastguard Worker brw_type_size_bits(src[0].type) == brw_type_size_bits(src[1].type);
302*61046927SAndroid Build Coastguard Worker
303*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_SEL:
304*61046927SAndroid Build Coastguard Worker /* MIN and MAX are commutative. */
305*61046927SAndroid Build Coastguard Worker if (conditional_mod == BRW_CONDITIONAL_GE ||
306*61046927SAndroid Build Coastguard Worker conditional_mod == BRW_CONDITIONAL_L) {
307*61046927SAndroid Build Coastguard Worker return true;
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker FALLTHROUGH;
310*61046927SAndroid Build Coastguard Worker default:
311*61046927SAndroid Build Coastguard Worker return false;
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker bool
is_3src(const struct brw_compiler * compiler) const316*61046927SAndroid Build Coastguard Worker fs_inst::is_3src(const struct brw_compiler *compiler) const
317*61046927SAndroid Build Coastguard Worker {
318*61046927SAndroid Build Coastguard Worker return ::is_3src(&compiler->isa, opcode);
319*61046927SAndroid Build Coastguard Worker }
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker bool
is_math() const322*61046927SAndroid Build Coastguard Worker fs_inst::is_math() const
323*61046927SAndroid Build Coastguard Worker {
324*61046927SAndroid Build Coastguard Worker return (opcode == SHADER_OPCODE_RCP ||
325*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_RSQ ||
326*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_SQRT ||
327*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_EXP2 ||
328*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_LOG2 ||
329*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_SIN ||
330*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_COS ||
331*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_INT_QUOTIENT ||
332*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_INT_REMAINDER ||
333*61046927SAndroid Build Coastguard Worker opcode == SHADER_OPCODE_POW);
334*61046927SAndroid Build Coastguard Worker }
335*61046927SAndroid Build Coastguard Worker
336*61046927SAndroid Build Coastguard Worker bool
is_control_flow_begin() const337*61046927SAndroid Build Coastguard Worker fs_inst::is_control_flow_begin() const
338*61046927SAndroid Build Coastguard Worker {
339*61046927SAndroid Build Coastguard Worker switch (opcode) {
340*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_DO:
341*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_IF:
342*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ELSE:
343*61046927SAndroid Build Coastguard Worker return true;
344*61046927SAndroid Build Coastguard Worker default:
345*61046927SAndroid Build Coastguard Worker return false;
346*61046927SAndroid Build Coastguard Worker }
347*61046927SAndroid Build Coastguard Worker }
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker bool
is_control_flow_end() const350*61046927SAndroid Build Coastguard Worker fs_inst::is_control_flow_end() const
351*61046927SAndroid Build Coastguard Worker {
352*61046927SAndroid Build Coastguard Worker switch (opcode) {
353*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ELSE:
354*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_WHILE:
355*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ENDIF:
356*61046927SAndroid Build Coastguard Worker return true;
357*61046927SAndroid Build Coastguard Worker default:
358*61046927SAndroid Build Coastguard Worker return false;
359*61046927SAndroid Build Coastguard Worker }
360*61046927SAndroid Build Coastguard Worker }
361*61046927SAndroid Build Coastguard Worker
362*61046927SAndroid Build Coastguard Worker bool
is_control_flow() const363*61046927SAndroid Build Coastguard Worker fs_inst::is_control_flow() const
364*61046927SAndroid Build Coastguard Worker {
365*61046927SAndroid Build Coastguard Worker switch (opcode) {
366*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_DO:
367*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_WHILE:
368*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_IF:
369*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ELSE:
370*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ENDIF:
371*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_BREAK:
372*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_CONTINUE:
373*61046927SAndroid Build Coastguard Worker return true;
374*61046927SAndroid Build Coastguard Worker default:
375*61046927SAndroid Build Coastguard Worker return false;
376*61046927SAndroid Build Coastguard Worker }
377*61046927SAndroid Build Coastguard Worker }
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker bool
uses_indirect_addressing() const380*61046927SAndroid Build Coastguard Worker fs_inst::uses_indirect_addressing() const
381*61046927SAndroid Build Coastguard Worker {
382*61046927SAndroid Build Coastguard Worker switch (opcode) {
383*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_BROADCAST:
384*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_CLUSTER_BROADCAST:
385*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_MOV_INDIRECT:
386*61046927SAndroid Build Coastguard Worker return true;
387*61046927SAndroid Build Coastguard Worker default:
388*61046927SAndroid Build Coastguard Worker return false;
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker }
391*61046927SAndroid Build Coastguard Worker
392*61046927SAndroid Build Coastguard Worker bool
can_do_saturate() const393*61046927SAndroid Build Coastguard Worker fs_inst::can_do_saturate() const
394*61046927SAndroid Build Coastguard Worker {
395*61046927SAndroid Build Coastguard Worker switch (opcode) {
396*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ADD:
397*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ADD3:
398*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_ASR:
399*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_AVG:
400*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_CSEL:
401*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_DP2:
402*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_DP3:
403*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_DP4:
404*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_DPH:
405*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_DP4A:
406*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_LINE:
407*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_LRP:
408*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_MAC:
409*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_MAD:
410*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_MATH:
411*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_MOV:
412*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_MUL:
413*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_MULH:
414*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_PLN:
415*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_RNDD:
416*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_RNDE:
417*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_RNDU:
418*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_RNDZ:
419*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_SEL:
420*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_SHL:
421*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_SHR:
422*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_COS:
423*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_EXP2:
424*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_LOG2:
425*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_POW:
426*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_RCP:
427*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_RSQ:
428*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_SIN:
429*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_SQRT:
430*61046927SAndroid Build Coastguard Worker return true;
431*61046927SAndroid Build Coastguard Worker default:
432*61046927SAndroid Build Coastguard Worker return false;
433*61046927SAndroid Build Coastguard Worker }
434*61046927SAndroid Build Coastguard Worker }
435*61046927SAndroid Build Coastguard Worker
436*61046927SAndroid Build Coastguard Worker bool
reads_accumulator_implicitly() const437*61046927SAndroid Build Coastguard Worker fs_inst::reads_accumulator_implicitly() const
438*61046927SAndroid Build Coastguard Worker {
439*61046927SAndroid Build Coastguard Worker switch (opcode) {
440*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_MAC:
441*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_MACH:
442*61046927SAndroid Build Coastguard Worker return true;
443*61046927SAndroid Build Coastguard Worker default:
444*61046927SAndroid Build Coastguard Worker return false;
445*61046927SAndroid Build Coastguard Worker }
446*61046927SAndroid Build Coastguard Worker }
447*61046927SAndroid Build Coastguard Worker
448*61046927SAndroid Build Coastguard Worker bool
writes_accumulator_implicitly(const struct intel_device_info * devinfo) const449*61046927SAndroid Build Coastguard Worker fs_inst::writes_accumulator_implicitly(const struct intel_device_info *devinfo) const
450*61046927SAndroid Build Coastguard Worker {
451*61046927SAndroid Build Coastguard Worker return writes_accumulator ||
452*61046927SAndroid Build Coastguard Worker (eot && intel_needs_workaround(devinfo, 14010017096));
453*61046927SAndroid Build Coastguard Worker }
454*61046927SAndroid Build Coastguard Worker
455*61046927SAndroid Build Coastguard Worker bool
has_side_effects() const456*61046927SAndroid Build Coastguard Worker fs_inst::has_side_effects() const
457*61046927SAndroid Build Coastguard Worker {
458*61046927SAndroid Build Coastguard Worker switch (opcode) {
459*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_SEND:
460*61046927SAndroid Build Coastguard Worker return send_has_side_effects;
461*61046927SAndroid Build Coastguard Worker
462*61046927SAndroid Build Coastguard Worker case BRW_OPCODE_SYNC:
463*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_MEMORY_STORE_LOGICAL:
464*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_MEMORY_ATOMIC_LOGICAL:
465*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_MEMORY_FENCE:
466*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_INTERLOCK:
467*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_URB_WRITE_LOGICAL:
468*61046927SAndroid Build Coastguard Worker case FS_OPCODE_FB_WRITE_LOGICAL:
469*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_BARRIER:
470*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_RND_MODE:
471*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_FLOAT_CONTROL_MODE:
472*61046927SAndroid Build Coastguard Worker case FS_OPCODE_SCHEDULING_FENCE:
473*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_BTD_SPAWN_LOGICAL:
474*61046927SAndroid Build Coastguard Worker case SHADER_OPCODE_BTD_RETIRE_LOGICAL:
475*61046927SAndroid Build Coastguard Worker case RT_OPCODE_TRACE_RAY_LOGICAL:
476*61046927SAndroid Build Coastguard Worker return true;
477*61046927SAndroid Build Coastguard Worker default:
478*61046927SAndroid Build Coastguard Worker return eot;
479*61046927SAndroid Build Coastguard Worker }
480*61046927SAndroid Build Coastguard Worker }
481*61046927SAndroid Build Coastguard Worker
482*61046927SAndroid Build Coastguard Worker bool
is_volatile() const483*61046927SAndroid Build Coastguard Worker fs_inst::is_volatile() const
484*61046927SAndroid Build Coastguard Worker {
485*61046927SAndroid Build Coastguard Worker return opcode == SHADER_OPCODE_MEMORY_LOAD_LOGICAL ||
486*61046927SAndroid Build Coastguard Worker (opcode == SHADER_OPCODE_SEND && send_is_volatile);
487*61046927SAndroid Build Coastguard Worker }
488*61046927SAndroid Build Coastguard Worker
489*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
490*61046927SAndroid Build Coastguard Worker static bool
inst_is_in_block(const bblock_t * block,const fs_inst * inst)491*61046927SAndroid Build Coastguard Worker inst_is_in_block(const bblock_t *block, const fs_inst *inst)
492*61046927SAndroid Build Coastguard Worker {
493*61046927SAndroid Build Coastguard Worker const exec_node *n = inst;
494*61046927SAndroid Build Coastguard Worker
495*61046927SAndroid Build Coastguard Worker /* Find the tail sentinel. If the tail sentinel is the sentinel from the
496*61046927SAndroid Build Coastguard Worker * list header in the bblock_t, then this instruction is in that basic
497*61046927SAndroid Build Coastguard Worker * block.
498*61046927SAndroid Build Coastguard Worker */
499*61046927SAndroid Build Coastguard Worker while (!n->is_tail_sentinel())
500*61046927SAndroid Build Coastguard Worker n = n->get_next();
501*61046927SAndroid Build Coastguard Worker
502*61046927SAndroid Build Coastguard Worker return n == &block->instructions.tail_sentinel;
503*61046927SAndroid Build Coastguard Worker }
504*61046927SAndroid Build Coastguard Worker #endif
505*61046927SAndroid Build Coastguard Worker
506*61046927SAndroid Build Coastguard Worker static void
adjust_later_block_ips(bblock_t * start_block,int ip_adjustment)507*61046927SAndroid Build Coastguard Worker adjust_later_block_ips(bblock_t *start_block, int ip_adjustment)
508*61046927SAndroid Build Coastguard Worker {
509*61046927SAndroid Build Coastguard Worker for (bblock_t *block_iter = start_block->next();
510*61046927SAndroid Build Coastguard Worker block_iter;
511*61046927SAndroid Build Coastguard Worker block_iter = block_iter->next()) {
512*61046927SAndroid Build Coastguard Worker block_iter->start_ip += ip_adjustment;
513*61046927SAndroid Build Coastguard Worker block_iter->end_ip += ip_adjustment;
514*61046927SAndroid Build Coastguard Worker }
515*61046927SAndroid Build Coastguard Worker }
516*61046927SAndroid Build Coastguard Worker
517*61046927SAndroid Build Coastguard Worker void
insert_after(bblock_t * block,fs_inst * inst)518*61046927SAndroid Build Coastguard Worker fs_inst::insert_after(bblock_t *block, fs_inst *inst)
519*61046927SAndroid Build Coastguard Worker {
520*61046927SAndroid Build Coastguard Worker assert(this != inst);
521*61046927SAndroid Build Coastguard Worker assert(block->end_ip_delta == 0);
522*61046927SAndroid Build Coastguard Worker
523*61046927SAndroid Build Coastguard Worker if (!this->is_head_sentinel())
524*61046927SAndroid Build Coastguard Worker assert(inst_is_in_block(block, this) || !"Instruction not in block");
525*61046927SAndroid Build Coastguard Worker
526*61046927SAndroid Build Coastguard Worker block->end_ip++;
527*61046927SAndroid Build Coastguard Worker
528*61046927SAndroid Build Coastguard Worker adjust_later_block_ips(block, 1);
529*61046927SAndroid Build Coastguard Worker
530*61046927SAndroid Build Coastguard Worker exec_node::insert_after(inst);
531*61046927SAndroid Build Coastguard Worker }
532*61046927SAndroid Build Coastguard Worker
533*61046927SAndroid Build Coastguard Worker void
insert_before(bblock_t * block,fs_inst * inst)534*61046927SAndroid Build Coastguard Worker fs_inst::insert_before(bblock_t *block, fs_inst *inst)
535*61046927SAndroid Build Coastguard Worker {
536*61046927SAndroid Build Coastguard Worker assert(this != inst);
537*61046927SAndroid Build Coastguard Worker assert(block->end_ip_delta == 0);
538*61046927SAndroid Build Coastguard Worker
539*61046927SAndroid Build Coastguard Worker if (!this->is_tail_sentinel())
540*61046927SAndroid Build Coastguard Worker assert(inst_is_in_block(block, this) || !"Instruction not in block");
541*61046927SAndroid Build Coastguard Worker
542*61046927SAndroid Build Coastguard Worker block->end_ip++;
543*61046927SAndroid Build Coastguard Worker
544*61046927SAndroid Build Coastguard Worker adjust_later_block_ips(block, 1);
545*61046927SAndroid Build Coastguard Worker
546*61046927SAndroid Build Coastguard Worker exec_node::insert_before(inst);
547*61046927SAndroid Build Coastguard Worker }
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker void
remove(bblock_t * block,bool defer_later_block_ip_updates)550*61046927SAndroid Build Coastguard Worker fs_inst::remove(bblock_t *block, bool defer_later_block_ip_updates)
551*61046927SAndroid Build Coastguard Worker {
552*61046927SAndroid Build Coastguard Worker assert(inst_is_in_block(block, this) || !"Instruction not in block");
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker if (exec_list_is_singular(&block->instructions)) {
555*61046927SAndroid Build Coastguard Worker this->opcode = BRW_OPCODE_NOP;
556*61046927SAndroid Build Coastguard Worker this->resize_sources(0);
557*61046927SAndroid Build Coastguard Worker this->dst = brw_reg();
558*61046927SAndroid Build Coastguard Worker this->size_written = 0;
559*61046927SAndroid Build Coastguard Worker return;
560*61046927SAndroid Build Coastguard Worker }
561*61046927SAndroid Build Coastguard Worker
562*61046927SAndroid Build Coastguard Worker if (defer_later_block_ip_updates) {
563*61046927SAndroid Build Coastguard Worker block->end_ip_delta--;
564*61046927SAndroid Build Coastguard Worker } else {
565*61046927SAndroid Build Coastguard Worker assert(block->end_ip_delta == 0);
566*61046927SAndroid Build Coastguard Worker adjust_later_block_ips(block, -1);
567*61046927SAndroid Build Coastguard Worker }
568*61046927SAndroid Build Coastguard Worker
569*61046927SAndroid Build Coastguard Worker if (block->start_ip == block->end_ip) {
570*61046927SAndroid Build Coastguard Worker if (block->end_ip_delta != 0) {
571*61046927SAndroid Build Coastguard Worker adjust_later_block_ips(block, block->end_ip_delta);
572*61046927SAndroid Build Coastguard Worker block->end_ip_delta = 0;
573*61046927SAndroid Build Coastguard Worker }
574*61046927SAndroid Build Coastguard Worker
575*61046927SAndroid Build Coastguard Worker block->cfg->remove_block(block);
576*61046927SAndroid Build Coastguard Worker } else {
577*61046927SAndroid Build Coastguard Worker block->end_ip--;
578*61046927SAndroid Build Coastguard Worker }
579*61046927SAndroid Build Coastguard Worker
580*61046927SAndroid Build Coastguard Worker exec_node::remove();
581*61046927SAndroid Build Coastguard Worker }
582*61046927SAndroid Build Coastguard Worker
583