ir_to_mesa.cpp revision 346daeca07d3c19c051799f96fa9f442262bd49f
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 3184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/* Quiet compiler warnings due to monoburg not marking functions defined 3284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * in the header as inline. 3384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 3484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#define g_new 3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#define g_error 3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "mesa_codegen.h" 3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h" 3984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h" 4084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h" 4184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h" 4284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h" 4384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 44aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" { 4584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "shader/prog_instruction.h" 46aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt#include "shader/prog_print.h" 47aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt} 4884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 4984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_src_reg ir_to_mesa_undef = { 50c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false, 5184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}; 5284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 53c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = { 54c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP 55c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}; 56c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 5784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 58c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_emit_op3(ir_to_mesa_visitor *v, ir_instruction *ir, 59c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt enum prog_opcode op, 6084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_dst_reg dst, 6184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_src_reg src0, 6284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_src_reg src1, 6384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_src_reg src2) 6484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 6584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_instruction *inst = new ir_to_mesa_instruction(); 6684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 6884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->dst_reg = dst; 6984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[0] = src0; 7084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[1] = src1; 7184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[2] = src2; 72c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 7384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 74c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt v->instructions.push_tail(inst); 7584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 7684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 7784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 7884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 7984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 8084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 81c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_emit_op2_full(ir_to_mesa_visitor *v, ir_instruction *ir, 82c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt enum prog_opcode op, 83bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt ir_to_mesa_dst_reg dst, 84bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt ir_to_mesa_src_reg src0, 85bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt ir_to_mesa_src_reg src1) 8684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 87c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt return ir_to_mesa_emit_op3(v, ir, 88c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt op, dst, src0, src1, ir_to_mesa_undef); 8984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 9084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 92bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholtir_to_mesa_emit_op2(struct mbtree *tree, enum prog_opcode op) 93bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 94c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt return ir_to_mesa_emit_op2_full(tree->v, tree->ir, op, 95bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt tree->dst_reg, 96bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt tree->left->src_reg, 97bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt tree->right->src_reg); 98bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 99bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 100bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholtir_to_mesa_instruction * 101c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_emit_op1_full(ir_to_mesa_visitor *v, ir_instruction *ir, 102c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt enum prog_opcode op, 103bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt ir_to_mesa_dst_reg dst, 104bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt ir_to_mesa_src_reg src0) 10584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 106c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt return ir_to_mesa_emit_op3(v, ir, op, 10784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt dst, src0, ir_to_mesa_undef, ir_to_mesa_undef); 10884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 10984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 110bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholtir_to_mesa_instruction * 111bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholtir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op) 112bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 113c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt return ir_to_mesa_emit_op1_full(tree->v, tree->ir, op, 114bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt tree->dst_reg, 115bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt tree->left->src_reg); 116bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 117bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 11812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 11912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 12012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 12112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 12212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 12312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 12412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 12512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 12612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 12712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtir_to_mesa_emit_scalar_op1(struct mbtree *tree, enum prog_opcode op, 12812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_dst_reg dst, 12912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_src_reg src0) 13012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 13112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 132315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 13312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 13412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 13512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 13612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 13712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 13812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 13912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int this_mask = (1 << i); 14012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 14112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_src_reg src = src0; 14212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 14312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 14412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 14512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 14612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int src_swiz = GET_SWZ(src.swizzle, i); 14712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 148315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt if (!(done_mask & (1 << j)) && GET_SWZ(src.swizzle, j) == src_swiz) { 14912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 15012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 15112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 15212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt src.swizzle = MAKE_SWIZZLE4(src_swiz, src_swiz, 15312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt src_swiz, src_swiz); 15412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 155c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst = ir_to_mesa_emit_op1_full(tree->v, tree->ir, op, 156bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt dst, 157bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt src); 15812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt inst->dst_reg.writemask = this_mask; 15912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 16012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 16112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 16212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 163b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtstatic void 164b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtir_to_mesa_set_tree_reg(struct mbtree *tree, int file, int index) 165b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 166b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->dst_reg.file = file; 167b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->dst_reg.index = index; 168b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 169b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->src_reg.file = file; 170b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->src_reg.index = index; 171b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt} 172b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 17384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstruct mbtree * 174b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholtir_to_mesa_visitor::create_tree(int op, 175b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt ir_instruction *ir, 176b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt struct mbtree *left, struct mbtree *right) 17784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 17884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct mbtree *tree = (struct mbtree *)calloc(sizeof(struct mbtree), 1); 17984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 180b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt assert(ir); 181b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 18284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->op = op; 18384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->left = left; 18484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->right = right; 18584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->v = this; 18684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->src_reg.swizzle = SWIZZLE_XYZW; 187c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt tree->src_reg.negate = 0; 188b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->dst_reg.writemask = WRITEMASK_XYZW; 189b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_to_mesa_set_tree_reg(tree, PROGRAM_UNDEFINED, 0); 190b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt tree->ir = ir; 19184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 19284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return tree; 19384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 19484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1951d20862c8a0e100e43458f01217c047c76da05f3Eric Anholtstruct mbtree * 1961d20862c8a0e100e43458f01217c047c76da05f3Eric Anholtir_to_mesa_visitor::create_tree_for_float(ir_instruction *ir, float val) 1971d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt{ 1981d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt struct mbtree *tree = (struct mbtree *)calloc(sizeof(struct mbtree), 1); 1991d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 2001d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL); 2011d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 2021d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt /* FINISHME: This will end up being _mesa_add_unnamed_constant, 2031d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt * which handles sharing values and sharing channels of vec4 2041d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt * constants for small values. 2051d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt */ 2061d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt /* FINISHME: Do something with the constant values for now. 2071d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt */ 2081d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt (void)val; 2091d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt ir_to_mesa_set_tree_reg(tree, PROGRAM_CONSTANT, this->next_constant++); 2101d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt tree->src_reg.swizzle = SWIZZLE_NOOP; 2111d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 2121d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt this->result = tree; 2131d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt return tree; 2141d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 2151d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 21684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/** 21784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * In the initial pass of codegen, we assign temporary numbers to 21884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * intermediate results. (not SSA -- variable assignments will reuse 21984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 22084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * pass over the Mesa IR later. 22184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 22284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 2233d70d1f4d684a943b8b4a65319641415882b72cbEric Anholtir_to_mesa_visitor::get_temp(struct mbtree *tree, int size) 22484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 225315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int swizzle[4]; 2263d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt int i; 2273d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt 228b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_to_mesa_set_tree_reg(tree, PROGRAM_TEMPORARY, this->next_temp++); 2293d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt 2303d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt for (i = 0; i < size; i++) 231315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt swizzle[i] = i; 2323d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt for (; i < 4; i++) 233315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt swizzle[i] = size - 1; 234315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt tree->src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], 235315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt swizzle[2], swizzle[3]); 2363d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt tree->dst_reg.writemask = (1 << size) - 1; 23784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 23884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2392c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 2402c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 2412c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 2422c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 2432c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 2442c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 2452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 2462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 2472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 2482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 2492c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 2502c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(!type->is_matrix()); 2512c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 2522c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * packing for things like floats, but otherwise arrays become a 2532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * mess. Hopefully a later pass over the code can pack scalars 2542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * down if appropriate. 2552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 2562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return 1; 2572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 2582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 2592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 2602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 2612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 2622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 2632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 2642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 2652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 2662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 2672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 2682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 2692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 27084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 27184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::get_temp_for_var(ir_variable *var, struct mbtree *tree) 27284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 27384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt temp_entry *entry; 27484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 27584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, this->variable_storage) { 27684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt entry = (temp_entry *)iter.get(); 27784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 27884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (entry->var == var) { 279b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_to_mesa_set_tree_reg(tree, entry->file, entry->index); 28084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return; 28184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 28284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 28384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2844e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt entry = new temp_entry(var, PROGRAM_TEMPORARY, this->next_temp); 28584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt this->variable_storage.push_tail(entry); 28684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt next_temp += type_size(var->type); 2884e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 289b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_to_mesa_set_tree_reg(tree, entry->file, entry->index); 29084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 29184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 29284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic void 29384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtreduce(struct mbtree *t, int goal) 29484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 29584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct mbtree *kids[10]; 29684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int rule = mono_burg_rule((MBState *)t->state, goal); 29784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const uint16_t *nts = mono_burg_nts[rule]; 29884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 29984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mono_burg_kids (t, rule, kids); 30184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; nts[i]; i++) { 30384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt reduce(kids[i], nts[i]); 30484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 30584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (t->left) { 30784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (mono_burg_func[rule]) { 30884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mono_burg_func[rule](t, NULL); 30984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 31084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("no code for rules %s\n", mono_burg_rule_string[rule]); 31184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 31284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 31384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 31484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (mono_burg_func[rule]) { 31584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("unused code for rule %s\n", mono_burg_rule_string[rule]); 31684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 31784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 31884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 31984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 32084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 32184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 32284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 32384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 32484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 32584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 32684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 32784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 32884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 32984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 33064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->from); 33164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->to); 33264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->increment); 33364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->counter); 33484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 33564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt ir_to_mesa_emit_op1_full(this, NULL, 33664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt OPCODE_BGNLOOP, ir_to_mesa_undef_dst, 33764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt ir_to_mesa_undef); 33864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt 33964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 34064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt 34164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt ir_to_mesa_emit_op1_full(this, NULL, 34264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt OPCODE_ENDLOOP, ir_to_mesa_undef_dst, 34364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt ir_to_mesa_undef); 34484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 34584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 34684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 34784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 34884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 34964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 35064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 35164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt ir_to_mesa_emit_op1_full(this, NULL, 35264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt OPCODE_BRK, ir_to_mesa_undef_dst, 35364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt ir_to_mesa_undef); 35464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 35564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 35664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt ir_to_mesa_emit_op1_full(this, NULL, 35764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt OPCODE_CONT, ir_to_mesa_undef_dst, 35864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt ir_to_mesa_undef); 35964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 36064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 36184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 36284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 36384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 36484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 36584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 36684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 36784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 36884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 36984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 37084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 37184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 37284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 37384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 37484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 37584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 37684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 37784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 37884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 37984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 38084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 38284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 38484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 38684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 38784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 38984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 39084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 39184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 39284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 39484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 39584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 39684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 39784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct mbtree *op[2]; 39884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1); 39984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1); 40084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1); 40184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 40284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 40384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt this->result = NULL; 40484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 40584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (!this->result) { 40684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 40784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 40884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 40984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 41084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 41184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 41284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 41384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 41484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt this->result = NULL; 41584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 41684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 4171d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 4181d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt this->result = this->create_tree_for_float(ir, 0.0); 4191d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt this->result = this->create_tree(MB_TERM_seq_vec4_vec4, ir, 4201d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt op[0], this->result); 4211d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 422c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 423c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt op[0]->src_reg.negate = ~op[0]->src_reg.negate; 424c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt this->result = op[0]; 425c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 4268c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp: 4278c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt this->result = this->create_tree(MB_TERM_exp_vec4, ir, op[0], NULL); 4288c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 4298c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 4308c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt this->result = this->create_tree(MB_TERM_exp2_vec4, ir, op[0], NULL); 4318c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 4328c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 4338c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt this->result = this->create_tree(MB_TERM_log_vec4, ir, op[0], NULL); 4348c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 4358c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 4368c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt this->result = this->create_tree(MB_TERM_log2_vec4, ir, op[0], NULL); 4378c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 4383c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 4393c5979565facebc82000a611b991d2977b8e9bbfEric Anholt this->result = this->create_tree(MB_TERM_sin_vec4, ir, op[0], NULL); 4403c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 4413c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 4423c5979565facebc82000a611b991d2977b8e9bbfEric Anholt this->result = this->create_tree(MB_TERM_cos_vec4, ir, op[0], NULL); 4433c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 44484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 445b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt this->result = this->create_tree(MB_TERM_add_vec4_vec4, ir, op[0], op[1]); 44684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 44784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 448b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt this->result = this->create_tree(MB_TERM_sub_vec4_vec4, ir, op[0], op[1]); 44984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 45084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 451b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt this->result = this->create_tree(MB_TERM_mul_vec4_vec4, ir, op[0], op[1]); 45284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 45384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 454b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt this->result = this->create_tree(MB_TERM_div_vec4_vec4, ir, op[0], op[1]); 45584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 45638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 45738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 45838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt this->result = this->create_tree(MB_TERM_slt_vec4_vec4, ir, op[0], op[1]); 45938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 46038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 46138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt this->result = this->create_tree(MB_TERM_sgt_vec4_vec4, ir, op[0], op[1]); 46238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 46338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 46438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt this->result = this->create_tree(MB_TERM_sle_vec4_vec4, ir, op[0], op[1]); 46538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 46638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 46738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt this->result = this->create_tree(MB_TERM_sge_vec4_vec4, ir, op[0], op[1]); 46838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 46938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 47038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt this->result = this->create_tree(MB_TERM_seq_vec4_vec4, ir, op[0], op[1]); 47138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 472763cd75863ed9a16912e585887580c44d1e8109fEric Anholt case ir_binop_logic_xor: 47338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_nequal: 47438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt this->result = this->create_tree(MB_TERM_sne_vec4_vec4, ir, op[0], op[1]); 47538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 47638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 4774380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_or: 4784380099c98119611ceee684669d00be26195c7d7Eric Anholt /* This could be a saturated add. */ 4794380099c98119611ceee684669d00be26195c7d7Eric Anholt this->result = this->create_tree(MB_TERM_add_vec4_vec4, ir, op[0], op[1]); 4804380099c98119611ceee684669d00be26195c7d7Eric Anholt this->result = this->create_tree(MB_TERM_sne_vec4_vec4, ir, 4814380099c98119611ceee684669d00be26195c7d7Eric Anholt this->create_tree_for_float(ir, 0.0), 4824380099c98119611ceee684669d00be26195c7d7Eric Anholt this->result); 4834380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 4844380099c98119611ceee684669d00be26195c7d7Eric Anholt 4854380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 4864380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 4874380099c98119611ceee684669d00be26195c7d7Eric Anholt this->result = this->create_tree(MB_TERM_mul_vec4_vec4, ir, op[0], op[1]); 4884380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 4894380099c98119611ceee684669d00be26195c7d7Eric Anholt 49084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 49184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (ir->operands[0]->type == vec4_type) { 49284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec4_type); 493b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt this->result = this->create_tree(MB_TERM_dp4_vec4_vec4, 494b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt ir, op[0], op[1]); 49584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec3_type) { 49684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec3_type); 497b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt this->result = this->create_tree(MB_TERM_dp3_vec4_vec4, 498b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt ir, op[0], op[1]); 49984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec2_type) { 50084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec2_type); 501b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt this->result = this->create_tree(MB_TERM_dp2_vec4_vec4, 502b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt ir, op[0], op[1]); 50384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 50484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 50584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 506b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt this->result = this->create_tree(MB_TERM_sqrt_vec4, ir, op[0], op[1]); 50784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 508878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 509878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt this->result = this->create_tree(MB_TERM_rsq_vec4, ir, op[0], op[1]); 510878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 51150ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 512423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 51350ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt this->result = op[0]; 51450ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 515423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 516423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt this->result = this->create_tree(MB_TERM_trunc_vec4, ir, op[0], NULL); 517423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 5181d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 5191d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt this->result = this->create_tree_for_float(ir, 0.0); 5201d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt this->result = this->create_tree(MB_TERM_sne_vec4_vec4, ir, 5211d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt op[0], this->result); 5221d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 523c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 524c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt this->result = this->create_tree(MB_TERM_trunc_vec4, ir, op[0], NULL); 525c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 526c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 527c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt this->result = this->create_tree(MB_TERM_ceil_vec4, ir, op[0], NULL); 528c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 529c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 530c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt this->result = this->create_tree(MB_TERM_floor_vec4, ir, op[0], NULL); 531c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 53284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt default: 53384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 53484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 53584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (!this->result) { 53684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 53784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression:\n"); 53884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(&v); 53984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 54084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 541b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 542b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt /* Allocate a temporary for the result. */ 5433d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt this->get_temp(this->result, ir->type->vector_elements); 54484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 54584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 54684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 54784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 54884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 54984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 55084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct mbtree *tree; 55184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 55284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 55384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 554b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 555b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 556b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 557b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 55884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 55984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(this->result); 56184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 562b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt tree = this->create_tree(MB_TERM_swizzle_vec4, ir, this->result, NULL); 5633d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt this->get_temp(tree, 4); 56484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 56584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 56684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 56784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 56884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 56984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt swizzle[i] = ir->mask.x; 57084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 57184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 57284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt swizzle[i] = ir->mask.y; 57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt swizzle[i] = ir->mask.z; 57684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 57784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 57884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt swizzle[i] = ir->mask.w; 57984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 58084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 58184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 58284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 58384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 58484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 58584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt swizzle[i] = ir->type->vector_elements - 1; 58684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 58784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 58884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 58984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], 59084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt swizzle[1], 59184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt swizzle[2], 59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt swizzle[3]); 59384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 59484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt this->result = tree; 59584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 597829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt/* This list should match up with builtin_variables.h */ 598829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholtstatic const struct { 599829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt const char *name; 600829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt int file; 601829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt int index; 602829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt} builtin_var_to_mesa_reg[] = { 603829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt /* core_vs */ 604829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_Position", PROGRAM_OUTPUT, VERT_RESULT_HPOS}, 605829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_PointSize", PROGRAM_OUTPUT, VERT_RESULT_PSIZ}, 606829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt 607829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt /* core_fs */ 608829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FragCoord", PROGRAM_INPUT, FRAG_ATTRIB_WPOS}, 609829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FrontFacing", PROGRAM_INPUT, FRAG_ATTRIB_FACE}, 610829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FragColor", PROGRAM_INPUT, FRAG_ATTRIB_COL0}, 611829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FragDepth", PROGRAM_UNDEFINED, FRAG_ATTRIB_WPOS}, /* FINISHME: WPOS.z */ 612829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt 613829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt /* 110_deprecated_fs */ 614829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_Color", PROGRAM_INPUT, FRAG_ATTRIB_COL0}, 615829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_SecondaryColor", PROGRAM_INPUT, FRAG_ATTRIB_COL1}, 616829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FogFragCoord", PROGRAM_INPUT, FRAG_ATTRIB_FOGC}, 617829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt 618829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt /* 110_deprecated_vs */ 619829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_Vertex", PROGRAM_INPUT, VERT_ATTRIB_POS}, 620829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_Normal", PROGRAM_INPUT, VERT_ATTRIB_NORMAL}, 621829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_Color", PROGRAM_INPUT, VERT_ATTRIB_COLOR0}, 622829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_SecondaryColor", PROGRAM_INPUT, VERT_ATTRIB_COLOR1}, 623829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_MultiTexCoord0", PROGRAM_INPUT, VERT_ATTRIB_TEX0}, 624829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_MultiTexCoord1", PROGRAM_INPUT, VERT_ATTRIB_TEX1}, 625829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_MultiTexCoord2", PROGRAM_INPUT, VERT_ATTRIB_TEX2}, 626829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_MultiTexCoord3", PROGRAM_INPUT, VERT_ATTRIB_TEX3}, 627829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_MultiTexCoord4", PROGRAM_INPUT, VERT_ATTRIB_TEX4}, 628829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_MultiTexCoord5", PROGRAM_INPUT, VERT_ATTRIB_TEX5}, 629829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_MultiTexCoord6", PROGRAM_INPUT, VERT_ATTRIB_TEX6}, 630829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_MultiTexCoord7", PROGRAM_INPUT, VERT_ATTRIB_TEX7}, 6314e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt {"gl_TexCoord", PROGRAM_OUTPUT, VERT_RESULT_TEX0}, /* array */ 632829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FogCoord", PROGRAM_INPUT, VERT_RESULT_FOGC}, 633829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt /*{"gl_ClipVertex", PROGRAM_OUTPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */ 634829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FrontColor", PROGRAM_OUTPUT, VERT_RESULT_COL0}, 635829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_BackColor", PROGRAM_OUTPUT, VERT_RESULT_BFC0}, 636829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FrontSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_COL1}, 637829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_BackSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_BFC1}, 638829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt {"gl_FogFragCoord", PROGRAM_OUTPUT, VERT_RESULT_FOGC}, 639829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt 640829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt /* 130_vs */ 641829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt /*{"gl_VertexID", PROGRAM_INPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */ 6424e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 6434e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt {"gl_FragData", PROGRAM_OUTPUT, FRAG_RESULT_DATA0}, /* array */ 644829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt}; 64584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 64684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 64784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 64884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 64984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct mbtree *tree; 65084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int size_swizzles[4] = { 65184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 65234195832669f0eb7c4a80997cc524f8d10319307Eric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 65334195832669f0eb7c4a80997cc524f8d10319307Eric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 65434195832669f0eb7c4a80997cc524f8d10319307Eric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 65584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt }; 6564e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt ir_variable *var = ir->var; 65784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 658829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt /* By the time we make it to this stage, matrices should be broken down 65984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * to vectors. 66084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 66184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(!var->type->is_matrix()); 66284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 663b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL); 66484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 66584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strncmp(var->name, "gl_", 3) == 0) { 666829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt unsigned int i; 667829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt 668829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) { 669829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt if (strcmp(var->name, builtin_var_to_mesa_reg[i].name) == 0) 670829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt break; 67184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 672829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt assert(i != ARRAY_SIZE(builtin_var_to_mesa_reg)); 673829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt ir_to_mesa_set_tree_reg(tree, builtin_var_to_mesa_reg[i].file, 674829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt builtin_var_to_mesa_reg[i].index); 67584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 67684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt this->get_temp_for_var(var, tree); 67784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 67884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 67984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 68084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1]; 68184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 68284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt this->result = tree; 68384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 68484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 68584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 68884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct mbtree *tree; 68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int size_swizzles[4] = { 69084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 69184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 69284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 69384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 69484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt }; 6958041bce333a48033975eb83d47ecc6bd7a91cd1dEric Anholt ir_variable *var = ir->variable_referenced(); 6968041bce333a48033975eb83d47ecc6bd7a91cd1dEric Anholt ir_constant *index = ir->array_index->constant_expression_value(); 6974e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 6984e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt /* By the time we make it to this stage, matrices should be broken down 6994e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt * to vectors. 7004e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt */ 7014e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt assert(!var->type->is_matrix()); 70284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 7034e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt if (strncmp(var->name, "gl_", 3) == 0) { 7044e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt unsigned int i; 7054e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt unsigned int offset = 0; 7064e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 707bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL); 7084e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 7094e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt offset = index->value.i[0]; 7104e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 7114e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) { 7124e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt if (strcmp(var->name, builtin_var_to_mesa_reg[i].name) == 0) 7134e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt break; 7144e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 7154e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt assert(i != ARRAY_SIZE(builtin_var_to_mesa_reg)); 7164e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt ir_to_mesa_set_tree_reg(tree, builtin_var_to_mesa_reg[i].file, 7174e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt builtin_var_to_mesa_reg[i].index + offset); 7184e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 719bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL); 7204e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt this->get_temp_for_var(var, tree); 7214e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 722bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt if (index) { 723bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt tree->src_reg.index += index->value.i[0]; 724bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt tree->dst_reg.index += index->value.i[0]; 725bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } else { 726bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 727bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt * base of the array and an index that offsets the Mesa register 728bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt * index. 729bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt */ 730bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt ir->array_index->accept(this); 731bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt 732bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt tree->src_reg.reladdr = true; 733bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt tree = this->create_tree(MB_TERM_array_reference_vec4_vec4, 734bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt ir, tree, this->result); 735bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt this->get_temp(tree, ir->type->vector_elements); 736bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 7374e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 73884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 73984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 74084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1]; 74184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 74284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt this->result = tree; 74384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 74484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 7452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 7462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 7472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 7482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir_variable *var = ir->variable_referenced(); 7492c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt const char *field = ir->field; 7502c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt struct mbtree *tree; 7512c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 7522c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 7532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt const glsl_type *struct_type = var->type; 7542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 7552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 7562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL); 7572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt this->get_temp_for_var(var, tree); 7582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 7592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 7602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt if (strcmp(struct_type->fields.structure[i].name, field) == 0) 7612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 7622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 7632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 7642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt tree->src_reg.index += offset; 7652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt tree->dst_reg.index += offset; 7662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 7672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 7682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 7692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 7702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 7712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 7722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * 7732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we 7742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * should only see potentially one variable array index of a vector, 7752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * and one swizzle, before getting to actual vec4 storage. So handle 7762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * those, then go use ir_dereference to handle the rest. 7772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 778b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtstatic struct mbtree * 779b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtget_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v) 780b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 781b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt struct mbtree *tree = NULL; 782b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_dereference *deref; 783b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_swizzle *swiz; 784b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 7852c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 7862c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt tree = v->result; 7872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 788b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt if ((deref = ir->as_dereference())) { 7892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 7902c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(!deref_array || deref_array->array->type->is_array()); 7912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 792b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir->accept(v); 793b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree = v->result; 794b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt } else if ((swiz = ir->as_swizzle())) { 795b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->dst_reg.writemask = 0; 796b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt if (swiz->mask.num_components >= 1) 797b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->dst_reg.writemask |= (1 << swiz->mask.x); 798b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt if (swiz->mask.num_components >= 2) 799b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->dst_reg.writemask |= (1 << swiz->mask.y); 800b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt if (swiz->mask.num_components >= 3) 801b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->dst_reg.writemask |= (1 << swiz->mask.z); 802b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt if (swiz->mask.num_components >= 4) 803b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt tree->dst_reg.writemask |= (1 << swiz->mask.w); 804b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt } 805b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 806b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt assert(tree); 807b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 808b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt return tree; 809b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt} 810b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 81184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 81284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 81384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 81484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct mbtree *l, *r, *t; 81584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 8162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(!ir->lhs->type->is_matrix()); 8172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(!ir->lhs->type->is_array()); 8182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT); 8192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 820b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt l = get_assignment_lhs(ir->lhs, this); 821b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 82284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 82384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 82484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(l); 82584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(r); 82684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 827346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 828346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt ir_constant *condition_constant; 829346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt 830346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt condition_constant = ir->condition->constant_expression_value(); 831346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt 832346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt assert(condition_constant && condition_constant->value.b[0]); 833346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 83484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 835b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt t = this->create_tree(MB_TERM_assign, ir, l, r); 83684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mono_burg_label(t, NULL); 83784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt reduce(t, MB_NTERM_stmt); 83884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 83984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 84284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 84384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 84484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct mbtree *tree; 84584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(!ir->type->is_matrix()); 84784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 848b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL); 84984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 85050ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT || 85150ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt ir->type->base_type == GLSL_TYPE_UINT || 85250ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt ir->type->base_type == GLSL_TYPE_INT || 85350ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt ir->type->base_type == GLSL_TYPE_BOOL); 85484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 85584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* FINISHME: This will end up being _mesa_add_unnamed_constant, 85684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * which handles sharing values and sharing channels of vec4 85784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * constants for small values. 85884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 85984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* FINISHME: Do something with the constant values for now. 86084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 861b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_to_mesa_set_tree_reg(tree, PROGRAM_CONSTANT, this->next_constant++); 86284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt tree->src_reg.swizzle = SWIZZLE_NOOP; 86384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt this->result = tree; 86584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 86684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 86984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 87084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 87184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Can't support call to %s\n", ir->callee_name()); 87284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 87384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 87484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 87584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 87684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 87784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 87884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 87984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 88084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 88184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->coordinate->accept(this); 88284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 88384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 88484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 88584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 88684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 88784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 88884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 88984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->get_value()->accept(this); 89084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 89184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 89284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 89384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 89484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 89584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 896c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_to_mesa_instruction *if_inst, *else_inst = NULL; 897c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 898c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 899c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt assert(this->result); 900c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 901c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_inst = ir_to_mesa_emit_op1_full(this, ir->condition, 902c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt OPCODE_IF, ir_to_mesa_undef_dst, 903c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->result->src_reg); 904c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 905c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 906c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 907c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 908c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 909c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 910c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt else_inst = ir_to_mesa_emit_op1_full(this, ir->condition, 911c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt OPCODE_ELSE, ir_to_mesa_undef_dst, 912c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_to_mesa_undef); 913c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 914c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 915c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 916c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_inst = ir_to_mesa_emit_op1_full(this, ir->condition, 917c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt OPCODE_ENDIF, ir_to_mesa_undef_dst, 918c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_to_mesa_undef); 91984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 921ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 922ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 923ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt result = NULL; 924ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 925ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_constant = 0; 926ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 927ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 92884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg) 93084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 93184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 93284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 93384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 934aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt assert(reg.index < (1 << INST_INDEX_BITS) - 1); 93584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 93634195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 937bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt mesa_reg.RelAddr = reg.reladdr; 93884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 93984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 94084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 94184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 942c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 943c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtset_branchtargets(struct prog_instruction *mesa_instructions, 944c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 945c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 94664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_count = 0, loop_count; 94764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 94864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 94964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 950c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 951c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 95264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 95364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 954c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 95564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 95664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 95764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 95864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 95964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 96064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 96164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 96264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 96364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 96464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 96564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 966c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 967c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 96864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack = (int *)calloc(if_count, sizeof(*if_stack)); 96964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack)); 970c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 971c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 972c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 973c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 97464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 975c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 976c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 977c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 97864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 97964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 980c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 981c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 98264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 983c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 984c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 98564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 98664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 98764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 98864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 98964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 99064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 99164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 99264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 99364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 99464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 99564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 99664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 99764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 99864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 99964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 100064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 100164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 100264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 100364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 100464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 100564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 1006c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 1007c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 1008c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1009c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1010c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1011c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt free(if_stack); 1012c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 1013c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1014c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 1015c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 1016c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 1017c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 1018c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 1019c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 1020c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 1021c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1022c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 1023c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 1024c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 1025c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 102664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 1027c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_print_visitor print; 1028c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->accept(&print); 1029c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 1030c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 1031c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1032c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1033c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt _mesa_print_instruction(mesa_inst); 1034c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1035c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 1036c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 103784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 103884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtdo_ir_to_mesa(exec_list *instructions) 103984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 104084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 104184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 1042c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 1043c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 104484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 104584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt visit_exec_list(instructions, &v); 104684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 104784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 104884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 104984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 105084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 105184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 105284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 105384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 105484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 1055c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation = 1056c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt (ir_instruction **)calloc(num_instructions, 1057c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt sizeof(*mesa_instruction_annotation)); 105884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 105984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 1060c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 106184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 106284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 1063b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 106484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 106584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.File = inst->dst_reg.file; 106684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.Index = inst->dst_reg.index; 10678197eeee3bbca4ab2deacfbf675285560f49e13cEric Anholt mesa_inst->DstReg.CondMask = COND_TR; 106812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask; 106984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]); 107084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]); 107184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); 1072c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 1073aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 107484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 1075c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 107684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 1077c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1078c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt set_branchtargets(mesa_instructions, num_instructions); 1079c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt print_program(mesa_instructions, mesa_instruction_annotation, num_instructions); 1080c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1081c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt free(mesa_instruction_annotation); 108284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 1083