16173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/*
26173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
36173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark *
46173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Permission is hereby granted, free of charge, to any person obtaining a
56173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * copy of this software and associated documentation files (the "Software"),
66173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * to deal in the Software without restriction, including without limitation
76173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * and/or sell copies of the Software, and to permit persons to whom the
96173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Software is furnished to do so, subject to the following conditions:
106173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark *
116173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * The above copyright notice and this permission notice (including the next
126173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * paragraph) shall be included in all copies or substantial portions of the
136173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Software.
146173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark *
156173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
176173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
186173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
196173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
206173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
216173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * SOFTWARE.
226173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark */
236173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark#include "ir-a2xx.h"
256173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
266173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include <stdlib.h>
276173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include <stdio.h>
286173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include <string.h>
296173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include <assert.h>
306173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
316173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include "freedreno_util.h"
32aac7f06ad843eaa696363e8e9c7781ca30cb4914Rob Clark#include "instr-a2xx.h"
336173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
346173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#define DEBUG_MSG(f, ...)  do { if (0) DBG(f, ##__VA_ARGS__); } while (0)
356173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#define WARN_MSG(f, ...)   DBG("WARN:  "f, ##__VA_ARGS__)
366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#define ERROR_MSG(f, ...)  DBG("ERROR: "f, ##__VA_ARGS__)
376173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
386173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#define REG_MASK 0x3f
396173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4026b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic int cf_emit(struct ir2_cf *cf, instr_cf_t *instr);
416173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4226b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic int instr_emit(struct ir2_instruction *instr, uint32_t *dwords,
4326b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		uint32_t idx, struct ir2_shader_info *info);
446173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic void reg_update_stats(struct ir2_register *reg,
4626b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		struct ir2_shader_info *info, bool dest);
4726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic uint32_t reg_fetch_src_swiz(struct ir2_register *reg, uint32_t n);
4826b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic uint32_t reg_fetch_dst_swiz(struct ir2_register *reg);
4926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic uint32_t reg_alu_dst_swiz(struct ir2_register *reg);
5026b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic uint32_t reg_alu_src_swiz(struct ir2_register *reg);
516173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
526173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/* simple allocator to carve allocations out of an up-front allocated heap,
536173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * so that we can free everything easily in one shot.
546173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark */
5526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic void * ir2_alloc(struct ir2_shader *shader, int sz)
566173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
576173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	void *ptr = &shader->heap[shader->heap_idx];
58eec37f1cdc1651588a4fcd5e87b57d85a57e431fRob Clark <Rob Clark	shader->heap_idx += align(sz, 4);
596173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return ptr;
606173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
616173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
6226b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic char * ir2_strdup(struct ir2_shader *shader, const char *str)
636173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
646173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	char *ptr = NULL;
656173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	if (str) {
666173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		int len = strlen(str);
6726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		ptr = ir2_alloc(shader, len+1);
686173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		memcpy(ptr, str, len);
696173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		ptr[len] = '\0';
706173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
716173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return ptr;
726173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
736173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
7426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstruct ir2_shader * ir2_shader_create(void)
756173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
766173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("");
7726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	return calloc(1, sizeof(struct ir2_shader));
786173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
796173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
8026b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkvoid ir2_shader_destroy(struct ir2_shader *shader)
816173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
826173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("");
836173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	free(shader);
846173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
856173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
866173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/* resolve addr/cnt/sequence fields in the individual CF's */
8726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic int shader_resolve(struct ir2_shader *shader, struct ir2_shader_info *info)
886173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
896173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	uint32_t addr;
906173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	unsigned i;
916173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	int j;
926173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
936173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	addr = shader->cfs_count / 2;
946173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	for (i = 0; i < shader->cfs_count; i++) {
9526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		struct ir2_cf *cf = shader->cfs[i];
966173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		if ((cf->cf_type == EXEC) || (cf->cf_type == EXEC_END)) {
976173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			uint32_t sequence = 0;
986173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
996173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			if (cf->exec.addr && (cf->exec.addr != addr))
1006173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				WARN_MSG("invalid addr '%d' at CF %d", cf->exec.addr, i);
1016173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			if (cf->exec.cnt && (cf->exec.cnt != cf->exec.instrs_count))
1026173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				WARN_MSG("invalid cnt '%d' at CF %d", cf->exec.cnt, i);
1036173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1046173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			for (j = cf->exec.instrs_count - 1; j >= 0; j--) {
10526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark				struct ir2_instruction *instr = cf->exec.instrs[j];
1066173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				sequence <<= 2;
10726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark				if (instr->instr_type == IR2_FETCH)
1086173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark					sequence |= 0x1;
1096173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				if (instr->sync)
1106173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark					sequence |= 0x2;
1116173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			}
1126173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1136173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			cf->exec.addr = addr;
1146173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			cf->exec.cnt  = cf->exec.instrs_count;
1156173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			cf->exec.sequence = sequence;
1166173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1176173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			addr += cf->exec.instrs_count;
1186173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
1196173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
1206173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1216173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	info->sizedwords = 3 * addr;
1226173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1236173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return 0;
1246173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
1256173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
12626b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkvoid * ir2_shader_assemble(struct ir2_shader *shader, struct ir2_shader_info *info)
1276173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
1286173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	uint32_t i, j;
1296173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	uint32_t *ptr, *dwords = NULL;
1306173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	uint32_t idx = 0;
1316173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	int ret;
1326173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1336173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	info->sizedwords    = 0;
1346173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	info->max_reg       = -1;
1356173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	info->max_input_reg = 0;
1366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	info->regs_written  = 0;
1376173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1386173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	/* we need an even # of CF's.. insert a NOP if needed */
139eec37f1cdc1651588a4fcd5e87b57d85a57e431fRob Clark <Rob Clark	if (shader->cfs_count != align(shader->cfs_count, 2))
14026b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		ir2_cf_create(shader, NOP);
1416173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1426173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	/* first pass, resolve sizes and addresses: */
1436173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	ret = shader_resolve(shader, info);
1446173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	if (ret) {
1456173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		ERROR_MSG("resolve failed: %d", ret);
1466173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		goto fail;
1476173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
1486173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
149c35f14f36880eb20f5e54480444e343520e9bec5Carl Worth	ptr = dwords = calloc(4, info->sizedwords);
1506173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1516173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	/* second pass, emit CF program in pairs: */
1526173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	for (i = 0; i < shader->cfs_count; i += 2) {
1536173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		instr_cf_t *cfs = (instr_cf_t *)ptr;
1546173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		ret = cf_emit(shader->cfs[i], &cfs[0]);
1556173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		if (ret) {
1566173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			ERROR_MSG("CF emit failed: %d\n", ret);
1576173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			goto fail;
1586173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
1596173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		ret = cf_emit(shader->cfs[i+1], &cfs[1]);
1606173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		if (ret) {
1616173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			ERROR_MSG("CF emit failed: %d\n", ret);
1626173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			goto fail;
1636173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
1646173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		ptr += 3;
1656173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert((ptr - dwords) <= info->sizedwords);
1666173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
1676173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1686173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	/* third pass, emit ALU/FETCH: */
1696173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	for (i = 0; i < shader->cfs_count; i++) {
17026b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		struct ir2_cf *cf = shader->cfs[i];
1716173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		if ((cf->cf_type == EXEC) || (cf->cf_type == EXEC_END)) {
1726173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			for (j = 0; j < cf->exec.instrs_count; j++) {
1736173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				ret = instr_emit(cf->exec.instrs[j], ptr, idx++, info);
1746173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				if (ret) {
1756173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark					ERROR_MSG("instruction emit failed: %d", ret);
1766173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark					goto fail;
1776173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				}
1786173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				ptr += 3;
1796173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				assert((ptr - dwords) <= info->sizedwords);
1806173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			}
1816173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
1826173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
1836173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1846173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return dwords;
1856173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1866173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clarkfail:
1876173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	free(dwords);
1886173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return NULL;
1896173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
1906173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1916173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
19226b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstruct ir2_cf * ir2_cf_create(struct ir2_shader *shader, instr_cf_opc_t cf_type)
1936173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
19426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_cf *cf = ir2_alloc(shader, sizeof(struct ir2_cf));
1956173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("%d", cf_type);
1966173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	cf->shader = shader;
1976173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	cf->cf_type = cf_type;
1986173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(shader->cfs_count < ARRAY_SIZE(shader->cfs));
1996173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	shader->cfs[shader->cfs_count++] = cf;
2006173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return cf;
2016173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
2026173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2036173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2046173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/*
2056173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * CF instructions:
2066173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark */
2076173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
20826b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic int cf_emit(struct ir2_cf *cf, instr_cf_t *instr)
2096173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
2106173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	memset(instr, 0, sizeof(*instr));
2116173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2126173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	instr->opc = cf->cf_type;
2136173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2146173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	switch (cf->cf_type) {
2156173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case NOP:
2166173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		break;
2176173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case EXEC:
2186173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case EXEC_END:
2196173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(cf->exec.addr <= 0x1ff);
2206173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(cf->exec.cnt <= 0x6);
2216173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(cf->exec.sequence <= 0xfff);
2226173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		instr->exec.address = cf->exec.addr;
2236173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		instr->exec.count = cf->exec.cnt;
2246173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		instr->exec.serialize = cf->exec.sequence;
2256173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		break;
2266173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case ALLOC:
2276173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(cf->alloc.size <= 0xf);
2286173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		instr->alloc.size = cf->alloc.size;
2296173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		switch (cf->alloc.type) {
2306173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		case SQ_POSITION:
2316173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		case SQ_PARAMETER_PIXEL:
2326173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			instr->alloc.buffer_select = cf->alloc.type;
2336173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			break;
2346173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		default:
2356173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			ERROR_MSG("invalid alloc type: %d", cf->alloc.type);
2366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			return -1;
2376173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
2386173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		break;
2396173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case COND_EXEC:
2406173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case COND_EXEC_END:
2416173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case COND_PRED_EXEC:
2426173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case COND_PRED_EXEC_END:
2436173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case LOOP_START:
2446173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case LOOP_END:
2456173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case COND_CALL:
2466173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case RETURN:
2476173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case COND_JMP:
2486173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case COND_EXEC_PRED_CLEAN:
2496173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case COND_EXEC_PRED_CLEAN_END:
2506173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case MARK_VS_FETCH_DONE:
2516173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		ERROR_MSG("TODO");
2526173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		return -1;
2536173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
2546173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2556173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return 0;
2566173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
2576173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2586173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
25926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstruct ir2_instruction * ir2_instr_create(struct ir2_cf *cf, int instr_type)
2606173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
26126b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_instruction *instr =
26226b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark			ir2_alloc(cf->shader, sizeof(struct ir2_instruction));
2636173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("%d", instr_type);
2646173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	instr->shader = cf->shader;
2656173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	instr->pred = cf->shader->pred;
2666173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	instr->instr_type = instr_type;
2676173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(cf->exec.instrs_count < ARRAY_SIZE(cf->exec.instrs));
2686173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	cf->exec.instrs[cf->exec.instrs_count++] = instr;
2696173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return instr;
2706173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
2716173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2726173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2736173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/*
2746173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * FETCH instructions:
2756173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark */
2766173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
27726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic int instr_emit_fetch(struct ir2_instruction *instr,
2786173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		uint32_t *dwords, uint32_t idx,
27926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		struct ir2_shader_info *info)
2806173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
2816173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	instr_fetch_t *fetch = (instr_fetch_t *)dwords;
2826173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	int reg = 0;
28326b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_register *dst_reg = instr->regs[reg++];
28426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_register *src_reg = instr->regs[reg++];
2856173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2866173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	memset(fetch, 0, sizeof(*fetch));
2876173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2886173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	reg_update_stats(dst_reg, info, true);
2896173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	reg_update_stats(src_reg, info, false);
2906173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2916173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	fetch->opc = instr->fetch.opc;
2926173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2936173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	if (instr->fetch.opc == VTX_FETCH) {
2946173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		instr_fetch_vtx_t *vtx = &fetch->vtx;
2956173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
2966173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(instr->fetch.stride <= 0xff);
2976173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(instr->fetch.fmt <= 0x3f);
2986173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(instr->fetch.const_idx <= 0x1f);
2996173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(instr->fetch.const_idx_sel <= 0x3);
3006173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3016173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->src_reg = src_reg->num;
3026173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->src_swiz = reg_fetch_src_swiz(src_reg, 1);
3036173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->dst_reg = dst_reg->num;
3046173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->dst_swiz = reg_fetch_dst_swiz(dst_reg);
3056173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->must_be_one = 1;
3066173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->const_index = instr->fetch.const_idx;
3076173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->const_index_sel = instr->fetch.const_idx_sel;
3086173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->format_comp_all = !!instr->fetch.is_signed;
3096173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->num_format_all = !instr->fetch.is_normalized;
3106173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->format = instr->fetch.fmt;
3116173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->stride = instr->fetch.stride;
3126173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->offset = instr->fetch.offset;
3136173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
31426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		if (instr->pred != IR2_PRED_NONE) {
3156173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			vtx->pred_select = 1;
31626b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark			vtx->pred_condition = (instr->pred == IR2_PRED_EQ) ? 1 : 0;
3176173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
3186173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3196173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		/* XXX seems like every FETCH but the first has
3206173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 * this bit set:
3216173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 */
3226173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->reserved3 = (idx > 0) ? 0x1 : 0x0;
3236173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		vtx->reserved0 = (idx > 0) ? 0x2 : 0x3;
3246173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	} else if (instr->fetch.opc == TEX_FETCH) {
3256173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		instr_fetch_tex_t *tex = &fetch->tex;
3266173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3276173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(instr->fetch.const_idx <= 0x1f);
3286173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3296173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->src_reg = src_reg->num;
3306173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->src_swiz = reg_fetch_src_swiz(src_reg, 3);
3316173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->dst_reg = dst_reg->num;
3326173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->dst_swiz = reg_fetch_dst_swiz(dst_reg);
3336173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->const_idx = instr->fetch.const_idx;
3346173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->mag_filter = TEX_FILTER_USE_FETCH_CONST;
3356173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->min_filter = TEX_FILTER_USE_FETCH_CONST;
3366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->mip_filter = TEX_FILTER_USE_FETCH_CONST;
3376173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->aniso_filter = ANISO_FILTER_USE_FETCH_CONST;
3386173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->arbitrary_filter = ARBITRARY_FILTER_USE_FETCH_CONST;
3396173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->vol_mag_filter = TEX_FILTER_USE_FETCH_CONST;
3406173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->vol_min_filter = TEX_FILTER_USE_FETCH_CONST;
3416173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->use_comp_lod = 1;
342d5d6ec884321ceaabe18ec4d33e9a27758696ef9Rob Clark		tex->use_reg_lod = !instr->fetch.is_cube;
3436173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		tex->sample_location = SAMPLE_CENTER;
3446173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
34526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		if (instr->pred != IR2_PRED_NONE) {
3466173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			tex->pred_select = 1;
34726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark			tex->pred_condition = (instr->pred == IR2_PRED_EQ) ? 1 : 0;
3486173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
3496173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3506173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	} else {
3516173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		ERROR_MSG("invalid fetch opc: %d\n", instr->fetch.opc);
3526173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		return -1;
3536173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
3546173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3556173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return 0;
3566173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
3576173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3586173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/*
3596173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * ALU instructions:
3606173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark */
3616173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
36226b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic int instr_emit_alu(struct ir2_instruction *instr, uint32_t *dwords,
36326b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		struct ir2_shader_info *info)
3646173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
3656173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	int reg = 0;
3666173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	instr_alu_t *alu = (instr_alu_t *)dwords;
36726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_register *dst_reg  = instr->regs[reg++];
36826b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_register *src1_reg;
36926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_register *src2_reg;
37026b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_register *src3_reg;
3716173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3726173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	memset(alu, 0, sizeof(*alu));
3736173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3746173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	/* handle instructions w/ 3 src operands: */
3756173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	switch (instr->alu.vector_opc) {
3766173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case MULADDv:
3776173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case CNDEv:
3786173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case CNDGTEv:
3796173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case CNDGTv:
3806173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	case DOT2ADDv:
3816173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		/* note: disassembler lists 3rd src first, ie:
3826173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 *   MULADDv Rdst = Rsrc3 + (Rsrc1 * Rsrc2)
3836173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 * which is the reason for this strange ordering.
3846173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 */
3856173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		src3_reg = instr->regs[reg++];
3866173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		break;
3876173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	default:
3886173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		src3_reg = NULL;
3896173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		break;
3906173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
3916173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3926173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	src1_reg = instr->regs[reg++];
3936173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	src2_reg = instr->regs[reg++];
3946173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
3956173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	reg_update_stats(dst_reg, info, true);
3966173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	reg_update_stats(src1_reg, info, false);
3976173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	reg_update_stats(src2_reg, info, false);
3986173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
39926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	assert((dst_reg->flags & ~IR2_REG_EXPORT) == 0);
4006173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(!dst_reg->swizzle || (strlen(dst_reg->swizzle) == 4));
40126b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	assert((src1_reg->flags & IR2_REG_EXPORT) == 0);
4026173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(!src1_reg->swizzle || (strlen(src1_reg->swizzle) == 4));
40326b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	assert((src2_reg->flags & IR2_REG_EXPORT) == 0);
4046173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(!src2_reg->swizzle || (strlen(src2_reg->swizzle) == 4));
4056173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
406a49fb4ab2d5b062a418e930dc46cb2c79380852efrancians@gmail.com	if (instr->alu.vector_opc == (instr_vector_opc_t)~0) {
4076173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->vector_opc          = MAXv;
4086173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->vector_write_mask   = 0;
4096173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	} else {
4106173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->vector_opc          = instr->alu.vector_opc;
4116173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->vector_write_mask   = reg_alu_dst_swiz(dst_reg);
4126173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
4136173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4146173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	alu->vector_dest         = dst_reg->num;
41526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	alu->export_data         = !!(dst_reg->flags & IR2_REG_EXPORT);
4166173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4176173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	// TODO predicate case/condition.. need to add to parser
4186173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4196173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	alu->src2_reg            = src2_reg->num;
4206173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	alu->src2_swiz           = reg_alu_src_swiz(src2_reg);
42126b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	alu->src2_reg_negate     = !!(src2_reg->flags & IR2_REG_NEGATE);
42226b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	alu->src2_reg_abs        = !!(src2_reg->flags & IR2_REG_ABS);
42326b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	alu->src2_sel            = !(src2_reg->flags & IR2_REG_CONST);
4246173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4256173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	alu->src1_reg            = src1_reg->num;
4266173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	alu->src1_swiz           = reg_alu_src_swiz(src1_reg);
42726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	alu->src1_reg_negate     = !!(src1_reg->flags & IR2_REG_NEGATE);
42826b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	alu->src1_reg_abs        = !!(src1_reg->flags & IR2_REG_ABS);
42926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	alu->src1_sel            = !(src1_reg->flags & IR2_REG_CONST);
4306173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4316173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	alu->vector_clamp        = instr->alu.vector_clamp;
4326173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	alu->scalar_clamp        = instr->alu.scalar_clamp;
4336173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
434a49fb4ab2d5b062a418e930dc46cb2c79380852efrancians@gmail.com	if (instr->alu.scalar_opc != (instr_scalar_opc_t)~0) {
43526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		struct ir2_register *sdst_reg = instr->regs[reg++];
4366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4376173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		reg_update_stats(sdst_reg, info, true);
4386173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4396173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		assert(sdst_reg->flags == dst_reg->flags);
4406173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4416173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		if (src3_reg) {
44268552266535747bad1eff34d856c43158398b9bfRob Clark			assert(src3_reg == instr->regs[reg]);
44368552266535747bad1eff34d856c43158398b9bfRob Clark			reg++;
4446173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		} else {
4456173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			src3_reg = instr->regs[reg++];
4466173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
4476173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4486173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->scalar_dest         = sdst_reg->num;
4496173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->scalar_write_mask   = reg_alu_dst_swiz(sdst_reg);
4506173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->scalar_opc          = instr->alu.scalar_opc;
4516173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	} else {
4526173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		/* not sure if this is required, but adreno compiler seems
4536173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 * to always set scalar opc to MAXs if it is not used:
4546173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 */
4556173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->scalar_opc = MAXs;
4566173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
4576173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4586173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	if (src3_reg) {
4596173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		reg_update_stats(src3_reg, info, false);
4606173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4616173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->src3_reg            = src3_reg->num;
4626173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->src3_swiz           = reg_alu_src_swiz(src3_reg);
46326b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		alu->src3_reg_negate     = !!(src3_reg->flags & IR2_REG_NEGATE);
46426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		alu->src3_reg_abs        = !!(src3_reg->flags & IR2_REG_ABS);
46526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		alu->src3_sel            = !(src3_reg->flags & IR2_REG_CONST);
4666173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	} else {
4676173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		/* not sure if this is required, but adreno compiler seems
4686173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 * to always set register bank for 3rd src if unused:
4696173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		 */
4706173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		alu->src3_sel = 1;
4716173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
4726173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
47326b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	if (instr->pred != IR2_PRED_NONE) {
47426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		alu->pred_select = (instr->pred == IR2_PRED_EQ) ? 3 : 2;
4756173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
4766173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4776173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return 0;
4786173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
4796173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
48026b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic int instr_emit(struct ir2_instruction *instr, uint32_t *dwords,
48126b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		uint32_t idx, struct ir2_shader_info *info)
4826173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
4836173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	switch (instr->instr_type) {
48426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	case IR2_FETCH: return instr_emit_fetch(instr, dwords, idx, info);
48526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	case IR2_ALU:   return instr_emit_alu(instr, dwords, info);
4866173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
4876173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return -1;
4886173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
4896173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
4906173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
49126b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstruct ir2_register * ir2_reg_create(struct ir2_instruction *instr,
4926173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		int num, const char *swizzle, int flags)
4936173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
49426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	struct ir2_register *reg =
49526b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark			ir2_alloc(instr->shader, sizeof(struct ir2_register));
4966173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("%x, %d, %s", flags, num, swizzle);
4976173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(num <= REG_MASK);
4986173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	reg->flags = flags;
4996173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	reg->num = num;
50026b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	reg->swizzle = ir2_strdup(instr->shader, swizzle);
5016173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(instr->regs_count < ARRAY_SIZE(instr->regs));
5026173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	instr->regs[instr->regs_count++] = reg;
5036173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return reg;
5046173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
5056173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
50626b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic void reg_update_stats(struct ir2_register *reg,
50726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark		struct ir2_shader_info *info, bool dest)
5086173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
50926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	if (!(reg->flags & (IR2_REG_CONST|IR2_REG_EXPORT))) {
510eec37f1cdc1651588a4fcd5e87b57d85a57e431fRob Clark <Rob Clark		info->max_reg = MAX2(info->max_reg, reg->num);
5116173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5126173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		if (dest) {
5136173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			info->regs_written |= (1 << reg->num);
5146173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		} else if (!(info->regs_written & (1 << reg->num))) {
5156173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			/* for registers that haven't been written, they must be an
5166173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			 * input register that the thread scheduler (presumably?)
5176173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			 * needs to know about:
5186173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			 */
519eec37f1cdc1651588a4fcd5e87b57d85a57e431fRob Clark <Rob Clark			info->max_input_reg = MAX2(info->max_input_reg, reg->num);
5206173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
5216173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
5226173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
5236173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
52426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic uint32_t reg_fetch_src_swiz(struct ir2_register *reg, uint32_t n)
5256173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
5266173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	uint32_t swiz = 0;
5276173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	int i;
5286173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5296173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(reg->flags == 0);
5306173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(reg->swizzle);
5316173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5326173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("fetch src R%d.%s", reg->num, reg->swizzle);
5336173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5346173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	for (i = n-1; i >= 0; i--) {
5356173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		swiz <<= 2;
5366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		switch (reg->swizzle[i]) {
5376173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		default:
5386173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			ERROR_MSG("invalid fetch src swizzle: %s", reg->swizzle);
5396173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		case 'x': swiz |= 0x0; break;
5406173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		case 'y': swiz |= 0x1; break;
5416173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		case 'z': swiz |= 0x2; break;
5426173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		case 'w': swiz |= 0x3; break;
5436173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
5446173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
5456173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5466173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return swiz;
5476173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
5486173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
54926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic uint32_t reg_fetch_dst_swiz(struct ir2_register *reg)
5506173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
5516173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	uint32_t swiz = 0;
5526173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	int i;
5536173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5546173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(reg->flags == 0);
5556173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
5566173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5576173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("fetch dst R%d.%s", reg->num, reg->swizzle);
5586173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5596173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	if (reg->swizzle) {
5606173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		for (i = 3; i >= 0; i--) {
5616173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			swiz <<= 3;
5626173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			switch (reg->swizzle[i]) {
5636173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			default:
5646173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				ERROR_MSG("invalid dst swizzle: %s", reg->swizzle);
5656173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case 'x': swiz |= 0x0; break;
5666173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case 'y': swiz |= 0x1; break;
5676173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case 'z': swiz |= 0x2; break;
5686173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case 'w': swiz |= 0x3; break;
5696173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case '0': swiz |= 0x4; break;
5706173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case '1': swiz |= 0x5; break;
5716173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case '_': swiz |= 0x7; break;
5726173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			}
5736173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
5746173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	} else {
5756173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		swiz = 0x688;
5766173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
5776173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5786173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return swiz;
5796173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
5806173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5816173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/* actually, a write-mask */
58226b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic uint32_t reg_alu_dst_swiz(struct ir2_register *reg)
5836173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
5846173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	uint32_t swiz = 0;
5856173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	int i;
5866173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
58726b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	assert((reg->flags & ~IR2_REG_EXPORT) == 0);
5886173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
5896173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5906173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("alu dst R%d.%s", reg->num, reg->swizzle);
5916173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
5926173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	if (reg->swizzle) {
5936173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		for (i = 3; i >= 0; i--) {
5946173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			swiz <<= 1;
5956173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			if (reg->swizzle[i] == "xyzw"[i]) {
5966173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				swiz |= 0x1;
5976173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			} else if (reg->swizzle[i] != '_') {
5986173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				ERROR_MSG("invalid dst swizzle: %s", reg->swizzle);
5996173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				break;
6006173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			}
6016173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
6026173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	} else {
6036173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		swiz = 0xf;
6046173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
6056173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
6066173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return swiz;
6076173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
6086173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
60926b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clarkstatic uint32_t reg_alu_src_swiz(struct ir2_register *reg)
6106173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
6116173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	uint32_t swiz = 0;
6126173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	int i;
6136173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
61426b39df08f480b3f1d71608ef3c2b56b8be94f3eRob Clark <Rob Clark	assert((reg->flags & IR2_REG_EXPORT) == 0);
6156173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
6166173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
6176173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	DEBUG_MSG("vector src R%d.%s", reg->num, reg->swizzle);
6186173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
6196173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	if (reg->swizzle) {
6206173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		for (i = 3; i >= 0; i--) {
6216173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			swiz <<= 2;
6226173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			switch (reg->swizzle[i]) {
6236173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			default:
6246173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark				ERROR_MSG("invalid vector src swizzle: %s", reg->swizzle);
6256173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case 'x': swiz |= (0x0 - i) & 0x3; break;
6266173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case 'y': swiz |= (0x1 - i) & 0x3; break;
6276173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case 'z': swiz |= (0x2 - i) & 0x3; break;
6286173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			case 'w': swiz |= (0x3 - i) & 0x3; break;
6296173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark			}
6306173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		}
6316173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	} else {
6326173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		swiz = 0x0;
6336173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
6346173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
6356173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	return swiz;
6366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
637