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