1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2009 Nicolai Haehnle.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2011 Tom Stellard <tstellar@gmail.com>
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software.
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_program_pair.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h>
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/register_allocate.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ralloc.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r300_fragprog_swizzle.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler_util.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_dataflow.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_list.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_variable.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define VERBOSE 0
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct register_info {
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct live_intervals Live[4];
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int Used:1;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int Allocated:1;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int File:3;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int Index:RC_REGISTER_INDEX_BITS;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int Writemask;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct regalloc_state {
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_compiler * C;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct register_info * Input;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int NumInputs;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct register_info * Temporary;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int NumTemporaries;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int Simple;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int LoopEnd;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum rc_reg_class {
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_SINGLE,
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_DOUBLE,
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_TRIPLE,
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_ALPHA,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_SINGLE_PLUS_ALPHA,
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_DOUBLE_PLUS_ALPHA,
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_TRIPLE_PLUS_ALPHA,
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_X,
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_Y,
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_Z,
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_XY,
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_YZ,
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_XZ,
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_XW,
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_YW,
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_ZW,
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_XYW,
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_YZW,
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_XZW,
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RC_REG_CLASS_COUNT
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct rc_class {
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum rc_reg_class Class;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int WritemaskCount;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/** This is 1 if this class is being used by the register allocator
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * and 0 otherwise */
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int Used;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/** This is the ID number assigned to this class by ra. */
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int Id;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/** List of writemasks that belong to this class */
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int Writemasks[3];
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void print_live_intervals(struct live_intervals * src)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!src || !src->Used) {
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		DBG("(null)");
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	DBG("(%i,%i)", src->Start, src->End);
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int overlap_live_intervals(struct live_intervals * a, struct live_intervals * b)
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (VERBOSE) {
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		DBG("overlap_live_intervals: ");
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print_live_intervals(a);
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		DBG(" to ");
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		print_live_intervals(b);
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		DBG("\n");
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!a->Used || !b->Used) {
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		DBG("    unused interval\n");
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return 0;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (a->Start > b->Start) {
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (a->Start < b->End) {
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			DBG("    overlap\n");
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return 1;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (b->Start > a->Start) {
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (b->Start < a->End) {
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			DBG("    overlap\n");
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return 1;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else { /* a->Start == b->Start */
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (a->Start != a->End && b->Start != b->End) {
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			DBG("    overlap\n");
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return 1;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	DBG("    no overlap\n");
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void scan_read_callback(void * data, struct rc_instruction * inst,
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_register_file file, unsigned int index, unsigned int mask)
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct regalloc_state * s = data;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct register_info * reg;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int i;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (file != RC_FILE_INPUT)
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s->Input[index].Used = 1;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	reg = &s->Input[index];
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < 4; i++) {
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!((mask >> i) & 0x1)) {
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		reg->Live[i].Used = 1;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		reg->Live[i].Start = 0;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		reg->Live[i].End =
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			s->LoopEnd > inst->IP ? s->LoopEnd : inst->IP;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void remap_register(void * data, struct rc_instruction * inst,
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_register_file * file, unsigned int * index)
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct regalloc_state * s = data;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct register_info * reg;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (*file == RC_FILE_TEMPORARY && s->Simple)
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		reg = &s->Temporary[*index];
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else if (*file == RC_FILE_INPUT)
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		reg = &s->Input[*index];
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (reg->Allocated) {
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*index = reg->Index;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void alloc_input_simple(void * data, unsigned int input,
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							unsigned int hwreg)
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct regalloc_state * s = data;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (input >= s->NumInputs)
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s->Input[input].Allocated = 1;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s->Input[input].File = RC_FILE_TEMPORARY;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s->Input[input].Index = hwreg;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This functions offsets the temporary register indices by the number
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of input registers, because input registers are actually temporaries and
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * should not occupy the same space.
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This pass is supposed to be used to maintain correct allocation of inputs
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if the standard register allocation is disabled. */
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void do_regalloc_inputs_only(struct regalloc_state * s)
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (unsigned i = 0; i < s->NumTemporaries; i++) {
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		s->Temporary[i].Allocated = 1;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		s->Temporary[i].File = RC_FILE_TEMPORARY;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		s->Temporary[i].Index = i + s->NumInputs;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int is_derivative(rc_opcode op)
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (op == RC_OPCODE_DDX || op == RC_OPCODE_DDY);
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int find_class(
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_class * classes,
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int writemask,
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int max_writemask_count)
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int i;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < RC_REG_CLASS_COUNT; i++) {
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned int j;
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (classes[i].WritemaskCount > max_writemask_count) {
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (j = 0; j < 3; j++) {
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (classes[i].Writemasks[j] == writemask) {
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				return i;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return -1;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct variable_get_class_cb_data {
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int * can_change_writemask;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int conversion_swizzle;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void variable_get_class_read_cb(
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void * userdata,
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_instruction * inst,
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_pair_instruction_arg * arg,
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_pair_instruction_source * src)
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct variable_get_class_cb_data * d = userdata;
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int new_swizzle = rc_adjust_channels(arg->Swizzle,
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							d->conversion_swizzle);
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!r300_swizzle_is_native_basic(new_swizzle)) {
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*d->can_change_writemask = 0;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum rc_reg_class variable_get_class(
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_variable * variable,
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_class * classes)
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int i;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int can_change_writemask= 1;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int writemask = rc_variable_writemask_sum(variable);
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_list * readers = rc_variable_readers_union(variable);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int class_index;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!variable->C->is_r500) {
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct rc_class c;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct rc_variable * var_ptr;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* The assumption here is that if an instruction has type
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * RC_INSTRUCTION_NORMAL then it is a TEX instruction.
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * r300 and r400 can't swizzle the result of a TEX lookup. */
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (var_ptr = variable; var_ptr; var_ptr = var_ptr->Friend) {
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (var_ptr->Inst->Type == RC_INSTRUCTION_NORMAL) {
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				writemask = RC_MASK_XYZW;
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* Check if it is possible to do swizzle packing for r300/r400
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * without creating non-native swizzles. */
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		class_index = find_class(classes, writemask, 3);
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (class_index < 0) {
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto error;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		c = classes[class_index];
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (c.WritemaskCount == 1) {
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto done;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (i = 0; i < c.WritemaskCount; i++) {
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct rc_variable * var_ptr;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for (var_ptr = variable; var_ptr;
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						var_ptr = var_ptr->Friend) {
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				int j;
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				unsigned int conversion_swizzle =
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						rc_make_conversion_swizzle(
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						writemask, c.Writemasks[i]);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				struct variable_get_class_cb_data d;
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				d.can_change_writemask = &can_change_writemask;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				d.conversion_swizzle = conversion_swizzle;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				/* If we get this far var_ptr->Inst has to
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 * be a pair instruction.  If variable or any
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 * of its friends are normal instructions,
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 * then the writemask will be set to RC_MASK_XYZW
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 * and the function will return before it gets
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 * here. */
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				rc_pair_for_all_reads_arg(var_ptr->Inst,
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					variable_get_class_read_cb, &d);
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				for (j = 0; j < var_ptr->ReaderCount; j++) {
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					unsigned int old_swizzle;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					unsigned int new_swizzle;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct rc_reader r = var_ptr->Readers[j];
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					if (r.Inst->Type ==
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							RC_INSTRUCTION_PAIR ) {
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						old_swizzle = r.U.P.Arg->Swizzle;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					} else {
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						old_swizzle = r.U.I.Src->Swizzle;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					}
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					new_swizzle = rc_adjust_channels(
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						old_swizzle, conversion_swizzle);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					if (!r300_swizzle_is_native_basic(
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org								new_swizzle)) {
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						can_change_writemask = 0;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						break;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					}
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if (!can_change_writemask) {
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					break;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (!can_change_writemask) {
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (variable->Inst->Type == RC_INSTRUCTION_PAIR) {
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* DDX/DDY seem to always fail when their writemasks are
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * changed.*/
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (is_derivative(variable->Inst->U.P.RGB.Opcode)
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    || is_derivative(variable->Inst->U.P.Alpha.Opcode)) {
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			can_change_writemask = 0;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for ( ; readers; readers = readers->Next) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct rc_reader * r = readers->Item;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (r->Inst->Type == RC_INSTRUCTION_PAIR) {
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (r->U.P.Arg->Source == RC_PAIR_PRESUB_SRC) {
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				can_change_writemask = 0;
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			/* DDX/DDY also fail when their swizzles are changed. */
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (is_derivative(r->Inst->U.P.RGB.Opcode)
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    || is_derivative(r->Inst->U.P.Alpha.Opcode)) {
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				can_change_writemask = 0;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	class_index = find_class(classes, writemask,
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						can_change_writemask ? 3 : 1);
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdone:
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (class_index > -1) {
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return classes[class_index].Class;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror:
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_error(variable->C,
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				"Could not find class for index=%u mask=%u\n",
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				variable->Dst.Index, writemask);
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return 0;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int overlap_live_intervals_array(
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct live_intervals * a,
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct live_intervals * b)
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int a_chan, b_chan;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (a_chan = 0; a_chan < 4; a_chan++) {
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (b_chan = 0; b_chan < 4; b_chan++) {
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (overlap_live_intervals(&a[a_chan], &b[b_chan])) {
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					return 1;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int reg_get_index(int reg)
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return reg / RC_MASK_XYZW;
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int reg_get_writemask(int reg)
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (reg % RC_MASK_XYZW) + 1;
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int get_reg_id(unsigned int index, unsigned int writemask)
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	assert(writemask);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (writemask == 0) {
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return 0;
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (index * RC_MASK_XYZW) + (writemask - 1);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if VERBOSE
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void print_reg(int reg)
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int index = reg_get_index(reg);
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int mask = reg_get_writemask(reg);
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fprintf(stderr, "Temp[%u].%c%c%c%c", index,
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		mask & RC_MASK_X ? 'x' : '_',
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		mask & RC_MASK_Y ? 'y' : '_',
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		mask & RC_MASK_Z ? 'z' : '_',
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		mask & RC_MASK_W ? 'w' : '_');
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void add_register_conflicts(
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct ra_regs * regs,
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int max_temp_regs)
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int index, a_mask, b_mask;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (index = 0; index < max_temp_regs; index++) {
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(a_mask = 1; a_mask <= RC_MASK_XYZW; a_mask++) {
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for (b_mask = a_mask + 1; b_mask <= RC_MASK_XYZW;
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org								b_mask++) {
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if (a_mask & b_mask) {
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					ra_add_reg_conflict(regs,
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						get_reg_id(index, a_mask),
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						get_reg_id(index, b_mask));
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void do_advanced_regalloc(struct regalloc_state * s)
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_class rc_class_list [] = {
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_SINGLE, 3, 0, 0,
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X,
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_Y,
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_Z}},
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_DOUBLE, 3, 0, 0,
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_Y,
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_X | RC_MASK_Z,
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_Y | RC_MASK_Z}},
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_TRIPLE, 1, 0, 0,
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_Y | RC_MASK_Z,
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_NONE,
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_NONE}},
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_ALPHA, 1, 0, 0,
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_W,
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_NONE,
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_NONE}},
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_SINGLE_PLUS_ALPHA, 3, 0, 0,
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_W,
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_Y | RC_MASK_W,
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_Z | RC_MASK_W}},
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_DOUBLE_PLUS_ALPHA, 3, 0, 0,
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_Y | RC_MASK_W,
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_X | RC_MASK_Z | RC_MASK_W,
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 RC_MASK_Y | RC_MASK_Z | RC_MASK_W}},
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_TRIPLE_PLUS_ALPHA, 1, 0, 0,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_Y | RC_MASK_Z | RC_MASK_W,
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_X, 1, 0, 0,
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X,
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_Y, 1, 0, 0,
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_Y,
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_Z, 1, 0, 0,
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_Z,
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_XY, 1, 0, 0,
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_Y,
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_YZ, 1, 0, 0,
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_Y | RC_MASK_Z,
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_XZ, 1, 0, 0,
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_Z,
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_XW, 1, 0, 0,
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_W,
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_YW, 1, 0, 0,
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_Y | RC_MASK_W,
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_ZW, 1, 0, 0,
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_Z | RC_MASK_W,
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_XYW, 1, 0, 0,
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_Y | RC_MASK_W,
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_YZW, 1, 0, 0,
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_Y | RC_MASK_Z | RC_MASK_W,
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}},
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{RC_REG_CLASS_XZW, 1, 0, 0,
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{RC_MASK_X | RC_MASK_Z | RC_MASK_W,
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE,
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			RC_MASK_NONE}}
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	};
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int i, j, index, input_node, node_count, node_index;
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int * node_classes;
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned int * input_classes;
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_instruction * inst;
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_list * var_ptr;
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct rc_list * variables;
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct ra_regs * regs;
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct ra_graph * graph;
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Allocate the main ra data structure */
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	regs = ra_alloc_reg_set(NULL, s->C->max_temp_regs * RC_MASK_XYZW);
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Get list of program variables */
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	variables = rc_get_variables(s->C);
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	node_count = rc_list_count(variables);
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	node_classes = memory_pool_malloc(&s->C->Pool,
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			node_count * sizeof(unsigned int));
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	input_classes = memory_pool_malloc(&s->C->Pool,
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			s->NumInputs * sizeof(unsigned int));
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (var_ptr = variables, node_index = 0; var_ptr;
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					var_ptr = var_ptr->Next, node_index++) {
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned int class_index;
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* Compute the live intervals */
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_variable_compute_live_intervals(var_ptr->Item);
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		class_index = variable_get_class(var_ptr->Item,	rc_class_list);
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* If we haven't used this register class yet, mark it
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * as used and allocate space for it. */
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!rc_class_list[class_index].Used) {
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rc_class_list[class_index].Used = 1;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rc_class_list[class_index].Id = ra_alloc_reg_class(regs);
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		node_classes[node_index] = rc_class_list[class_index].Id;
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Assign registers to the classes */
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < RC_REG_CLASS_COUNT; i++) {
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct rc_class class = rc_class_list[i];
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!class.Used) {
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue;
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (index = 0; index < s->C->max_temp_regs; index++) {
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for (j = 0; j < class.WritemaskCount; j++) {
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				int reg_id = get_reg_id(index,
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							class.Writemasks[j]);
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				ra_class_add_reg(regs, class.Id, reg_id);
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Add register conflicts */
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	add_register_conflicts(regs, s->C->max_temp_regs);
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Calculate live intervals for input registers */
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (inst = s->C->Program.Instructions.Next;
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					inst != &s->C->Program.Instructions;
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					inst = inst->Next) {
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_opcode op = rc_get_flow_control_inst(inst);
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (op == RC_OPCODE_BGNLOOP) {
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct rc_instruction * endloop =
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							rc_match_bgnloop(inst);
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (endloop->IP > s->LoopEnd) {
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				s->LoopEnd = endloop->IP;
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_for_all_reads_mask(inst, scan_read_callback, s);
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Create classes for input registers */
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < s->NumInputs; i++) {
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned int chan, class_id, writemask = 0;
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (chan = 0; chan < 4; chan++) {
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (s->Input[i].Live[chan].Used) {
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				writemask |= (1 << chan);
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		s->Input[i].Writemask = writemask;
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!writemask) {
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue;
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		class_id = ra_alloc_reg_class(regs);
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		input_classes[i] = class_id;
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ra_class_add_reg(regs, class_id,
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				get_reg_id(s->Input[i].Index, writemask));
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ra_set_finalize(regs);
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	graph = ra_alloc_interference_graph(regs, node_count + s->NumInputs);
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Build the interference graph */
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (var_ptr = variables, node_index = 0; var_ptr;
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					var_ptr = var_ptr->Next,node_index++) {
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct rc_list * a, * b;
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned int b_index;
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ra_set_node_class(graph, node_index, node_classes[node_index]);
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (a = var_ptr, b = var_ptr->Next, b_index = node_index + 1;
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						b; b = b->Next, b_index++) {
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct rc_variable * var_a = a->Item;
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			while (var_a) {
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				struct rc_variable * var_b = b->Item;
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				while (var_b) {
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					if (overlap_live_intervals_array(var_a->Live, var_b->Live)) {
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						ra_add_node_interference(graph,
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							node_index, b_index);
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					}
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					var_b = var_b->Friend;
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				var_a = var_a->Friend;
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Add input registers to the interference graph */
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0, input_node = 0; i< s->NumInputs; i++) {
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!s->Input[i].Writemask) {
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue;
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ra_set_node_class(graph, node_count + input_node,
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							input_classes[i]);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (var_ptr = variables, node_index = 0;
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				var_ptr; var_ptr = var_ptr->Next, node_index++) {
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct rc_variable * var = var_ptr->Item;
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (overlap_live_intervals_array(s->Input[i].Live,
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org								var->Live)) {
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				ra_add_node_interference(graph, node_index,
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						node_count + input_node);
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* Manually allocate a register for this input */
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ra_set_node_reg(graph, node_count + input_node, get_reg_id(
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				s->Input[i].Index, s->Input[i].Writemask));
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		input_node++;
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!ra_allocate_no_spills(graph)) {
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_error(s->C, "Ran out of hardware temporaries\n");
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Rewrite the registers */
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (var_ptr = variables, node_index = 0; var_ptr;
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				var_ptr = var_ptr->Next, node_index++) {
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int reg = ra_get_node_reg(graph, node_index);
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned int writemask = reg_get_writemask(reg);
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned int index = reg_get_index(reg);
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct rc_variable * var = var_ptr->Item;
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!s->C->is_r500 && var->Inst->Type == RC_INSTRUCTION_NORMAL) {
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			writemask = rc_variable_writemask_sum(var);
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (var->Dst.File == RC_FILE_INPUT) {
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue;
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_variable_change_dst(var, index, writemask);
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ralloc_free(graph);
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ralloc_free(regs);
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param user This parameter should be a pointer to an integer value.  If this
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integer value is zero, then a simple register allocator will be used that
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * only allocates space for input registers (\sa do_regalloc_inputs_only).  If
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * user is non-zero, then the regular register allocator will be used
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (\sa do_regalloc).
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  */
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_pair_regalloc(struct radeon_compiler *cc, void *user)
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r300_fragment_program_compiler *c =
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				(struct r300_fragment_program_compiler*)cc;
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct regalloc_state s;
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int * do_full_regalloc = (int*)user;
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	memset(&s, 0, sizeof(s));
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s.C = cc;
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s.NumInputs = rc_get_max_index(cc, RC_FILE_INPUT) + 1;
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s.Input = memory_pool_malloc(&cc->Pool,
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			s.NumInputs * sizeof(struct register_info));
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	memset(s.Input, 0, s.NumInputs * sizeof(struct register_info));
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s.NumTemporaries = rc_get_max_index(cc, RC_FILE_TEMPORARY) + 1;
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	s.Temporary = memory_pool_malloc(&cc->Pool,
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			s.NumTemporaries * sizeof(struct register_info));
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	memset(s.Temporary, 0, s.NumTemporaries * sizeof(struct register_info));
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rc_recompute_ips(s.C);
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	c->AllocateHwInputs(c, &alloc_input_simple, &s);
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (*do_full_regalloc) {
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		do_advanced_regalloc(&s);
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		s.Simple = 1;
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		do_regalloc_inputs_only(&s);
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Rewrite inputs and if we are doing the simple allocation, rewrite
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * temporaries too. */
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (struct rc_instruction *inst = s.C->Program.Instructions.Next;
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					inst != &s.C->Program.Instructions;
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					inst = inst->Next) {
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rc_remap_registers(inst, &remap_register, &s);
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
754