ir_to_mesa.cpp revision 0a1b54df7ac118722bb627c61cb322cb4e248ace
184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/*
284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Copyright © 2010 Intel Corporation
384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * copy of this software and associated documentation files (the "Software"),
684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * to deal in the Software without restriction, including without limitation
784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software is furnished to do so, subject to the following conditions:
1084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
1184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * The above copyright notice and this permission notice (including the next
1284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * paragraph) shall be included in all copies or substantial portions of the
1384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software.
1484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
1584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * DEALINGS IN THE SOFTWARE.
2284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
2384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/**
2584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * \file ir_to_mesa.cpp
2684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
2784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Translates the IR to ARB_fragment_program text if possible,
2884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * printing the result
2984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
3084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
310161515c395c44233529c8d51f823b60050bc7baEric Anholt#include <stdio.h>
3284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h"
3384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h"
3484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h"
3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h"
3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h"
3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
38aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" {
390a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h"
4084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "shader/prog_instruction.h"
41aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt#include "shader/prog_print.h"
42aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt}
4384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
44554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/**
45554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with
46554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields.
47554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */
48554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg {
49554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
50554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
51554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
52554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int negate; /**< NEGATE_XYZW mask from mesa */
53554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   bool reladdr; /**< Register index should be offset by address reg. */
54554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg;
55554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
56554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg {
57554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
58554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
59554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
60554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg;
61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
62554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef;
63554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
64554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node {
65554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
66554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   enum prog_opcode op;
67554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_dst_reg dst_reg;
68554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_src_reg src_reg[3];
69554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** Pointer to the ir source this tree came from for debugging */
70554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_instruction *ir;
71554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
72554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
73554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass temp_entry : public exec_node {
74554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
75554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   temp_entry(ir_variable *var, int file, int index)
76554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      : file(file), index(index), var(var)
77554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   {
78554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      /* empty */
79554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   }
80554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
81554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file;
82554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index;
83554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_variable *var; /* variable that maps to this, if any */
84554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
85554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
86554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor {
87554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
88554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_visitor();
89554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
90554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int next_temp;
91554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int next_constant;
92a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   int next_uniform;
93a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
94a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   temp_entry *find_variable_storage(ir_variable *var);
95554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
968364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   ir_to_mesa_src_reg get_temp(const glsl_type *type);
97554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg src_reg_for_float(float val);
99554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /**
101554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * \name Visit methods
102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    *
103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * As typical for the visitor pattern, there must be one \c visit method for
104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * each concrete subclass of \c ir_instruction.  Virtual base classes within
105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * the hierarchy should not have \c visit methods.
106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    */
107554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@{*/
108554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_variable *);
109554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop *);
110554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop_jump *);
111554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function_signature *);
112554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function *);
113554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_expression *);
114554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_swizzle *);
115554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_variable  *);
116554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_array *);
117554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_record *);
118554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_assignment *);
119554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_constant *);
120554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_call *);
121554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_return *);
122554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_texture *);
123554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_if *);
124554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@}*/
125554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
126554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg result;
127554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
128554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** List of temp_entry */
129554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   exec_list variable_storage;
130554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
131554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** List of ir_to_mesa_instruction */
132554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   exec_list instructions;
133554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
134554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
135554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
136554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
137554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0);
138554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
139554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
140554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
141554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
142554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
143554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1);
144554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
145554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
146554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
147554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
148554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
149554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1,
150554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src2);
151554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
152554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
153554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   enum prog_opcode op,
154554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_dst_reg dst,
155554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_src_reg src0);
1560ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt
1570ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt   /* talloc context (the ) */
1580ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt   void *ctx;
159554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
160554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
16184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_src_reg ir_to_mesa_undef = {
162c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false,
16384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt};
16484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
165c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
166c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
167c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt};
168c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1690161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = {
1700161515c395c44233529c8d51f823b60050bc7baEric Anholt   PROGRAM_ADDRESS, 0, WRITEMASK_X
1710161515c395c44233529c8d51f823b60050bc7baEric Anholt};
1720161515c395c44233529c8d51f823b60050bc7baEric Anholt
1730161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size)
1740161515c395c44233529c8d51f823b60050bc7baEric Anholt{
1750161515c395c44233529c8d51f823b60050bc7baEric Anholt   int size_swizzles[4] = {
1760161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
1770161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
1780161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
1790161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
1800161515c395c44233529c8d51f823b60050bc7baEric Anholt   };
1810161515c395c44233529c8d51f823b60050bc7baEric Anholt
1820161515c395c44233529c8d51f823b60050bc7baEric Anholt   return size_swizzles[size - 1];
1830161515c395c44233529c8d51f823b60050bc7baEric Anholt}
1840161515c395c44233529c8d51f823b60050bc7baEric Anholt
1858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt/* This list should match up with builtin_variables.h */
1868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholtstatic const struct {
1878364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   const char *name;
1888364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   int file;
1898364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   int index;
1908364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt} builtin_var_to_mesa_reg[] = {
1918364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* core_vs */
1928364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Position", PROGRAM_OUTPUT, VERT_RESULT_HPOS},
1938364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_PointSize", PROGRAM_OUTPUT, VERT_RESULT_PSIZ},
1948364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
1958364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* core_fs */
1968364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FragCoord", PROGRAM_INPUT, FRAG_ATTRIB_WPOS},
1978364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FrontFacing", PROGRAM_INPUT, FRAG_ATTRIB_FACE},
1988364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FragColor", PROGRAM_OUTPUT, FRAG_ATTRIB_COL0},
1998364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FragDepth", PROGRAM_UNDEFINED, FRAG_ATTRIB_WPOS}, /* FINISHME: WPOS.z */
2008364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2018364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* 110_deprecated_fs */
2028364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Color", PROGRAM_INPUT, FRAG_ATTRIB_COL0},
2038364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_SecondaryColor", PROGRAM_INPUT, FRAG_ATTRIB_COL1},
2048364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FogFragCoord", PROGRAM_INPUT, FRAG_ATTRIB_FOGC},
2058364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_TexCoord", PROGRAM_INPUT, FRAG_ATTRIB_TEX0}, /* array */
2068364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2078364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* 110_deprecated_vs */
2088364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Vertex", PROGRAM_INPUT, VERT_ATTRIB_POS},
2098364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Normal", PROGRAM_INPUT, VERT_ATTRIB_NORMAL},
2108364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Color", PROGRAM_INPUT, VERT_ATTRIB_COLOR0},
2118364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_SecondaryColor", PROGRAM_INPUT, VERT_ATTRIB_COLOR1},
2128364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord0", PROGRAM_INPUT, VERT_ATTRIB_TEX0},
2138364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord1", PROGRAM_INPUT, VERT_ATTRIB_TEX1},
2148364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord2", PROGRAM_INPUT, VERT_ATTRIB_TEX2},
2158364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord3", PROGRAM_INPUT, VERT_ATTRIB_TEX3},
2168364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord4", PROGRAM_INPUT, VERT_ATTRIB_TEX4},
2178364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord5", PROGRAM_INPUT, VERT_ATTRIB_TEX5},
2188364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord6", PROGRAM_INPUT, VERT_ATTRIB_TEX6},
2198364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord7", PROGRAM_INPUT, VERT_ATTRIB_TEX7},
2208364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_TexCoord", PROGRAM_OUTPUT, VERT_RESULT_TEX0}, /* array */
2218364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FogCoord", PROGRAM_INPUT, VERT_RESULT_FOGC},
2228364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /*{"gl_ClipVertex", PROGRAM_OUTPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
2238364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FrontColor", PROGRAM_OUTPUT, VERT_RESULT_COL0},
2248364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_BackColor", PROGRAM_OUTPUT, VERT_RESULT_BFC0},
2258364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FrontSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_COL1},
2268364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_BackSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_BFC1},
2278364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FogFragCoord", PROGRAM_OUTPUT, VERT_RESULT_FOGC},
2288364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2298364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* 130_vs */
2308364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /*{"gl_VertexID", PROGRAM_INPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
2318364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2328364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FragData", PROGRAM_OUTPUT, FRAG_RESULT_DATA0}, /* array */
2338364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt};
2348364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
23584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2360161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
2370161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2380161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2390161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
2400161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1,
2410161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src2)
24284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
2430ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt   ir_to_mesa_instruction *inst = new(ctx) ir_to_mesa_instruction();
24484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
24584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->op = op;
24684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->dst_reg = dst;
24784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[0] = src0;
24884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[1] = src1;
24984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[2] = src2;
250c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   inst->ir = ir;
25184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2520161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->instructions.push_tail(inst);
25384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
25484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return inst;
25584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
25684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
25784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
25884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2590161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
2600161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2610161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2620161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
2630161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1)
26484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
2650161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
26684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
26784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
26884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2690161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
2700161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2710161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2720161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0)
273bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{
2740161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst,
2750161515c395c44233529c8d51f823b60050bc7baEric Anholt			      src0, ir_to_mesa_undef, ir_to_mesa_undef);
276bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
277bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
2780161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg
2790161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
28084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
2810161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_dst_reg dst_reg;
28284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2830161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.file = reg.file;
2840161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.index = reg.index;
2850161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.writemask = WRITEMASK_XYZW;
2860161515c395c44233529c8d51f823b60050bc7baEric Anholt
2870161515c395c44233529c8d51f823b60050bc7baEric Anholt   return dst_reg;
288bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
289bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
29012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/**
29112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels.
29212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt *
29312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
29412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels.  So to do a vec4
29512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used
29612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels.
29712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */
29812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid
2990161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
3000161515c395c44233529c8d51f823b60050bc7baEric Anholt					       enum prog_opcode op,
3010161515c395c44233529c8d51f823b60050bc7baEric Anholt					       ir_to_mesa_dst_reg dst,
3020161515c395c44233529c8d51f823b60050bc7baEric Anholt					       ir_to_mesa_src_reg src0)
30312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{
30412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   int i, j;
305315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int done_mask = ~dst.writemask;
30612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
30712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   /* Mesa RCP is a scalar operation splatting results to all channels,
30812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
30912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * dst channels.
31012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    */
31112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   for (i = 0; i < 4; i++) {
31212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      int this_mask = (1 << i);
31312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_instruction *inst;
31412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_src_reg src = src0;
31512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
31612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      if (done_mask & this_mask)
31712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 continue;
31812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
31912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      int src_swiz = GET_SWZ(src.swizzle, i);
32012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      for (j = i + 1; j < 4; j++) {
321315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt	 if (!(done_mask & (1 << j)) && GET_SWZ(src.swizzle, j) == src_swiz) {
32212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	    this_mask |= (1 << j);
32312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 }
32412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      }
32512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      src.swizzle = MAKE_SWIZZLE4(src_swiz, src_swiz,
32612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt				  src_swiz, src_swiz);
32712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
3280161515c395c44233529c8d51f823b60050bc7baEric Anholt      inst = ir_to_mesa_emit_op1(ir, op,
3290161515c395c44233529c8d51f823b60050bc7baEric Anholt				 dst,
3300161515c395c44233529c8d51f823b60050bc7baEric Anholt				 src);
33112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      inst->dst_reg.writemask = this_mask;
33212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      done_mask |= this_mask;
33312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   }
33412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt}
33512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
3360161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg
3370161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val)
338b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
3390161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
3401d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
3411d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   /* FINISHME: This will end up being _mesa_add_unnamed_constant,
3421d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt    * which handles sharing values and sharing channels of vec4
3431d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt    * constants for small values.
3441d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt    */
3451d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   /* FINISHME: Do something with the constant values for now.
3461d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt    */
3471d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   (void)val;
3480161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.file = PROGRAM_CONSTANT;
3490161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.index = this->next_constant++;
3500161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = SWIZZLE_NOOP;
3511d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
3520161515c395c44233529c8d51f823b60050bc7baEric Anholt   return src_reg;
3531d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt}
3541d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
35584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/**
35684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * In the initial pass of codegen, we assign temporary numbers to
35784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * intermediate results.  (not SSA -- variable assignments will reuse
35884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * storage).  Actual register allocation for the Mesa VM occurs in a
35984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * pass over the Mesa IR later.
36084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
3610161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_src_reg
3628364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type)
36384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3640161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
365315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int swizzle[4];
3663d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt   int i;
3673d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt
3688364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   assert(!type->is_array());
3698364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
3700161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.file = PROGRAM_TEMPORARY;
3718364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.index = type->matrix_columns;
372f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt   src_reg.reladdr = false;
3733d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt
3748364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   for (i = 0; i < type->vector_elements; i++)
375315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt      swizzle[i] = i;
3763d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt   for (; i < 4; i++)
3778364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      swizzle[i] = type->vector_elements - 1;
3780161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
3790161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[2], swizzle[3]);
3800161515c395c44233529c8d51f823b60050bc7baEric Anholt
3810161515c395c44233529c8d51f823b60050bc7baEric Anholt   return src_reg;
38284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
38384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3842c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int
3852c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type)
3862c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
3872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
3882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int size;
3892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
3902c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   switch (type->base_type) {
3912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_UINT:
3922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_INT:
3932c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_FLOAT:
3942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_BOOL:
395a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      if (type->is_matrix()) {
396a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return 4; /* FINISHME: Not all matrices are 4x4. */
397a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      } else {
398a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 /* Regardless of size of vector, it gets a vec4. This is bad
399a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * packing for things like floats, but otherwise arrays become a
400a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * mess.  Hopefully a later pass over the code can pack scalars
401a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * down if appropriate.
402a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  */
403a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return 1;
404a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      }
4052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_ARRAY:
4062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return type_size(type->fields.array) * type->length;
4072c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_STRUCT:
4082c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      size = 0;
4092c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      for (i = 0; i < type->length; i++) {
4102c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 size += type_size(type->fields.structure[i].type);
4112c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      }
4122c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return size;
4132c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   default:
4142c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(0);
4152c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
4162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
4172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
418a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholttemp_entry *
419a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var)
42084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
421a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
42284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   temp_entry *entry;
42384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
42484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, this->variable_storage) {
42584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      entry = (temp_entry *)iter.get();
42684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
4270161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (entry->var == var)
428a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return entry;
42984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
43084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
431a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   return NULL;
432a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt}
43384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
43484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
43584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir)
43684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
4378364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   (void)ir;
43884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
43984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
44084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
44184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir)
44284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
44364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->from);
44464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->to);
44564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->increment);
44664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->counter);
44784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
4480161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_emit_op1(NULL, OPCODE_BGNLOOP,
4490161515c395c44233529c8d51f823b60050bc7baEric Anholt		       ir_to_mesa_undef_dst, ir_to_mesa_undef);
45064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt
45164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   visit_exec_list(&ir->body_instructions, this);
45264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt
4530161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_emit_op1(NULL, OPCODE_ENDLOOP,
4540161515c395c44233529c8d51f823b60050bc7baEric Anholt		       ir_to_mesa_undef_dst, ir_to_mesa_undef);
45584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
45684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
45784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
45884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir)
45984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
46064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   switch (ir->mode) {
46164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_break:
4620161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(NULL, OPCODE_BRK,
4630161515c395c44233529c8d51f823b60050bc7baEric Anholt			  ir_to_mesa_undef_dst, ir_to_mesa_undef);
46464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
46564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_continue:
4660161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(NULL, OPCODE_CONT,
4670161515c395c44233529c8d51f823b60050bc7baEric Anholt			  ir_to_mesa_undef_dst, ir_to_mesa_undef);
46864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
46964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   }
47084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
47184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
47284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
47384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
47484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir)
47584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
47684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
47784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   (void)ir;
47884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
47984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
48084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
48184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir)
48284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
48384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
48484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
48584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
48684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (strcmp(ir->name, "main") == 0) {
48784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      const ir_function_signature *sig;
48884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exec_list empty;
48984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
49084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      sig = ir->matching_signature(&empty);
49184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
49284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      assert(sig);
49384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
49484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      foreach_iter(exec_list_iterator, iter, sig->body) {
49584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_instruction *ir = (ir_instruction *)iter.get();
49684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
49784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->accept(this);
49884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
49984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
50084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
50184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
50284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
50384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir)
50484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
50584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   unsigned int operand;
506f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt   struct ir_to_mesa_src_reg op[2];
5070161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg result_src;
5080161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg result_dst;
50984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
51084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
51184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
51284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
51384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
5140161515c395c44233529c8d51f823b60050bc7baEric Anholt      this->result.file = PROGRAM_UNDEFINED;
51584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->operands[operand]->accept(this);
5160161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (this->result.file == PROGRAM_UNDEFINED) {
51784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_print_visitor v;
51884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("Failed to get tree for expression operand:\n");
51984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->operands[operand]->accept(&v);
52084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
52184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
52284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      op[operand] = this->result;
5238364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
5248364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      /* Only expression implemented for matrices yet */
5258364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      assert(!ir->operands[operand]->type->is_matrix() ||
5268364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	     ir->operation == ir_binop_mul);
52784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
52884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
5290161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.file = PROGRAM_UNDEFINED;
5300161515c395c44233529c8d51f823b60050bc7baEric Anholt
5310161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
5320161515c395c44233529c8d51f823b60050bc7baEric Anholt    * the actual storage for the result here, instead.
5330161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
5348364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   result_src = get_temp(ir->type);
5350161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* convenience for the emit functions below. */
5360161515c395c44233529c8d51f823b60050bc7baEric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
5379cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   /* Limit writes to the channels that will be used by result_src later.
5389cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * This does limit this temp's use as a temporary for multi-instruction
5399cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * sequences.
5409cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    */
5419cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
54284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
54384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   switch (ir->operation) {
5441d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_logic_not:
545f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
546f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt			  op[0], src_reg_for_float(0.0));
5471d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
548c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   case ir_unop_neg:
5490161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
5500161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
551c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      break;
5528c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp:
5530161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EXP, result_dst, op[0]);
5548c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
5558c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp2:
5560161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
5578c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
5588c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log:
5590161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
5608c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
5618c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log2:
5620161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
5638c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
5643c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_sin:
5650161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
5663c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
5673c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_cos:
5680161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
5693c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
57084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_add:
5710161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
57284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_sub:
5740161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
57684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_mul:
5778364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      if (ir->operands[0]->type->is_matrix() &&
5788364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	  !ir->operands[1]->type->is_matrix()) {
5798364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 if (ir->operands[0]->type->is_scalar()) {
5808364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_dst_reg dst_column = result_dst;
5818364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_src_reg src_column = op[0];
5828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
5838364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       ir_to_mesa_emit_op2(ir, OPCODE_MUL,
5848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt				   dst_column, src_column, op[1]);
5858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       dst_column.index++;
5868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       src_column.index++;
5878364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    }
5888364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 } else {
5898364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_dst_reg dst_chan = result_dst;
5908364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_src_reg src_column = op[0];
5918364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_src_reg src_chan = op[1];
5928364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
5938364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       dst_chan.writemask = (1 << i);
5948364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       src_chan.swizzle = MAKE_SWIZZLE4(i, i, i, i);
5958364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       ir_to_mesa_emit_op2(ir, OPCODE_MUL,
5968364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt				   dst_chan, src_column, src_chan);
5978364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       src_column.index++;
5988364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    }
5998364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 }
6008364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      } else {
6018364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 assert(!ir->operands[0]->type->is_matrix());
6028364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 assert(!ir->operands[1]->type->is_matrix());
6038364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
6048364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      }
60584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
60684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_div:
6070161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[1]);
6089d2b8e0b70acce2678bea2cb6a990e0dee380b37Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], result_src);
60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
61038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
61138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_less:
612f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
61338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
61438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_greater:
615f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
61638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
61738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_lequal:
618f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
61938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
62038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_gequal:
621f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
62238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
62338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_equal:
624f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
62538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
626763cd75863ed9a16912e585887580c44d1e8109fEric Anholt   case ir_binop_logic_xor:
62738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_nequal:
628f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
62938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
63038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
6314380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_or:
6320161515c395c44233529c8d51f823b60050bc7baEric Anholt      /* This could be a saturated add and skip the SNE. */
6330161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD,
6340161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
6350161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
6360161515c395c44233529c8d51f823b60050bc7baEric Anholt
6370161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
6380161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
6390161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
6404380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
6414380099c98119611ceee684669d00be26195c7d7Eric Anholt
6424380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_and:
6434380099c98119611ceee684669d00be26195c7d7Eric Anholt      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
6440161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL,
6450161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
6460161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
6474380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
6484380099c98119611ceee684669d00be26195c7d7Eric Anholt
64984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_dot:
65084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (ir->operands[0]->type == vec4_type) {
65184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec4_type);
6520161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
6530161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
6540161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
65584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec3_type) {
65684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec3_type);
6570161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
6580161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
6590161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
66084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec2_type) {
66184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec2_type);
6620161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
6630161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
6640161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
66584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
66684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
66784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_unop_sqrt:
6680161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
6690161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_RCP, result_dst, result_src);
67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
671878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt   case ir_unop_rsq:
6720161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
673878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt      break;
67450ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   case ir_unop_i2f:
675423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      /* Mesa IR lacks types, ints are stored as truncated floats. */
6760161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
67750ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt      break;
678423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt   case ir_unop_f2i:
6790161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
680423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      break;
6811d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_f2b:
6820161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
6830161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
6841d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
685c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_trunc:
6860161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
687c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
688c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_ceil:
6890161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
6900161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
6910161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src.negate = ~result_src.negate;
692c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
693c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_floor:
6940161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
695c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
696c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_min:
6970161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
698c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
699c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_max:
7000161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
701c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
70284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   default:
70384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_print_visitor v;
70484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      printf("Failed to get tree for expression:\n");
70584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->accept(&v);
70684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exit(1);
7070161515c395c44233529c8d51f823b60050bc7baEric Anholt      break;
70884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
709b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt
7100161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = result_src;
71184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
71284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
71384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
71484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
71584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir)
71684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
7170161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
71884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int i;
71984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int swizzle[4];
72084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
721b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   /* Note that this is only swizzles in expressions, not those on the left
722b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * hand side of an assignment, which do write masking.  See ir_assignment
723b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * for that.
724b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    */
72584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
72684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->val->accept(this);
7274006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   src_reg = this->result;
7284006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   assert(src_reg.file != PROGRAM_UNDEFINED);
72984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
73084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (i = 0; i < 4; i++) {
73184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (i < ir->type->vector_elements) {
73284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 switch (i) {
73384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 0:
73484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    swizzle[i] = ir->mask.x;
73584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
73684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 1:
73784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    swizzle[i] = ir->mask.y;
73884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
73984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 2:
74084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    swizzle[i] = ir->mask.z;
74184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
74284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 3:
74384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    swizzle[i] = ir->mask.w;
74484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
74584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 }
74684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else {
74784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 /* If the type is smaller than a vec4, replicate the last
74884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  * channel out.
74984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  */
75084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 swizzle[i] = ir->type->vector_elements - 1;
75184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
75284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
75384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7540161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
7550161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[1],
7560161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[2],
7570161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[3]);
75884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7590161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
76084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
76184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
76284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
76384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir)
76484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
7650161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
7668364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   temp_entry *entry = find_variable_storage(ir->var);
7678364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   unsigned int i;
7688364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   bool var_in;
76984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7708364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   if (!entry) {
7718364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      switch (ir->var->mode) {
7728364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_uniform:
7730ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt	 entry = new(ctx)  temp_entry(ir->var, PROGRAM_UNIFORM,
7740ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt				      this->next_uniform);
7758364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 this->variable_storage.push_tail(entry);
776224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
7778364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 this->next_uniform += type_size(ir->var->type);
7788364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
7798364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_in:
7808364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_out:
7818364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_inout:
7828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 var_in = (ir->var->mode == ir_var_in ||
7838364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt		   ir->var->mode == ir_var_inout);
7848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
7858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) {
7868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    bool in = builtin_var_to_mesa_reg[i].file == PROGRAM_INPUT;
7878364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
7888364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    if (strcmp(ir->var->name, builtin_var_to_mesa_reg[i].name) == 0 &&
7898364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt		!(var_in ^ in))
7908364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       break;
7918364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 }
7928364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 if (i == ARRAY_SIZE(builtin_var_to_mesa_reg)) {
7938364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    printf("Failed to find builtin for %s variable %s\n",
7948364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt		   var_in ? "in" : "out",
7958364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt		   ir->var->name);
7968364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    abort();
7978364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 }
7980ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt	 entry = new(ctx)  temp_entry(ir->var,
7990ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt				      builtin_var_to_mesa_reg[i].file,
8000ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt				      builtin_var_to_mesa_reg[i].index);
8018364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
8028364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_auto:
8030ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt	 entry = new(ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
8040ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt				     this->next_temp);
8058364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 this->variable_storage.push_tail(entry);
806224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
8078364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 next_temp += type_size(ir->var->type);
8088364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
80984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
8108364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
8118364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      if (!entry) {
8128364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 printf("Failed to make storage for %s\n", ir->var->name);
8138364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 exit(1);
814224f712950494730c76b48864f2ca19acde1c8cfEric Anholt      }
81584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
81684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
8178364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.file = entry->file;
8188364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.index = entry->index;
81984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
8208364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
8210161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.reladdr = false;
8220161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.negate = 0;
82384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
8240161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
82584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
82684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
82784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
82884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir)
82984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
830ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir_constant *index;
8310161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
832ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt
833ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   index = ir->array_index->constant_expression_value();
8344e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
8354e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   /* By the time we make it to this stage, matrices should be broken down
8364e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt    * to vectors.
8374e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt    */
838ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   assert(!ir->type->is_matrix());
8394e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
840ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir->array->accept(this);
8410161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg = this->result;
8424e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
8430161515c395c44233529c8d51f823b60050bc7baEric Anholt   if (src_reg.file == PROGRAM_INPUT ||
8440161515c395c44233529c8d51f823b60050bc7baEric Anholt       src_reg.file == PROGRAM_OUTPUT) {
845ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt      assert(index); /* FINISHME: Handle variable indexing of builtins. */
8464e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
8470161515c395c44233529c8d51f823b60050bc7baEric Anholt      src_reg.index += index->value.i[0];
8484e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   } else {
849bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      if (index) {
8500161515c395c44233529c8d51f823b60050bc7baEric Anholt	 src_reg.index += index->value.i[0];
851bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      } else {
8520161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_src_reg array_base = this->result;
853bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 /* Variable index array dereference.  It eats the "vec4" of the
854bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  * base of the array and an index that offsets the Mesa register
855bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  * index.
856bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  */
857bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 ir->array_index->accept(this);
858bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt
8590161515c395c44233529c8d51f823b60050bc7baEric Anholt	 /* FINISHME: This doesn't work when we're trying to do the LHS
8600161515c395c44233529c8d51f823b60050bc7baEric Anholt	  * of an assignment.
8610161515c395c44233529c8d51f823b60050bc7baEric Anholt	  */
8620161515c395c44233529c8d51f823b60050bc7baEric Anholt	 src_reg.reladdr = true;
8630161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
8640161515c395c44233529c8d51f823b60050bc7baEric Anholt			     this->result);
8650161515c395c44233529c8d51f823b60050bc7baEric Anholt
8668364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 this->result = get_temp(ir->type);
8670161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV,
8680161515c395c44233529c8d51f823b60050bc7baEric Anholt			     ir_to_mesa_dst_reg_from_src(this->result),
8690161515c395c44233529c8d51f823b60050bc7baEric Anholt			     src_reg);
870bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      }
8714e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   }
87284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
87384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
8740161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
87584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
8760161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
87784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
87884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
8792c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid
8802c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir)
8812c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
8822c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
8830161515c395c44233529c8d51f823b60050bc7baEric Anholt   const glsl_type *struct_type = ir->record->type;
8842c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int offset = 0;
8852c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
8860161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir->record->accept(this);
8872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
8882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   for (i = 0; i < struct_type->length; i++) {
8890161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
8902c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 break;
8912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
8922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
8930161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.index += offset;
8942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
8952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
8962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/**
8972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage
8982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the
8992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler.
9002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt *
9012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
9022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * should only see potentially one variable array index of a vector,
9032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * and one swizzle, before getting to actual vec4 storage.  So handle
9042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * those, then go use ir_dereference to handle the rest.
9052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */
9060161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg
907b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtget_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
908b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
9090161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg dst_reg;
910b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_dereference *deref;
911b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_swizzle *swiz;
912b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
9130161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Use the rvalue deref handler for the most part.  We'll ignore
9140161515c395c44233529c8d51f823b60050bc7baEric Anholt    * swizzles in it and write swizzles using writemask, though.
9150161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
9162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   ir->accept(v);
9170161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
9182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
919b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   if ((deref = ir->as_dereference())) {
9202c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      ir_dereference_array *deref_array = ir->as_dereference_array();
9212c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(!deref_array || deref_array->array->type->is_array());
9222c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
923b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      ir->accept(v);
924b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   } else if ((swiz = ir->as_swizzle())) {
9250161515c395c44233529c8d51f823b60050bc7baEric Anholt      dst_reg.writemask = 0;
926b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 1)
9270161515c395c44233529c8d51f823b60050bc7baEric Anholt	 dst_reg.writemask |= (1 << swiz->mask.x);
928b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 2)
9290161515c395c44233529c8d51f823b60050bc7baEric Anholt	 dst_reg.writemask |= (1 << swiz->mask.y);
930b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 3)
9310161515c395c44233529c8d51f823b60050bc7baEric Anholt	 dst_reg.writemask |= (1 << swiz->mask.z);
932b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 4)
9330161515c395c44233529c8d51f823b60050bc7baEric Anholt	 dst_reg.writemask |= (1 << swiz->mask.w);
934b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   }
935b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
9360161515c395c44233529c8d51f823b60050bc7baEric Anholt   return dst_reg;
937b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt}
938b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
93984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
94084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir)
94184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
9420161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg l;
9430161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg r;
94484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(!ir->lhs->type->is_matrix());
9462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(!ir->lhs->type->is_array());
9472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT);
9482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
949b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   l = get_assignment_lhs(ir->lhs, this);
950b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
95184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->rhs->accept(this);
95284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   r = this->result;
9530161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(l.file != PROGRAM_UNDEFINED);
9540161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(r.file != PROGRAM_UNDEFINED);
95584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
956346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   if (ir->condition) {
957346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 ir_constant *condition_constant;
958346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt
959346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 condition_constant = ir->condition->constant_expression_value();
960346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt
961346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 assert(condition_constant && condition_constant->value.b[0]);
962346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   }
96384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9640161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
96584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
96684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
96784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
96884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
96984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir)
97084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
9710161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
97284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
97350ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   assert(ir->type->base_type == GLSL_TYPE_FLOAT ||
97450ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt	  ir->type->base_type == GLSL_TYPE_UINT ||
97550ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt	  ir->type->base_type == GLSL_TYPE_INT ||
97650ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt	  ir->type->base_type == GLSL_TYPE_BOOL);
97784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
97884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* FINISHME: This will end up being _mesa_add_unnamed_constant,
97984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * which handles sharing values and sharing channels of vec4
98084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * constants for small values.
98184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
98284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* FINISHME: Do something with the constant values for now.
98384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
9840161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.file = PROGRAM_CONSTANT;
98576720647566db8126b9f29a0e705ba03ebcdad27Eric Anholt   src_reg.index = this->next_constant;
9860161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = SWIZZLE_NOOP;
9870161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.reladdr = false;
9880161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.negate = 0;
98984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
99076720647566db8126b9f29a0e705ba03ebcdad27Eric Anholt   this->next_constant += type_size(ir->type);
99176720647566db8126b9f29a0e705ba03ebcdad27Eric Anholt
9920161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
99384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
99484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
99584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
99684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
99784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir)
99884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
99984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   printf("Can't support call to %s\n", ir->callee_name());
100084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   exit(1);
100184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
100284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
100384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
100484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
100584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir)
100684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
100784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
100884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
100984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->coordinate->accept(this);
101084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
101184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
101284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
101384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir)
101484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
101584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
101684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
101784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->get_value()->accept(this);
101884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
101984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
102084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
102184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
102284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir)
102384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1024c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_to_mesa_instruction *if_inst, *else_inst = NULL;
1025c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1026c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir->condition->accept(this);
10270161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(this->result.file != PROGRAM_UNDEFINED);
1028c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
10290161515c395c44233529c8d51f823b60050bc7baEric Anholt   if_inst = ir_to_mesa_emit_op1(ir->condition,
10300161515c395c44233529c8d51f823b60050bc7baEric Anholt				 OPCODE_IF, ir_to_mesa_undef_dst,
10310161515c395c44233529c8d51f823b60050bc7baEric Anholt				 this->result);
1032c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1033c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   this->instructions.push_tail(if_inst);
1034c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1035c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   visit_exec_list(&ir->then_instructions, this);
1036c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1037c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if (!ir->else_instructions.is_empty()) {
10380161515c395c44233529c8d51f823b60050bc7baEric Anholt      else_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ELSE,
10390161515c395c44233529c8d51f823b60050bc7baEric Anholt				      ir_to_mesa_undef_dst,
10400161515c395c44233529c8d51f823b60050bc7baEric Anholt				      ir_to_mesa_undef);
1041c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      visit_exec_list(&ir->then_instructions, this);
1042c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1043c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
10440161515c395c44233529c8d51f823b60050bc7baEric Anholt   if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
10450161515c395c44233529c8d51f823b60050bc7baEric Anholt				 ir_to_mesa_undef_dst, ir_to_mesa_undef);
104684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
104784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1048ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor()
1049ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{
10500161515c395c44233529c8d51f823b60050bc7baEric Anholt   result.file = PROGRAM_UNDEFINED;
1051ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_temp = 1;
1052ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_constant = 0;
1053a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   next_uniform = 0;
1054ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt}
1055ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt
105684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register
105784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
105884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
105984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_src_register mesa_reg;
106084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
106184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.File = reg.file;
1062aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
106384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.Index = reg.index;
106434195832669f0eb7c4a80997cc524f8d10319307Eric Anholt   mesa_reg.Swizzle = reg.swizzle;
1065bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt   mesa_reg.RelAddr = reg.reladdr;
106684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
106784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return mesa_reg;
106884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
106984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1070c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
1071c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtset_branchtargets(struct prog_instruction *mesa_instructions,
1072c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt		  int num_instructions)
1073c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
107464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_count = 0, loop_count;
107564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int *if_stack, *loop_stack;
107664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_stack_pos = 0, loop_stack_pos = 0;
107764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int i, j;
1078c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1079c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
108064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      switch (mesa_instructions[i].Opcode) {
108164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_IF:
1082c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_count++;
108364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
108464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
108564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_count++;
108664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
108764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BRK:
108864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_CONT:
108964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = -1;
109064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
109164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      default:
109264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
109364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      }
1094c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1095c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
109664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   if_stack = (int *)calloc(if_count, sizeof(*if_stack));
109764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
1098c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1099c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1100c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      switch (mesa_instructions[i].Opcode) {
1101c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_IF:
110264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos] = i;
1103c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos++;
1104c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1105c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ELSE:
110664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
110764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos - 1] = i;
1108c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1109c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ENDIF:
111064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1111c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos--;
1112c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
111364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
111464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack[loop_stack_pos] = i;
111564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos++;
111664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
111764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_ENDLOOP:
111864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos--;
111964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* Rewrite any breaks/conts at this nesting level (haven't
112064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * already had a BranchTarget assigned) to point to the end
112164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * of the loop.
112264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  */
112364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
112464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    if (mesa_instructions[j].Opcode == OPCODE_BRK ||
112564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		mesa_instructions[j].Opcode == OPCODE_CONT) {
112664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       if (mesa_instructions[j].BranchTarget == -1) {
112764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		  mesa_instructions[j].BranchTarget = i;
112864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       }
112964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    }
113064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 }
113164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* The loop ends point at each other. */
113264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
113364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
1134c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      default:
1135c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1136c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1137c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1138c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1139c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   free(if_stack);
1140c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1141c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1142c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
1143c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions,
1144c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      ir_instruction **mesa_instruction_annotation,
1145c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      int num_instructions)
1146c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
1147c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction *last_ir = NULL;
1148c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
1149c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1150c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1151c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      struct prog_instruction *mesa_inst = mesa_instructions + i;
1152c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      ir_instruction *ir = mesa_instruction_annotation[i];
1153c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
115464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      if (last_ir != ir && ir) {
1155c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 ir_print_visitor print;
1156c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 ir->accept(&print);
1157c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 printf("\n");
1158c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 last_ir = ir;
1159c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1160c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1161c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      _mesa_print_instruction(mesa_inst);
1162c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1163c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1164c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
116584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
116684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtdo_ir_to_mesa(exec_list *instructions)
116784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
116884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir_to_mesa_visitor v;
116984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_instruction *mesa_instructions, *mesa_inst;
1170c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction **mesa_instruction_annotation;
1171c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
117284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
11730ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt   v.ctx = talloc_new(NULL);
117484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   visit_exec_list(instructions, &v);
117584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
117684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int num_instructions = 0;
117784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
117884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      num_instructions++;
117984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
118084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
118184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_instructions =
118284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      (struct prog_instruction *)calloc(num_instructions,
118384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					sizeof(*mesa_instructions));
1184c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   mesa_instruction_annotation =
1185c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      (ir_instruction **)calloc(num_instructions,
1186c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt				sizeof(*mesa_instruction_annotation));
118784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
118884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_inst = mesa_instructions;
1189c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   i = 0;
119084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
119184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
1192b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt
119384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->Opcode = inst->op;
119484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.File = inst->dst_reg.file;
119584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.Index = inst->dst_reg.index;
11968197eeee3bbca4ab2deacfbf675285560f49e13cEric Anholt      mesa_inst->DstReg.CondMask = COND_TR;
119712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
119884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
119984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
120084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
1201c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      mesa_instruction_annotation[i] = inst->ir;
1202aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt
120384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst++;
1204c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      i++;
120584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
1206c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1207c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   set_branchtargets(mesa_instructions, num_instructions);
1208c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   print_program(mesa_instructions, mesa_instruction_annotation, num_instructions);
1209c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1210c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   free(mesa_instruction_annotation);
12110ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt   talloc_free(v.ctx);
121284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
1213