11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/*
21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright (C) 2008-2009 Nicolai Haehnle.
31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
41c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * All Rights Reserved.
51c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
61c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining
71c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * a copy of this software and associated documentation files (the
81c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * "Software"), to deal in the Software without restriction, including
91c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * without limitation the rights to use, copy, modify, merge, publish,
101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * distribute, sublicense, and/or sell copies of the Software, and to
111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * permit persons to whom the Software is furnished to do so, subject to
121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the following conditions:
131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The above copyright notice and this permission notice (including the
151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * next paragraph) shall be included in all copies or substantial
161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * portions of the Software.
171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */
271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_program_pair.h"
291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler_util.h"
311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include <stdlib.h>
331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/**
351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Return the source slot where we installed the given register access,
361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * or -1 if no slot was free anymore.
371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */
381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint rc_pair_alloc_source(struct rc_pair_instruction *pair,
391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int rgb, unsigned int alpha,
401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	rc_register_file file, unsigned int index)
411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int candidate = -1;
431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int candidate_quality = -1;
441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int alpha_used = 0;
451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int rgb_used = 0;
461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int i;
471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if ((!rgb && !alpha) || file == RC_FILE_NONE)
491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return 0;
501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Make sure only one presubtract operation is used per instruction. */
521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (file == RC_FILE_PRESUB) {
531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (rgb && pair->RGB.Src[RC_PAIR_PRESUB_SRC].Used
541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			&& index != pair->RGB.Src[RC_PAIR_PRESUB_SRC].Index) {
551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				return -1;
561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (alpha && pair->Alpha.Src[RC_PAIR_PRESUB_SRC].Used
591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			&& index != pair->Alpha.Src[RC_PAIR_PRESUB_SRC].Index) {
601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				return -1;
611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for(i = 0; i < 3; ++i) {
651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		int q = 0;
661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (rgb) {
671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (pair->RGB.Src[i].Used) {
681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				if (pair->RGB.Src[i].File != file ||
691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				    pair->RGB.Src[i].Index != index) {
701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					rgb_used++;
711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					continue;
721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				}
731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				q++;
741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (alpha) {
771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (pair->Alpha.Src[i].Used) {
781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				if (pair->Alpha.Src[i].File != file ||
791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				    pair->Alpha.Src[i].Index != index) {
801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					alpha_used++;
811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					continue;
821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				}
831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				q++;
841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (q > candidate_quality) {
871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			candidate_quality = q;
881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			candidate = i;
891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (file == RC_FILE_PRESUB) {
931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		candidate = RC_PAIR_PRESUB_SRC;
941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	} else if (candidate < 0 || (rgb && rgb_used > 2)
951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			|| (alpha && alpha_used > 2)) {
961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return -1;
971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* candidate >= 0 */
1001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (rgb) {
1021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		pair->RGB.Src[candidate].Used = 1;
1031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		pair->RGB.Src[candidate].File = file;
1041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		pair->RGB.Src[candidate].Index = index;
1051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (candidate == RC_PAIR_PRESUB_SRC) {
1061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			/* For registers with the RC_FILE_PRESUB file,
1071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 * the index stores the presubtract op. */
1081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			int src_regs = rc_presubtract_src_reg_count(index);
1091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			for(i = 0; i < src_regs; i++) {
1101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				pair->RGB.Src[i].Used = 1;
1111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
1121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (alpha) {
1151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		pair->Alpha.Src[candidate].Used = 1;
1161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		pair->Alpha.Src[candidate].File = file;
1171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		pair->Alpha.Src[candidate].Index = index;
1181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (candidate == RC_PAIR_PRESUB_SRC) {
1191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			/* For registers with the RC_FILE_PRESUB file,
1201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 * the index stores the presubtract op. */
1211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			int src_regs = rc_presubtract_src_reg_count(index);
1221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			for(i=0; i < src_regs; i++) {
1231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				pair->Alpha.Src[i].Used = 1;
1241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
1251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return candidate;
1291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void pair_foreach_source_callback(
1321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_pair_instruction * pair,
1331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	void * data,
1341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	rc_pair_foreach_src_fn cb,
1351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int swz,
1361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int src)
1371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* swz > 3 means that the swizzle is either not used, or a constant
1391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	 * swizzle (e.g. 0, 1, 0.5). */
1401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if(swz > 3)
1411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return;
1421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if(swz == RC_SWIZZLE_W) {
1441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (src == RC_PAIR_PRESUB_SRC) {
1451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			unsigned int i;
1461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			unsigned int src_count = rc_presubtract_src_reg_count(
1471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				pair->Alpha.Src[RC_PAIR_PRESUB_SRC].Index);
1481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			for(i = 0; i < src_count; i++) {
1491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				cb(data, &pair->Alpha.Src[i]);
1501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
1511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		} else {
1521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			cb(data, &pair->Alpha.Src[src]);
1531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	} else {
1551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (src == RC_PAIR_PRESUB_SRC) {
1561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			unsigned int i;
1571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			unsigned int src_count = rc_presubtract_src_reg_count(
1581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				pair->RGB.Src[RC_PAIR_PRESUB_SRC].Index);
1591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			for(i = 0; i < src_count; i++) {
1601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				cb(data, &pair->RGB.Src[i]);
1611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
1621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		else {
1641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			cb(data, &pair->RGB.Src[src]);
1651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_pair_foreach_source_that_alpha_reads(
1701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_pair_instruction * pair,
1711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	void * data,
1721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	rc_pair_foreach_src_fn cb)
1731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int i;
1751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	const struct rc_opcode_info * info =
1761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				rc_get_opcode_info(pair->Alpha.Opcode);
1771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for(i = 0; i < info->NumSrcRegs; i++) {
1781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		pair_foreach_source_callback(pair, data, cb,
1791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					GET_SWZ(pair->Alpha.Arg[i].Swizzle, 0),
1801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					pair->Alpha.Arg[i].Source);
1811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_pair_foreach_source_that_rgb_reads(
1851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_pair_instruction * pair,
1861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	void * data,
1871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	rc_pair_foreach_src_fn cb)
1881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int i;
1901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	const struct rc_opcode_info * info =
1911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				rc_get_opcode_info(pair->RGB.Opcode);
1921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for(i = 0; i < info->NumSrcRegs; i++) {
1931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		unsigned int chan;
1941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		unsigned int swz = RC_SWIZZLE_UNUSED;
1951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		/* Find a swizzle that is either X,Y,Z,or W.  We assume here
1961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		 * that if one channel swizzles X,Y, or Z, then none of the
1971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		 * other channels swizzle W, and vice-versa. */
1981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for(chan = 0; chan < 4; chan++) {
1991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			swz = GET_SWZ(pair->RGB.Arg[i].Swizzle, chan);
2001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if(swz == RC_SWIZZLE_X || swz == RC_SWIZZLE_Y
2011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			|| swz == RC_SWIZZLE_Z || swz == RC_SWIZZLE_W)
2021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				continue;
2031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
2041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		pair_foreach_source_callback(pair, data, cb,
2051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					swz,
2061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					pair->RGB.Arg[i].Source);
2071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
2081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_pair_instruction_source * rc_pair_get_src(
2111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_pair_instruction * pair_inst,
2121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_pair_instruction_arg * arg)
2131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int type;
2151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	type = rc_source_type_swz(arg->Swizzle);
2171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (type & RC_SOURCE_RGB) {
2191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return &pair_inst->RGB.Src[arg->Source];
2201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	} else if (type & RC_SOURCE_ALPHA) {
2211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return &pair_inst->Alpha.Src[arg->Source];
2221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	} else {
2231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return NULL;
2241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
2251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint rc_pair_get_src_index(
2281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_pair_instruction * pair_inst,
2291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_pair_instruction_source * src)
2301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int i;
2321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (i = 0; i < 3; i++) {
2331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (&pair_inst->RGB.Src[i] == src
2341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			|| &pair_inst->Alpha.Src[i] == src) {
2351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			return i;
2361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
2371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
2381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return -1;
2391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
240