xref: /aosp_15_r20/external/igt-gpu-tools/assembler/brw_eu_compact.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2012 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  */
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker /** @file brw_eu_compact.c
25*d83cc019SAndroid Build Coastguard Worker  *
26*d83cc019SAndroid Build Coastguard Worker  * Instruction compaction is a feature of gm45 and newer hardware that allows
27*d83cc019SAndroid Build Coastguard Worker  * for a smaller instruction encoding.
28*d83cc019SAndroid Build Coastguard Worker  *
29*d83cc019SAndroid Build Coastguard Worker  * The instruction cache is on the order of 32KB, and many programs generate
30*d83cc019SAndroid Build Coastguard Worker  * far more instructions than that.  The instruction cache is built to barely
31*d83cc019SAndroid Build Coastguard Worker  * keep up with instruction dispatch abaility in cache hit cases -- L1
32*d83cc019SAndroid Build Coastguard Worker  * instruction cache misses that still hit in the next level could limit
33*d83cc019SAndroid Build Coastguard Worker  * throughput by around 50%.
34*d83cc019SAndroid Build Coastguard Worker  *
35*d83cc019SAndroid Build Coastguard Worker  * The idea of instruction compaction is that most instructions use a tiny
36*d83cc019SAndroid Build Coastguard Worker  * subset of the GPU functionality, so we can encode what would be a 16 byte
37*d83cc019SAndroid Build Coastguard Worker  * instruction in 8 bytes using some lookup tables for various fields.
38*d83cc019SAndroid Build Coastguard Worker  */
39*d83cc019SAndroid Build Coastguard Worker 
40*d83cc019SAndroid Build Coastguard Worker #include <string.h>
41*d83cc019SAndroid Build Coastguard Worker 
42*d83cc019SAndroid Build Coastguard Worker #include "brw_compat.h"
43*d83cc019SAndroid Build Coastguard Worker #include "brw_context.h"
44*d83cc019SAndroid Build Coastguard Worker #include "brw_eu.h"
45*d83cc019SAndroid Build Coastguard Worker 
46*d83cc019SAndroid Build Coastguard Worker static const uint32_t gen6_control_index_table[32] = {
47*d83cc019SAndroid Build Coastguard Worker    0b00000000000000000,
48*d83cc019SAndroid Build Coastguard Worker    0b01000000000000000,
49*d83cc019SAndroid Build Coastguard Worker    0b00110000000000000,
50*d83cc019SAndroid Build Coastguard Worker    0b00000000100000000,
51*d83cc019SAndroid Build Coastguard Worker    0b00010000000000000,
52*d83cc019SAndroid Build Coastguard Worker    0b00001000100000000,
53*d83cc019SAndroid Build Coastguard Worker    0b00000000100000010,
54*d83cc019SAndroid Build Coastguard Worker    0b00000000000000010,
55*d83cc019SAndroid Build Coastguard Worker    0b01000000100000000,
56*d83cc019SAndroid Build Coastguard Worker    0b01010000000000000,
57*d83cc019SAndroid Build Coastguard Worker    0b10110000000000000,
58*d83cc019SAndroid Build Coastguard Worker    0b00100000000000000,
59*d83cc019SAndroid Build Coastguard Worker    0b11010000000000000,
60*d83cc019SAndroid Build Coastguard Worker    0b11000000000000000,
61*d83cc019SAndroid Build Coastguard Worker    0b01001000100000000,
62*d83cc019SAndroid Build Coastguard Worker    0b01000000000001000,
63*d83cc019SAndroid Build Coastguard Worker    0b01000000000000100,
64*d83cc019SAndroid Build Coastguard Worker    0b00000000000001000,
65*d83cc019SAndroid Build Coastguard Worker    0b00000000000000100,
66*d83cc019SAndroid Build Coastguard Worker    0b00111000100000000,
67*d83cc019SAndroid Build Coastguard Worker    0b00001000100000010,
68*d83cc019SAndroid Build Coastguard Worker    0b00110000100000000,
69*d83cc019SAndroid Build Coastguard Worker    0b00110000000000001,
70*d83cc019SAndroid Build Coastguard Worker    0b00100000000000001,
71*d83cc019SAndroid Build Coastguard Worker    0b00110000000000010,
72*d83cc019SAndroid Build Coastguard Worker    0b00110000000000101,
73*d83cc019SAndroid Build Coastguard Worker    0b00110000000001001,
74*d83cc019SAndroid Build Coastguard Worker    0b00110000000010000,
75*d83cc019SAndroid Build Coastguard Worker    0b00110000000000011,
76*d83cc019SAndroid Build Coastguard Worker    0b00110000000000100,
77*d83cc019SAndroid Build Coastguard Worker    0b00110000100001000,
78*d83cc019SAndroid Build Coastguard Worker    0b00100000000001001
79*d83cc019SAndroid Build Coastguard Worker };
80*d83cc019SAndroid Build Coastguard Worker 
81*d83cc019SAndroid Build Coastguard Worker static const uint32_t gen6_datatype_table[32] = {
82*d83cc019SAndroid Build Coastguard Worker    0b001001110000000000,
83*d83cc019SAndroid Build Coastguard Worker    0b001000110000100000,
84*d83cc019SAndroid Build Coastguard Worker    0b001001110000000001,
85*d83cc019SAndroid Build Coastguard Worker    0b001000000001100000,
86*d83cc019SAndroid Build Coastguard Worker    0b001010110100101001,
87*d83cc019SAndroid Build Coastguard Worker    0b001000000110101101,
88*d83cc019SAndroid Build Coastguard Worker    0b001100011000101100,
89*d83cc019SAndroid Build Coastguard Worker    0b001011110110101101,
90*d83cc019SAndroid Build Coastguard Worker    0b001000000111101100,
91*d83cc019SAndroid Build Coastguard Worker    0b001000000001100001,
92*d83cc019SAndroid Build Coastguard Worker    0b001000110010100101,
93*d83cc019SAndroid Build Coastguard Worker    0b001000000001000001,
94*d83cc019SAndroid Build Coastguard Worker    0b001000001000110001,
95*d83cc019SAndroid Build Coastguard Worker    0b001000001000101001,
96*d83cc019SAndroid Build Coastguard Worker    0b001000000000100000,
97*d83cc019SAndroid Build Coastguard Worker    0b001000001000110010,
98*d83cc019SAndroid Build Coastguard Worker    0b001010010100101001,
99*d83cc019SAndroid Build Coastguard Worker    0b001011010010100101,
100*d83cc019SAndroid Build Coastguard Worker    0b001000000110100101,
101*d83cc019SAndroid Build Coastguard Worker    0b001100011000101001,
102*d83cc019SAndroid Build Coastguard Worker    0b001011011000101100,
103*d83cc019SAndroid Build Coastguard Worker    0b001011010110100101,
104*d83cc019SAndroid Build Coastguard Worker    0b001011110110100101,
105*d83cc019SAndroid Build Coastguard Worker    0b001111011110111101,
106*d83cc019SAndroid Build Coastguard Worker    0b001111011110111100,
107*d83cc019SAndroid Build Coastguard Worker    0b001111011110111101,
108*d83cc019SAndroid Build Coastguard Worker    0b001111011110011101,
109*d83cc019SAndroid Build Coastguard Worker    0b001111011110111110,
110*d83cc019SAndroid Build Coastguard Worker    0b001000000000100001,
111*d83cc019SAndroid Build Coastguard Worker    0b001000000000100010,
112*d83cc019SAndroid Build Coastguard Worker    0b001001111111011101,
113*d83cc019SAndroid Build Coastguard Worker    0b001000001110111110,
114*d83cc019SAndroid Build Coastguard Worker };
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker static const uint32_t gen6_subreg_table[32] = {
117*d83cc019SAndroid Build Coastguard Worker    0b000000000000000,
118*d83cc019SAndroid Build Coastguard Worker    0b000000000000100,
119*d83cc019SAndroid Build Coastguard Worker    0b000000110000000,
120*d83cc019SAndroid Build Coastguard Worker    0b111000000000000,
121*d83cc019SAndroid Build Coastguard Worker    0b011110000001000,
122*d83cc019SAndroid Build Coastguard Worker    0b000010000000000,
123*d83cc019SAndroid Build Coastguard Worker    0b000000000010000,
124*d83cc019SAndroid Build Coastguard Worker    0b000110000001100,
125*d83cc019SAndroid Build Coastguard Worker    0b001000000000000,
126*d83cc019SAndroid Build Coastguard Worker    0b000001000000000,
127*d83cc019SAndroid Build Coastguard Worker    0b000001010010100,
128*d83cc019SAndroid Build Coastguard Worker    0b000000001010110,
129*d83cc019SAndroid Build Coastguard Worker    0b010000000000000,
130*d83cc019SAndroid Build Coastguard Worker    0b110000000000000,
131*d83cc019SAndroid Build Coastguard Worker    0b000100000000000,
132*d83cc019SAndroid Build Coastguard Worker    0b000000010000000,
133*d83cc019SAndroid Build Coastguard Worker    0b000000000001000,
134*d83cc019SAndroid Build Coastguard Worker    0b100000000000000,
135*d83cc019SAndroid Build Coastguard Worker    0b000001010000000,
136*d83cc019SAndroid Build Coastguard Worker    0b001010000000000,
137*d83cc019SAndroid Build Coastguard Worker    0b001100000000000,
138*d83cc019SAndroid Build Coastguard Worker    0b000000001010100,
139*d83cc019SAndroid Build Coastguard Worker    0b101101010010100,
140*d83cc019SAndroid Build Coastguard Worker    0b010100000000000,
141*d83cc019SAndroid Build Coastguard Worker    0b000000010001111,
142*d83cc019SAndroid Build Coastguard Worker    0b011000000000000,
143*d83cc019SAndroid Build Coastguard Worker    0b111110000000000,
144*d83cc019SAndroid Build Coastguard Worker    0b101000000000000,
145*d83cc019SAndroid Build Coastguard Worker    0b000000000001111,
146*d83cc019SAndroid Build Coastguard Worker    0b000100010001111,
147*d83cc019SAndroid Build Coastguard Worker    0b001000010001111,
148*d83cc019SAndroid Build Coastguard Worker    0b000110000000000,
149*d83cc019SAndroid Build Coastguard Worker };
150*d83cc019SAndroid Build Coastguard Worker 
151*d83cc019SAndroid Build Coastguard Worker static const uint32_t gen6_src_index_table[32] = {
152*d83cc019SAndroid Build Coastguard Worker    0b000000000000,
153*d83cc019SAndroid Build Coastguard Worker    0b010110001000,
154*d83cc019SAndroid Build Coastguard Worker    0b010001101000,
155*d83cc019SAndroid Build Coastguard Worker    0b001000101000,
156*d83cc019SAndroid Build Coastguard Worker    0b011010010000,
157*d83cc019SAndroid Build Coastguard Worker    0b000100100000,
158*d83cc019SAndroid Build Coastguard Worker    0b010001101100,
159*d83cc019SAndroid Build Coastguard Worker    0b010101110000,
160*d83cc019SAndroid Build Coastguard Worker    0b011001111000,
161*d83cc019SAndroid Build Coastguard Worker    0b001100101000,
162*d83cc019SAndroid Build Coastguard Worker    0b010110001100,
163*d83cc019SAndroid Build Coastguard Worker    0b001000100000,
164*d83cc019SAndroid Build Coastguard Worker    0b010110001010,
165*d83cc019SAndroid Build Coastguard Worker    0b000000000010,
166*d83cc019SAndroid Build Coastguard Worker    0b010101010000,
167*d83cc019SAndroid Build Coastguard Worker    0b010101101000,
168*d83cc019SAndroid Build Coastguard Worker    0b111101001100,
169*d83cc019SAndroid Build Coastguard Worker    0b111100101100,
170*d83cc019SAndroid Build Coastguard Worker    0b011001110000,
171*d83cc019SAndroid Build Coastguard Worker    0b010110001001,
172*d83cc019SAndroid Build Coastguard Worker    0b010101011000,
173*d83cc019SAndroid Build Coastguard Worker    0b001101001000,
174*d83cc019SAndroid Build Coastguard Worker    0b010000101100,
175*d83cc019SAndroid Build Coastguard Worker    0b010000000000,
176*d83cc019SAndroid Build Coastguard Worker    0b001101110000,
177*d83cc019SAndroid Build Coastguard Worker    0b001100010000,
178*d83cc019SAndroid Build Coastguard Worker    0b001100000000,
179*d83cc019SAndroid Build Coastguard Worker    0b010001101010,
180*d83cc019SAndroid Build Coastguard Worker    0b001101111000,
181*d83cc019SAndroid Build Coastguard Worker    0b000001110000,
182*d83cc019SAndroid Build Coastguard Worker    0b001100100000,
183*d83cc019SAndroid Build Coastguard Worker    0b001101010000,
184*d83cc019SAndroid Build Coastguard Worker };
185*d83cc019SAndroid Build Coastguard Worker 
186*d83cc019SAndroid Build Coastguard Worker static const uint32_t gen7_control_index_table[32] = {
187*d83cc019SAndroid Build Coastguard Worker    0b0000000000000000010,
188*d83cc019SAndroid Build Coastguard Worker    0b0000100000000000000,
189*d83cc019SAndroid Build Coastguard Worker    0b0000100000000000001,
190*d83cc019SAndroid Build Coastguard Worker    0b0000100000000000010,
191*d83cc019SAndroid Build Coastguard Worker    0b0000100000000000011,
192*d83cc019SAndroid Build Coastguard Worker    0b0000100000000000100,
193*d83cc019SAndroid Build Coastguard Worker    0b0000100000000000101,
194*d83cc019SAndroid Build Coastguard Worker    0b0000100000000000111,
195*d83cc019SAndroid Build Coastguard Worker    0b0000100000000001000,
196*d83cc019SAndroid Build Coastguard Worker    0b0000100000000001001,
197*d83cc019SAndroid Build Coastguard Worker    0b0000100000000001101,
198*d83cc019SAndroid Build Coastguard Worker    0b0000110000000000000,
199*d83cc019SAndroid Build Coastguard Worker    0b0000110000000000001,
200*d83cc019SAndroid Build Coastguard Worker    0b0000110000000000010,
201*d83cc019SAndroid Build Coastguard Worker    0b0000110000000000011,
202*d83cc019SAndroid Build Coastguard Worker    0b0000110000000000100,
203*d83cc019SAndroid Build Coastguard Worker    0b0000110000000000101,
204*d83cc019SAndroid Build Coastguard Worker    0b0000110000000000111,
205*d83cc019SAndroid Build Coastguard Worker    0b0000110000000001001,
206*d83cc019SAndroid Build Coastguard Worker    0b0000110000000001101,
207*d83cc019SAndroid Build Coastguard Worker    0b0000110000000010000,
208*d83cc019SAndroid Build Coastguard Worker    0b0000110000100000000,
209*d83cc019SAndroid Build Coastguard Worker    0b0001000000000000000,
210*d83cc019SAndroid Build Coastguard Worker    0b0001000000000000010,
211*d83cc019SAndroid Build Coastguard Worker    0b0001000000000000100,
212*d83cc019SAndroid Build Coastguard Worker    0b0001000000100000000,
213*d83cc019SAndroid Build Coastguard Worker    0b0010110000000000000,
214*d83cc019SAndroid Build Coastguard Worker    0b0010110000000010000,
215*d83cc019SAndroid Build Coastguard Worker    0b0011000000000000000,
216*d83cc019SAndroid Build Coastguard Worker    0b0011000000100000000,
217*d83cc019SAndroid Build Coastguard Worker    0b0101000000000000000,
218*d83cc019SAndroid Build Coastguard Worker    0b0101000000100000000
219*d83cc019SAndroid Build Coastguard Worker };
220*d83cc019SAndroid Build Coastguard Worker 
221*d83cc019SAndroid Build Coastguard Worker static const uint32_t gen7_datatype_table[32] = {
222*d83cc019SAndroid Build Coastguard Worker    0b001000000000000001,
223*d83cc019SAndroid Build Coastguard Worker    0b001000000000100000,
224*d83cc019SAndroid Build Coastguard Worker    0b001000000000100001,
225*d83cc019SAndroid Build Coastguard Worker    0b001000000001100001,
226*d83cc019SAndroid Build Coastguard Worker    0b001000000010111101,
227*d83cc019SAndroid Build Coastguard Worker    0b001000001011111101,
228*d83cc019SAndroid Build Coastguard Worker    0b001000001110100001,
229*d83cc019SAndroid Build Coastguard Worker    0b001000001110100101,
230*d83cc019SAndroid Build Coastguard Worker    0b001000001110111101,
231*d83cc019SAndroid Build Coastguard Worker    0b001000010000100001,
232*d83cc019SAndroid Build Coastguard Worker    0b001000110000100000,
233*d83cc019SAndroid Build Coastguard Worker    0b001000110000100001,
234*d83cc019SAndroid Build Coastguard Worker    0b001001010010100101,
235*d83cc019SAndroid Build Coastguard Worker    0b001001110010100100,
236*d83cc019SAndroid Build Coastguard Worker    0b001001110010100101,
237*d83cc019SAndroid Build Coastguard Worker    0b001111001110111101,
238*d83cc019SAndroid Build Coastguard Worker    0b001111011110011101,
239*d83cc019SAndroid Build Coastguard Worker    0b001111011110111100,
240*d83cc019SAndroid Build Coastguard Worker    0b001111011110111101,
241*d83cc019SAndroid Build Coastguard Worker    0b001111111110111100,
242*d83cc019SAndroid Build Coastguard Worker    0b000000001000001100,
243*d83cc019SAndroid Build Coastguard Worker    0b001000000000111101,
244*d83cc019SAndroid Build Coastguard Worker    0b001000000010100101,
245*d83cc019SAndroid Build Coastguard Worker    0b001000010000100000,
246*d83cc019SAndroid Build Coastguard Worker    0b001001010010100100,
247*d83cc019SAndroid Build Coastguard Worker    0b001001110010000100,
248*d83cc019SAndroid Build Coastguard Worker    0b001010010100001001,
249*d83cc019SAndroid Build Coastguard Worker    0b001101111110111101,
250*d83cc019SAndroid Build Coastguard Worker    0b001111111110111101,
251*d83cc019SAndroid Build Coastguard Worker    0b001011110110101100,
252*d83cc019SAndroid Build Coastguard Worker    0b001010010100101000,
253*d83cc019SAndroid Build Coastguard Worker    0b001010110100101000
254*d83cc019SAndroid Build Coastguard Worker };
255*d83cc019SAndroid Build Coastguard Worker 
256*d83cc019SAndroid Build Coastguard Worker static const uint32_t gen7_subreg_table[32] = {
257*d83cc019SAndroid Build Coastguard Worker    0b000000000000000,
258*d83cc019SAndroid Build Coastguard Worker    0b000000000000001,
259*d83cc019SAndroid Build Coastguard Worker    0b000000000001000,
260*d83cc019SAndroid Build Coastguard Worker    0b000000000001111,
261*d83cc019SAndroid Build Coastguard Worker    0b000000000010000,
262*d83cc019SAndroid Build Coastguard Worker    0b000000010000000,
263*d83cc019SAndroid Build Coastguard Worker    0b000000100000000,
264*d83cc019SAndroid Build Coastguard Worker    0b000000110000000,
265*d83cc019SAndroid Build Coastguard Worker    0b000001000000000,
266*d83cc019SAndroid Build Coastguard Worker    0b000001000010000,
267*d83cc019SAndroid Build Coastguard Worker    0b000010100000000,
268*d83cc019SAndroid Build Coastguard Worker    0b001000000000000,
269*d83cc019SAndroid Build Coastguard Worker    0b001000000000001,
270*d83cc019SAndroid Build Coastguard Worker    0b001000010000001,
271*d83cc019SAndroid Build Coastguard Worker    0b001000010000010,
272*d83cc019SAndroid Build Coastguard Worker    0b001000010000011,
273*d83cc019SAndroid Build Coastguard Worker    0b001000010000100,
274*d83cc019SAndroid Build Coastguard Worker    0b001000010000111,
275*d83cc019SAndroid Build Coastguard Worker    0b001000010001000,
276*d83cc019SAndroid Build Coastguard Worker    0b001000010001110,
277*d83cc019SAndroid Build Coastguard Worker    0b001000010001111,
278*d83cc019SAndroid Build Coastguard Worker    0b001000110000000,
279*d83cc019SAndroid Build Coastguard Worker    0b001000111101000,
280*d83cc019SAndroid Build Coastguard Worker    0b010000000000000,
281*d83cc019SAndroid Build Coastguard Worker    0b010000110000000,
282*d83cc019SAndroid Build Coastguard Worker    0b011000000000000,
283*d83cc019SAndroid Build Coastguard Worker    0b011110010000111,
284*d83cc019SAndroid Build Coastguard Worker    0b100000000000000,
285*d83cc019SAndroid Build Coastguard Worker    0b101000000000000,
286*d83cc019SAndroid Build Coastguard Worker    0b110000000000000,
287*d83cc019SAndroid Build Coastguard Worker    0b111000000000000,
288*d83cc019SAndroid Build Coastguard Worker    0b111000000011100
289*d83cc019SAndroid Build Coastguard Worker };
290*d83cc019SAndroid Build Coastguard Worker 
291*d83cc019SAndroid Build Coastguard Worker static const uint32_t gen7_src_index_table[32] = {
292*d83cc019SAndroid Build Coastguard Worker    0b000000000000,
293*d83cc019SAndroid Build Coastguard Worker    0b000000000010,
294*d83cc019SAndroid Build Coastguard Worker    0b000000010000,
295*d83cc019SAndroid Build Coastguard Worker    0b000000010010,
296*d83cc019SAndroid Build Coastguard Worker    0b000000011000,
297*d83cc019SAndroid Build Coastguard Worker    0b000000100000,
298*d83cc019SAndroid Build Coastguard Worker    0b000000101000,
299*d83cc019SAndroid Build Coastguard Worker    0b000001001000,
300*d83cc019SAndroid Build Coastguard Worker    0b000001010000,
301*d83cc019SAndroid Build Coastguard Worker    0b000001110000,
302*d83cc019SAndroid Build Coastguard Worker    0b000001111000,
303*d83cc019SAndroid Build Coastguard Worker    0b001100000000,
304*d83cc019SAndroid Build Coastguard Worker    0b001100000010,
305*d83cc019SAndroid Build Coastguard Worker    0b001100001000,
306*d83cc019SAndroid Build Coastguard Worker    0b001100010000,
307*d83cc019SAndroid Build Coastguard Worker    0b001100010010,
308*d83cc019SAndroid Build Coastguard Worker    0b001100100000,
309*d83cc019SAndroid Build Coastguard Worker    0b001100101000,
310*d83cc019SAndroid Build Coastguard Worker    0b001100111000,
311*d83cc019SAndroid Build Coastguard Worker    0b001101000000,
312*d83cc019SAndroid Build Coastguard Worker    0b001101000010,
313*d83cc019SAndroid Build Coastguard Worker    0b001101001000,
314*d83cc019SAndroid Build Coastguard Worker    0b001101010000,
315*d83cc019SAndroid Build Coastguard Worker    0b001101100000,
316*d83cc019SAndroid Build Coastguard Worker    0b001101101000,
317*d83cc019SAndroid Build Coastguard Worker    0b001101110000,
318*d83cc019SAndroid Build Coastguard Worker    0b001101110001,
319*d83cc019SAndroid Build Coastguard Worker    0b001101111000,
320*d83cc019SAndroid Build Coastguard Worker    0b010001101000,
321*d83cc019SAndroid Build Coastguard Worker    0b010001101001,
322*d83cc019SAndroid Build Coastguard Worker    0b010001101010,
323*d83cc019SAndroid Build Coastguard Worker    0b010110001000
324*d83cc019SAndroid Build Coastguard Worker };
325*d83cc019SAndroid Build Coastguard Worker 
326*d83cc019SAndroid Build Coastguard Worker static const uint32_t *control_index_table;
327*d83cc019SAndroid Build Coastguard Worker static const uint32_t *datatype_table;
328*d83cc019SAndroid Build Coastguard Worker static const uint32_t *subreg_table;
329*d83cc019SAndroid Build Coastguard Worker static const uint32_t *src_index_table;
330*d83cc019SAndroid Build Coastguard Worker 
331*d83cc019SAndroid Build Coastguard Worker static bool
set_control_index(struct intel_context * intel,struct brw_compact_instruction * dst,struct brw_instruction * src)332*d83cc019SAndroid Build Coastguard Worker set_control_index(struct intel_context *intel,
333*d83cc019SAndroid Build Coastguard Worker                   struct brw_compact_instruction *dst,
334*d83cc019SAndroid Build Coastguard Worker                   struct brw_instruction *src)
335*d83cc019SAndroid Build Coastguard Worker {
336*d83cc019SAndroid Build Coastguard Worker    uint32_t *src_u32 = (uint32_t *)src;
337*d83cc019SAndroid Build Coastguard Worker    uint32_t uncompacted = 0;
338*d83cc019SAndroid Build Coastguard Worker 
339*d83cc019SAndroid Build Coastguard Worker    uncompacted |= ((src_u32[0] >> 8) & 0xffff) << 0;
340*d83cc019SAndroid Build Coastguard Worker    uncompacted |= ((src_u32[0] >> 31) & 0x1) << 16;
341*d83cc019SAndroid Build Coastguard Worker    /* On gen7, the flag register number gets integrated into the control
342*d83cc019SAndroid Build Coastguard Worker     * index.
343*d83cc019SAndroid Build Coastguard Worker     */
344*d83cc019SAndroid Build Coastguard Worker    if (intel->gen >= 7)
345*d83cc019SAndroid Build Coastguard Worker       uncompacted |= ((src_u32[2] >> 25) & 0x3) << 17;
346*d83cc019SAndroid Build Coastguard Worker 
347*d83cc019SAndroid Build Coastguard Worker    for (int i = 0; i < 32; i++) {
348*d83cc019SAndroid Build Coastguard Worker       if (control_index_table[i] == uncompacted) {
349*d83cc019SAndroid Build Coastguard Worker 	 dst->dw0.control_index = i;
350*d83cc019SAndroid Build Coastguard Worker 	 return true;
351*d83cc019SAndroid Build Coastguard Worker       }
352*d83cc019SAndroid Build Coastguard Worker    }
353*d83cc019SAndroid Build Coastguard Worker 
354*d83cc019SAndroid Build Coastguard Worker    return false;
355*d83cc019SAndroid Build Coastguard Worker }
356*d83cc019SAndroid Build Coastguard Worker 
357*d83cc019SAndroid Build Coastguard Worker static bool
set_datatype_index(struct brw_compact_instruction * dst,struct brw_instruction * src)358*d83cc019SAndroid Build Coastguard Worker set_datatype_index(struct brw_compact_instruction *dst,
359*d83cc019SAndroid Build Coastguard Worker                    struct brw_instruction *src)
360*d83cc019SAndroid Build Coastguard Worker {
361*d83cc019SAndroid Build Coastguard Worker    uint32_t uncompacted = 0;
362*d83cc019SAndroid Build Coastguard Worker 
363*d83cc019SAndroid Build Coastguard Worker    uncompacted |= src->bits1.ud & 0x7fff;
364*d83cc019SAndroid Build Coastguard Worker    uncompacted |= (src->bits1.ud >> 29) << 15;
365*d83cc019SAndroid Build Coastguard Worker 
366*d83cc019SAndroid Build Coastguard Worker    for (int i = 0; i < 32; i++) {
367*d83cc019SAndroid Build Coastguard Worker       if (datatype_table[i] == uncompacted) {
368*d83cc019SAndroid Build Coastguard Worker 	 dst->dw0.data_type_index = i;
369*d83cc019SAndroid Build Coastguard Worker 	 return true;
370*d83cc019SAndroid Build Coastguard Worker       }
371*d83cc019SAndroid Build Coastguard Worker    }
372*d83cc019SAndroid Build Coastguard Worker 
373*d83cc019SAndroid Build Coastguard Worker    return false;
374*d83cc019SAndroid Build Coastguard Worker }
375*d83cc019SAndroid Build Coastguard Worker 
376*d83cc019SAndroid Build Coastguard Worker static bool
set_subreg_index(struct brw_compact_instruction * dst,struct brw_instruction * src)377*d83cc019SAndroid Build Coastguard Worker set_subreg_index(struct brw_compact_instruction *dst,
378*d83cc019SAndroid Build Coastguard Worker                  struct brw_instruction *src)
379*d83cc019SAndroid Build Coastguard Worker {
380*d83cc019SAndroid Build Coastguard Worker    uint32_t uncompacted = 0;
381*d83cc019SAndroid Build Coastguard Worker 
382*d83cc019SAndroid Build Coastguard Worker    uncompacted |= src->bits1.da1.dest_subreg_nr << 0;
383*d83cc019SAndroid Build Coastguard Worker    uncompacted |= src->bits2.da1.src0_subreg_nr << 5;
384*d83cc019SAndroid Build Coastguard Worker    uncompacted |= src->bits3.da1.src1_subreg_nr << 10;
385*d83cc019SAndroid Build Coastguard Worker 
386*d83cc019SAndroid Build Coastguard Worker    for (int i = 0; i < 32; i++) {
387*d83cc019SAndroid Build Coastguard Worker       if (subreg_table[i] == uncompacted) {
388*d83cc019SAndroid Build Coastguard Worker 	 dst->dw0.sub_reg_index = i;
389*d83cc019SAndroid Build Coastguard Worker 	 return true;
390*d83cc019SAndroid Build Coastguard Worker       }
391*d83cc019SAndroid Build Coastguard Worker    }
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker    return false;
394*d83cc019SAndroid Build Coastguard Worker }
395*d83cc019SAndroid Build Coastguard Worker 
396*d83cc019SAndroid Build Coastguard Worker static bool
get_src_index(uint32_t uncompacted,uint32_t * compacted)397*d83cc019SAndroid Build Coastguard Worker get_src_index(uint32_t uncompacted,
398*d83cc019SAndroid Build Coastguard Worker               uint32_t *compacted)
399*d83cc019SAndroid Build Coastguard Worker {
400*d83cc019SAndroid Build Coastguard Worker    for (int i = 0; i < 32; i++) {
401*d83cc019SAndroid Build Coastguard Worker       if (src_index_table[i] == uncompacted) {
402*d83cc019SAndroid Build Coastguard Worker 	 *compacted = i;
403*d83cc019SAndroid Build Coastguard Worker 	 return true;
404*d83cc019SAndroid Build Coastguard Worker       }
405*d83cc019SAndroid Build Coastguard Worker    }
406*d83cc019SAndroid Build Coastguard Worker 
407*d83cc019SAndroid Build Coastguard Worker    return false;
408*d83cc019SAndroid Build Coastguard Worker }
409*d83cc019SAndroid Build Coastguard Worker 
410*d83cc019SAndroid Build Coastguard Worker static bool
set_src0_index(struct brw_compact_instruction * dst,struct brw_instruction * src)411*d83cc019SAndroid Build Coastguard Worker set_src0_index(struct brw_compact_instruction *dst,
412*d83cc019SAndroid Build Coastguard Worker                struct brw_instruction *src)
413*d83cc019SAndroid Build Coastguard Worker {
414*d83cc019SAndroid Build Coastguard Worker    uint32_t compacted, uncompacted = 0;
415*d83cc019SAndroid Build Coastguard Worker 
416*d83cc019SAndroid Build Coastguard Worker    uncompacted |= (src->bits2.ud >> 13) & 0xfff;
417*d83cc019SAndroid Build Coastguard Worker 
418*d83cc019SAndroid Build Coastguard Worker    if (!get_src_index(uncompacted, &compacted))
419*d83cc019SAndroid Build Coastguard Worker       return false;
420*d83cc019SAndroid Build Coastguard Worker 
421*d83cc019SAndroid Build Coastguard Worker    dst->dw0.src0_index = compacted & 0x3;
422*d83cc019SAndroid Build Coastguard Worker    dst->dw1.src0_index = compacted >> 2;
423*d83cc019SAndroid Build Coastguard Worker 
424*d83cc019SAndroid Build Coastguard Worker    return true;
425*d83cc019SAndroid Build Coastguard Worker }
426*d83cc019SAndroid Build Coastguard Worker 
427*d83cc019SAndroid Build Coastguard Worker static bool
set_src1_index(struct brw_compact_instruction * dst,struct brw_instruction * src)428*d83cc019SAndroid Build Coastguard Worker set_src1_index(struct brw_compact_instruction *dst,
429*d83cc019SAndroid Build Coastguard Worker                struct brw_instruction *src)
430*d83cc019SAndroid Build Coastguard Worker {
431*d83cc019SAndroid Build Coastguard Worker    uint32_t compacted, uncompacted = 0;
432*d83cc019SAndroid Build Coastguard Worker 
433*d83cc019SAndroid Build Coastguard Worker    uncompacted |= (src->bits3.ud >> 13) & 0xfff;
434*d83cc019SAndroid Build Coastguard Worker 
435*d83cc019SAndroid Build Coastguard Worker    if (!get_src_index(uncompacted, &compacted))
436*d83cc019SAndroid Build Coastguard Worker       return false;
437*d83cc019SAndroid Build Coastguard Worker 
438*d83cc019SAndroid Build Coastguard Worker    dst->dw1.src1_index = compacted;
439*d83cc019SAndroid Build Coastguard Worker 
440*d83cc019SAndroid Build Coastguard Worker    return true;
441*d83cc019SAndroid Build Coastguard Worker }
442*d83cc019SAndroid Build Coastguard Worker 
443*d83cc019SAndroid Build Coastguard Worker /**
444*d83cc019SAndroid Build Coastguard Worker  * Tries to compact instruction src into dst.
445*d83cc019SAndroid Build Coastguard Worker  *
446*d83cc019SAndroid Build Coastguard Worker  * It doesn't modify dst unless src is compactable, which is relied on by
447*d83cc019SAndroid Build Coastguard Worker  * brw_compact_instructions().
448*d83cc019SAndroid Build Coastguard Worker  */
449*d83cc019SAndroid Build Coastguard Worker bool
brw_try_compact_instruction(struct brw_compile * p,struct brw_compact_instruction * dst,struct brw_instruction * src)450*d83cc019SAndroid Build Coastguard Worker brw_try_compact_instruction(struct brw_compile *p,
451*d83cc019SAndroid Build Coastguard Worker                             struct brw_compact_instruction *dst,
452*d83cc019SAndroid Build Coastguard Worker                             struct brw_instruction *src)
453*d83cc019SAndroid Build Coastguard Worker {
454*d83cc019SAndroid Build Coastguard Worker    struct brw_context *brw = p->brw;
455*d83cc019SAndroid Build Coastguard Worker    struct intel_context *intel = &brw->intel;
456*d83cc019SAndroid Build Coastguard Worker    struct brw_compact_instruction temp;
457*d83cc019SAndroid Build Coastguard Worker 
458*d83cc019SAndroid Build Coastguard Worker    if (src->header.opcode == BRW_OPCODE_IF ||
459*d83cc019SAndroid Build Coastguard Worker        src->header.opcode == BRW_OPCODE_ELSE ||
460*d83cc019SAndroid Build Coastguard Worker        src->header.opcode == BRW_OPCODE_ENDIF ||
461*d83cc019SAndroid Build Coastguard Worker        src->header.opcode == BRW_OPCODE_HALT ||
462*d83cc019SAndroid Build Coastguard Worker        src->header.opcode == BRW_OPCODE_DO ||
463*d83cc019SAndroid Build Coastguard Worker        src->header.opcode == BRW_OPCODE_WHILE) {
464*d83cc019SAndroid Build Coastguard Worker       /* FINISHME: The fixup code below, and brw_set_uip_jip and friends, needs
465*d83cc019SAndroid Build Coastguard Worker        * to be able to handle compacted flow control instructions..
466*d83cc019SAndroid Build Coastguard Worker        */
467*d83cc019SAndroid Build Coastguard Worker       return false;
468*d83cc019SAndroid Build Coastguard Worker    }
469*d83cc019SAndroid Build Coastguard Worker 
470*d83cc019SAndroid Build Coastguard Worker    /* FINISHME: immediates */
471*d83cc019SAndroid Build Coastguard Worker    if (src->bits1.da1.src0_reg_file == BRW_IMMEDIATE_VALUE ||
472*d83cc019SAndroid Build Coastguard Worker        src->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE)
473*d83cc019SAndroid Build Coastguard Worker       return false;
474*d83cc019SAndroid Build Coastguard Worker 
475*d83cc019SAndroid Build Coastguard Worker    memset(&temp, 0, sizeof(temp));
476*d83cc019SAndroid Build Coastguard Worker 
477*d83cc019SAndroid Build Coastguard Worker    temp.dw0.opcode = src->header.opcode;
478*d83cc019SAndroid Build Coastguard Worker    temp.dw0.debug_control = src->header.debug_control;
479*d83cc019SAndroid Build Coastguard Worker    if (!set_control_index(intel, &temp, src))
480*d83cc019SAndroid Build Coastguard Worker       return false;
481*d83cc019SAndroid Build Coastguard Worker    if (!set_datatype_index(&temp, src))
482*d83cc019SAndroid Build Coastguard Worker       return false;
483*d83cc019SAndroid Build Coastguard Worker    if (!set_subreg_index(&temp, src))
484*d83cc019SAndroid Build Coastguard Worker       return false;
485*d83cc019SAndroid Build Coastguard Worker    temp.dw0.acc_wr_control = src->header.acc_wr_control;
486*d83cc019SAndroid Build Coastguard Worker    temp.dw0.conditionalmod = src->header.destreg__conditionalmod;
487*d83cc019SAndroid Build Coastguard Worker    if (intel->gen <= 6)
488*d83cc019SAndroid Build Coastguard Worker       temp.dw0.flag_subreg_nr = src->bits2.da1.flag_subreg_nr;
489*d83cc019SAndroid Build Coastguard Worker    temp.dw0.cmpt_ctrl = 1;
490*d83cc019SAndroid Build Coastguard Worker    if (!set_src0_index(&temp, src))
491*d83cc019SAndroid Build Coastguard Worker       return false;
492*d83cc019SAndroid Build Coastguard Worker    if (!set_src1_index(&temp, src))
493*d83cc019SAndroid Build Coastguard Worker       return false;
494*d83cc019SAndroid Build Coastguard Worker    temp.dw1.dst_reg_nr = src->bits1.da1.dest_reg_nr;
495*d83cc019SAndroid Build Coastguard Worker    temp.dw1.src0_reg_nr = src->bits2.da1.src0_reg_nr;
496*d83cc019SAndroid Build Coastguard Worker    temp.dw1.src1_reg_nr = src->bits3.da1.src1_reg_nr;
497*d83cc019SAndroid Build Coastguard Worker 
498*d83cc019SAndroid Build Coastguard Worker    *dst = temp;
499*d83cc019SAndroid Build Coastguard Worker 
500*d83cc019SAndroid Build Coastguard Worker    return true;
501*d83cc019SAndroid Build Coastguard Worker }
502*d83cc019SAndroid Build Coastguard Worker 
503*d83cc019SAndroid Build Coastguard Worker static void
set_uncompacted_control(struct intel_context * intel,struct brw_instruction * dst,struct brw_compact_instruction * src)504*d83cc019SAndroid Build Coastguard Worker set_uncompacted_control(struct intel_context *intel,
505*d83cc019SAndroid Build Coastguard Worker                         struct brw_instruction *dst,
506*d83cc019SAndroid Build Coastguard Worker                         struct brw_compact_instruction *src)
507*d83cc019SAndroid Build Coastguard Worker {
508*d83cc019SAndroid Build Coastguard Worker    uint32_t *dst_u32 = (uint32_t *)dst;
509*d83cc019SAndroid Build Coastguard Worker    uint32_t uncompacted = control_index_table[src->dw0.control_index];
510*d83cc019SAndroid Build Coastguard Worker 
511*d83cc019SAndroid Build Coastguard Worker    dst_u32[0] |= ((uncompacted >> 0) & 0xffff) << 8;
512*d83cc019SAndroid Build Coastguard Worker    dst_u32[0] |= ((uncompacted >> 16) & 0x1) << 31;
513*d83cc019SAndroid Build Coastguard Worker 
514*d83cc019SAndroid Build Coastguard Worker    if (intel->gen >= 7)
515*d83cc019SAndroid Build Coastguard Worker       dst_u32[2] |= ((uncompacted >> 17) & 0x3) << 25;
516*d83cc019SAndroid Build Coastguard Worker }
517*d83cc019SAndroid Build Coastguard Worker 
518*d83cc019SAndroid Build Coastguard Worker static void
set_uncompacted_datatype(struct brw_instruction * dst,struct brw_compact_instruction * src)519*d83cc019SAndroid Build Coastguard Worker set_uncompacted_datatype(struct brw_instruction *dst,
520*d83cc019SAndroid Build Coastguard Worker                          struct brw_compact_instruction *src)
521*d83cc019SAndroid Build Coastguard Worker {
522*d83cc019SAndroid Build Coastguard Worker    uint32_t uncompacted = datatype_table[src->dw0.data_type_index];
523*d83cc019SAndroid Build Coastguard Worker 
524*d83cc019SAndroid Build Coastguard Worker    dst->bits1.ud &= ~(0x7 << 29);
525*d83cc019SAndroid Build Coastguard Worker    dst->bits1.ud |= ((uncompacted >> 15) & 0x7) << 29;
526*d83cc019SAndroid Build Coastguard Worker    dst->bits1.ud &= ~0x7fff;
527*d83cc019SAndroid Build Coastguard Worker    dst->bits1.ud |= uncompacted & 0x7fff;
528*d83cc019SAndroid Build Coastguard Worker }
529*d83cc019SAndroid Build Coastguard Worker 
530*d83cc019SAndroid Build Coastguard Worker static void
set_uncompacted_subreg(struct brw_instruction * dst,struct brw_compact_instruction * src)531*d83cc019SAndroid Build Coastguard Worker set_uncompacted_subreg(struct brw_instruction *dst,
532*d83cc019SAndroid Build Coastguard Worker                        struct brw_compact_instruction *src)
533*d83cc019SAndroid Build Coastguard Worker {
534*d83cc019SAndroid Build Coastguard Worker    uint32_t uncompacted = subreg_table[src->dw0.sub_reg_index];
535*d83cc019SAndroid Build Coastguard Worker 
536*d83cc019SAndroid Build Coastguard Worker    dst->bits1.da1.dest_subreg_nr = (uncompacted >> 0)  & 0x1f;
537*d83cc019SAndroid Build Coastguard Worker    dst->bits2.da1.src0_subreg_nr = (uncompacted >> 5)  & 0x1f;
538*d83cc019SAndroid Build Coastguard Worker    dst->bits3.da1.src1_subreg_nr = (uncompacted >> 10) & 0x1f;
539*d83cc019SAndroid Build Coastguard Worker }
540*d83cc019SAndroid Build Coastguard Worker 
541*d83cc019SAndroid Build Coastguard Worker static void
set_uncompacted_src0(struct brw_instruction * dst,struct brw_compact_instruction * src)542*d83cc019SAndroid Build Coastguard Worker set_uncompacted_src0(struct brw_instruction *dst,
543*d83cc019SAndroid Build Coastguard Worker                      struct brw_compact_instruction *src)
544*d83cc019SAndroid Build Coastguard Worker {
545*d83cc019SAndroid Build Coastguard Worker    uint32_t compacted = src->dw0.src0_index | src->dw1.src0_index << 2;
546*d83cc019SAndroid Build Coastguard Worker    uint32_t uncompacted = src_index_table[compacted];
547*d83cc019SAndroid Build Coastguard Worker 
548*d83cc019SAndroid Build Coastguard Worker    dst->bits2.ud |= uncompacted << 13;
549*d83cc019SAndroid Build Coastguard Worker }
550*d83cc019SAndroid Build Coastguard Worker 
551*d83cc019SAndroid Build Coastguard Worker static void
set_uncompacted_src1(struct brw_instruction * dst,struct brw_compact_instruction * src)552*d83cc019SAndroid Build Coastguard Worker set_uncompacted_src1(struct brw_instruction *dst,
553*d83cc019SAndroid Build Coastguard Worker                      struct brw_compact_instruction *src)
554*d83cc019SAndroid Build Coastguard Worker {
555*d83cc019SAndroid Build Coastguard Worker    uint32_t uncompacted = src_index_table[src->dw1.src1_index];
556*d83cc019SAndroid Build Coastguard Worker 
557*d83cc019SAndroid Build Coastguard Worker    dst->bits3.ud |= uncompacted << 13;
558*d83cc019SAndroid Build Coastguard Worker }
559*d83cc019SAndroid Build Coastguard Worker 
560*d83cc019SAndroid Build Coastguard Worker void
brw_uncompact_instruction(struct intel_context * intel,struct brw_instruction * dst,struct brw_compact_instruction * src)561*d83cc019SAndroid Build Coastguard Worker brw_uncompact_instruction(struct intel_context *intel,
562*d83cc019SAndroid Build Coastguard Worker                           struct brw_instruction *dst,
563*d83cc019SAndroid Build Coastguard Worker                           struct brw_compact_instruction *src)
564*d83cc019SAndroid Build Coastguard Worker {
565*d83cc019SAndroid Build Coastguard Worker    memset(dst, 0, sizeof(*dst));
566*d83cc019SAndroid Build Coastguard Worker 
567*d83cc019SAndroid Build Coastguard Worker    dst->header.opcode = src->dw0.opcode;
568*d83cc019SAndroid Build Coastguard Worker    dst->header.debug_control = src->dw0.debug_control;
569*d83cc019SAndroid Build Coastguard Worker 
570*d83cc019SAndroid Build Coastguard Worker    set_uncompacted_control(intel, dst, src);
571*d83cc019SAndroid Build Coastguard Worker    set_uncompacted_datatype(dst, src);
572*d83cc019SAndroid Build Coastguard Worker    set_uncompacted_subreg(dst, src);
573*d83cc019SAndroid Build Coastguard Worker    dst->header.acc_wr_control = src->dw0.acc_wr_control;
574*d83cc019SAndroid Build Coastguard Worker    dst->header.destreg__conditionalmod = src->dw0.conditionalmod;
575*d83cc019SAndroid Build Coastguard Worker    if (intel->gen <= 6)
576*d83cc019SAndroid Build Coastguard Worker       dst->bits2.da1.flag_subreg_nr = src->dw0.flag_subreg_nr;
577*d83cc019SAndroid Build Coastguard Worker    set_uncompacted_src0(dst, src);
578*d83cc019SAndroid Build Coastguard Worker    set_uncompacted_src1(dst, src);
579*d83cc019SAndroid Build Coastguard Worker    dst->bits1.da1.dest_reg_nr = src->dw1.dst_reg_nr;
580*d83cc019SAndroid Build Coastguard Worker    dst->bits2.da1.src0_reg_nr = src->dw1.src0_reg_nr;
581*d83cc019SAndroid Build Coastguard Worker    dst->bits3.da1.src1_reg_nr = src->dw1.src1_reg_nr;
582*d83cc019SAndroid Build Coastguard Worker }
583*d83cc019SAndroid Build Coastguard Worker 
brw_debug_compact_uncompact(struct intel_context * intel,struct brw_instruction * orig,struct brw_instruction * uncompacted)584*d83cc019SAndroid Build Coastguard Worker void brw_debug_compact_uncompact(struct intel_context *intel,
585*d83cc019SAndroid Build Coastguard Worker                                  struct brw_instruction *orig,
586*d83cc019SAndroid Build Coastguard Worker                                  struct brw_instruction *uncompacted)
587*d83cc019SAndroid Build Coastguard Worker {
588*d83cc019SAndroid Build Coastguard Worker    fprintf(stderr, "Instruction compact/uncompact changed (gen%d):\n",
589*d83cc019SAndroid Build Coastguard Worker            intel->gen);
590*d83cc019SAndroid Build Coastguard Worker 
591*d83cc019SAndroid Build Coastguard Worker    fprintf(stderr, "  before: ");
592*d83cc019SAndroid Build Coastguard Worker    brw_disasm(stderr, orig, intel->gen);
593*d83cc019SAndroid Build Coastguard Worker 
594*d83cc019SAndroid Build Coastguard Worker    fprintf(stderr, "  after:  ");
595*d83cc019SAndroid Build Coastguard Worker    brw_disasm(stderr, uncompacted, intel->gen);
596*d83cc019SAndroid Build Coastguard Worker 
597*d83cc019SAndroid Build Coastguard Worker    uint32_t *before_bits = (uint32_t *)orig;
598*d83cc019SAndroid Build Coastguard Worker    uint32_t *after_bits = (uint32_t *)uncompacted;
599*d83cc019SAndroid Build Coastguard Worker    printf("  changed bits:\n");
600*d83cc019SAndroid Build Coastguard Worker    for (int i = 0; i < 128; i++) {
601*d83cc019SAndroid Build Coastguard Worker       uint32_t before = before_bits[i / 32] & (1 << (i & 31));
602*d83cc019SAndroid Build Coastguard Worker       uint32_t after = after_bits[i / 32] & (1 << (i & 31));
603*d83cc019SAndroid Build Coastguard Worker 
604*d83cc019SAndroid Build Coastguard Worker       if (before != after) {
605*d83cc019SAndroid Build Coastguard Worker          printf("  bit %d, %s to %s\n", i,
606*d83cc019SAndroid Build Coastguard Worker                 before ? "set" : "unset",
607*d83cc019SAndroid Build Coastguard Worker                 after ? "set" : "unset");
608*d83cc019SAndroid Build Coastguard Worker       }
609*d83cc019SAndroid Build Coastguard Worker    }
610*d83cc019SAndroid Build Coastguard Worker }
611*d83cc019SAndroid Build Coastguard Worker 
612*d83cc019SAndroid Build Coastguard Worker static int
compacted_between(int old_ip,int old_target_ip,int * compacted_counts)613*d83cc019SAndroid Build Coastguard Worker compacted_between(int old_ip, int old_target_ip, int *compacted_counts)
614*d83cc019SAndroid Build Coastguard Worker {
615*d83cc019SAndroid Build Coastguard Worker    int this_compacted_count = compacted_counts[old_ip];
616*d83cc019SAndroid Build Coastguard Worker    int target_compacted_count = compacted_counts[old_target_ip];
617*d83cc019SAndroid Build Coastguard Worker    return target_compacted_count - this_compacted_count;
618*d83cc019SAndroid Build Coastguard Worker }
619*d83cc019SAndroid Build Coastguard Worker 
620*d83cc019SAndroid Build Coastguard Worker static void
update_uip_jip(struct brw_instruction * insn,int this_old_ip,int * compacted_counts)621*d83cc019SAndroid Build Coastguard Worker update_uip_jip(struct brw_instruction *insn, int this_old_ip,
622*d83cc019SAndroid Build Coastguard Worker                int *compacted_counts)
623*d83cc019SAndroid Build Coastguard Worker {
624*d83cc019SAndroid Build Coastguard Worker    int target_old_ip;
625*d83cc019SAndroid Build Coastguard Worker 
626*d83cc019SAndroid Build Coastguard Worker    target_old_ip = this_old_ip + insn->bits3.break_cont.jip;
627*d83cc019SAndroid Build Coastguard Worker    insn->bits3.break_cont.jip -= compacted_between(this_old_ip,
628*d83cc019SAndroid Build Coastguard Worker                                                    target_old_ip,
629*d83cc019SAndroid Build Coastguard Worker                                                    compacted_counts);
630*d83cc019SAndroid Build Coastguard Worker 
631*d83cc019SAndroid Build Coastguard Worker    target_old_ip = this_old_ip + insn->bits3.break_cont.uip;
632*d83cc019SAndroid Build Coastguard Worker    insn->bits3.break_cont.uip -= compacted_between(this_old_ip,
633*d83cc019SAndroid Build Coastguard Worker                                                    target_old_ip,
634*d83cc019SAndroid Build Coastguard Worker                                                    compacted_counts);
635*d83cc019SAndroid Build Coastguard Worker }
636*d83cc019SAndroid Build Coastguard Worker 
637*d83cc019SAndroid Build Coastguard Worker void
brw_init_compaction_tables(struct intel_context * intel)638*d83cc019SAndroid Build Coastguard Worker brw_init_compaction_tables(struct intel_context *intel)
639*d83cc019SAndroid Build Coastguard Worker {
640*d83cc019SAndroid Build Coastguard Worker    assert(gen6_control_index_table[ARRAY_SIZE(gen6_control_index_table) - 1] != 0);
641*d83cc019SAndroid Build Coastguard Worker    assert(gen6_datatype_table[ARRAY_SIZE(gen6_datatype_table) - 1] != 0);
642*d83cc019SAndroid Build Coastguard Worker    assert(gen6_subreg_table[ARRAY_SIZE(gen6_subreg_table) - 1] != 0);
643*d83cc019SAndroid Build Coastguard Worker    assert(gen6_src_index_table[ARRAY_SIZE(gen6_src_index_table) - 1] != 0);
644*d83cc019SAndroid Build Coastguard Worker    assert(gen7_control_index_table[ARRAY_SIZE(gen6_control_index_table) - 1] != 0);
645*d83cc019SAndroid Build Coastguard Worker    assert(gen7_datatype_table[ARRAY_SIZE(gen6_datatype_table) - 1] != 0);
646*d83cc019SAndroid Build Coastguard Worker    assert(gen7_subreg_table[ARRAY_SIZE(gen6_subreg_table) - 1] != 0);
647*d83cc019SAndroid Build Coastguard Worker    assert(gen7_src_index_table[ARRAY_SIZE(gen6_src_index_table) - 1] != 0);
648*d83cc019SAndroid Build Coastguard Worker 
649*d83cc019SAndroid Build Coastguard Worker    switch (intel->gen) {
650*d83cc019SAndroid Build Coastguard Worker    case 7:
651*d83cc019SAndroid Build Coastguard Worker       control_index_table = gen7_control_index_table;
652*d83cc019SAndroid Build Coastguard Worker       datatype_table = gen7_datatype_table;
653*d83cc019SAndroid Build Coastguard Worker       subreg_table = gen7_subreg_table;
654*d83cc019SAndroid Build Coastguard Worker       src_index_table = gen7_src_index_table;
655*d83cc019SAndroid Build Coastguard Worker       break;
656*d83cc019SAndroid Build Coastguard Worker    case 6:
657*d83cc019SAndroid Build Coastguard Worker       control_index_table = gen6_control_index_table;
658*d83cc019SAndroid Build Coastguard Worker       datatype_table = gen6_datatype_table;
659*d83cc019SAndroid Build Coastguard Worker       subreg_table = gen6_subreg_table;
660*d83cc019SAndroid Build Coastguard Worker       src_index_table = gen6_src_index_table;
661*d83cc019SAndroid Build Coastguard Worker       break;
662*d83cc019SAndroid Build Coastguard Worker    default:
663*d83cc019SAndroid Build Coastguard Worker       return;
664*d83cc019SAndroid Build Coastguard Worker    }
665*d83cc019SAndroid Build Coastguard Worker }
666*d83cc019SAndroid Build Coastguard Worker 
667*d83cc019SAndroid Build Coastguard Worker void
brw_compact_instructions(struct brw_compile * p)668*d83cc019SAndroid Build Coastguard Worker brw_compact_instructions(struct brw_compile *p)
669*d83cc019SAndroid Build Coastguard Worker {
670*d83cc019SAndroid Build Coastguard Worker    struct brw_context *brw = p->brw;
671*d83cc019SAndroid Build Coastguard Worker    struct intel_context *intel = &brw->intel;
672*d83cc019SAndroid Build Coastguard Worker    void *store = p->store;
673*d83cc019SAndroid Build Coastguard Worker    /* For an instruction at byte offset 8*i before compaction, this is the number
674*d83cc019SAndroid Build Coastguard Worker     * of compacted instructions that preceded it.
675*d83cc019SAndroid Build Coastguard Worker     */
676*d83cc019SAndroid Build Coastguard Worker    int compacted_counts[p->next_insn_offset / 8];
677*d83cc019SAndroid Build Coastguard Worker    /* For an instruction at byte offset 8*i after compaction, this is the
678*d83cc019SAndroid Build Coastguard Worker     * 8-byte offset it was at before compaction.
679*d83cc019SAndroid Build Coastguard Worker     */
680*d83cc019SAndroid Build Coastguard Worker    int old_ip[p->next_insn_offset / 8];
681*d83cc019SAndroid Build Coastguard Worker 
682*d83cc019SAndroid Build Coastguard Worker    if (intel->gen < 6)
683*d83cc019SAndroid Build Coastguard Worker       return;
684*d83cc019SAndroid Build Coastguard Worker 
685*d83cc019SAndroid Build Coastguard Worker    int src_offset;
686*d83cc019SAndroid Build Coastguard Worker    int offset = 0;
687*d83cc019SAndroid Build Coastguard Worker    int compacted_count = 0;
688*d83cc019SAndroid Build Coastguard Worker    for (src_offset = 0; src_offset < p->nr_insn * 16;) {
689*d83cc019SAndroid Build Coastguard Worker       struct brw_instruction *src = store + src_offset;
690*d83cc019SAndroid Build Coastguard Worker       void *dst = store + offset;
691*d83cc019SAndroid Build Coastguard Worker 
692*d83cc019SAndroid Build Coastguard Worker       old_ip[offset / 8] = src_offset / 8;
693*d83cc019SAndroid Build Coastguard Worker       compacted_counts[src_offset / 8] = compacted_count;
694*d83cc019SAndroid Build Coastguard Worker 
695*d83cc019SAndroid Build Coastguard Worker       struct brw_instruction saved = *src;
696*d83cc019SAndroid Build Coastguard Worker 
697*d83cc019SAndroid Build Coastguard Worker       if (!src->header.cmpt_control &&
698*d83cc019SAndroid Build Coastguard Worker           brw_try_compact_instruction(p, dst, src)) {
699*d83cc019SAndroid Build Coastguard Worker          compacted_count++;
700*d83cc019SAndroid Build Coastguard Worker 
701*d83cc019SAndroid Build Coastguard Worker          if (INTEL_DEBUG) {
702*d83cc019SAndroid Build Coastguard Worker             struct brw_instruction uncompacted;
703*d83cc019SAndroid Build Coastguard Worker             brw_uncompact_instruction(intel, &uncompacted, dst);
704*d83cc019SAndroid Build Coastguard Worker             if (memcmp(&saved, &uncompacted, sizeof(uncompacted))) {
705*d83cc019SAndroid Build Coastguard Worker                brw_debug_compact_uncompact(intel, &saved, &uncompacted);
706*d83cc019SAndroid Build Coastguard Worker             }
707*d83cc019SAndroid Build Coastguard Worker          }
708*d83cc019SAndroid Build Coastguard Worker 
709*d83cc019SAndroid Build Coastguard Worker          offset += 8;
710*d83cc019SAndroid Build Coastguard Worker          src_offset += 16;
711*d83cc019SAndroid Build Coastguard Worker       } else {
712*d83cc019SAndroid Build Coastguard Worker          int size = src->header.cmpt_control ? 8 : 16;
713*d83cc019SAndroid Build Coastguard Worker 
714*d83cc019SAndroid Build Coastguard Worker          /* It appears that the end of thread SEND instruction needs to be
715*d83cc019SAndroid Build Coastguard Worker           * aligned, or the GPU hangs.
716*d83cc019SAndroid Build Coastguard Worker           */
717*d83cc019SAndroid Build Coastguard Worker          if ((src->header.opcode == BRW_OPCODE_SEND ||
718*d83cc019SAndroid Build Coastguard Worker               src->header.opcode == BRW_OPCODE_SENDC) &&
719*d83cc019SAndroid Build Coastguard Worker              src->bits3.generic.end_of_thread &&
720*d83cc019SAndroid Build Coastguard Worker              (offset & 8) != 0) {
721*d83cc019SAndroid Build Coastguard Worker             struct brw_compact_instruction *align = store + offset;
722*d83cc019SAndroid Build Coastguard Worker             memset(align, 0, sizeof(*align));
723*d83cc019SAndroid Build Coastguard Worker             align->dw0.opcode = BRW_OPCODE_NOP;
724*d83cc019SAndroid Build Coastguard Worker             align->dw0.cmpt_ctrl = 1;
725*d83cc019SAndroid Build Coastguard Worker             offset += 8;
726*d83cc019SAndroid Build Coastguard Worker             old_ip[offset / 8] = src_offset / 8;
727*d83cc019SAndroid Build Coastguard Worker             dst = store + offset;
728*d83cc019SAndroid Build Coastguard Worker          }
729*d83cc019SAndroid Build Coastguard Worker 
730*d83cc019SAndroid Build Coastguard Worker          /* If we didn't compact this intruction, we need to move it down into
731*d83cc019SAndroid Build Coastguard Worker           * place.
732*d83cc019SAndroid Build Coastguard Worker           */
733*d83cc019SAndroid Build Coastguard Worker          if (offset != src_offset) {
734*d83cc019SAndroid Build Coastguard Worker             memmove(dst, src, size);
735*d83cc019SAndroid Build Coastguard Worker          }
736*d83cc019SAndroid Build Coastguard Worker          offset += size;
737*d83cc019SAndroid Build Coastguard Worker          src_offset += size;
738*d83cc019SAndroid Build Coastguard Worker       }
739*d83cc019SAndroid Build Coastguard Worker    }
740*d83cc019SAndroid Build Coastguard Worker 
741*d83cc019SAndroid Build Coastguard Worker    /* Fix up control flow offsets. */
742*d83cc019SAndroid Build Coastguard Worker    p->next_insn_offset = offset;
743*d83cc019SAndroid Build Coastguard Worker    for (offset = 0; offset < p->next_insn_offset;) {
744*d83cc019SAndroid Build Coastguard Worker       struct brw_instruction *insn = store + offset;
745*d83cc019SAndroid Build Coastguard Worker       int this_old_ip = old_ip[offset / 8];
746*d83cc019SAndroid Build Coastguard Worker       int this_compacted_count = compacted_counts[this_old_ip];
747*d83cc019SAndroid Build Coastguard Worker       int target_old_ip, target_compacted_count;
748*d83cc019SAndroid Build Coastguard Worker 
749*d83cc019SAndroid Build Coastguard Worker       switch (insn->header.opcode) {
750*d83cc019SAndroid Build Coastguard Worker       case BRW_OPCODE_BREAK:
751*d83cc019SAndroid Build Coastguard Worker       case BRW_OPCODE_CONTINUE:
752*d83cc019SAndroid Build Coastguard Worker       case BRW_OPCODE_HALT:
753*d83cc019SAndroid Build Coastguard Worker          update_uip_jip(insn, this_old_ip, compacted_counts);
754*d83cc019SAndroid Build Coastguard Worker          break;
755*d83cc019SAndroid Build Coastguard Worker 
756*d83cc019SAndroid Build Coastguard Worker       case BRW_OPCODE_IF:
757*d83cc019SAndroid Build Coastguard Worker       case BRW_OPCODE_ELSE:
758*d83cc019SAndroid Build Coastguard Worker       case BRW_OPCODE_ENDIF:
759*d83cc019SAndroid Build Coastguard Worker       case BRW_OPCODE_WHILE:
760*d83cc019SAndroid Build Coastguard Worker          if (intel->gen == 6) {
761*d83cc019SAndroid Build Coastguard Worker             target_old_ip = this_old_ip + insn->bits1.branch_gen6.jump_count;
762*d83cc019SAndroid Build Coastguard Worker             target_compacted_count = compacted_counts[target_old_ip];
763*d83cc019SAndroid Build Coastguard Worker             insn->bits1.branch_gen6.jump_count -= (target_compacted_count -
764*d83cc019SAndroid Build Coastguard Worker                                                    this_compacted_count);
765*d83cc019SAndroid Build Coastguard Worker          } else {
766*d83cc019SAndroid Build Coastguard Worker             update_uip_jip(insn, this_old_ip, compacted_counts);
767*d83cc019SAndroid Build Coastguard Worker          }
768*d83cc019SAndroid Build Coastguard Worker          break;
769*d83cc019SAndroid Build Coastguard Worker       }
770*d83cc019SAndroid Build Coastguard Worker 
771*d83cc019SAndroid Build Coastguard Worker       if (insn->header.cmpt_control) {
772*d83cc019SAndroid Build Coastguard Worker          offset += 8;
773*d83cc019SAndroid Build Coastguard Worker       } else {
774*d83cc019SAndroid Build Coastguard Worker          offset += 16;
775*d83cc019SAndroid Build Coastguard Worker       }
776*d83cc019SAndroid Build Coastguard Worker    }
777*d83cc019SAndroid Build Coastguard Worker 
778*d83cc019SAndroid Build Coastguard Worker    /* p->nr_insn is counting the number of uncompacted instructions still, so
779*d83cc019SAndroid Build Coastguard Worker     * divide.  We do want to be sure there's a valid instruction in any
780*d83cc019SAndroid Build Coastguard Worker     * alignment padding, so that the next compression pass (for the FS 8/16
781*d83cc019SAndroid Build Coastguard Worker     * compile passes) parses correctly.
782*d83cc019SAndroid Build Coastguard Worker     */
783*d83cc019SAndroid Build Coastguard Worker    if (p->next_insn_offset & 8) {
784*d83cc019SAndroid Build Coastguard Worker       struct brw_compact_instruction *align = store + offset;
785*d83cc019SAndroid Build Coastguard Worker       memset(align, 0, sizeof(*align));
786*d83cc019SAndroid Build Coastguard Worker       align->dw0.opcode = BRW_OPCODE_NOP;
787*d83cc019SAndroid Build Coastguard Worker       align->dw0.cmpt_ctrl = 1;
788*d83cc019SAndroid Build Coastguard Worker       p->next_insn_offset += 8;
789*d83cc019SAndroid Build Coastguard Worker    }
790*d83cc019SAndroid Build Coastguard Worker    p->nr_insn = p->next_insn_offset / 16;
791*d83cc019SAndroid Build Coastguard Worker 
792*d83cc019SAndroid Build Coastguard Worker    if (0) {
793*d83cc019SAndroid Build Coastguard Worker       fprintf(stdout, "dumping compacted program\n");
794*d83cc019SAndroid Build Coastguard Worker       brw_dump_compile(p, stdout, 0, p->next_insn_offset);
795*d83cc019SAndroid Build Coastguard Worker 
796*d83cc019SAndroid Build Coastguard Worker       int cmp = 0;
797*d83cc019SAndroid Build Coastguard Worker       for (offset = 0; offset < p->next_insn_offset;) {
798*d83cc019SAndroid Build Coastguard Worker          struct brw_instruction *insn = store + offset;
799*d83cc019SAndroid Build Coastguard Worker 
800*d83cc019SAndroid Build Coastguard Worker          if (insn->header.cmpt_control) {
801*d83cc019SAndroid Build Coastguard Worker             offset += 8;
802*d83cc019SAndroid Build Coastguard Worker             cmp++;
803*d83cc019SAndroid Build Coastguard Worker          } else {
804*d83cc019SAndroid Build Coastguard Worker             offset += 16;
805*d83cc019SAndroid Build Coastguard Worker          }
806*d83cc019SAndroid Build Coastguard Worker       }
807*d83cc019SAndroid Build Coastguard Worker       fprintf(stderr, "%db/%db saved (%d%%)\n", cmp * 8, offset + cmp * 8,
808*d83cc019SAndroid Build Coastguard Worker               cmp * 8 * 100 / (offset + cmp * 8));
809*d83cc019SAndroid Build Coastguard Worker    }
810*d83cc019SAndroid Build Coastguard Worker }
811