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