11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/*
21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright (C) 2009 Nicolai Haehnle.
31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright 2011 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_program_pair.h"
301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include <stdio.h>
321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "main/glheader.h"
341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "program/register_allocate.h"
351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "ralloc.h"
361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "r300_fragprog_swizzle.h"
381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler.h"
391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler_util.h"
401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_dataflow.h"
411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_list.h"
421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_variable.h"
431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define VERBOSE 0
451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct register_info {
511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct live_intervals Live[4];
521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int Used:1;
541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int Allocated:1;
551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int File:3;
561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int Index:RC_REGISTER_INDEX_BITS;
571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int Writemask;
581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák};
591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct regalloc_state {
611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct radeon_compiler * C;
621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct register_info * Input;
641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int NumInputs;
651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct register_info * Temporary;
671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int NumTemporaries;
681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int Simple;
701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int LoopEnd;
711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák};
721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákenum rc_reg_class {
741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_SINGLE,
751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_DOUBLE,
761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_TRIPLE,
771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_ALPHA,
781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_SINGLE_PLUS_ALPHA,
791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_DOUBLE_PLUS_ALPHA,
801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_TRIPLE_PLUS_ALPHA,
811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_X,
821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_Y,
831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_Z,
841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_XY,
851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_YZ,
861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_XZ,
871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_XW,
881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_YW,
891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_ZW,
901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_XYW,
911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_YZW,
921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_XZW,
931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	RC_REG_CLASS_COUNT
941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák};
951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_class {
971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	enum rc_reg_class Class;
981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int WritemaskCount;
1001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/** This is 1 if this class is being used by the register allocator
1021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	 * and 0 otherwise */
1031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int Used;
1041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/** This is the ID number assigned to this class by ra. */
1061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int Id;
1071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/** List of writemasks that belong to this class */
1091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int Writemasks[3];
1101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák};
1131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void print_live_intervals(struct live_intervals * src)
1151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (!src || !src->Used) {
1171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		DBG("(null)");
1181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return;
1191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	DBG("(%i,%i)", src->Start, src->End);
1221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int overlap_live_intervals(struct live_intervals * a, struct live_intervals * b)
1251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (VERBOSE) {
1271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		DBG("overlap_live_intervals: ");
1281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		print_live_intervals(a);
1291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		DBG(" to ");
1301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		print_live_intervals(b);
1311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		DBG("\n");
1321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (!a->Used || !b->Used) {
1351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		DBG("    unused interval\n");
1361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return 0;
1371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (a->Start > b->Start) {
1401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (a->Start < b->End) {
1411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			DBG("    overlap\n");
1421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			return 1;
1431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	} else if (b->Start > a->Start) {
1451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (b->Start < a->End) {
1461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			DBG("    overlap\n");
1471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			return 1;
1481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	} else { /* a->Start == b->Start */
1501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (a->Start != a->End && b->Start != b->End) {
1511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			DBG("    overlap\n");
1521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			return 1;
1531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	DBG("    no overlap\n");
1571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return 0;
1591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void scan_read_callback(void * data, struct rc_instruction * inst,
1621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_register_file file, unsigned int index, unsigned int mask)
1631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct regalloc_state * s = data;
1651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct register_info * reg;
1661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int i;
1671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (file != RC_FILE_INPUT)
1691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return;
1701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s->Input[index].Used = 1;
1721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	reg = &s->Input[index];
1731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (i = 0; i < 4; i++) {
1751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (!((mask >> i) & 0x1)) {
1761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			continue;
1771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		reg->Live[i].Used = 1;
1791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		reg->Live[i].Start = 0;
1801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		reg->Live[i].End =
1811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			s->LoopEnd > inst->IP ? s->LoopEnd : inst->IP;
1821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void remap_register(void * data, struct rc_instruction * inst,
1861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_register_file * file, unsigned int * index)
1871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct regalloc_state * s = data;
1891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	const struct register_info * reg;
1901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (*file == RC_FILE_TEMPORARY && s->Simple)
1921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		reg = &s->Temporary[*index];
1931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	else if (*file == RC_FILE_INPUT)
1941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		reg = &s->Input[*index];
1951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	else
1961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return;
1971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (reg->Allocated) {
1991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		*index = reg->Index;
2001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
2011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void alloc_input_simple(void * data, unsigned int input,
2041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák							unsigned int hwreg)
2051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct regalloc_state * s = data;
2071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (input >= s->NumInputs)
2091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return;
2101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s->Input[input].Allocated = 1;
2121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s->Input[input].File = RC_FILE_TEMPORARY;
2131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s->Input[input].Index = hwreg;
2141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* This functions offsets the temporary register indices by the number
2171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * of input registers, because input registers are actually temporaries and
2181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * should not occupy the same space.
2191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
2201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This pass is supposed to be used to maintain correct allocation of inputs
2211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * if the standard register allocation is disabled. */
2221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void do_regalloc_inputs_only(struct regalloc_state * s)
2231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (unsigned i = 0; i < s->NumTemporaries; i++) {
2251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		s->Temporary[i].Allocated = 1;
2261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		s->Temporary[i].File = RC_FILE_TEMPORARY;
2271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		s->Temporary[i].Index = i + s->NumInputs;
2281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
2291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int is_derivative(rc_opcode op)
2321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return (op == RC_OPCODE_DDX || op == RC_OPCODE_DDY);
2341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int find_class(
2371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_class * classes,
2381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int writemask,
2391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int max_writemask_count)
2401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int i;
2421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (i = 0; i < RC_REG_CLASS_COUNT; i++) {
2431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		unsigned int j;
2441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (classes[i].WritemaskCount > max_writemask_count) {
2451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			continue;
2461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
2471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for (j = 0; j < 3; j++) {
2481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (classes[i].Writemasks[j] == writemask) {
2491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				return i;
2501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
2511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
2521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
2531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return -1;
2541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2566fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellardstruct variable_get_class_cb_data {
2576fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	unsigned int * can_change_writemask;
2586fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	unsigned int conversion_swizzle;
2596fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard};
2606fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard
2616fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellardstatic void variable_get_class_read_cb(
2626fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	void * userdata,
2636fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	struct rc_instruction * inst,
2646fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	struct rc_pair_instruction_arg * arg,
2656fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	struct rc_pair_instruction_source * src)
2666fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard{
2676fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	struct variable_get_class_cb_data * d = userdata;
2686fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	unsigned int new_swizzle = rc_adjust_channels(arg->Swizzle,
2696fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard							d->conversion_swizzle);
2706fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	if (!r300_swizzle_is_native_basic(new_swizzle)) {
2716fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard		*d->can_change_writemask = 0;
2726fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard	}
2736fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard}
2746fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard
2751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic enum rc_reg_class variable_get_class(
2761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_variable * variable,
2771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_class * classes)
2781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int i;
2801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int can_change_writemask= 1;
2811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int writemask = rc_variable_writemask_sum(variable);
2821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_list * readers = rc_variable_readers_union(variable);
2831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int class_index;
2841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (!variable->C->is_r500) {
2861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		struct rc_class c;
2876fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard		struct rc_variable * var_ptr;
2881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		/* The assumption here is that if an instruction has type
2891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		 * RC_INSTRUCTION_NORMAL then it is a TEX instruction.
2901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		 * r300 and r400 can't swizzle the result of a TEX lookup. */
2916fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard		for (var_ptr = variable; var_ptr; var_ptr = var_ptr->Friend) {
2926fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard			if (var_ptr->Inst->Type == RC_INSTRUCTION_NORMAL) {
2936fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				writemask = RC_MASK_XYZW;
2946fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard			}
2951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
2961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		/* Check if it is possible to do swizzle packing for r300/r400
2981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		 * without creating non-native swizzles. */
2991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		class_index = find_class(classes, writemask, 3);
3001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (class_index < 0) {
3011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			goto error;
3021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
3031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		c = classes[class_index];
3046fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard		if (c.WritemaskCount == 1) {
3056fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard			goto done;
3066fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard		}
3071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for (i = 0; i < c.WritemaskCount; i++) {
3086fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard			struct rc_variable * var_ptr;
3096fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard			for (var_ptr = variable; var_ptr;
3106fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard						var_ptr = var_ptr->Friend) {
3116fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				int j;
3126fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				unsigned int conversion_swizzle =
3131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák						rc_make_conversion_swizzle(
3141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák						writemask, c.Writemasks[i]);
3156fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				struct variable_get_class_cb_data d;
3166fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				d.can_change_writemask = &can_change_writemask;
3176fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				d.conversion_swizzle = conversion_swizzle;
3186fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				/* If we get this far var_ptr->Inst has to
3196fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				 * be a pair instruction.  If variable or any
3206fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				 * of its friends are normal instructions,
3216fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				 * then the writemask will be set to RC_MASK_XYZW
3226fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				 * and the function will return before it gets
3236fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				 * here. */
3246fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				rc_pair_for_all_reads_arg(var_ptr->Inst,
3256fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					variable_get_class_read_cb, &d);
3266fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard
3276fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				for (j = 0; j < var_ptr->ReaderCount; j++) {
3286fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					unsigned int old_swizzle;
3296fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					unsigned int new_swizzle;
3306fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					struct rc_reader r = var_ptr->Readers[j];
3316fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					if (r.Inst->Type ==
3326fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard							RC_INSTRUCTION_PAIR ) {
3336fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard						old_swizzle = r.U.P.Arg->Swizzle;
3346fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					} else {
3356fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard						old_swizzle = r.U.I.Src->Swizzle;
3366fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					}
3376fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					new_swizzle = rc_adjust_channels(
3386fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard						old_swizzle, conversion_swizzle);
3396fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					if (!r300_swizzle_is_native_basic(
3406fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard								new_swizzle)) {
3416fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard						can_change_writemask = 0;
3426fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard						break;
3436fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard					}
3441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				}
3456fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellard				if (!can_change_writemask) {
3461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					break;
3471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				}
3481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
3491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (!can_change_writemask) {
3501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				break;
3511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
3521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
3531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
3541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
3551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (variable->Inst->Type == RC_INSTRUCTION_PAIR) {
3561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		/* DDX/DDY seem to always fail when their writemasks are
3571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		 * changed.*/
3581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (is_derivative(variable->Inst->U.P.RGB.Opcode)
3591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		    || is_derivative(variable->Inst->U.P.Alpha.Opcode)) {
3601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			can_change_writemask = 0;
3611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
3621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
3631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for ( ; readers; readers = readers->Next) {
3641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		struct rc_reader * r = readers->Item;
3651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (r->Inst->Type == RC_INSTRUCTION_PAIR) {
3661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (r->U.P.Arg->Source == RC_PAIR_PRESUB_SRC) {
3671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				can_change_writemask = 0;
3681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				break;
3691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
3701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			/* DDX/DDY also fail when their swizzles are changed. */
3711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (is_derivative(r->Inst->U.P.RGB.Opcode)
3721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			    || is_derivative(r->Inst->U.P.Alpha.Opcode)) {
3731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				can_change_writemask = 0;
3741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				break;
3751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
3761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
3771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
3781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
3791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	class_index = find_class(classes, writemask,
3801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák						can_change_writemask ? 3 : 1);
3816fafb6beb7df333cc2f7837407796c7970a6bfa6Tom Stellarddone:
3821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (class_index > -1) {
3831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return classes[class_index].Class;
3841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	} else {
3851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákerror:
3861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_error(variable->C,
3871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				"Could not find class for index=%u mask=%u\n",
3881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				variable->Dst.Index, writemask);
3891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return 0;
3901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
3911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
3921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
3931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int overlap_live_intervals_array(
3941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct live_intervals * a,
3951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct live_intervals * b)
3961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
3971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int a_chan, b_chan;
3981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (a_chan = 0; a_chan < 4; a_chan++) {
3991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for (b_chan = 0; b_chan < 4; b_chan++) {
4001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (overlap_live_intervals(&a[a_chan], &b[b_chan])) {
4011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					return 1;
4021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
4031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
4041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
4051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return 0;
4061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
4071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
4081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int reg_get_index(int reg)
4091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
4101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return reg / RC_MASK_XYZW;
4111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
4121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
4131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int reg_get_writemask(int reg)
4141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
4151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return (reg % RC_MASK_XYZW) + 1;
4161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
4171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
4181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int get_reg_id(unsigned int index, unsigned int writemask)
4191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
4201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	assert(writemask);
4211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (writemask == 0) {
4221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return 0;
4231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
4241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return (index * RC_MASK_XYZW) + (writemask - 1);
4251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
4261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
4271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#if VERBOSE
4281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void print_reg(int reg)
4291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
4301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int index = reg_get_index(reg);
4311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int mask = reg_get_writemask(reg);
4321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	fprintf(stderr, "Temp[%u].%c%c%c%c", index,
4331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		mask & RC_MASK_X ? 'x' : '_',
4341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		mask & RC_MASK_Y ? 'y' : '_',
4351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		mask & RC_MASK_Z ? 'z' : '_',
4361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		mask & RC_MASK_W ? 'w' : '_');
4371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
4381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#endif
4391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
4401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void add_register_conflicts(
4411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct ra_regs * regs,
4421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int max_temp_regs)
4431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
4441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int index, a_mask, b_mask;
4451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (index = 0; index < max_temp_regs; index++) {
4461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for(a_mask = 1; a_mask <= RC_MASK_XYZW; a_mask++) {
4471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			for (b_mask = a_mask + 1; b_mask <= RC_MASK_XYZW;
4481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák								b_mask++) {
4491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				if (a_mask & b_mask) {
4501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					ra_add_reg_conflict(regs,
4511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák						get_reg_id(index, a_mask),
4521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák						get_reg_id(index, b_mask));
4531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				}
4541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
4551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
4561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
4571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
4581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
4591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void do_advanced_regalloc(struct regalloc_state * s)
4601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
4611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_class rc_class_list [] = {
4621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_SINGLE, 3, 0, 0,
4631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X,
4641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_Y,
4651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_Z}},
4661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_DOUBLE, 3, 0, 0,
4671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_Y,
4681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_X | RC_MASK_Z,
4691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_Y | RC_MASK_Z}},
4701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_TRIPLE, 1, 0, 0,
4711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_Y | RC_MASK_Z,
4721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_NONE,
4731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_NONE}},
4741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_ALPHA, 1, 0, 0,
4751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_W,
4761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_NONE,
4771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_NONE}},
4781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_SINGLE_PLUS_ALPHA, 3, 0, 0,
4791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_W,
4801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_Y | RC_MASK_W,
4811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_Z | RC_MASK_W}},
4821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_DOUBLE_PLUS_ALPHA, 3, 0, 0,
4831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_Y | RC_MASK_W,
4841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_X | RC_MASK_Z | RC_MASK_W,
4851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			 RC_MASK_Y | RC_MASK_Z | RC_MASK_W}},
4861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_TRIPLE_PLUS_ALPHA, 1, 0, 0,
4871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_Y | RC_MASK_Z | RC_MASK_W,
4881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
4891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
4901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_X, 1, 0, 0,
4911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X,
4921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
4931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
4941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_Y, 1, 0, 0,
4951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_Y,
4961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
4971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
4981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_Z, 1, 0, 0,
4991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_Z,
5001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_XY, 1, 0, 0,
5031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_Y,
5041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_YZ, 1, 0, 0,
5071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_Y | RC_MASK_Z,
5081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_XZ, 1, 0, 0,
5111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_Z,
5121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_XW, 1, 0, 0,
5151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_W,
5161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_YW, 1, 0, 0,
5191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_Y | RC_MASK_W,
5201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_ZW, 1, 0, 0,
5231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_Z | RC_MASK_W,
5241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_XYW, 1, 0, 0,
5271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_Y | RC_MASK_W,
5281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_YZW, 1, 0, 0,
5311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_Y | RC_MASK_Z | RC_MASK_W,
5321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}},
5341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		{RC_REG_CLASS_XZW, 1, 0, 0,
5351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			{RC_MASK_X | RC_MASK_Z | RC_MASK_W,
5361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE,
5371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			RC_MASK_NONE}}
5381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	};
5391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int i, j, index, input_node, node_count, node_index;
5411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int * node_classes;
5421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int * input_classes;
5431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_instruction * inst;
5441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_list * var_ptr;
5451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_list * variables;
5461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct ra_regs * regs;
5471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct ra_graph * graph;
5481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Allocate the main ra data structure */
550b972744c78e45928876ea781b9eeef09b3baf083Eric Anholt	regs = ra_alloc_reg_set(NULL, s->C->max_temp_regs * RC_MASK_XYZW);
5511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Get list of program variables */
5531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	variables = rc_get_variables(s->C);
5541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	node_count = rc_list_count(variables);
5551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	node_classes = memory_pool_malloc(&s->C->Pool,
5561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			node_count * sizeof(unsigned int));
5571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	input_classes = memory_pool_malloc(&s->C->Pool,
5581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			s->NumInputs * sizeof(unsigned int));
5591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (var_ptr = variables, node_index = 0; var_ptr;
5611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					var_ptr = var_ptr->Next, node_index++) {
5621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		unsigned int class_index;
5631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		/* Compute the live intervals */
5641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_variable_compute_live_intervals(var_ptr->Item);
5651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		class_index = variable_get_class(var_ptr->Item,	rc_class_list);
5671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		/* If we haven't used this register class yet, mark it
5691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		 * as used and allocate space for it. */
5701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (!rc_class_list[class_index].Used) {
5711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			rc_class_list[class_index].Used = 1;
5721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			rc_class_list[class_index].Id = ra_alloc_reg_class(regs);
5731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
5741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		node_classes[node_index] = rc_class_list[class_index].Id;
5761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
5771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Assign registers to the classes */
5801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (i = 0; i < RC_REG_CLASS_COUNT; i++) {
5811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		struct rc_class class = rc_class_list[i];
5821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (!class.Used) {
5831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			continue;
5841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
5851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for (index = 0; index < s->C->max_temp_regs; index++) {
5871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			for (j = 0; j < class.WritemaskCount; j++) {
5881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				int reg_id = get_reg_id(index,
5891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák							class.Writemasks[j]);
5901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				ra_class_add_reg(regs, class.Id, reg_id);
5911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
5921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
5931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
5941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Add register conflicts */
5961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	add_register_conflicts(regs, s->C->max_temp_regs);
5971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
5981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Calculate live intervals for input registers */
5991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (inst = s->C->Program.Instructions.Next;
6001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					inst != &s->C->Program.Instructions;
6011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					inst = inst->Next) {
6021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_opcode op = rc_get_flow_control_inst(inst);
6031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (op == RC_OPCODE_BGNLOOP) {
6041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			struct rc_instruction * endloop =
6051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák							rc_match_bgnloop(inst);
6061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (endloop->IP > s->LoopEnd) {
6071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				s->LoopEnd = endloop->IP;
6081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
6091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
6101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_for_all_reads_mask(inst, scan_read_callback, s);
6111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
6121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Create classes for input registers */
6141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (i = 0; i < s->NumInputs; i++) {
6151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		unsigned int chan, class_id, writemask = 0;
6161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for (chan = 0; chan < 4; chan++) {
6171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (s->Input[i].Live[chan].Used) {
6181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				writemask |= (1 << chan);
6191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
6201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
6211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		s->Input[i].Writemask = writemask;
6221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (!writemask) {
6231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			continue;
6241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
6251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		class_id = ra_alloc_reg_class(regs);
6271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		input_classes[i] = class_id;
6281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		ra_class_add_reg(regs, class_id,
6291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				get_reg_id(s->Input[i].Index, writemask));
6301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
6311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	ra_set_finalize(regs);
6331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	graph = ra_alloc_interference_graph(regs, node_count + s->NumInputs);
6351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Build the interference graph */
6371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (var_ptr = variables, node_index = 0; var_ptr;
6381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					var_ptr = var_ptr->Next,node_index++) {
6391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		struct rc_list * a, * b;
6401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		unsigned int b_index;
6411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		ra_set_node_class(graph, node_index, node_classes[node_index]);
6431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for (a = var_ptr, b = var_ptr->Next, b_index = node_index + 1;
6451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák						b; b = b->Next, b_index++) {
6461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			struct rc_variable * var_a = a->Item;
6471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			while (var_a) {
6481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				struct rc_variable * var_b = b->Item;
6491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				while (var_b) {
6501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					if (overlap_live_intervals_array(var_a->Live, var_b->Live)) {
6511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák						ra_add_node_interference(graph,
6521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák							node_index, b_index);
6531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					}
6541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					var_b = var_b->Friend;
6551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				}
6561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				var_a = var_a->Friend;
6571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
6581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
6591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
6601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Add input registers to the interference graph */
6621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (i = 0, input_node = 0; i< s->NumInputs; i++) {
6631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (!s->Input[i].Writemask) {
6641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			continue;
6651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
6661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		ra_set_node_class(graph, node_count + input_node,
6671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák							input_classes[i]);
6681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for (var_ptr = variables, node_index = 0;
6691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				var_ptr; var_ptr = var_ptr->Next, node_index++) {
6701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			struct rc_variable * var = var_ptr->Item;
6711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (overlap_live_intervals_array(s->Input[i].Live,
6721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák								var->Live)) {
6731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				ra_add_node_interference(graph, node_index,
6741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák						node_count + input_node);
6751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			}
6761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
6771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		/* Manually allocate a register for this input */
6781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		ra_set_node_reg(graph, node_count + input_node, get_reg_id(
6791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				s->Input[i].Index, s->Input[i].Writemask));
6801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		input_node++;
6811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
6821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (!ra_allocate_no_spills(graph)) {
6841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_error(s->C, "Ran out of hardware temporaries\n");
6851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return;
6861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
6871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Rewrite the registers */
6891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (var_ptr = variables, node_index = 0; var_ptr;
6901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				var_ptr = var_ptr->Next, node_index++) {
6911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		int reg = ra_get_node_reg(graph, node_index);
6921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		unsigned int writemask = reg_get_writemask(reg);
6931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		unsigned int index = reg_get_index(reg);
6941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		struct rc_variable * var = var_ptr->Item;
6951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
6961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (!s->C->is_r500 && var->Inst->Type == RC_INSTRUCTION_NORMAL) {
6971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			writemask = rc_variable_writemask_sum(var);
6981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
6991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
7001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if (var->Dst.File == RC_FILE_INPUT) {
7011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			continue;
7021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
7031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_variable_change_dst(var, index, writemask);
7041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
7051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
7061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	ralloc_free(graph);
7071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	ralloc_free(regs);
7081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
7091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
7101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/**
7111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param user This parameter should be a pointer to an integer value.  If this
7121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * integer value is zero, then a simple register allocator will be used that
7131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * only allocates space for input registers (\sa do_regalloc_inputs_only).  If
7141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * user is non-zero, then the regular register allocator will be used
7151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * (\sa do_regalloc).
7161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák  */
7171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_pair_regalloc(struct radeon_compiler *cc, void *user)
7181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
7191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct r300_fragment_program_compiler *c =
7201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				(struct r300_fragment_program_compiler*)cc;
7211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct regalloc_state s;
7221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int * do_full_regalloc = (int*)user;
7231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
7241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	memset(&s, 0, sizeof(s));
7251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s.C = cc;
7261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s.NumInputs = rc_get_max_index(cc, RC_FILE_INPUT) + 1;
7271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s.Input = memory_pool_malloc(&cc->Pool,
7281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			s.NumInputs * sizeof(struct register_info));
7291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	memset(s.Input, 0, s.NumInputs * sizeof(struct register_info));
7301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
7311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s.NumTemporaries = rc_get_max_index(cc, RC_FILE_TEMPORARY) + 1;
7321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	s.Temporary = memory_pool_malloc(&cc->Pool,
7331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			s.NumTemporaries * sizeof(struct register_info));
7341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	memset(s.Temporary, 0, s.NumTemporaries * sizeof(struct register_info));
7351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
7361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	rc_recompute_ips(s.C);
7371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
7381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	c->AllocateHwInputs(c, &alloc_input_simple, &s);
7391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (*do_full_regalloc) {
7401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		do_advanced_regalloc(&s);
7411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	} else {
7421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		s.Simple = 1;
7431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		do_regalloc_inputs_only(&s);
7441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
7451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
7461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	/* Rewrite inputs and if we are doing the simple allocation, rewrite
7471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	 * temporaries too. */
7481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for (struct rc_instruction *inst = s.C->Program.Instructions.Next;
7491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					inst != &s.C->Program.Instructions;
7501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák					inst = inst->Next) {
7511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_remap_registers(inst, &remap_register, &s);
7521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
7531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
754