brw_eu.c revision 3f5e938a9ded42ae8dc9ae2486e8d5c8b64cfe07
19f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*
29f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Copyright (C) Intel Corp.  2006.  All Rights Reserved.
39f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
49f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt develop this 3D driver.
59f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
69f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Permission is hereby granted, free of charge, to any person obtaining
79f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt a copy of this software and associated documentation files (the
89f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "Software"), to deal in the Software without restriction, including
99f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt without limitation the rights to use, copy, modify, merge, publish,
109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt distribute, sublicense, and/or sell copies of the Software, and to
119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt permit persons to whom the Software is furnished to do so, subject to
129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt the following conditions:
139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt The above copyright notice and this permission notice (including the
159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt next paragraph) shall be included in all copies or substantial
169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt portions of the Software.
179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt **********************************************************************/
279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /*
289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  * Authors:
299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  *   Keith Whitwell <keith@tungstengraphics.com>
309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  */
319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_context.h"
349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_defines.h"
359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_eu.h"
369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
372f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ralloc.h"
385936d96d33e767aa99f6afa92f2a6582ff04df23Kenneth Graunke
39811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt/* Returns the corresponding conditional mod for swapping src0 and
40811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt * src1 in e.g. CMP.
41811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt */
42811c147220d2630b769e505ce4d40ef9108fe034Eric Anholtuint32_t
43811c147220d2630b769e505ce4d40ef9108fe034Eric Anholtbrw_swap_cmod(uint32_t cmod)
44811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt{
45811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   switch (cmod) {
46811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   case BRW_CONDITIONAL_Z:
47811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   case BRW_CONDITIONAL_NZ:
48811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt      return cmod;
49811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   case BRW_CONDITIONAL_G:
50811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt      return BRW_CONDITIONAL_LE;
51811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   case BRW_CONDITIONAL_GE:
52811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt      return BRW_CONDITIONAL_L;
53811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   case BRW_CONDITIONAL_L:
54811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt      return BRW_CONDITIONAL_GE;
55811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   case BRW_CONDITIONAL_LE:
56811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt      return BRW_CONDITIONAL_G;
57811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   default:
58811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt      return ~0;
59811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt   }
60811c147220d2630b769e505ce4d40ef9108fe034Eric Anholt}
619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/* How does predicate control work when execution_size != 8?  Do I
649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * need to test/set for 0xffff when execution_size is 16?
659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value )
679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->current->header.predicate_control = BRW_PREDICATE_NONE;
699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (value != 0xff) {
719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (value != p->flag_value) {
729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 brw_push_insn_state(p);
739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 brw_MOV(p, brw_flag_reg(), brw_imm_uw(value));
749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 p->flag_value = value;
759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 brw_pop_insn_state(p);
769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_set_predicate_control( struct brw_compile *p, GLuint pc )
839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->current->header.predicate_control = pc;
859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
874847f802c28e595130bda14055cd52c9b1f51cd7Eric Anholtvoid brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse)
884847f802c28e595130bda14055cd52c9b1f51cd7Eric Anholt{
894847f802c28e595130bda14055cd52c9b1f51cd7Eric Anholt   p->current->header.predicate_inverse = predicate_inverse;
904847f802c28e595130bda14055cd52c9b1f51cd7Eric Anholt}
914847f802c28e595130bda14055cd52c9b1f51cd7Eric Anholt
929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_set_conditionalmod( struct brw_compile *p, GLuint conditional )
939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
94b010814e9c7ed30cbdd60a49d81a6ea774c8c3a3Eric Anholt   p->current->header.destreg__conditionalmod = conditional;
959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_set_access_mode( struct brw_compile *p, GLuint access_mode )
989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->current->header.access_mode = access_mode;
1009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1023f5e938a9ded42ae8dc9ae2486e8d5c8b64cfe07Kenneth Graunkevoid
1033f5e938a9ded42ae8dc9ae2486e8d5c8b64cfe07Kenneth Graunkebrw_set_compression_control(struct brw_compile *p,
1043f5e938a9ded42ae8dc9ae2486e8d5c8b64cfe07Kenneth Graunke			    enum brw_compression compression_control)
1059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
106245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt   p->compressed = (compression_control == BRW_COMPRESSION_COMPRESSED);
107245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt
108245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt   if (p->brw->intel.gen >= 6) {
109245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt      /* Since we don't use the 32-wide support in gen6, we translate
110245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt       * the pre-gen6 compression control here.
111245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt       */
112245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt      switch (compression_control) {
113245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt      case BRW_COMPRESSION_NONE:
114245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 /* This is the "use the first set of bits of dmask/vmask/arf
115245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	  * according to execsize" option.
116245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	  */
117245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 p->current->header.compression_control = GEN6_COMPRESSION_1Q;
118245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 break;
119245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt      case BRW_COMPRESSION_2NDHALF:
120245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 /* For 8-wide, this is "use the second set of 8 bits." */
121245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 p->current->header.compression_control = GEN6_COMPRESSION_2Q;
122245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 break;
123245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt      case BRW_COMPRESSION_COMPRESSED:
124245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 /* For 16-wide instruction compression, use the first set of 16 bits
125245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	  * since we don't do 32-wide dispatch.
126245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	  */
127245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 p->current->header.compression_control = GEN6_COMPRESSION_1H;
128245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 break;
129245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt      default:
130245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 assert(!"not reached");
131245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 p->current->header.compression_control = GEN6_COMPRESSION_1H;
132245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt	 break;
133245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt      }
134245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt   } else {
135245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt      p->current->header.compression_control = compression_control;
136245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt   }
1379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_set_mask_control( struct brw_compile *p, GLuint value )
1409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->current->header.mask_control = value;
1429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_set_saturate( struct brw_compile *p, GLuint value )
1459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->current->header.saturate = value;
1479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
14993ba0055c325007656c14ba38302e21be3dc599fZhenyu Wangvoid brw_set_acc_write_control(struct brw_compile *p, GLuint value)
15093ba0055c325007656c14ba38302e21be3dc599fZhenyu Wang{
15193ba0055c325007656c14ba38302e21be3dc599fZhenyu Wang   if (p->brw->intel.gen >= 6)
15293ba0055c325007656c14ba38302e21be3dc599fZhenyu Wang      p->current->header.acc_wr_control = value;
15393ba0055c325007656c14ba38302e21be3dc599fZhenyu Wang}
15493ba0055c325007656c14ba38302e21be3dc599fZhenyu Wang
1559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_push_insn_state( struct brw_compile *p )
1569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
1589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   memcpy(p->current+1, p->current, sizeof(struct brw_instruction));
159245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt   p->compressed_stack[p->current - p->stack] = p->compressed;
1609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->current++;
1619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_pop_insn_state( struct brw_compile *p )
1649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   assert(p->current != p->stack);
1669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->current--;
167245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt   p->compressed = p->compressed_stack[p->current - p->stack];
1689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
1729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
173774fb90db3e83d5e7326b7a72e05ce805c306b24Kenneth Graunkevoid
174774fb90db3e83d5e7326b7a72e05ce805c306b24Kenneth Graunkebrw_init_compile(struct brw_context *brw, struct brw_compile *p, void *mem_ctx)
1759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1768e444fb9e2685e3eac42beb848b08e91dc20c88aXiang, Haihao   p->brw = brw;
1779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->nr_insn = 0;
1789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   p->current = p->stack;
179245662f3083795e272fe9ef5d4cbeb6d048cf0e5Eric Anholt   p->compressed = false;
1809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   memset(p->current, 0, sizeof(p->current[0]));
1819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
182774fb90db3e83d5e7326b7a72e05ce805c306b24Kenneth Graunke   p->mem_ctx = mem_ctx;
183774fb90db3e83d5e7326b7a72e05ce805c306b24Kenneth Graunke
1849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Some defaults?
1859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
1869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */
1879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   brw_set_saturate(p, 0);
1889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   brw_set_predicate_control_flag_value(p, 0xff);
1905936d96d33e767aa99f6afa92f2a6582ff04df23Kenneth Graunke
1915936d96d33e767aa99f6afa92f2a6582ff04df23Kenneth Graunke   /* Set up control flow stack */
1925936d96d33e767aa99f6afa92f2a6582ff04df23Kenneth Graunke   p->if_stack_depth = 0;
1935936d96d33e767aa99f6afa92f2a6582ff04df23Kenneth Graunke   p->if_stack_array_size = 16;
1945936d96d33e767aa99f6afa92f2a6582ff04df23Kenneth Graunke   p->if_stack =
1955936d96d33e767aa99f6afa92f2a6582ff04df23Kenneth Graunke      rzalloc_array(mem_ctx, struct brw_instruction *, p->if_stack_array_size);
1969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtconst GLuint *brw_get_program( struct brw_compile *p,
2009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       GLuint *sz )
2019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint i;
2039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (i = 0; i < 8; i++)
2059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      brw_NOP(p);
2069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   *sz = p->nr_insn * sizeof(struct brw_instruction);
2089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return (const GLuint *)p->store;
2099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
211c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
212c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
213c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul/**
214c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * Subroutine calls require special attention.
215c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * Mesa instructions may be expanded into multiple hardware instructions
216c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * so the prog_instruction::BranchTarget field can't be used as an index
217c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * into the hardware instructions.
218c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul *
219c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * The BranchTarget field isn't needed, however.  Mesa's GLSL compiler
220c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * emits CAL and BGNSUB instructions with labels that can be used to map
221c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * subroutine calls to actual subroutine code blocks.
222c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul *
223c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * The structures and function here implement patching of CAL instructions
224c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * so they jump to the right subroutine code...
225c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul */
226c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
227c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
228c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul/**
229c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * For each OPCODE_BGNSUB we create one of these.
230c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul */
231c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulstruct brw_glsl_label
232c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul{
233c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   const char *name; /**< the label string */
234c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   GLuint position;  /**< the position of the brw instruction for this label */
235c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   struct brw_glsl_label *next;  /**< next in linked list */
236c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul};
237c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
238c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
239c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul/**
240c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * For each OPCODE_CAL we create one of these.
241c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul */
242c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulstruct brw_glsl_call
243c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul{
244c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   GLuint call_inst_pos;  /**< location of the CAL instruction */
245c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   const char *sub_name;  /**< name of subroutine to call */
246c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   struct brw_glsl_call *next;  /**< next in linked list */
247c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul};
248c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
249c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
250c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul/**
251c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * Called for each OPCODE_BGNSUB.
252c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul */
253c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulvoid
254c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulbrw_save_label(struct brw_compile *c, const char *name, GLuint position)
255c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul{
256c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   struct brw_glsl_label *label = CALLOC_STRUCT(brw_glsl_label);
257c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   label->name = name;
258c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   label->position = position;
259c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   label->next = c->first_label;
260c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   c->first_label = label;
261c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul}
262c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
263c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
264c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul/**
265c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * Called for each OPCODE_CAL.
266c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul */
267c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulvoid
268c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulbrw_save_call(struct brw_compile *c, const char *name, GLuint call_pos)
269c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul{
270c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   struct brw_glsl_call *call = CALLOC_STRUCT(brw_glsl_call);
271c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   call->call_inst_pos = call_pos;
272c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   call->sub_name = name;
273c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   call->next = c->first_call;
274c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   c->first_call = call;
275c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul}
276c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
277c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
278c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul/**
279c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * Lookup a label, return label's position/offset.
280c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul */
281c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulstatic GLuint
282c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulbrw_lookup_label(struct brw_compile *c, const char *name)
283c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul{
284c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   const struct brw_glsl_label *label;
285c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   for (label = c->first_label; label; label = label->next) {
286c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul      if (strcmp(name, label->name) == 0) {
287c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul         return label->position;
288c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul      }
289c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   }
290c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   abort();  /* should never happen */
291c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul   return ~0;
292c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul}
293c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
294c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
295c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul/**
296c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * When we're done generating code, this function is called to resolve
297c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul * subroutine calls.
298c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul */
299c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulvoid
300c51c822ee02cb47ddba46da668577d51b7c02831Brian Paulbrw_resolve_cals(struct brw_compile *c)
301c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul{
302c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    const struct brw_glsl_call *call;
303c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
304c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    for (call = c->first_call; call; call = call->next) {
305c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul        const GLuint sub_loc = brw_lookup_label(c, call->sub_name);
306c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	struct brw_instruction *brw_call_inst = &c->store[call->call_inst_pos];
307c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	struct brw_instruction *brw_sub_inst = &c->store[sub_loc];
308c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	GLint offset = brw_sub_inst - brw_call_inst;
309c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
310c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	/* patch brw_inst1 to point to brw_inst2 */
3111309d2ea723613f1e755dd7785d22456dd39bb08Kenneth Graunke	brw_set_src1(c, brw_call_inst, brw_imm_d(offset * 16));
312c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    }
313c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
314c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    /* free linked list of calls */
315c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    {
316c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul        struct brw_glsl_call *call, *next;
317c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul        for (call = c->first_call; call; call = next) {
318c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	    next = call->next;
31932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	    free(call);
320c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	}
321c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	c->first_call = NULL;
322c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    }
323c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul
324c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    /* free linked list of labels */
325c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    {
326c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul        struct brw_glsl_label *label, *next;
327c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	for (label = c->first_label; label; label = next) {
328c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	    next = label->next;
32932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	    free(label);
330c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	}
331c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul	c->first_label = NULL;
332c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul    }
333c51c822ee02cb47ddba46da668577d51b7c02831Brian Paul}
334