11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* 21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright (C) 2009 Nicolai Haehnle. 31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright 2010 Tom Stellard <tstellar@gmail.com> 41c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 51c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * All Rights Reserved. 61c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 71c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining 81c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * a copy of this software and associated documentation files (the 91c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * "Software"), to deal in the Software without restriction, including 101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * without limitation the rights to use, copy, modify, merge, publish, 111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * distribute, sublicense, and/or sell copies of the Software, and to 121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * permit persons to whom the Software is furnished to do so, subject to 131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the following conditions: 141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The above copyright notice and this permission notice (including the 161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * next paragraph) shall be included in all copies or substantial 171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * portions of the Software. 181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_dataflow.h" 301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler.h" 321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler_util.h" 331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_program.h" 341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct read_write_mask_data { 361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * UserData; 371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_write_mask_fn Cb; 381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void reads_normal_callback( 411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * userdata, 421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * fullinst, 431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register * src) 441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct read_write_mask_data * cb_data = userdata; 461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int refmask = 0; 471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int chan; 481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(chan = 0; chan < 4; chan++) { 491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák refmask |= 1 << GET_SWZ(src->Swizzle, chan); 501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák refmask &= RC_MASK_XYZW; 521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (refmask) { 541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data->Cb(cb_data->UserData, fullinst, src->File, 551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src->Index, refmask); 561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (refmask && src->RelAddr) { 591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data->Cb(cb_data->UserData, fullinst, RC_FILE_ADDRESS, 0, 601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_MASK_X); 611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void pair_get_src_refmasks(unsigned int * refmasks, 651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction * inst, 661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int swz, unsigned int src) 671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (swz >= 4) 691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (swz == RC_SWIZZLE_X || swz == RC_SWIZZLE_Y || swz == RC_SWIZZLE_Z) { 721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if(src == RC_PAIR_PRESUB_SRC) { 731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int srcp_regs = 751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_presubtract_src_reg_count( 761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->RGB.Src[src].Index); 771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(i = 0; i < srcp_regs; i++) { 781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák refmasks[i] |= 1 << swz; 791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák else { 821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák refmasks[src] |= 1 << swz; 831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (swz == RC_SWIZZLE_W) { 871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src == RC_PAIR_PRESUB_SRC) { 881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int srcp_regs = rc_presubtract_src_reg_count( 901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->Alpha.Src[src].Index); 911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(i = 0; i < srcp_regs; i++) { 921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák refmasks[i] |= 1 << swz; 931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák else { 961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák refmasks[src] |= 1 << swz; 971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void reads_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata) 1021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction * inst = &fullinst->U.P; 1041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int refmasks[3] = { 0, 0, 0 }; 1051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int arg; 1071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(arg = 0; arg < 3; ++arg) { 1091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int chan; 1101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(chan = 0; chan < 3; ++chan) { 1111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int swz_rgb = 1121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák GET_SWZ(inst->RGB.Arg[arg].Swizzle, chan); 1131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int swz_alpha = 1141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák GET_SWZ(inst->Alpha.Arg[arg].Swizzle, chan); 1151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_get_src_refmasks(refmasks, inst, swz_rgb, 1161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->RGB.Arg[arg].Source); 1171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_get_src_refmasks(refmasks, inst, swz_alpha, 1181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->Alpha.Arg[arg].Source); 1191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(unsigned int src = 0; src < 3; ++src) { 1231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.Src[src].Used && (refmasks[src] & RC_MASK_XYZ)) 1241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, inst->RGB.Src[src].File, inst->RGB.Src[src].Index, 1251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák refmasks[src] & RC_MASK_XYZ); 1261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.Src[src].Used && (refmasks[src] & RC_MASK_W)) 1281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, inst->Alpha.Src[src].File, inst->Alpha.Src[src].Index, RC_MASK_W); 1291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void pair_sub_for_all_args( 1331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * fullinst, 1341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_sub_instruction * sub, 1351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_read_arg_fn cb, 1361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * userdata) 1371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int i; 1391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode); 1401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(i = 0; i < info->NumSrcRegs; i++) { 1421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int src_type; 1431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src_type = rc_source_type_swz(sub->Arg[i].Swizzle); 1451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src_type == RC_SOURCE_NONE) 1471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 1481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (sub->Arg[i].Source == RC_PAIR_PRESUB_SRC) { 1501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int presub_type; 1511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int presub_src_count; 1521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction_source * src_array; 1531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int j; 1541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src_type & RC_SOURCE_RGB) { 1561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák presub_type = fullinst-> 1571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Index; 1581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src_array = fullinst->U.P.RGB.Src; 1591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 1601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák presub_type = fullinst-> 1611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Index; 1621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src_array = fullinst->U.P.Alpha.Src; 1631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák presub_src_count 1651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák = rc_presubtract_src_reg_count(presub_type); 1661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(j = 0; j < presub_src_count; j++) { 1671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &sub->Arg[i], 1681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák &src_array[j]); 1691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 1711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction_source * src = 1721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_get_src(&fullinst->U.P, &sub->Arg[i]); 1731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src) { 1741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &sub->Arg[i], src); 1751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* This function calls the callback function (cb) for each source used by 1811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the instruction. 1821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * */ 1831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_for_all_reads_src( 1841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 1851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_src_fn cb, 1861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * userdata) 1871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák const struct rc_opcode_info * opcode = 1891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_get_opcode_info(inst->U.I.Opcode); 1901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* This function only works with normal instructions. */ 1921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Type != RC_INSTRUCTION_NORMAL) { 1931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák assert(0); 1941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 1951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) { 1981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.SrcReg[src].File == RC_FILE_NONE) 2001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 2011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.SrcReg[src].File == RC_FILE_PRESUB) { 2031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 2041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int srcp_regs = rc_presubtract_src_reg_count( 2051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.PreSub.Opcode); 2061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for( i = 0; i < srcp_regs; i++) { 2071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, inst, &inst->U.I.PreSub.SrcReg[i]); 2081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 2101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, inst, &inst->U.I.SrcReg[src]); 2111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 2161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This function calls the callback function (cb) for each arg of the RGB and 2171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * alpha components. 2181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 2191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_pair_for_all_reads_arg( 2201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 2211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_read_arg_fn cb, 2221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * userdata) 2231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* This function only works with pair instructions. */ 2251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Type != RC_INSTRUCTION_PAIR) { 2261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák assert(0); 2271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 2281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_sub_for_all_args(inst, &inst->U.P.RGB, cb, userdata); 2311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pair_sub_for_all_args(inst, &inst->U.P.Alpha, cb, userdata); 2321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 2351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Calls a callback function for all register reads. 2361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 2371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This is conservative, i.e. if the same register is referenced multiple times, 2381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the callback may also be called multiple times. 2391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Also, the writemask of the instruction is not taken into account. 2401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 2411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_for_all_reads_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata) 2421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Type == RC_INSTRUCTION_NORMAL) { 2441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct read_write_mask_data cb_data; 2451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data.UserData = userdata; 2461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data.Cb = cb; 2471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_for_all_reads_src(inst, reads_normal_callback, &cb_data); 2491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 2501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reads_pair(inst, cb, userdata); 2511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void writes_normal(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata) 2571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_sub_instruction * inst = &fullinst->U.I; 2591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode); 2601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (opcode->HasDstReg && inst->DstReg.WriteMask) 2621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, inst->DstReg.File, inst->DstReg.Index, inst->DstReg.WriteMask); 2631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->WriteALUResult) 2651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, RC_MASK_X); 2661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void writes_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata) 2691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction * inst = &fullinst->U.P; 2711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.WriteMask) 2731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->RGB.DestIndex, inst->RGB.WriteMask); 2741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.WriteMask) 2761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->Alpha.DestIndex, RC_MASK_W); 2771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->WriteALUResult) 2791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, RC_MASK_X); 2801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 2831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Calls a callback function for all register writes in the instruction, 2841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * reporting writemasks to the callback function. 2851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 2861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \warning Does not report output registers for paired instructions! 2871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 2881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_for_all_writes_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata) 2891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Type == RC_INSTRUCTION_NORMAL) { 2911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writes_normal(inst, cb, userdata); 2921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 2931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák writes_pair(inst, cb, userdata); 2941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct mask_to_chan_data { 2991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * UserData; 3001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_write_chan_fn Fn; 3011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 3021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void mask_to_chan_cb(void * data, struct rc_instruction * inst, 3041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file, unsigned int index, unsigned int mask) 3051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct mask_to_chan_data * d = data; 3071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(unsigned int chan = 0; chan < 4; ++chan) { 3081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (GET_BIT(mask, chan)) 3091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->Fn(d->UserData, inst, file, index, chan); 3101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 3141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Calls a callback function for all sourced register channels. 3151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 3161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This is conservative, i.e. channels may be called multiple times, 3171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * and the writemask of the instruction is not taken into account. 3181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 3191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_for_all_reads_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata) 3201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct mask_to_chan_data d; 3221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d.UserData = userdata; 3231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d.Fn = cb; 3241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_for_all_reads_mask(inst, &mask_to_chan_cb, &d); 3251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 3281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Calls a callback function for all written register channels. 3291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 3301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \warning Does not report output registers for paired instructions! 3311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 3321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_for_all_writes_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata) 3331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct mask_to_chan_data d; 3351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d.UserData = userdata; 3361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d.Fn = cb; 3371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_for_all_writes_mask(inst, &mask_to_chan_cb, &d); 3381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void remap_normal_instruction(struct rc_instruction * fullinst, 3411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remap_register_fn cb, void * userdata) 3421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_sub_instruction * inst = &fullinst->U.I; 3441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode); 3451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int remapped_presub = 0; 3461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (opcode->HasDstReg) { 3481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file = inst->DstReg.File; 3491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index = inst->DstReg.Index; 3501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &file, &index); 3521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->DstReg.File = file; 3541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->DstReg.Index = index; 3551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) { 3581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file = inst->SrcReg[src].File; 3591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index = inst->SrcReg[src].Index; 3601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (file == RC_FILE_PRESUB) { 3621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int i; 3631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int srcp_srcs = rc_presubtract_src_reg_count( 3641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->PreSub.Opcode); 3651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Make sure we only remap presubtract sources once in 3661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * case more than one source register reads the 3671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * presubtract result. */ 3681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (remapped_presub) 3691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 3701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(i = 0; i < srcp_srcs; i++) { 3721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák file = inst->PreSub.SrcReg[i].File; 3731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák index = inst->PreSub.SrcReg[i].Index; 3741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &file, &index); 3751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->PreSub.SrcReg[i].File = file; 3761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->PreSub.SrcReg[i].Index = index; 3771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák remapped_presub = 1; 3791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák else { 3811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &file, &index); 3821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->SrcReg[src].File = file; 3841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->SrcReg[src].Index = index; 3851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void remap_pair_instruction(struct rc_instruction * fullinst, 3901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remap_register_fn cb, void * userdata) 3911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction * inst = &fullinst->U.P; 3931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.WriteMask) { 3951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file = RC_FILE_TEMPORARY; 3961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index = inst->RGB.DestIndex; 3971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &file, &index); 3991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->RGB.DestIndex = index; 4011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.WriteMask) { 4041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file = RC_FILE_TEMPORARY; 4051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index = inst->Alpha.DestIndex; 4061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &file, &index); 4081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->Alpha.DestIndex = index; 4101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(unsigned int src = 0; src < 3; ++src) { 4131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.Src[src].Used) { 4141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file = inst->RGB.Src[src].File; 4151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index = inst->RGB.Src[src].Index; 4161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &file, &index); 4181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->RGB.Src[src].File = file; 4201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->RGB.Src[src].Index = index; 4211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.Src[src].Used) { 4241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file = inst->Alpha.Src[src].File; 4251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index = inst->Alpha.Src[src].Index; 4261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb(userdata, fullinst, &file, &index); 4281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->Alpha.Src[src].File = file; 4301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->Alpha.Src[src].Index = index; 4311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 4371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Remap all register accesses according to the given function. 4381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * That is, call the function \p cb for each referenced register (both read and written) 4391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * and update the given instruction \p inst accordingly 4401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * if it modifies its \ref pfile and \ref pindex contents. 4411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 4421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata) 4431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Type == RC_INSTRUCTION_NORMAL) 4451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák remap_normal_instruction(inst, cb, userdata); 4461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák else 4471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák remap_pair_instruction(inst, cb, userdata); 4481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct branch_write_mask { 4511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int IfWriteMask:4; 4521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int ElseWriteMask:4; 4531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int HasElse:1; 4541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 4551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákunion get_readers_read_cb { 4571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_src_fn I; 4581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_read_arg_fn P; 4591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 4601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct get_readers_callback_data { 4621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * C; 4631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data * ReaderData; 4641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_src_fn ReadNormalCB; 4651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_read_arg_fn ReadPairCB; 4661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_write_mask_fn WriteCB; 4671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file DstFile; 4681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int DstIndex; 4691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int DstMask; 4701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int AliveWriteMask; 4711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* For convenience, this is indexed starting at 1 */ 4721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct branch_write_mask BranchMasks[R500_PFS_MAX_BRANCH_DEPTH_FULL + 1]; 4731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 4741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_reader * add_reader( 4761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct memory_pool * pool, 4771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data * data, 4781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 4791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int mask) 4801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader * new; 4821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memory_pool_array_reserve(pool, struct rc_reader, data->Readers, 4831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák data->ReaderCount, data->ReadersReserved, 1); 4841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new = &data->Readers[data->ReaderCount++]; 4851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->Inst = inst; 4861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->WriteMask = mask; 4871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return new; 4881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void add_reader_normal( 4911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct memory_pool * pool, 4921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data * data, 4931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 4941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int mask, 4951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register * src) 4961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader * new = add_reader(pool, data, inst, mask); 4981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->U.I.Src = src; 4991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void add_reader_pair( 5031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct memory_pool * pool, 5041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data * data, 5051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 5061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int mask, 5071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction_arg * arg, 5081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction_source * src) 5091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader * new = add_reader(pool, data, inst, mask); 5111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->U.P.Src = src; 5121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák new->U.P.Arg = arg; 5131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int get_readers_read_callback( 5161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data * cb_data, 5171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int has_rel_addr, 5181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file, 5191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index, 5201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int swizzle) 5211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int shared_mask, read_mask; 5231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (has_rel_addr) { 5251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data->ReaderData->Abort = 1; 5261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return RC_MASK_NONE; 5271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák shared_mask = rc_src_reads_dst_mask(file, index, swizzle, 5301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data->DstFile, cb_data->DstIndex, cb_data->AliveWriteMask); 5311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (shared_mask == RC_MASK_NONE) 5331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return shared_mask; 5341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* If we make it this far, it means that this source reads from the 5361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * same register written to by d->ReaderData->Writer. */ 5371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák read_mask = rc_swizzle_to_writemask(swizzle); 5391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (cb_data->ReaderData->AbortOnRead & read_mask) { 5401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data->ReaderData->Abort = 1; 5411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return shared_mask; 5421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (cb_data->ReaderData->LoopDepth > 0) { 5451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data->ReaderData->AbortOnWrite |= 5461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (read_mask & cb_data->AliveWriteMask); 5471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* XXX The behavior in this case should be configurable. */ 5501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if ((read_mask & cb_data->AliveWriteMask) != read_mask) { 5511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák cb_data->ReaderData->Abort = 1; 5521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return shared_mask; 5531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return shared_mask; 5561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void get_readers_pair_read_callback( 5591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * userdata, 5601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 5611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction_arg * arg, 5621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction_source * src) 5631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int shared_mask; 5651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data * d = userdata; 5661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák shared_mask = get_readers_read_callback(d, 5681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 0 /*Pair Instructions don't use RelAddr*/, 5691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src->File, src->Index, arg->Swizzle); 5701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (shared_mask == RC_MASK_NONE) 5721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 5731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReadPairCB) 5751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReadPairCB(d->ReaderData, inst, arg, src); 5761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReaderData->ExitOnAbort && d->ReaderData->Abort) 5781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 5791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák add_reader_pair(&d->C->Pool, d->ReaderData, inst, shared_mask, arg, src); 5811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 5841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This function is used by rc_get_readers_normal() to determine whether inst 5851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * is a reader of userdata->ReaderData->Writer 5861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 5871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void get_readers_normal_read_callback( 5881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * userdata, 5891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 5901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register * src) 5911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data * d = userdata; 5931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int shared_mask; 5941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák shared_mask = get_readers_read_callback(d, 5961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src->RelAddr, src->File, src->Index, src->Swizzle); 5971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (shared_mask == RC_MASK_NONE) 5991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 6001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* The callback function could potentially clear d->ReaderData->Abort, 6011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * so we need to call it before we return. */ 6021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReadNormalCB) 6031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReadNormalCB(d->ReaderData, inst, src); 6041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReaderData->ExitOnAbort && d->ReaderData->Abort) 6061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 6071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák add_reader_normal(&d->C->Pool, d->ReaderData, inst, shared_mask, src); 6091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 6121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This function is used by rc_get_readers_normal() to determine when 6131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * userdata->ReaderData->Writer is dead (i. e. All compontents of its 6141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * destination register have been overwritten by other instructions). 6151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 6161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void get_readers_write_callback( 6171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void *userdata, 6181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst, 6191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file file, 6201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int index, 6211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int mask) 6221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data * d = userdata; 6241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (index == d->DstIndex && file == d->DstFile) { 6261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int shared_mask = mask & d->DstMask; 6271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnRead &= ~shared_mask; 6281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->AliveWriteMask &= ~shared_mask; 6291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReaderData->AbortOnWrite & shared_mask) { 6301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->Abort = 1; 6311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if(d->WriteCB) 6351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->WriteCB(d->ReaderData, inst, file, index, mask); 6361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void push_branch_mask( 6391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data * d, 6401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int * branch_depth) 6411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (*branch_depth)++; 6431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (*branch_depth > R500_PFS_MAX_BRANCH_DEPTH_FULL) { 6441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->Abort = 1; 6451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 6461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->BranchMasks[*branch_depth].IfWriteMask = 6481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->AliveWriteMask; 6491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void pop_branch_mask( 6521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data * d, 6531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int * branch_depth) 6541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct branch_write_mask * masks = &d->BranchMasks[*branch_depth]; 6561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (masks->HasElse) { 6581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Abort on read for components that were written in the IF 6591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * block. */ 6601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnRead |= 6611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák masks->IfWriteMask & ~masks->ElseWriteMask; 6621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Abort on read for components that were written in the ELSE 6631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * block. */ 6641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnRead |= 6651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák masks->ElseWriteMask & ~d->AliveWriteMask; 6661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->AliveWriteMask = masks->IfWriteMask 6681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ^ ((masks->IfWriteMask ^ masks->ElseWriteMask) 6691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & (masks->IfWriteMask ^ d->AliveWriteMask)); 6701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 6711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnRead |= 6721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák masks->IfWriteMask & ~d->AliveWriteMask; 6731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->AliveWriteMask = masks->IfWriteMask; 6741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(masks, 0, sizeof(struct branch_write_mask)); 6771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (*branch_depth)--; 6781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void get_readers_for_single_write( 6811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void * userdata, 6821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * writer, 6831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_register_file dst_file, 6841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int dst_index, 6851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int dst_mask) 6861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * tmp; 6881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int branch_depth = 0; 6891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * endloop = NULL; 6901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int abort_on_read_at_endloop = 0; 6911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data * d = userdata; 6921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->Writer = writer; 6941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnRead = 0; 6951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnWrite = 0; 6961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->LoopDepth = 0; 6971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->InElse = 0; 6981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->DstFile = dst_file; 6991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->DstIndex = dst_index; 7001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->DstMask = dst_mask; 7011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->AliveWriteMask = dst_mask; 7021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(d->BranchMasks, 0, sizeof(d->BranchMasks)); 7031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!dst_mask) 7051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 7061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(tmp = writer->Next; tmp != &d->C->Program.Instructions; 7081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tmp = tmp->Next){ 7091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_opcode opcode = rc_get_flow_control_inst(tmp); 7101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(opcode) { 7111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_BGNLOOP: 7121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->LoopDepth++; 7131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák push_branch_mask(d, &branch_depth); 7141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 7151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_ENDLOOP: 7161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReaderData->LoopDepth > 0) { 7171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->LoopDepth--; 7181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReaderData->LoopDepth == 0) { 7191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnWrite = 0; 7201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pop_branch_mask(d, &branch_depth); 7221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 7231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Here we have reached an ENDLOOP without 7241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * seeing its BGNLOOP. These means that 7251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the writer was written inside of a loop, 7261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * so it could have readers that are above it 7271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * (i.e. they have a lower IP). To find these 7281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * readers we jump to the BGNLOOP instruction 7291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * and check each instruction until we get 7301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * back to the writer. 7311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 7321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák endloop = tmp; 7331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tmp = rc_match_endloop(tmp); 7341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!tmp) { 7351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_error(d->C, "Failed to match endloop.\n"); 7361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->Abort = 1; 7371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 7381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák abort_on_read_at_endloop = d->ReaderData->AbortOnRead; 7401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnRead |= d->AliveWriteMask; 7411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 7421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 7441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_IF: 7451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák push_branch_mask(d, &branch_depth); 7461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 7471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_ELSE: 7481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (branch_depth == 0) { 7491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->InElse = 1; 7501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 7511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int temp_mask = d->AliveWriteMask; 7521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->AliveWriteMask = 7531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->BranchMasks[branch_depth].IfWriteMask; 7541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->BranchMasks[branch_depth].ElseWriteMask = 7551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák temp_mask; 7561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->BranchMasks[branch_depth].HasElse = 1; 7571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 7591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_ENDIF: 7601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (branch_depth == 0) { 7611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnRead = d->AliveWriteMask; 7621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->InElse = 0; 7631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák else { 7651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák pop_branch_mask(d, &branch_depth); 7661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 7681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák default: 7691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 7701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReaderData->InElse) 7731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 7741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (tmp->Type == RC_INSTRUCTION_NORMAL) { 7761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_for_all_reads_src(tmp, 7771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_readers_normal_read_callback, d); 7781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 7791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_for_all_reads_arg(tmp, 7801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_readers_pair_read_callback, d); 7811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* This can happen when we jump from an ENDLOOP to BGNLOOP */ 7841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (tmp == writer) { 7851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tmp = endloop; 7861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák endloop = NULL; 7871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData->AbortOnRead = abort_on_read_at_endloop; 7881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 7891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_for_all_writes_mask(tmp, get_readers_write_callback, d); 7911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (d->ReaderData->ExitOnAbort && d->ReaderData->Abort) 7931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 7941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (branch_depth == 0 && !d->AliveWriteMask) 7961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 7971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 7981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 7991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void init_get_readers_callback_data( 8011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data * d, 8021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data * reader_data, 8031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, 8041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_src_fn read_normal_cb, 8051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_read_arg_fn read_pair_cb, 8061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_write_mask_fn write_cb) 8071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 8081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader_data->Abort = 0; 8091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader_data->ReaderCount = 0; 8101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader_data->ReadersReserved = 0; 8111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák reader_data->Readers = NULL; 8121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->C = c; 8141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReaderData = reader_data; 8151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReadNormalCB = read_normal_cb; 8161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->ReadPairCB = read_pair_cb; 8171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák d->WriteCB = write_cb; 8181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 8191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 8211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This function will create a list of readers via the rc_reader_data struct. 8221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This function will abort (set the flag data->Abort) and return if it 8231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * encounters an instruction that reads from @param writer and also a different 8241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * instruction. Here are some examples: 8251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 8261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * writer = instruction 0; 8271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 0 MOV TEMP[0].xy, TEMP[1].xy 8281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 1 MOV TEMP[0].zw, TEMP[2].xy 8291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 2 MOV TEMP[3], TEMP[0] 8301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The Abort flag will be set on instruction 2, because it reads values written 8311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * by instructions 0 and 1. 8321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 8331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * writer = instruction 1; 8341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 0 IF TEMP[0].x 8351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 1 MOV TEMP[1], TEMP[2] 8361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 2 ELSE 8371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 3 MOV TEMP[1], TEMP[2] 8381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 4 ENDIF 8391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 5 MOV TEMP[3], TEMP[1] 8401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The Abort flag will be set on instruction 5, because it could read from the 8411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * value written by either instruction 1 or 3, depending on the jump decision 8421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * made at instruction 0. 8431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 8441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * writer = instruction 0; 8451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 0 MOV TEMP[0], TEMP[1] 8461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 2 BGNLOOP 8471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 3 ADD TEMP[0], TEMP[0], none.1 8481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 4 ENDLOOP 8491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The Abort flag will be set on instruction 3, because in the first iteration 8501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * of the loop it reads the value written by instruction 0 and in all other 8511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * iterations it reads the value written by instruction 3. 8521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 8531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param read_cb This function will be called for for every instruction that 8541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * has been determined to be a reader of writer. 8551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param write_cb This function will be called for every instruction after 8561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * writer. 8571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 8581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_get_readers( 8591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, 8601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * writer, 8611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data * data, 8621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_src_fn read_normal_cb, 8631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_read_arg_fn read_pair_cb, 8641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_write_mask_fn write_cb) 8651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 8661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data d; 8671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák init_get_readers_callback_data(&d, data, c, read_normal_cb, 8691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák read_pair_cb, write_cb); 8701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_for_all_writes_mask(writer, get_readers_for_single_write, &d); 8721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 8731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_get_readers_sub( 8751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, 8761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * writer, 8771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_sub_instruction * sub_writer, 8781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_reader_data * data, 8791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_src_fn read_normal_cb, 8801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_pair_read_arg_fn read_pair_cb, 8811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_read_write_mask_fn write_cb) 8821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 8831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct get_readers_callback_data d; 8841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák init_get_readers_callback_data(&d, data, c, read_normal_cb, 8861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák read_pair_cb, write_cb); 8871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (sub_writer->WriteMask) { 8891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák get_readers_for_single_write(&d, writer, RC_FILE_TEMPORARY, 8901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sub_writer->DestIndex, sub_writer->WriteMask); 8911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 8921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 893