xref: /aosp_15_r20/external/igt-gpu-tools/assembler/brw_eu.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3*d83cc019SAndroid Build Coastguard Worker  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4*d83cc019SAndroid Build Coastguard Worker  develop this 3D driver.
5*d83cc019SAndroid Build Coastguard Worker 
6*d83cc019SAndroid Build Coastguard Worker  Permission is hereby granted, free of charge, to any person obtaining
7*d83cc019SAndroid Build Coastguard Worker  a copy of this software and associated documentation files (the
8*d83cc019SAndroid Build Coastguard Worker  "Software"), to deal in the Software without restriction, including
9*d83cc019SAndroid Build Coastguard Worker  without limitation the rights to use, copy, modify, merge, publish,
10*d83cc019SAndroid Build Coastguard Worker  distribute, sublicense, and/or sell copies of the Software, and to
11*d83cc019SAndroid Build Coastguard Worker  permit persons to whom the Software is furnished to do so, subject to
12*d83cc019SAndroid Build Coastguard Worker  the following conditions:
13*d83cc019SAndroid Build Coastguard Worker 
14*d83cc019SAndroid Build Coastguard Worker  The above copyright notice and this permission notice (including the
15*d83cc019SAndroid Build Coastguard Worker  next paragraph) shall be included in all copies or substantial
16*d83cc019SAndroid Build Coastguard Worker  portions of the Software.
17*d83cc019SAndroid Build Coastguard Worker 
18*d83cc019SAndroid Build Coastguard Worker  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19*d83cc019SAndroid Build Coastguard Worker  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*d83cc019SAndroid Build Coastguard Worker  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21*d83cc019SAndroid Build Coastguard Worker  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22*d83cc019SAndroid Build Coastguard Worker  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23*d83cc019SAndroid Build Coastguard Worker  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24*d83cc019SAndroid Build Coastguard Worker  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25*d83cc019SAndroid Build Coastguard Worker 
26*d83cc019SAndroid Build Coastguard Worker  **********************************************************************/
27*d83cc019SAndroid Build Coastguard Worker  /*
28*d83cc019SAndroid Build Coastguard Worker   * Authors:
29*d83cc019SAndroid Build Coastguard Worker   *   Keith Whitwell <[email protected]>
30*d83cc019SAndroid Build Coastguard Worker   */
31*d83cc019SAndroid Build Coastguard Worker 
32*d83cc019SAndroid Build Coastguard Worker 
33*d83cc019SAndroid Build Coastguard Worker #include <string.h>
34*d83cc019SAndroid Build Coastguard Worker 
35*d83cc019SAndroid Build Coastguard Worker #include "brw_context.h"
36*d83cc019SAndroid Build Coastguard Worker #include "brw_defines.h"
37*d83cc019SAndroid Build Coastguard Worker #include "brw_eu.h"
38*d83cc019SAndroid Build Coastguard Worker 
39*d83cc019SAndroid Build Coastguard Worker #include "ralloc.h"
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker /* Returns the corresponding conditional mod for swapping src0 and
42*d83cc019SAndroid Build Coastguard Worker  * src1 in e.g. CMP.
43*d83cc019SAndroid Build Coastguard Worker  */
44*d83cc019SAndroid Build Coastguard Worker uint32_t
brw_swap_cmod(uint32_t cmod)45*d83cc019SAndroid Build Coastguard Worker brw_swap_cmod(uint32_t cmod)
46*d83cc019SAndroid Build Coastguard Worker {
47*d83cc019SAndroid Build Coastguard Worker    switch (cmod) {
48*d83cc019SAndroid Build Coastguard Worker    case BRW_CONDITIONAL_Z:
49*d83cc019SAndroid Build Coastguard Worker    case BRW_CONDITIONAL_NZ:
50*d83cc019SAndroid Build Coastguard Worker       return cmod;
51*d83cc019SAndroid Build Coastguard Worker    case BRW_CONDITIONAL_G:
52*d83cc019SAndroid Build Coastguard Worker       return BRW_CONDITIONAL_L;
53*d83cc019SAndroid Build Coastguard Worker    case BRW_CONDITIONAL_GE:
54*d83cc019SAndroid Build Coastguard Worker       return BRW_CONDITIONAL_LE;
55*d83cc019SAndroid Build Coastguard Worker    case BRW_CONDITIONAL_L:
56*d83cc019SAndroid Build Coastguard Worker       return BRW_CONDITIONAL_G;
57*d83cc019SAndroid Build Coastguard Worker    case BRW_CONDITIONAL_LE:
58*d83cc019SAndroid Build Coastguard Worker       return BRW_CONDITIONAL_GE;
59*d83cc019SAndroid Build Coastguard Worker    default:
60*d83cc019SAndroid Build Coastguard Worker       return ~0;
61*d83cc019SAndroid Build Coastguard Worker    }
62*d83cc019SAndroid Build Coastguard Worker }
63*d83cc019SAndroid Build Coastguard Worker 
64*d83cc019SAndroid Build Coastguard Worker 
65*d83cc019SAndroid Build Coastguard Worker /* How does predicate control work when execution_size != 8?  Do I
66*d83cc019SAndroid Build Coastguard Worker  * need to test/set for 0xffff when execution_size is 16?
67*d83cc019SAndroid Build Coastguard Worker  */
brw_set_predicate_control_flag_value(struct brw_compile * p,unsigned value)68*d83cc019SAndroid Build Coastguard Worker void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value )
69*d83cc019SAndroid Build Coastguard Worker {
70*d83cc019SAndroid Build Coastguard Worker    p->current->header.predicate_control = BRW_PREDICATE_NONE;
71*d83cc019SAndroid Build Coastguard Worker 
72*d83cc019SAndroid Build Coastguard Worker    if (value != 0xff) {
73*d83cc019SAndroid Build Coastguard Worker       if (value != p->flag_value) {
74*d83cc019SAndroid Build Coastguard Worker 	 brw_push_insn_state(p);
75*d83cc019SAndroid Build Coastguard Worker 	 brw_MOV(p, brw_flag_reg(0, 0), brw_imm_uw(value));
76*d83cc019SAndroid Build Coastguard Worker 	 p->flag_value = value;
77*d83cc019SAndroid Build Coastguard Worker 	 brw_pop_insn_state(p);
78*d83cc019SAndroid Build Coastguard Worker       }
79*d83cc019SAndroid Build Coastguard Worker 
80*d83cc019SAndroid Build Coastguard Worker       p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
81*d83cc019SAndroid Build Coastguard Worker    }
82*d83cc019SAndroid Build Coastguard Worker }
83*d83cc019SAndroid Build Coastguard Worker 
brw_set_predicate_control(struct brw_compile * p,unsigned pc)84*d83cc019SAndroid Build Coastguard Worker void brw_set_predicate_control( struct brw_compile *p, unsigned pc )
85*d83cc019SAndroid Build Coastguard Worker {
86*d83cc019SAndroid Build Coastguard Worker    p->current->header.predicate_control = pc;
87*d83cc019SAndroid Build Coastguard Worker }
88*d83cc019SAndroid Build Coastguard Worker 
brw_set_predicate_inverse(struct brw_compile * p,bool predicate_inverse)89*d83cc019SAndroid Build Coastguard Worker void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse)
90*d83cc019SAndroid Build Coastguard Worker {
91*d83cc019SAndroid Build Coastguard Worker    p->current->header.predicate_inverse = predicate_inverse;
92*d83cc019SAndroid Build Coastguard Worker }
93*d83cc019SAndroid Build Coastguard Worker 
brw_set_conditionalmod(struct brw_compile * p,unsigned conditional)94*d83cc019SAndroid Build Coastguard Worker void brw_set_conditionalmod( struct brw_compile *p, unsigned conditional )
95*d83cc019SAndroid Build Coastguard Worker {
96*d83cc019SAndroid Build Coastguard Worker    p->current->header.destreg__conditionalmod = conditional;
97*d83cc019SAndroid Build Coastguard Worker }
98*d83cc019SAndroid Build Coastguard Worker 
brw_set_flag_reg(struct brw_compile * p,int reg,int subreg)99*d83cc019SAndroid Build Coastguard Worker void brw_set_flag_reg(struct brw_compile *p, int reg, int subreg)
100*d83cc019SAndroid Build Coastguard Worker {
101*d83cc019SAndroid Build Coastguard Worker    p->current->bits2.da1.flag_reg_nr = reg;
102*d83cc019SAndroid Build Coastguard Worker    p->current->bits2.da1.flag_subreg_nr = subreg;
103*d83cc019SAndroid Build Coastguard Worker }
104*d83cc019SAndroid Build Coastguard Worker 
brw_set_access_mode(struct brw_compile * p,unsigned access_mode)105*d83cc019SAndroid Build Coastguard Worker void brw_set_access_mode( struct brw_compile *p, unsigned access_mode )
106*d83cc019SAndroid Build Coastguard Worker {
107*d83cc019SAndroid Build Coastguard Worker    p->current->header.access_mode = access_mode;
108*d83cc019SAndroid Build Coastguard Worker }
109*d83cc019SAndroid Build Coastguard Worker 
110*d83cc019SAndroid Build Coastguard Worker void
brw_set_compression_control(struct brw_compile * p,enum brw_compression compression_control)111*d83cc019SAndroid Build Coastguard Worker brw_set_compression_control(struct brw_compile *p,
112*d83cc019SAndroid Build Coastguard Worker 			    enum brw_compression compression_control)
113*d83cc019SAndroid Build Coastguard Worker {
114*d83cc019SAndroid Build Coastguard Worker    p->compressed = (compression_control == BRW_COMPRESSION_COMPRESSED);
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker    if (p->brw->intel.gen >= 6) {
117*d83cc019SAndroid Build Coastguard Worker       /* Since we don't use the 32-wide support in gen6, we translate
118*d83cc019SAndroid Build Coastguard Worker        * the pre-gen6 compression control here.
119*d83cc019SAndroid Build Coastguard Worker        */
120*d83cc019SAndroid Build Coastguard Worker       switch (compression_control) {
121*d83cc019SAndroid Build Coastguard Worker       case BRW_COMPRESSION_NONE:
122*d83cc019SAndroid Build Coastguard Worker 	 /* This is the "use the first set of bits of dmask/vmask/arf
123*d83cc019SAndroid Build Coastguard Worker 	  * according to execsize" option.
124*d83cc019SAndroid Build Coastguard Worker 	  */
125*d83cc019SAndroid Build Coastguard Worker 	 p->current->header.compression_control = GEN6_COMPRESSION_1Q;
126*d83cc019SAndroid Build Coastguard Worker 	 break;
127*d83cc019SAndroid Build Coastguard Worker       case BRW_COMPRESSION_2NDHALF:
128*d83cc019SAndroid Build Coastguard Worker 	 /* For 8-wide, this is "use the second set of 8 bits." */
129*d83cc019SAndroid Build Coastguard Worker 	 p->current->header.compression_control = GEN6_COMPRESSION_2Q;
130*d83cc019SAndroid Build Coastguard Worker 	 break;
131*d83cc019SAndroid Build Coastguard Worker       case BRW_COMPRESSION_COMPRESSED:
132*d83cc019SAndroid Build Coastguard Worker 	 /* For 16-wide instruction compression, use the first set of 16 bits
133*d83cc019SAndroid Build Coastguard Worker 	  * since we don't do 32-wide dispatch.
134*d83cc019SAndroid Build Coastguard Worker 	  */
135*d83cc019SAndroid Build Coastguard Worker 	 p->current->header.compression_control = GEN6_COMPRESSION_1H;
136*d83cc019SAndroid Build Coastguard Worker 	 break;
137*d83cc019SAndroid Build Coastguard Worker       default:
138*d83cc019SAndroid Build Coastguard Worker 	 assert(!"not reached");
139*d83cc019SAndroid Build Coastguard Worker 	 p->current->header.compression_control = GEN6_COMPRESSION_1H;
140*d83cc019SAndroid Build Coastguard Worker 	 break;
141*d83cc019SAndroid Build Coastguard Worker       }
142*d83cc019SAndroid Build Coastguard Worker    } else {
143*d83cc019SAndroid Build Coastguard Worker       p->current->header.compression_control = compression_control;
144*d83cc019SAndroid Build Coastguard Worker    }
145*d83cc019SAndroid Build Coastguard Worker }
146*d83cc019SAndroid Build Coastguard Worker 
brw_set_mask_control(struct brw_compile * p,unsigned value)147*d83cc019SAndroid Build Coastguard Worker void brw_set_mask_control( struct brw_compile *p, unsigned value )
148*d83cc019SAndroid Build Coastguard Worker {
149*d83cc019SAndroid Build Coastguard Worker    p->current->header.mask_control = value;
150*d83cc019SAndroid Build Coastguard Worker }
151*d83cc019SAndroid Build Coastguard Worker 
brw_set_saturate(struct brw_compile * p,bool enable)152*d83cc019SAndroid Build Coastguard Worker void brw_set_saturate( struct brw_compile *p, bool enable )
153*d83cc019SAndroid Build Coastguard Worker {
154*d83cc019SAndroid Build Coastguard Worker    p->current->header.saturate = enable;
155*d83cc019SAndroid Build Coastguard Worker }
156*d83cc019SAndroid Build Coastguard Worker 
brw_set_acc_write_control(struct brw_compile * p,unsigned value)157*d83cc019SAndroid Build Coastguard Worker void brw_set_acc_write_control(struct brw_compile *p, unsigned value)
158*d83cc019SAndroid Build Coastguard Worker {
159*d83cc019SAndroid Build Coastguard Worker    if (p->brw->intel.gen >= 6)
160*d83cc019SAndroid Build Coastguard Worker       p->current->header.acc_wr_control = value;
161*d83cc019SAndroid Build Coastguard Worker }
162*d83cc019SAndroid Build Coastguard Worker 
brw_push_insn_state(struct brw_compile * p)163*d83cc019SAndroid Build Coastguard Worker void brw_push_insn_state( struct brw_compile *p )
164*d83cc019SAndroid Build Coastguard Worker {
165*d83cc019SAndroid Build Coastguard Worker    assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
166*d83cc019SAndroid Build Coastguard Worker    memcpy(p->current+1, p->current, sizeof(struct brw_instruction));
167*d83cc019SAndroid Build Coastguard Worker    p->compressed_stack[p->current - p->stack] = p->compressed;
168*d83cc019SAndroid Build Coastguard Worker    p->current++;
169*d83cc019SAndroid Build Coastguard Worker }
170*d83cc019SAndroid Build Coastguard Worker 
brw_pop_insn_state(struct brw_compile * p)171*d83cc019SAndroid Build Coastguard Worker void brw_pop_insn_state( struct brw_compile *p )
172*d83cc019SAndroid Build Coastguard Worker {
173*d83cc019SAndroid Build Coastguard Worker    assert(p->current != p->stack);
174*d83cc019SAndroid Build Coastguard Worker    p->current--;
175*d83cc019SAndroid Build Coastguard Worker    p->compressed = p->compressed_stack[p->current - p->stack];
176*d83cc019SAndroid Build Coastguard Worker }
177*d83cc019SAndroid Build Coastguard Worker 
178*d83cc019SAndroid Build Coastguard Worker 
179*d83cc019SAndroid Build Coastguard Worker /***********************************************************************
180*d83cc019SAndroid Build Coastguard Worker  */
181*d83cc019SAndroid Build Coastguard Worker void
brw_init_compile(struct brw_context * brw,struct brw_compile * p,void * mem_ctx)182*d83cc019SAndroid Build Coastguard Worker brw_init_compile(struct brw_context *brw, struct brw_compile *p, void *mem_ctx)
183*d83cc019SAndroid Build Coastguard Worker {
184*d83cc019SAndroid Build Coastguard Worker    memset(p, 0, sizeof(*p));
185*d83cc019SAndroid Build Coastguard Worker 
186*d83cc019SAndroid Build Coastguard Worker    p->brw = brw;
187*d83cc019SAndroid Build Coastguard Worker    /*
188*d83cc019SAndroid Build Coastguard Worker     * Set the initial instruction store array size to 1024, if found that
189*d83cc019SAndroid Build Coastguard Worker     * isn't enough, then it will double the store size at brw_next_insn()
190*d83cc019SAndroid Build Coastguard Worker     * until out of memory.
191*d83cc019SAndroid Build Coastguard Worker     */
192*d83cc019SAndroid Build Coastguard Worker    p->store_size = 1024;
193*d83cc019SAndroid Build Coastguard Worker    p->store = rzalloc_array(mem_ctx, struct brw_instruction, p->store_size);
194*d83cc019SAndroid Build Coastguard Worker    p->nr_insn = 0;
195*d83cc019SAndroid Build Coastguard Worker    p->current = p->stack;
196*d83cc019SAndroid Build Coastguard Worker    p->compressed = false;
197*d83cc019SAndroid Build Coastguard Worker    memset(p->current, 0, sizeof(p->current[0]));
198*d83cc019SAndroid Build Coastguard Worker 
199*d83cc019SAndroid Build Coastguard Worker    p->mem_ctx = mem_ctx;
200*d83cc019SAndroid Build Coastguard Worker 
201*d83cc019SAndroid Build Coastguard Worker    /* Some defaults?
202*d83cc019SAndroid Build Coastguard Worker     */
203*d83cc019SAndroid Build Coastguard Worker    brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */
204*d83cc019SAndroid Build Coastguard Worker    brw_set_saturate(p, 0);
205*d83cc019SAndroid Build Coastguard Worker    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
206*d83cc019SAndroid Build Coastguard Worker    brw_set_predicate_control_flag_value(p, 0xff);
207*d83cc019SAndroid Build Coastguard Worker 
208*d83cc019SAndroid Build Coastguard Worker    /* Set up control flow stack */
209*d83cc019SAndroid Build Coastguard Worker    p->if_stack_depth = 0;
210*d83cc019SAndroid Build Coastguard Worker    p->if_stack_array_size = 16;
211*d83cc019SAndroid Build Coastguard Worker    p->if_stack = rzalloc_array(mem_ctx, int, p->if_stack_array_size);
212*d83cc019SAndroid Build Coastguard Worker 
213*d83cc019SAndroid Build Coastguard Worker    p->loop_stack_depth = 0;
214*d83cc019SAndroid Build Coastguard Worker    p->loop_stack_array_size = 16;
215*d83cc019SAndroid Build Coastguard Worker    p->loop_stack = rzalloc_array(mem_ctx, int, p->loop_stack_array_size);
216*d83cc019SAndroid Build Coastguard Worker    p->if_depth_in_loop = rzalloc_array(mem_ctx, int, p->loop_stack_array_size);
217*d83cc019SAndroid Build Coastguard Worker 
218*d83cc019SAndroid Build Coastguard Worker    brw_init_compaction_tables(&brw->intel);
219*d83cc019SAndroid Build Coastguard Worker }
220*d83cc019SAndroid Build Coastguard Worker 
221*d83cc019SAndroid Build Coastguard Worker 
brw_get_program(struct brw_compile * p,unsigned * sz)222*d83cc019SAndroid Build Coastguard Worker const unsigned *brw_get_program( struct brw_compile *p,
223*d83cc019SAndroid Build Coastguard Worker 			       unsigned *sz )
224*d83cc019SAndroid Build Coastguard Worker {
225*d83cc019SAndroid Build Coastguard Worker    brw_compact_instructions(p);
226*d83cc019SAndroid Build Coastguard Worker 
227*d83cc019SAndroid Build Coastguard Worker    *sz = p->next_insn_offset;
228*d83cc019SAndroid Build Coastguard Worker    return (const unsigned *)p->store;
229*d83cc019SAndroid Build Coastguard Worker }
230*d83cc019SAndroid Build Coastguard Worker 
231*d83cc019SAndroid Build Coastguard Worker void
brw_dump_compile(struct brw_compile * p,FILE * out,int start,int end)232*d83cc019SAndroid Build Coastguard Worker brw_dump_compile(struct brw_compile *p, FILE *out, int start, int end)
233*d83cc019SAndroid Build Coastguard Worker {
234*d83cc019SAndroid Build Coastguard Worker    struct brw_context *brw = p->brw;
235*d83cc019SAndroid Build Coastguard Worker    struct intel_context *intel = &brw->intel;
236*d83cc019SAndroid Build Coastguard Worker    void *store = p->store;
237*d83cc019SAndroid Build Coastguard Worker    bool dump_hex = false;
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker    for (int offset = start; offset < end;) {
240*d83cc019SAndroid Build Coastguard Worker       struct brw_instruction *insn = store + offset;
241*d83cc019SAndroid Build Coastguard Worker       struct brw_instruction uncompacted;
242*d83cc019SAndroid Build Coastguard Worker       printf("0x%08x: ", offset);
243*d83cc019SAndroid Build Coastguard Worker 
244*d83cc019SAndroid Build Coastguard Worker       if (insn->header.cmpt_control) {
245*d83cc019SAndroid Build Coastguard Worker 	 struct brw_compact_instruction *compacted = (void *)insn;
246*d83cc019SAndroid Build Coastguard Worker 	 if (dump_hex) {
247*d83cc019SAndroid Build Coastguard Worker 	    printf("0x%08x 0x%08x                       ",
248*d83cc019SAndroid Build Coastguard Worker 		   ((uint32_t *)insn)[1],
249*d83cc019SAndroid Build Coastguard Worker 		   ((uint32_t *)insn)[0]);
250*d83cc019SAndroid Build Coastguard Worker 	 }
251*d83cc019SAndroid Build Coastguard Worker 
252*d83cc019SAndroid Build Coastguard Worker 	 brw_uncompact_instruction(intel, &uncompacted, compacted);
253*d83cc019SAndroid Build Coastguard Worker 	 insn = &uncompacted;
254*d83cc019SAndroid Build Coastguard Worker 	 offset += 8;
255*d83cc019SAndroid Build Coastguard Worker       } else {
256*d83cc019SAndroid Build Coastguard Worker 	 if (dump_hex) {
257*d83cc019SAndroid Build Coastguard Worker 	    printf("0x%08x 0x%08x 0x%08x 0x%08x ",
258*d83cc019SAndroid Build Coastguard Worker 		   ((uint32_t *)insn)[3],
259*d83cc019SAndroid Build Coastguard Worker 		   ((uint32_t *)insn)[2],
260*d83cc019SAndroid Build Coastguard Worker 		   ((uint32_t *)insn)[1],
261*d83cc019SAndroid Build Coastguard Worker 		   ((uint32_t *)insn)[0]);
262*d83cc019SAndroid Build Coastguard Worker 	 }
263*d83cc019SAndroid Build Coastguard Worker 	 offset += 16;
264*d83cc019SAndroid Build Coastguard Worker       }
265*d83cc019SAndroid Build Coastguard Worker 
266*d83cc019SAndroid Build Coastguard Worker       brw_disasm(stdout, insn, p->brw->intel.gen);
267*d83cc019SAndroid Build Coastguard Worker    }
268*d83cc019SAndroid Build Coastguard Worker }
269