11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/*
21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright (C) 2008 Nicolai Haehnle.
31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
41c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * All Rights Reserved.
51c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
61c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining
71c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * a copy of this software and associated documentation files (the
81c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * "Software"), to deal in the Software without restriction, including
91c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * without limitation the rights to use, copy, modify, merge, publish,
101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * distribute, sublicense, and/or sell copies of the Software, and to
111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * permit persons to whom the Software is furnished to do so, subject to
121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the following conditions:
131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The above copyright notice and this permission notice (including the
151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * next paragraph) shall be included in all copies or substantial
161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * portions of the Software.
171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */
271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_program.h"
291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include <stdio.h>
311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler.h"
331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_dataflow.h"
341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/**
371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Transform the given clause in the following way:
381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *  1. Replace it with an empty clause
391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *  2. For every instruction in the original clause, try the given
401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *     transformations in order.
411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *  3. If one of the transformations returns GL_TRUE, assume that it
421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *     has emitted the appropriate instruction(s) into the new clause;
431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *     otherwise, copy the instruction verbatim.
441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \note The transformation is currently not recursive; in other words,
461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * instructions emitted by transformations are not transformed.
471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák *
481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \note The transform is called 'local' because it can only look at
491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * one instruction at a time.
501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */
511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_local_transform(
521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct radeon_compiler * c,
531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	void *user)
541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct radeon_program_transformation *transformations =
561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		(struct radeon_program_transformation*)user;
571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_instruction * inst = c->Program.Instructions.Next;
581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	while(inst != &c->Program.Instructions) {
601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		struct rc_instruction * current = inst;
611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		int i;
621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		inst = inst->Next;
641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		for(i = 0; transformations[i].function; ++i) {
661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			struct radeon_program_transformation* t = transformations + i;
671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			if (t->function(c, current, t->userData))
691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák				break;
701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct get_used_temporaries_data {
751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned char * Used;
761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int UsedLength;
771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák};
781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void get_used_temporaries_cb(
801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	void * userdata,
811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_instruction * inst,
821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	rc_register_file file,
831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int index,
841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int mask)
851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct get_used_temporaries_data * d = userdata;
871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (file != RC_FILE_TEMPORARY)
891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return;
901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (index >= d->UsedLength)
921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return;
931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	d->Used[index] |= mask;
951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/**
981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * This function fills in the parameter 'used' with a writemask that
991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * represent which components of each temporary register are used by the
1001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * program.  This is meant to be combined with rc_find_free_temporary_list as a
1011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * more efficient version of rc_find_free_temporary.
1021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param used The function does not initialize this parameter.
1031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */
1041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_get_used_temporaries(
1051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct radeon_compiler * c,
1061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned char * used,
1071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int used_length)
1081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_instruction * inst;
1101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct get_used_temporaries_data d;
1111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	d.Used = used;
1121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	d.UsedLength = used_length;
1131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for(inst = c->Program.Instructions.Next;
1151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			inst != &c->Program.Instructions; inst = inst->Next) {
1161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_for_all_reads_mask(inst, get_used_temporaries_cb, &d);
1181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_for_all_writes_mask(inst, get_used_temporaries_cb, &d);
1191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* Search a list of used temporaries for a free one
1231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \sa rc_get_used_temporaries
1241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @note If this functions finds a free temporary, it will mark it as used
1251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * in the used temporary list (param 'used')
1261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param used list of used temporaries
1271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param used_length number of items in param 'used'
1281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param mask which components must be free in the temporary index that is
1291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * returned.
1301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @return -1 If there are no more free temporaries, otherwise the index of
1311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * a temporary register where the components specified in param 'mask' are
1321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * not being used.
1331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */
1341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint rc_find_free_temporary_list(
1351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct radeon_compiler * c,
1361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned char * used,
1371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int used_length,
1381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int mask)
1391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int i;
1411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for(i = 0; i < used_length; i++) {
1421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		if ((~used[i] & mask) == mask) {
1431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			used[i] |= mask;
1441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák			return i;
1451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		}
1461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return -1;
1481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákunsigned int rc_find_free_temporary(struct radeon_compiler * c)
1511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned char used[RC_REGISTER_MAX_INDEX];
1531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	int free;
1541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	memset(used, 0, sizeof(used));
1561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	rc_get_used_temporaries(c, used, RC_REGISTER_MAX_INDEX);
1581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	free = rc_find_free_temporary_list(c, used, RC_REGISTER_MAX_INDEX,
1601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák								RC_MASK_XYZW);
1611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	if (free < 0) {
1621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		rc_error(c, "Ran out of temporary registers\n");
1631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		return 0;
1641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
1651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return free;
1661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c)
1701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_instruction * inst = memory_pool_malloc(&c->Pool, sizeof(struct rc_instruction));
1721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	memset(inst, 0, sizeof(struct rc_instruction));
1741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->U.I.Opcode = RC_OPCODE_ILLEGAL_OPCODE;
1761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
1771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
1781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZW;
1791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_XYZW;
1801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return inst;
1821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_insert_instruction(struct rc_instruction * after, struct rc_instruction * inst)
1851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->Prev = after;
1871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->Next = after->Next;
1881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->Prev->Next = inst;
1901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->Next->Prev = inst;
1911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
1921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after)
1941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
1951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_instruction * inst = rc_alloc_instruction(c);
1961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	rc_insert_instruction(after, inst);
1981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
1991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return inst;
2001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_remove_instruction(struct rc_instruction * inst)
2031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->Prev->Next = inst->Next;
2051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	inst->Next->Prev = inst->Prev;
2061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
2071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/**
2091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Return the number of instructions in the program.
2101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */
2111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákunsigned int rc_recompute_ips(struct radeon_compiler * c)
2121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{
2131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	unsigned int ip = 0;
2141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	struct rc_instruction * inst;
2151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	for(inst = c->Program.Instructions.Next;
2171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	    inst != &c->Program.Instructions;
2181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	    inst = inst->Next) {
2191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák		inst->IP = ip++;
2201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	}
2211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	c->Program.Instructions.IP = 0xcafedead;
2231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák
2241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák	return ip;
2251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}
226