2 * Copyright (C) 2020 Collabora Ltd.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * Authors (Collabora):
24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
29 /* Does an instruction respect outmods and source mods? Depend
30 * on the types involved */
33 bi_has_outmod(bi_instruction
*ins
)
35 bool classy
= bi_class_props
[ins
->type
] & BI_MODS
;
36 bool floaty
= nir_alu_type_get_base_type(ins
->dest_type
) == nir_type_float
;
38 return classy
&& floaty
;
41 /* Have to check source for e.g. compares */
44 bi_has_source_mods(bi_instruction
*ins
)
46 bool classy
= bi_class_props
[ins
->type
] & BI_MODS
;
47 bool floaty
= nir_alu_type_get_base_type(ins
->src_types
[0]) == nir_type_float
;
49 return classy
&& floaty
;
52 /* A source is swizzled if the op is swizzlable, in 8-bit or
53 * 16-bit mode, and the swizzled op. TODO: multi args */
56 bi_is_src_swizzled(bi_instruction
*ins
, unsigned s
)
58 bool classy
= bi_class_props
[ins
->type
] & BI_SWIZZLABLE
;
59 bool small
= nir_alu_type_get_type_size(ins
->dest_type
) < 32;
60 bool first
= (s
== 0); /* TODO: prop? */
62 return classy
&& small
&& first
;
66 bi_has_arg(bi_instruction
*ins
, unsigned arg
)
71 bi_foreach_src(ins
, s
) {
72 if (ins
->src
[s
] == arg
)
80 bi_from_bytemask(uint16_t bytemask
, unsigned bytes
)
84 for (unsigned c
= 0, d
= 0; c
< 16; c
+= bytes
, ++d
) {
85 bool a
= (bytemask
& (1 << c
)) != 0;
87 for (unsigned q
= c
; q
< bytes
; ++q
)
88 assert(((bytemask
& (1 << q
)) != 0) == a
);
97 bi_get_component_count(bi_instruction
*ins
, signed src
)
99 /* Discards and branches are oddball since they're not BI_VECTOR but no
100 * destination. So special case.. */
101 if (ins
->type
== BI_DISCARD
|| ins
->type
== BI_BRANCH
)
104 if (bi_class_props
[ins
->type
] & BI_VECTOR
) {
105 assert(ins
->vector_channels
);
106 return (src
<= 0) ? ins
->vector_channels
: 1;
108 unsigned bytes
= nir_alu_type_get_type_size(src
< 0 ? ins
->dest_type
: ins
->src_types
[src
]);
110 if (ins
->type
== BI_ATEST
|| ins
->type
== BI_SELECT
)
113 return MAX2(32 / bytes
, 1);
118 bi_bytemask_of_read_components(bi_instruction
*ins
, unsigned node
)
122 bi_foreach_src(ins
, s
) {
123 if (ins
->src
[s
] != node
) continue;
124 unsigned component_count
= bi_get_component_count(ins
, s
);
125 nir_alu_type T
= ins
->src_types
[s
];
126 unsigned size
= nir_alu_type_get_type_size(T
);
127 unsigned bytes
= size
/ 8;
128 unsigned cmask
= (1 << bytes
) - 1;
130 for (unsigned i
= 0; i
< component_count
; ++i
) {
131 unsigned c
= ins
->swizzle
[s
][i
];
132 mask
|= (cmask
<< (c
* bytes
));
140 bi_get_immediate(bi_instruction
*ins
, unsigned index
)
142 unsigned v
= ins
->src
[index
];
143 assert(v
& BIR_INDEX_CONSTANT
);
144 unsigned shift
= v
& ~BIR_INDEX_CONSTANT
;
145 uint64_t shifted
= ins
->constant
.u64
>> shift
;
147 /* Mask off the accessed part */
148 unsigned sz
= nir_alu_type_get_type_size(ins
->src_types
[index
]);
153 return shifted
& ((1ull << sz
) - 1);
157 bi_writes_component(bi_instruction
*ins
, unsigned comp
)
159 return comp
< bi_get_component_count(ins
, -1);
163 bi_writemask(bi_instruction
*ins
)
165 nir_alu_type T
= ins
->dest_type
;
166 unsigned size
= nir_alu_type_get_type_size(T
);
167 unsigned bytes_per_comp
= size
/ 8;
168 unsigned components
= bi_get_component_count(ins
, -1);
169 unsigned bytes
= bytes_per_comp
* components
;
170 unsigned mask
= (1 << bytes
) - 1;
171 unsigned shift
= ins
->dest_offset
* 4; /* 32-bit words */
172 return (mask
<< shift
);