1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2009 Nicolai Haehnle. 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 Tom Stellard <tstellar@gmail.com> 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software. 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_dataflow.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler_util.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_program.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct read_write_mask_data { 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * UserData; 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_write_mask_fn Cb; 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void reads_normal_callback( 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * userdata, 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * fullinst, 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_src_register * src) 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct read_write_mask_data * cb_data = userdata; 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int refmask = 0; 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int chan; 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(chan = 0; chan < 4; chan++) { 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmask |= 1 << GET_SWZ(src->Swizzle, chan); 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmask &= RC_MASK_XYZW; 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (refmask) { 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data->Cb(cb_data->UserData, fullinst, src->File, 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src->Index, refmask); 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (refmask && src->RelAddr) { 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data->Cb(cb_data->UserData, fullinst, RC_FILE_ADDRESS, 0, 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MASK_X); 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void pair_get_src_refmasks(unsigned int * refmasks, 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction * inst, 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int swz, unsigned int src) 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (swz >= 4) 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (swz == RC_SWIZZLE_X || swz == RC_SWIZZLE_Y || swz == RC_SWIZZLE_Z) { 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(src == RC_PAIR_PRESUB_SRC) { 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int srcp_regs = 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_presubtract_src_reg_count( 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->RGB.Src[src].Index); 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < srcp_regs; i++) { 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmasks[i] |= 1 << swz; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmasks[src] |= 1 << swz; 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (swz == RC_SWIZZLE_W) { 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src == RC_PAIR_PRESUB_SRC) { 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int srcp_regs = rc_presubtract_src_reg_count( 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Alpha.Src[src].Index); 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < srcp_regs; i++) { 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmasks[i] |= 1 << swz; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmasks[src] |= 1 << swz; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void reads_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata) 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction * inst = &fullinst->U.P; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int refmasks[3] = { 0, 0, 0 }; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int arg; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(arg = 0; arg < 3; ++arg) { 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int chan; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(chan = 0; chan < 3; ++chan) { 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int swz_rgb = 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(inst->RGB.Arg[arg].Swizzle, chan); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int swz_alpha = 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(inst->Alpha.Arg[arg].Swizzle, chan); 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pair_get_src_refmasks(refmasks, inst, swz_rgb, 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->RGB.Arg[arg].Source); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pair_get_src_refmasks(refmasks, inst, swz_alpha, 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Alpha.Arg[arg].Source); 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int src = 0; src < 3; ++src) { 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->RGB.Src[src].Used && (refmasks[src] & RC_MASK_XYZ)) 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, inst->RGB.Src[src].File, inst->RGB.Src[src].Index, 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmasks[src] & RC_MASK_XYZ); 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Alpha.Src[src].Used && (refmasks[src] & RC_MASK_W)) 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, inst->Alpha.Src[src].File, inst->Alpha.Src[src].Index, RC_MASK_W); 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void pair_sub_for_all_args( 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * fullinst, 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_sub_instruction * sub, 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_read_arg_fn cb, 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * userdata) 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode); 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < info->NumSrcRegs; i++) { 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int src_type; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_type = rc_source_type_swz(sub->Arg[i].Swizzle); 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src_type == RC_SOURCE_NONE) 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sub->Arg[i].Source == RC_PAIR_PRESUB_SRC) { 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int presub_type; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int presub_src_count; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction_source * src_array; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int j; 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src_type & RC_SOURCE_RGB) { 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org presub_type = fullinst-> 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Index; 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_array = fullinst->U.P.RGB.Src; 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org presub_type = fullinst-> 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Index; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_array = fullinst->U.P.Alpha.Src; 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org presub_src_count 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = rc_presubtract_src_reg_count(presub_type); 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(j = 0; j < presub_src_count; j++) { 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &sub->Arg[i], 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &src_array[j]); 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction_source * src = 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_get_src(&fullinst->U.P, &sub->Arg[i]); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src) { 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &sub->Arg[i], src); 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This function calls the callback function (cb) for each source used by 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the instruction. 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * */ 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_for_all_reads_src( 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_src_fn cb, 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * userdata) 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_get_opcode_info(inst->U.I.Opcode); 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This function only works with normal instructions. */ 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Type != RC_INSTRUCTION_NORMAL) { 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) { 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.SrcReg[src].File == RC_FILE_NONE) 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.SrcReg[src].File == RC_FILE_PRESUB) { 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int srcp_regs = rc_presubtract_src_reg_count( 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.PreSub.Opcode); 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for( i = 0; i < srcp_regs; i++) { 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, inst, &inst->U.I.PreSub.SrcReg[i]); 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, inst, &inst->U.I.SrcReg[src]); 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function calls the callback function (cb) for each arg of the RGB and 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * alpha components. 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_pair_for_all_reads_arg( 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_read_arg_fn cb, 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * userdata) 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This function only works with pair instructions. */ 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Type != RC_INSTRUCTION_PAIR) { 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pair_sub_for_all_args(inst, &inst->U.P.RGB, cb, userdata); 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pair_sub_for_all_args(inst, &inst->U.P.Alpha, cb, userdata); 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Calls a callback function for all register reads. 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is conservative, i.e. if the same register is referenced multiple times, 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the callback may also be called multiple times. 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Also, the writemask of the instruction is not taken into account. 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_for_all_reads_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata) 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Type == RC_INSTRUCTION_NORMAL) { 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct read_write_mask_data cb_data; 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data.UserData = userdata; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data.Cb = cb; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_for_all_reads_src(inst, reads_normal_callback, &cb_data); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reads_pair(inst, cb, userdata); 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void writes_normal(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata) 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_sub_instruction * inst = &fullinst->U.I; 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode); 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode->HasDstReg && inst->DstReg.WriteMask) 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, inst->DstReg.File, inst->DstReg.Index, inst->DstReg.WriteMask); 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->WriteALUResult) 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, RC_MASK_X); 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void writes_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata) 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction * inst = &fullinst->U.P; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->RGB.WriteMask) 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->RGB.DestIndex, inst->RGB.WriteMask); 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Alpha.WriteMask) 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->Alpha.DestIndex, RC_MASK_W); 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->WriteALUResult) 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, RC_MASK_X); 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Calls a callback function for all register writes in the instruction, 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * reporting writemasks to the callback function. 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \warning Does not report output registers for paired instructions! 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_for_all_writes_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata) 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Type == RC_INSTRUCTION_NORMAL) { 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writes_normal(inst, cb, userdata); 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writes_pair(inst, cb, userdata); 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct mask_to_chan_data { 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * UserData; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_write_chan_fn Fn; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void mask_to_chan_cb(void * data, struct rc_instruction * inst, 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file, unsigned int index, unsigned int mask) 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct mask_to_chan_data * d = data; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int chan = 0; chan < 4; ++chan) { 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (GET_BIT(mask, chan)) 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->Fn(d->UserData, inst, file, index, chan); 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Calls a callback function for all sourced register channels. 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is conservative, i.e. channels may be called multiple times, 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and the writemask of the instruction is not taken into account. 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_for_all_reads_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata) 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct mask_to_chan_data d; 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d.UserData = userdata; 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d.Fn = cb; 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_for_all_reads_mask(inst, &mask_to_chan_cb, &d); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Calls a callback function for all written register channels. 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \warning Does not report output registers for paired instructions! 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_for_all_writes_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata) 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct mask_to_chan_data d; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d.UserData = userdata; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d.Fn = cb; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_for_all_writes_mask(inst, &mask_to_chan_cb, &d); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void remap_normal_instruction(struct rc_instruction * fullinst, 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_remap_register_fn cb, void * userdata) 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_sub_instruction * inst = &fullinst->U.I; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode); 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int remapped_presub = 0; 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode->HasDstReg) { 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file = inst->DstReg.File; 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index = inst->DstReg.Index; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &file, &index); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->DstReg.File = file; 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->DstReg.Index = index; 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) { 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file = inst->SrcReg[src].File; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index = inst->SrcReg[src].Index; 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (file == RC_FILE_PRESUB) { 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int srcp_srcs = rc_presubtract_src_reg_count( 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->PreSub.Opcode); 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make sure we only remap presubtract sources once in 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * case more than one source register reads the 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * presubtract result. */ 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (remapped_presub) 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < srcp_srcs; i++) { 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org file = inst->PreSub.SrcReg[i].File; 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index = inst->PreSub.SrcReg[i].Index; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &file, &index); 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->PreSub.SrcReg[i].File = file; 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->PreSub.SrcReg[i].Index = index; 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org remapped_presub = 1; 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &file, &index); 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->SrcReg[src].File = file; 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->SrcReg[src].Index = index; 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void remap_pair_instruction(struct rc_instruction * fullinst, 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_remap_register_fn cb, void * userdata) 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction * inst = &fullinst->U.P; 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->RGB.WriteMask) { 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file = RC_FILE_TEMPORARY; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index = inst->RGB.DestIndex; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &file, &index); 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->RGB.DestIndex = index; 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Alpha.WriteMask) { 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file = RC_FILE_TEMPORARY; 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index = inst->Alpha.DestIndex; 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &file, &index); 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Alpha.DestIndex = index; 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int src = 0; src < 3; ++src) { 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->RGB.Src[src].Used) { 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file = inst->RGB.Src[src].File; 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index = inst->RGB.Src[src].Index; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &file, &index); 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->RGB.Src[src].File = file; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->RGB.Src[src].Index = index; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Alpha.Src[src].Used) { 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file = inst->Alpha.Src[src].File; 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index = inst->Alpha.Src[src].Index; 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(userdata, fullinst, &file, &index); 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Alpha.Src[src].File = file; 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Alpha.Src[src].Index = index; 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Remap all register accesses according to the given function. 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * That is, call the function \p cb for each referenced register (both read and written) 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and update the given instruction \p inst accordingly 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if it modifies its \ref pfile and \ref pindex contents. 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata) 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Type == RC_INSTRUCTION_NORMAL) 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org remap_normal_instruction(inst, cb, userdata); 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org remap_pair_instruction(inst, cb, userdata); 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct branch_write_mask { 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int IfWriteMask:4; 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int ElseWriteMask:4; 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int HasElse:1; 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunion get_readers_read_cb { 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_src_fn I; 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_read_arg_fn P; 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct get_readers_callback_data { 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct radeon_compiler * C; 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader_data * ReaderData; 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_src_fn ReadNormalCB; 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_read_arg_fn ReadPairCB; 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_write_mask_fn WriteCB; 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file DstFile; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int DstIndex; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int DstMask; 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int AliveWriteMask; 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For convenience, this is indexed starting at 1 */ 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct branch_write_mask BranchMasks[R500_PFS_MAX_BRANCH_DEPTH_FULL + 1]; 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct rc_reader * add_reader( 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct memory_pool * pool, 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader_data * data, 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int mask) 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader * new; 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memory_pool_array_reserve(pool, struct rc_reader, data->Readers, 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data->ReaderCount, data->ReadersReserved, 1); 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new = &data->Readers[data->ReaderCount++]; 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new->Inst = inst; 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new->WriteMask = mask; 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new; 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void add_reader_normal( 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct memory_pool * pool, 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader_data * data, 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int mask, 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_src_register * src) 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader * new = add_reader(pool, data, inst, mask); 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new->U.I.Src = src; 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void add_reader_pair( 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct memory_pool * pool, 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader_data * data, 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int mask, 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction_arg * arg, 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction_source * src) 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader * new = add_reader(pool, data, inst, mask); 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new->U.P.Src = src; 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new->U.P.Arg = arg; 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int get_readers_read_callback( 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data * cb_data, 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int has_rel_addr, 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file, 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index, 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int swizzle) 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int shared_mask, read_mask; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (has_rel_addr) { 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data->ReaderData->Abort = 1; 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RC_MASK_NONE; 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shared_mask = rc_src_reads_dst_mask(file, index, swizzle, 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data->DstFile, cb_data->DstIndex, cb_data->AliveWriteMask); 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (shared_mask == RC_MASK_NONE) 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return shared_mask; 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If we make it this far, it means that this source reads from the 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * same register written to by d->ReaderData->Writer. */ 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_mask = rc_swizzle_to_writemask(swizzle); 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cb_data->ReaderData->AbortOnRead & read_mask) { 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data->ReaderData->Abort = 1; 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return shared_mask; 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cb_data->ReaderData->LoopDepth > 0) { 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data->ReaderData->AbortOnWrite |= 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (read_mask & cb_data->AliveWriteMask); 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX The behavior in this case should be configurable. */ 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((read_mask & cb_data->AliveWriteMask) != read_mask) { 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb_data->ReaderData->Abort = 1; 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return shared_mask; 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return shared_mask; 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void get_readers_pair_read_callback( 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * userdata, 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction_arg * arg, 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_instruction_source * src) 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int shared_mask; 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data * d = userdata; 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shared_mask = get_readers_read_callback(d, 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0 /*Pair Instructions don't use RelAddr*/, 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src->File, src->Index, arg->Swizzle); 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (shared_mask == RC_MASK_NONE) 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReadPairCB) 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReadPairCB(d->ReaderData, inst, arg, src); 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReaderData->ExitOnAbort && d->ReaderData->Abort) 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org add_reader_pair(&d->C->Pool, d->ReaderData, inst, shared_mask, arg, src); 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function is used by rc_get_readers_normal() to determine whether inst 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is a reader of userdata->ReaderData->Writer 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void get_readers_normal_read_callback( 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * userdata, 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_src_register * src) 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data * d = userdata; 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int shared_mask; 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shared_mask = get_readers_read_callback(d, 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src->RelAddr, src->File, src->Index, src->Swizzle); 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (shared_mask == RC_MASK_NONE) 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The callback function could potentially clear d->ReaderData->Abort, 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so we need to call it before we return. */ 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReadNormalCB) 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReadNormalCB(d->ReaderData, inst, src); 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReaderData->ExitOnAbort && d->ReaderData->Abort) 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org add_reader_normal(&d->C->Pool, d->ReaderData, inst, shared_mask, src); 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function is used by rc_get_readers_normal() to determine when 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * userdata->ReaderData->Writer is dead (i. e. All compontents of its 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * destination register have been overwritten by other instructions). 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void get_readers_write_callback( 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *userdata, 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file, 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int index, 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int mask) 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data * d = userdata; 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (index == d->DstIndex && file == d->DstFile) { 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int shared_mask = mask & d->DstMask; 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnRead &= ~shared_mask; 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->AliveWriteMask &= ~shared_mask; 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReaderData->AbortOnWrite & shared_mask) { 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->Abort = 1; 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(d->WriteCB) 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->WriteCB(d->ReaderData, inst, file, index, mask); 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void push_branch_mask( 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data * d, 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int * branch_depth) 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (*branch_depth)++; 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (*branch_depth > R500_PFS_MAX_BRANCH_DEPTH_FULL) { 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->Abort = 1; 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->BranchMasks[*branch_depth].IfWriteMask = 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->AliveWriteMask; 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void pop_branch_mask( 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data * d, 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int * branch_depth) 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct branch_write_mask * masks = &d->BranchMasks[*branch_depth]; 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (masks->HasElse) { 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Abort on read for components that were written in the IF 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * block. */ 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnRead |= 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org masks->IfWriteMask & ~masks->ElseWriteMask; 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Abort on read for components that were written in the ELSE 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * block. */ 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnRead |= 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org masks->ElseWriteMask & ~d->AliveWriteMask; 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->AliveWriteMask = masks->IfWriteMask 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ^ ((masks->IfWriteMask ^ masks->ElseWriteMask) 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org & (masks->IfWriteMask ^ d->AliveWriteMask)); 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnRead |= 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org masks->IfWriteMask & ~d->AliveWriteMask; 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->AliveWriteMask = masks->IfWriteMask; 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(masks, 0, sizeof(struct branch_write_mask)); 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (*branch_depth)--; 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void get_readers_for_single_write( 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void * userdata, 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * writer, 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file dst_file, 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int dst_index, 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int dst_mask) 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * tmp; 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int branch_depth = 0; 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * endloop = NULL; 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int abort_on_read_at_endloop = 0; 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data * d = userdata; 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->Writer = writer; 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnRead = 0; 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnWrite = 0; 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->LoopDepth = 0; 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->InElse = 0; 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->DstFile = dst_file; 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->DstIndex = dst_index; 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->DstMask = dst_mask; 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->AliveWriteMask = dst_mask; 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(d->BranchMasks, 0, sizeof(d->BranchMasks)); 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!dst_mask) 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(tmp = writer->Next; tmp != &d->C->Program.Instructions; 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = tmp->Next){ 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_opcode opcode = rc_get_flow_control_inst(tmp); 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(opcode) { 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_BGNLOOP: 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->LoopDepth++; 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org push_branch_mask(d, &branch_depth); 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_ENDLOOP: 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReaderData->LoopDepth > 0) { 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->LoopDepth--; 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReaderData->LoopDepth == 0) { 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnWrite = 0; 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pop_branch_mask(d, &branch_depth); 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Here we have reached an ENDLOOP without 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * seeing its BGNLOOP. These means that 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the writer was written inside of a loop, 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so it could have readers that are above it 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (i.e. they have a lower IP). To find these 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * readers we jump to the BGNLOOP instruction 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and check each instruction until we get 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * back to the writer. 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endloop = tmp; 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = rc_match_endloop(tmp); 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!tmp) { 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(d->C, "Failed to match endloop.\n"); 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->Abort = 1; 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org abort_on_read_at_endloop = d->ReaderData->AbortOnRead; 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnRead |= d->AliveWriteMask; 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_IF: 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org push_branch_mask(d, &branch_depth); 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_ELSE: 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branch_depth == 0) { 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->InElse = 1; 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int temp_mask = d->AliveWriteMask; 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->AliveWriteMask = 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->BranchMasks[branch_depth].IfWriteMask; 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->BranchMasks[branch_depth].ElseWriteMask = 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_mask; 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->BranchMasks[branch_depth].HasElse = 1; 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_ENDIF: 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branch_depth == 0) { 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnRead = d->AliveWriteMask; 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->InElse = 0; 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pop_branch_mask(d, &branch_depth); 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReaderData->InElse) 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->Type == RC_INSTRUCTION_NORMAL) { 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_for_all_reads_src(tmp, 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_readers_normal_read_callback, d); 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_for_all_reads_arg(tmp, 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_readers_pair_read_callback, d); 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This can happen when we jump from an ENDLOOP to BGNLOOP */ 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp == writer) { 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = endloop; 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endloop = NULL; 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData->AbortOnRead = abort_on_read_at_endloop; 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_for_all_writes_mask(tmp, get_readers_write_callback, d); 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d->ReaderData->ExitOnAbort && d->ReaderData->Abort) 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branch_depth == 0 && !d->AliveWriteMask) 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void init_get_readers_callback_data( 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data * d, 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader_data * reader_data, 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct radeon_compiler * c, 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_src_fn read_normal_cb, 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_read_arg_fn read_pair_cb, 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_write_mask_fn write_cb) 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reader_data->Abort = 0; 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reader_data->ReaderCount = 0; 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reader_data->ReadersReserved = 0; 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reader_data->Readers = NULL; 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->C = c; 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReaderData = reader_data; 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReadNormalCB = read_normal_cb; 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->ReadPairCB = read_pair_cb; 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->WriteCB = write_cb; 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function will create a list of readers via the rc_reader_data struct. 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function will abort (set the flag data->Abort) and return if it 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * encounters an instruction that reads from @param writer and also a different 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction. Here are some examples: 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * writer = instruction 0; 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0 MOV TEMP[0].xy, TEMP[1].xy 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1 MOV TEMP[0].zw, TEMP[2].xy 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2 MOV TEMP[3], TEMP[0] 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The Abort flag will be set on instruction 2, because it reads values written 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by instructions 0 and 1. 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * writer = instruction 1; 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0 IF TEMP[0].x 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1 MOV TEMP[1], TEMP[2] 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2 ELSE 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3 MOV TEMP[1], TEMP[2] 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4 ENDIF 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5 MOV TEMP[3], TEMP[1] 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The Abort flag will be set on instruction 5, because it could read from the 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * value written by either instruction 1 or 3, depending on the jump decision 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * made at instruction 0. 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * writer = instruction 0; 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0 MOV TEMP[0], TEMP[1] 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2 BGNLOOP 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3 ADD TEMP[0], TEMP[0], none.1 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4 ENDLOOP 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The Abort flag will be set on instruction 3, because in the first iteration 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the loop it reads the value written by instruction 0 and in all other 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * iterations it reads the value written by instruction 3. 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param read_cb This function will be called for for every instruction that 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * has been determined to be a reader of writer. 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param write_cb This function will be called for every instruction after 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * writer. 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_get_readers( 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct radeon_compiler * c, 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * writer, 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader_data * data, 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_src_fn read_normal_cb, 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_read_arg_fn read_pair_cb, 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_write_mask_fn write_cb) 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data d; 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org init_get_readers_callback_data(&d, data, c, read_normal_cb, 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_pair_cb, write_cb); 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_for_all_writes_mask(writer, get_readers_for_single_write, &d); 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_get_readers_sub( 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct radeon_compiler * c, 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * writer, 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_pair_sub_instruction * sub_writer, 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_reader_data * data, 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_src_fn read_normal_cb, 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_pair_read_arg_fn read_pair_cb, 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_read_write_mask_fn write_cb) 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct get_readers_callback_data d; 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org init_get_readers_callback_data(&d, data, c, read_normal_cb, 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_pair_cb, write_cb); 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sub_writer->WriteMask) { 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_readers_for_single_write(&d, writer, RC_FILE_TEMPORARY, 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sub_writer->DestIndex, sub_writer->WriteMask); 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 893