ir3_compiler.c revision 33c9ad97bf25271fcb034bc6054b74fff8a552fb
13e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 23e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 33e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton/* 43e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> 53e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * 63e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * Permission is hereby granted, free of charge, to any person obtaining a 73e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * copy of this software and associated documentation files (the "Software"), 8c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * to deal in the Software without restriction, including without limitation 9f733a013b2d1546e58dd6d4d3cdcb083e2176beaNeal Norwitz * the rights to use, copy, modify, merge, publish, distribute, sublicense, 103e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * and/or sell copies of the Software, and to permit persons to whom the 11c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * Software is furnished to do so, subject to the following conditions: 12f733a013b2d1546e58dd6d4d3cdcb083e2176beaNeal Norwitz * 133e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * The above copyright notice and this permission notice (including the next 143e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * paragraph) shall be included in all copies or substantial portions of the 153e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * Software. 16944d3eb1546e38d4944db5f2f41f5560d55a5053Nick Coghlan * 17e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hylton * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hylton * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hylton * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20f733a013b2d1546e58dd6d4d3cdcb083e2176beaNeal Norwitz * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21f733a013b2d1546e58dd6d4d3cdcb083e2176beaNeal Norwitz * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 223e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 233f5da24ea304e674a9abbdcffc4d671e32aa70f1Guido van Rossum * SOFTWARE. 2479f25d9a7b853a9f491a0cfe4b81eeb9e2d19569Guido van Rossum * 253f5da24ea304e674a9abbdcffc4d671e32aa70f1Guido van Rossum * Authors: 263e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * Rob Clark <robclark@freedesktop.org> 2710dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum */ 28adb69fcdffdc50ee3e1d33b00cd874020197b445Neal Norwitz 293e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton#include <stdarg.h> 303e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 3110dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum#include "pipe/p_state.h" 324b38da664c107bc08768235a66621429beef5444Jeremy Hylton#include "util/u_string.h" 3310dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum#include "util/u_memory.h" 34b05a5c7698cd8dff3e5c02e513db765ba12281f0Guido van Rossum#include "util/u_inlines.h" 358e793d925c1fa43840bc2a45292843c28a497976Guido van Rossum#include "tgsi/tgsi_parse.h" 368e793d925c1fa43840bc2a45292843c28a497976Guido van Rossum#include "tgsi/tgsi_ureg.h" 373e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton#include "tgsi/tgsi_info.h" 383e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton#include "tgsi/tgsi_strings.h" 393e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton#include "tgsi/tgsi_dump.h" 403e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton#include "tgsi/tgsi_scan.h" 413e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 42b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti#include "freedreno_lowering.h" 43b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti#include "freedreno_util.h" 44b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti 45b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti#include "ir3_compiler.h" 463e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton#include "ir3_shader.h" 47c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 48c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#include "instr-a3xx.h" 49c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#include "ir3.h" 50c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 51c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustruct ir3_compile_context { 52c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct tgsi_token *tokens; 53c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bool free_tokens; 543e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3 *ir; 5529906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton struct ir3_shader_variant *so; 563e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 5712603c41daedcf0387c7eb08b17fe32549acfc31Jeremy Hylton struct ir3_block *block; 5812603c41daedcf0387c7eb08b17fe32549acfc31Jeremy Hylton struct ir3_instruction *current_instr; 5912603c41daedcf0387c7eb08b17fe32549acfc31Jeremy Hylton 60c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* we need to defer updates to block->outputs[] until the end 61c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * of an instruction (so we don't see new value until *after* 62c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * the src registers are processed) 63c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 64c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct { 65c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr, **instrp; 66c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } output_updates[16]; 67c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned num_output_updates; 68c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 69c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* are we in a sequence of "atomic" instructions? 70c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 71c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bool atomic; 72c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 73c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* For fragment shaders, from the hw perspective the only 74c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * actual input is r0.xy position register passed to bary.f. 75c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * But TGSI doesn't know that, it still declares things as 76c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * IN[] registers. So we do all the input tracking normally 77c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * and fix things up after compile_instructions() 783e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * 793e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * NOTE that frag_pos is the hardware position (possibly it 803e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * is actually an index or tag or some such.. it is *not* 813e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * values that can be directly used for gl_FragCoord..) 82e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hylton */ 83e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hylton struct ir3_instruction *frag_pos, *frag_face, *frag_coord[4]; 84e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hylton 853e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_parse_context parser; 8639e2f3f82499e2c06c092d38b77d554bee6f31e8Jeremy Hylton unsigned type; 873e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 88897b82123d3b446778a1ef7537404cd8df1da9c9Jeremy Hylton struct tgsi_shader_info info; 893e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 90c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* for calculating input/output positions/linkages: */ 91c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned next_inloc; 923e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 93e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton unsigned num_internal_temps; 943e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_src_register internal_temps[8]; 953e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 963e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* idx/slot for last compiler generated immediate */ 973e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton unsigned immediate_idx; 98c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 99c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* stack of branch instructions that mark (potentially nested) 100c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * branch if/else/loop/etc 101c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 102c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct { 103c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr, *cond; 104c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bool inv; /* true iff in else leg of branch */ 105c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } branch[16]; 106c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned int branch_count; 107c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 108c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* list of kill instructions: */ 109c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *kill[16]; 110c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned int kill_count; 111c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 112c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* used when dst is same as one of the src, to avoid overwriting a 113c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * src element before the remaining scalar instructions that make 114c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * up the vector operation 115c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 116c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register tmp_dst; 117c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *tmp_src; 118c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 119c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* just for catching incorrect use of get_dst()/put_dst(): 120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bool using_tmp_dst; 122c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou}; 123c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 124c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 125c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void vectorize(struct ir3_compile_context *ctx, 1263f5da24ea304e674a9abbdcffc4d671e32aa70f1Guido van Rossum struct ir3_instruction *instr, struct tgsi_dst_register *dst, 1273f5da24ea304e674a9abbdcffc4d671e32aa70f1Guido van Rossum int nsrcs, ...); 128c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void create_mov(struct ir3_compile_context *ctx, 129609346273903cd848d055b046ec46d9cc831b750Michael W. Hudson struct tgsi_dst_register *dst, struct tgsi_src_register *src); 130e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hyltonstatic type_t get_ftype(struct ir3_compile_context *ctx); 131c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 132e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hyltonstatic unsigned 1333e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltoncompile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so, 134609346273903cd848d055b046ec46d9cc831b750Michael W. Hudson const struct tgsi_token *tokens) 1353e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton{ 136c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned ret; 137c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_shader_info *info = &ctx->info; 138c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct fd_lowering_config lconfig = { 139c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou .color_two_side = so->key.color_two_side, 140609346273903cd848d055b046ec46d9cc831b750Michael W. Hudson .lower_DST = true, 141c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou .lower_XPD = true, 142c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou .lower_SCS = true, 143609346273903cd848d055b046ec46d9cc831b750Michael W. Hudson .lower_LRP = true, 144c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou .lower_FRC = true, 145c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou .lower_POW = true, 146c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou .lower_LIT = true, 1473e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton .lower_EXP = true, 148bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum .lower_LOG = true, 1493e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton .lower_DP4 = true, 1503e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton .lower_DP3 = true, 1513e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton .lower_DPH = true, 1523e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton .lower_DP2 = true, 1533e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton .lower_DP2A = true, 1543e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton }; 1553e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 1563e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton switch (so->type) { 1573e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case SHADER_FRAGMENT: 1583e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case SHADER_COMPUTE: 1593e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton lconfig.saturate_s = so->key.fsaturate_s; 1603e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton lconfig.saturate_t = so->key.fsaturate_t; 1613e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton lconfig.saturate_r = so->key.fsaturate_r; 1623e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton break; 1633e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case SHADER_VERTEX: 1643e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton lconfig.saturate_s = so->key.vsaturate_s; 1653e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton lconfig.saturate_t = so->key.vsaturate_t; 1663e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton lconfig.saturate_r = so->key.vsaturate_r; 167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1683e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 1693e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 170c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->tokens = fd_transform_lowering(&lconfig, tokens, &ctx->info); 1713e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->free_tokens = !!ctx->tokens; 172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!ctx->tokens) { 17382271f13e7eab69b909d538556e4781e971f7584Jeremy Hylton /* no lowering */ 17482271f13e7eab69b909d538556e4781e971f7584Jeremy Hylton ctx->tokens = tokens; 1753e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 1763e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->ir = so->ir; 1773e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->so = so; 1783e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->next_inloc = 8; 179c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->num_internal_temps = 0; 180c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->branch_count = 0; 1813e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->kill_count = 0; 1823e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->block = NULL; 1833e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->current_instr = NULL; 184402b73fb8d54ec2b24b52fdd77d389d903fa6c44Larry Hastings ctx->num_output_updates = 0; 185402b73fb8d54ec2b24b52fdd77d389d903fa6c44Larry Hastings ctx->atomic = false; 1863e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->frag_pos = NULL; 1877b782b61c597a989a21a22c15ee95decf997429fAnthony Baxter ctx->frag_face = NULL; 188bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum ctx->tmp_src = NULL; 189c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->using_tmp_dst = false; 190c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 191c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou memset(ctx->frag_coord, 0, sizeof(ctx->frag_coord)); 192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define FM(x) (1 << TGSI_FILE_##x) 194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* optimize can't deal with relative addressing: */ 195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (info->indirect_files & (FM(TEMPORARY) | FM(INPUT) | FM(OUTPUT))) 196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return TGSI_PARSE_ERROR; 197c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 198c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* NOTE: if relative addressing is used, we set constlen in 199c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * the compiler (to worst-case value) since we don't know in 200c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * the assembler what the max addr reg value can be: 201c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 202c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (info->indirect_files & FM(CONSTANT)) 203c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->constlen = 4 * (ctx->info.file_max[TGSI_FILE_CONSTANT] + 1); 204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 205c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* Immediates go after constants: */ 206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->first_immediate = info->file_max[TGSI_FILE_CONSTANT] + 1; 207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->immediate_idx = 4 * (ctx->info.file_max[TGSI_FILE_IMMEDIATE] + 1); 208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ret = tgsi_parse_init(&ctx->parser, ctx->tokens); 210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ret != TGSI_PARSE_OK) 211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return ret; 212c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 213c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->type = ctx->parser.FullHeader.Processor.Processor; 214c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 215c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return ret; 216c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 217c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 218c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 219c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucompile_error(struct ir3_compile_context *ctx, const char *format, ...) 220c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 221c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou va_list ap; 222c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou va_start(ap, format); 223c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou _debug_vprintf(format, ap); 224022db598acdc33a7c026322a25b54ff594f54042Antoine Pitrou va_end(ap); 225022db598acdc33a7c026322a25b54ff594f54042Antoine Pitrou tgsi_dump(ctx->tokens, 0); 226022db598acdc33a7c026322a25b54ff594f54042Antoine Pitrou debug_assert(0); 227022db598acdc33a7c026322a25b54ff594f54042Antoine Pitrou} 228022db598acdc33a7c026322a25b54ff594f54042Antoine Pitrou 229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define compile_assert(ctx, cond) do { \ 230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!(cond)) compile_error((ctx), "failed assert: "#cond"\n"); \ 231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } while (0) 232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 233c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 234c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucompile_free(struct ir3_compile_context *ctx) 235c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 236c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx->free_tokens) 237c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou free((void *)ctx->tokens); 238c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tgsi_parse_free(&ctx->parser); 2393e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton} 240bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum 2413e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonstruct instr_translater { 2423e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton void (*fxn)(const struct instr_translater *t, 2433e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3_compile_context *ctx, 244c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst); 2453e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton unsigned tgsi_opc; 246c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou opc_t opc; 247c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou opc_t hopc; /* opc to use for half_precision mode, if different */ 248c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned arg; 2493e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton}; 250c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2513e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonstatic void 252bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossuminstr_finish(struct ir3_compile_context *ctx) 2533e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton{ 254adb69fcdffdc50ee3e1d33b00cd874020197b445Neal Norwitz unsigned i; 255c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 256c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx->atomic) 257c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return; 258c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 259c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < ctx->num_output_updates; i++) 260c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou *(ctx->output_updates[i].instrp) = ctx->output_updates[i].instr; 261c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 262c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->num_output_updates = 0; 263c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 264c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 265c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* For "atomic" groups of instructions, for example the four scalar 266c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * instructions to perform a vec4 operation. Basically this just 267c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * blocks out handling of output_updates so the next scalar instruction 268c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * still sees the result from before the start of the atomic group. 269c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 270c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * NOTE: when used properly, this could probably replace get/put_dst() 271c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * stuff. 272c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 273c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 274c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouinstr_atomic_start(struct ir3_compile_context *ctx) 275c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 276c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->atomic = true; 277c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 278c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 279c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouinstr_atomic_end(struct ir3_compile_context *ctx) 281c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 282c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->atomic = false; 283c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr_finish(ctx); 284c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 285c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 286c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 287c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouinstr_create(struct ir3_compile_context *ctx, int category, opc_t opc) 288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 289c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr_finish(ctx); 290c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return (ctx->current_instr = ir3_instr_create(ctx->block, category, opc)); 291c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 292c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2933e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonstatic struct ir3_instruction * 2941175c43a12c3020a11c596f45d6bd19226025e8cThomas Woutersinstr_clone(struct ir3_compile_context *ctx, struct ir3_instruction *instr) 295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 296c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr_finish(ctx); 297c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return (ctx->current_instr = ir3_instr_clone(instr)); 298bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum} 299bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum 3003e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonstatic struct ir3_block * 3013e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonpush_block(struct ir3_compile_context *ctx) 30210dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum{ 303c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_block *block; 304c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned ntmp, nin, nout; 305c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 306c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define SCALAR_REGS(file) (4 * (ctx->info.file_max[TGSI_FILE_ ## file] + 1)) 307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 308c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* hmm, give ourselves room to create 8 extra temporaries (vec4): 309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 310c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ntmp = SCALAR_REGS(TEMPORARY); 311c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ntmp += 8 * 4; 312c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 31310dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum nout = SCALAR_REGS(OUTPUT); 31410dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum nin = SCALAR_REGS(INPUT); 3153e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 3163e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* for outermost block, 'inputs' are the actual shader INPUT 3172dff991f6b3f0be50e8f97d2172ddb140adeec50Guido van Rossum * register file. Reads from INPUT registers always go back to 318c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * top block. For nested blocks, 'inputs' is used to track any 319c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * TEMPORARY file register from one of the enclosing blocks that 320c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * is ready in this block. 321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!ctx->block) { 3232dff991f6b3f0be50e8f97d2172ddb140adeec50Guido van Rossum /* NOTE: fragment shaders actually have two inputs (r0.xy, the 3242dff991f6b3f0be50e8f97d2172ddb140adeec50Guido van Rossum * position) 3253e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton */ 3263e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (ctx->type == TGSI_PROCESSOR_FRAGMENT) { 3272e8f8a398e135ce4ec235c33eb64c29e6b6114eaGuido van Rossum int n = 2; 328c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx->info.reads_position) 329c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou n += 4; 330c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx->info.uses_frontface) 331c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou n += 4; 332c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou nin = MAX2(n, nin); 333c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou nout += ARRAY_SIZE(ctx->kill); 334c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 335c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 336c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou nin = ntmp; 337c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 338c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 339c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block = ir3_block_create(ctx->ir, ntmp, nin, nout); 340c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3417791165fb36ecca2398ac81e9b6bc0248821262cVictor Stinner if ((ctx->type == TGSI_PROCESSOR_FRAGMENT) && !ctx->block) 342c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->noutputs -= ARRAY_SIZE(ctx->kill); 343c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 344c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->parent = ctx->block; 345c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->block = block; 346c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 347c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return block; 348c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 350c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 351c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroupop_block(struct ir3_compile_context *ctx) 3522e8f8a398e135ce4ec235c33eb64c29e6b6114eaGuido van Rossum{ 3532e8f8a398e135ce4ec235c33eb64c29e6b6114eaGuido van Rossum ctx->block = ctx->block->parent; 3543e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton compile_assert(ctx, ctx->block); 355644a12b00ce6a361089b488aa8096a6c86b52275Guido van Rossum} 356e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hylton 357c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 358e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hyltoncreate_output(struct ir3_block *block, struct ir3_instruction *instr, 359e9357b21c091a8d0145f7cb046d970bcbb2e7430Jeremy Hylton unsigned n) 3603e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton{ 361fc5ce61abd7f21c2674afc49cc1f2659bef2aa20Guido van Rossum struct ir3_instruction *out; 3623e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 3633e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton out = ir3_instr_create(block, -1, OPC_META_OUTPUT); 364fc5ce61abd7f21c2674afc49cc1f2659bef2aa20Guido van Rossum out->inout.block = block; 3650e3755e58a0495f835fc2eb89c7a72e87366346cMeador Inge ir3_reg_create(out, n, 0); 366c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (instr) 3676642d1f97d7b89509159214253900eb3d970e223Meador Inge ir3_reg_create(out, 0, IR3_REG_SSA)->instr = instr; 368c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return out; 370c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 371c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 372c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 3736642d1f97d7b89509159214253900eb3d970e223Meador Ingecreate_input(struct ir3_block *block, struct ir3_instruction *instr, 3746642d1f97d7b89509159214253900eb3d970e223Meador Inge unsigned n) 3756642d1f97d7b89509159214253900eb3d970e223Meador Inge{ 3766642d1f97d7b89509159214253900eb3d970e223Meador Inge struct ir3_instruction *in; 3776642d1f97d7b89509159214253900eb3d970e223Meador Inge 3786642d1f97d7b89509159214253900eb3d970e223Meador Inge in = ir3_instr_create(block, -1, OPC_META_INPUT); 3796642d1f97d7b89509159214253900eb3d970e223Meador Inge in->inout.block = block; 3806642d1f97d7b89509159214253900eb3d970e223Meador Inge ir3_reg_create(in, n, 0); 3816642d1f97d7b89509159214253900eb3d970e223Meador Inge if (instr) 3826642d1f97d7b89509159214253900eb3d970e223Meador Inge ir3_reg_create(in, 0, IR3_REG_SSA)->instr = instr; 3836642d1f97d7b89509159214253900eb3d970e223Meador Inge 3846642d1f97d7b89509159214253900eb3d970e223Meador Inge return in; 385b8a569065eb05b14a7aef1d837159e7135defbfbMeador Inge} 3866642d1f97d7b89509159214253900eb3d970e223Meador Inge 3876642d1f97d7b89509159214253900eb3d970e223Meador Ingestatic struct ir3_instruction * 3886642d1f97d7b89509159214253900eb3d970e223Meador Ingeblock_input(struct ir3_block *block, unsigned n) 3896642d1f97d7b89509159214253900eb3d970e223Meador Inge{ 390c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* references to INPUT register file always go back up to 391c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * top level: 392c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 393c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (block->parent) 394c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return block_input(block->parent, n); 395c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return block->inputs[n]; 396c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 3976642d1f97d7b89509159214253900eb3d970e223Meador Inge 398c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* return temporary in scope, creating if needed meta-input node 399c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * to track block inputs 400c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 401c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 4027791165fb36ecca2398ac81e9b6bc0248821262cVictor Stinnerblock_temporary(struct ir3_block *block, unsigned n) 403c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 4046642d1f97d7b89509159214253900eb3d970e223Meador Inge /* references to TEMPORARY register file, find the nearest 405c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * enclosing block which has already assigned this temporary, 406c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * creating meta-input instructions along the way to keep 407c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * track of block inputs 408c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 409c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (block->parent && !block->temporaries[n]) { 410c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* if already have input for this block, reuse: */ 411c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!block->inputs[n]) 412c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->inputs[n] = block_temporary(block->parent, n); 413c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 4146642d1f97d7b89509159214253900eb3d970e223Meador Inge /* and create new input to return: */ 415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return create_input(block, block->inputs[n], n); 41664949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton } 41764949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton return block->temporaries[n]; 4183e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton} 4193e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 42064949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hyltonstatic struct ir3_instruction * 421c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucreate_immed(struct ir3_compile_context *ctx, float val) 422c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 423c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* NOTE: *don't* use instr_create() here! 424c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = ir3_instr_create(ctx->block, 1, 0); 427c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = get_ftype(ctx); 428c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = get_ftype(ctx); 429c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, 0); 430c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_IMMED)->fim_val = val; 431c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return instr; 432c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 433c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 434c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 435c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroussa_dst(struct ir3_compile_context *ctx, struct ir3_instruction *instr, 43664949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton const struct tgsi_dst_register *dst, unsigned chan) 4374bad92cc8a452bad690f8bbdddbb2421b0361360Guido van Rossum{ 4385acc0c0cfc3b47ac993cb27e67b8e171a9d4f22dJeremy Hylton unsigned n = regid(dst->Index, chan); 4393e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton unsigned idx = ctx->num_output_updates; 4405acc0c0cfc3b47ac993cb27e67b8e171a9d4f22dJeremy Hylton 441c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, idx < ARRAY_SIZE(ctx->output_updates)); 442c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 443c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* NOTE: defer update of temporaries[idx] or output[idx] 444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * until instr_finish(), so that if the current instruction 445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * reads the same TEMP/OUT[] it gets the old value: 446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * bleh.. this might be a bit easier to just figure out 448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * in instr_finish(). But at that point we've already 449c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * lost information about OUTPUT vs TEMPORARY register 450c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * file.. 451c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 452c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 453c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (dst->File) { 454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_OUTPUT: 455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, n < ctx->block->noutputs); 456c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->output_updates[idx].instrp = &ctx->block->outputs[n]; 457c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->output_updates[idx].instr = instr; 458c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->num_output_updates++; 459c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 460c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_TEMPORARY: 4615acc0c0cfc3b47ac993cb27e67b8e171a9d4f22dJeremy Hylton compile_assert(ctx, n < ctx->block->ntemporaries); 4625acc0c0cfc3b47ac993cb27e67b8e171a9d4f22dJeremy Hylton ctx->output_updates[idx].instrp = &ctx->block->temporaries[n]; 4633e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->output_updates[idx].instr = instr; 4643e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ctx->num_output_updates++; 465c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 466c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_ADDRESS: 467c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, n < 1); 468c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->output_updates[idx].instrp = &ctx->block->address; 469c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->output_updates[idx].instr = instr; 470c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->num_output_updates++; 471c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 472c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 473c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 474c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 475c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 476c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroussa_src(struct ir3_compile_context *ctx, struct ir3_register *reg, 477c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct tgsi_src_register *src, unsigned chan) 478c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 479c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_block *block = ctx->block; 480c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned n = regid(src->Index, chan); 481c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 482c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (src->File) { 483c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_INPUT: 484c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->flags |= IR3_REG_SSA; 485c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->instr = block_input(ctx->block, n); 486c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 487c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_OUTPUT: 488c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* really this should just happen in case of 'MOV_SAT OUT[n], ..', 489c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * for the following clamp instructions: 490c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 491c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->flags |= IR3_REG_SSA; 492c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->instr = block->outputs[n]; 493c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* we don't have to worry about read from an OUTPUT that was 494c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * assigned outside of the current block, because the _SAT 495c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * clamp instructions will always be in the same block as 496c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * the original instruction which wrote the OUTPUT 497c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 498c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, reg->instr); 499c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 500c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_TEMPORARY: 501c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->flags |= IR3_REG_SSA; 502c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->instr = block_temporary(ctx->block, n); 503c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 504c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 505c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 506c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if ((reg->flags & IR3_REG_SSA) && !reg->instr) { 507c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* this can happen when registers (or components of a TGSI 508c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * register) are used as src before they have been assigned 509c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * (undefined contents). To avoid confusing the rest of the 510c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * compiler, and to generally keep things peachy, substitute 511c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * an instruction that sets the src to 0.0. Or to keep 512c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * things undefined, I could plug in a random number? :-P 513c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 514c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * NOTE: *don't* use instr_create() here! 515c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 516c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->instr = create_immed(ctx, 0.0); 517c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 518c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 519c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 520c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_register * 521c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouadd_dst_reg_wrmask(struct ir3_compile_context *ctx, 522c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr, const struct tgsi_dst_register *dst, 523c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned chan, unsigned wrmask) 524c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 525c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned flags = 0, num = 0; 526c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_register *reg; 527c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 528c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (dst->File) { 529c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_OUTPUT: 530c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_TEMPORARY: 531c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* uses SSA */ 532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 533c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_ADDRESS: 534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou flags |= IR3_REG_ADDR; 535e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton /* uses SSA */ 536e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton break; 537c396d9edd6bb42778bc8ced808f90cb0adf9c312Neil Schemenauer default: 5383e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton compile_error(ctx, "unsupported dst register file: %s\n", 5393e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton tgsi_file_name(dst->File)); 540c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 541c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 542c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 543c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (dst->Indirect) 544c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou flags |= IR3_REG_RELATIV; 545c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 546c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg = ir3_reg_create(instr, regid(num, chan), flags); 547c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 548c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* NOTE: do not call ssa_dst() if atomic.. vectorize() 549c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * itself will call ssa_dst(). This is to filter out 550c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * the (initially bogus) .x component dst which is 551c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * created (but not necessarily used, ie. if the net 552c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * result of the vector operation does not write to 553c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * the .x component) 554c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 555c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 556c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->wrmask = wrmask; 557c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (wrmask == 0x1) { 55810dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum /* normal case */ 55910dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum if (!ctx->atomic) 56010dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum ssa_dst(ctx, instr, dst, chan); 5613e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } else if ((dst->File == TGSI_FILE_TEMPORARY) || 5623e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton (dst->File == TGSI_FILE_OUTPUT) || 5633e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton (dst->File == TGSI_FILE_ADDRESS)) { 5648b993a98db507cc3a75067af4c865ffc8afbada1Guido van Rossum unsigned i; 5653e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 5663e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* if instruction writes multiple, we need to create 5678b993a98db507cc3a75067af4c865ffc8afbada1Guido van Rossum * some place-holder collect the registers: 568c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 569c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < 4; i++) { 5703e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (wrmask & (1 << i)) { 571c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *collect = 572c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_instr_create(ctx->block, -1, OPC_META_FO); 573c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou collect->fo.off = i; 574c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* unused dst reg: */ 575c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(collect, 0, 0); 576c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* and src reg used to hold original instr */ 577c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(collect, 0, IR3_REG_SSA)->instr = instr; 578c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!ctx->atomic) 579c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_dst(ctx, collect, dst, chan+i); 580c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 581c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 5828b993a98db507cc3a75067af4c865ffc8afbada1Guido van Rossum } 5838b993a98db507cc3a75067af4c865ffc8afbada1Guido van Rossum 5843e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton return reg; 5853e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton} 58693a569d6342215fbcf3d1df78184d669ac42527dJeremy Hylton 587c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_register * 588c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouadd_dst_reg(struct ir3_compile_context *ctx, struct ir3_instruction *instr, 589c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct tgsi_dst_register *dst, unsigned chan) 590c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 591c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return add_dst_reg_wrmask(ctx, instr, dst, chan, 0x1); 59293a569d6342215fbcf3d1df78184d669ac42527dJeremy Hylton} 59393a569d6342215fbcf3d1df78184d669ac42527dJeremy Hylton 5943e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonstatic struct ir3_register * 5953e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonadd_src_reg_wrmask(struct ir3_compile_context *ctx, 59610dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum struct ir3_instruction *instr, const struct tgsi_src_register *src, 597c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned chan, unsigned wrmask) 598c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 599c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned flags = 0, num = 0; 600c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_register *reg; 601c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *orig = NULL; 602c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 60310dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum /* TODO we need to use a mov to temp for const >= 64.. or maybe 60410dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum * we could use relative addressing.. 6053e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton */ 6063e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton compile_assert(ctx, src->Index < 64); 60710dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum 608c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (src->File) { 609c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_IMMEDIATE: 610c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* TODO if possible, use actual immediate instead of const.. but 611c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * TGSI has vec4 immediates, we can only embed scalar (of limited 61210dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum * size, depending on instruction..) 61310dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum */ 6143e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton flags |= IR3_REG_CONST; 6153e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton num = src->Index + ctx->so->first_immediate; 6163e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton break; 617f733a013b2d1546e58dd6d4d3cdcb083e2176beaNeal Norwitz case TGSI_FILE_CONSTANT: 618da4eb5c3b55df9b7d6957ddd0458313102f0a92eGuido van Rossum flags |= IR3_REG_CONST; 6193e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton num = src->Index; 6203e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton break; 6213e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case TGSI_FILE_OUTPUT: 622c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* NOTE: we should only end up w/ OUTPUT file for things like 623c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * clamp()'ing saturated dst instructions 624c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 625c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_INPUT: 626c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_FILE_TEMPORARY: 627c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* uses SSA */ 628c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 629c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou default: 630c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_error(ctx, "unsupported src register file: %s\n", 631c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tgsi_file_name(src->File)); 632c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 633c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 634c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 635c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (src->Absolute) 636c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou flags |= IR3_REG_ABS; 637c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (src->Negate) 638c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou flags |= IR3_REG_NEGATE; 639c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 640c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (src->Indirect) { 641c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou flags |= IR3_REG_RELATIV; 642c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 643c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* shouldn't happen, and we can't cope with it below: */ 644c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, wrmask == 0x1); 645c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 646c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* wrap in a meta-deref to track both the src and address: */ 647c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou orig = instr; 648c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 649c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = ir3_instr_create(ctx->block, -1, OPC_META_DEREF); 650c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, 0); 651c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = ctx->block->address; 652c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 653c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 654c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg = ir3_reg_create(instr, regid(num, chan), flags); 655c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 656c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->wrmask = wrmask; 657c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (wrmask == 0x1) { 658c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* normal case */ 659c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, reg, src, chan); 66080d937e986300d8e0cae93cb29bcb4211a65f92cArmin Rigo } else if ((src->File == TGSI_FILE_TEMPORARY) || 66180d937e986300d8e0cae93cb29bcb4211a65f92cArmin Rigo (src->File == TGSI_FILE_OUTPUT) || 6626fd03bb6070586a3b069c90cf3892ba7573d6bf5Amaury Forgeot d'Arc (src->File == TGSI_FILE_INPUT)) { 6636fd03bb6070586a3b069c90cf3892ba7573d6bf5Amaury Forgeot d'Arc struct ir3_instruction *collect; 66412603c41daedcf0387c7eb08b17fe32549acfc31Jeremy Hylton unsigned i; 66512603c41daedcf0387c7eb08b17fe32549acfc31Jeremy Hylton 6666fd03bb6070586a3b069c90cf3892ba7573d6bf5Amaury Forgeot d'Arc compile_assert(ctx, !src->Indirect); 6676fd03bb6070586a3b069c90cf3892ba7573d6bf5Amaury Forgeot d'Arc 6686fd03bb6070586a3b069c90cf3892ba7573d6bf5Amaury Forgeot d'Arc /* if instruction reads multiple, we need to create 6696fd03bb6070586a3b069c90cf3892ba7573d6bf5Amaury Forgeot d'Arc * some place-holder collect the registers: 6706fd03bb6070586a3b069c90cf3892ba7573d6bf5Amaury Forgeot d'Arc */ 6716fd03bb6070586a3b069c90cf3892ba7573d6bf5Amaury Forgeot d'Arc collect = ir3_instr_create(ctx->block, -1, OPC_META_FI); 672f733a013b2d1546e58dd6d4d3cdcb083e2176beaNeal Norwitz ir3_reg_create(collect, 0, 0); /* unused dst reg */ 67312603c41daedcf0387c7eb08b17fe32549acfc31Jeremy Hylton 67480d937e986300d8e0cae93cb29bcb4211a65f92cArmin Rigo for (i = 0; i < 4; i++) { 6753e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (wrmask & (1 << i)) { 67610dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum /* and src reg used point to the original instr */ 677c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), 678c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src, chan + i); 679c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else if (wrmask & ~((i << i) - 1)) { 680c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* if any remaining components, then dummy 681c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * placeholder src reg to fill in the blanks: 682c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 68310dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum ir3_reg_create(collect, 0, 0); 68410dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum } 6853e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 6863e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 68710dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum reg->flags |= IR3_REG_SSA; 688c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->instr = collect; 689c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 690c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 691c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (src->Indirect) { 692c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg = ir3_reg_create(orig, 0, flags | IR3_REG_SSA); 693c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->instr = instr; 694c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 695c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return reg; 696c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 697c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 698c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_register * 699c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouadd_src_reg(struct ir3_compile_context *ctx, struct ir3_instruction *instr, 700c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct tgsi_src_register *src, unsigned chan) 701c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 702c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return add_src_reg_wrmask(ctx, instr, src, chan, 0x1); 703c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 704c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 705c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 706c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrousrc_from_dst(struct tgsi_src_register *src, struct tgsi_dst_register *dst) 707c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 708c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->File = dst->File; 709c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->Indirect = dst->Indirect; 710c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->Dimension = dst->Dimension; 711c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->Index = dst->Index; 712c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->Absolute = 0; 713c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->Negate = 0; 714c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->SwizzleX = TGSI_SWIZZLE_X; 715c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->SwizzleY = TGSI_SWIZZLE_Y; 716c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->SwizzleZ = TGSI_SWIZZLE_Z; 717c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->SwizzleW = TGSI_SWIZZLE_W; 718c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 719c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 720c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* Get internal-temp src/dst to use for a sequence of instructions 721c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * generated by a single TGSI op. 722c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 723c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct tgsi_src_register * 724c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouget_internal_temp(struct ir3_compile_context *ctx, 725c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *tmp_dst) 726c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 727c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *tmp_src; 728c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou int n; 729c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 730c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_dst->File = TGSI_FILE_TEMPORARY; 731c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_dst->WriteMask = TGSI_WRITEMASK_XYZW; 732c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_dst->Indirect = 0; 733c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_dst->Dimension = 0; 734c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 735c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* assign next temporary: */ 736c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou n = ctx->num_internal_temps++; 737c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, n < ARRAY_SIZE(ctx->internal_temps)); 738c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_src = &ctx->internal_temps[n]; 739c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 740c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_dst->Index = ctx->info.file_max[TGSI_FILE_TEMPORARY] + n + 1; 741c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 742c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src_from_dst(tmp_src, tmp_dst); 743c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 744c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return tmp_src; 745c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 746c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 747c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic inline bool 748c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouis_const(struct tgsi_src_register *src) 749c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 750c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return (src->File == TGSI_FILE_CONSTANT) || 751c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (src->File == TGSI_FILE_IMMEDIATE); 752c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 753c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 754c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic inline bool 755c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouis_relative(struct tgsi_src_register *src) 756c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 757c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return src->Indirect; 758c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 759c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 760c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic inline bool 761c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouis_rel_or_const(struct tgsi_src_register *src) 762c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 763c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return is_relative(src) || is_const(src); 764c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 765c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 766c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic type_t 767c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouget_ftype(struct ir3_compile_context *ctx) 768c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 769c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return TYPE_F32; 770c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 771c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 772c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic type_t 773c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouget_utype(struct ir3_compile_context *ctx) 774c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 775c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return TYPE_U32; 776c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 777c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 778c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic type_t 779c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouget_stype(struct ir3_compile_context *ctx) 780c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 781c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return TYPE_S32; 782c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 783c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 784c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic unsigned 785c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrousrc_swiz(struct tgsi_src_register *src, int chan) 786c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 787c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (chan) { 788c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 0: return src->SwizzleX; 789c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 1: return src->SwizzleY; 790c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 2: return src->SwizzleZ; 791c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 3: return src->SwizzleW; 792c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 793c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou assert(0); 794c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return 0; 795c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 796c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 797c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* for instructions that cannot take a const register as src, if needed 798c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * generate a move to temporary gpr: 799c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 800c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct tgsi_src_register * 801c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouget_unconst(struct ir3_compile_context *ctx, struct tgsi_src_register *src) 802c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 803c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register tmp_dst; 804c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *tmp_src; 805c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 806c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, is_rel_or_const(src)); 807c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 808c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_src = get_internal_temp(ctx, &tmp_dst); 809c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 810c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou create_mov(ctx, &tmp_dst, src); 811c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 812c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return tmp_src; 813c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 814c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 815c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 816c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouget_immediate(struct ir3_compile_context *ctx, 817c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *reg, uint32_t val) 818c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 819c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned neg, swiz, idx, i; 820c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* actually maps 1:1 currently.. not sure if that is safe to rely on: */ 821c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou static const unsigned swiz2tgsi[] = { 822c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W, 823c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou }; 824c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 825c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < ctx->immediate_idx; i++) { 826c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou swiz = i % 4; 827c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou idx = i / 4; 828c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 829c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx->so->immediates[idx].val[swiz] == val) { 830c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou neg = 0; 831c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 832c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 833c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 834c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx->so->immediates[idx].val[swiz] == -val) { 835c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou neg = 1; 836c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 837c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 838c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 839c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 840c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (i == ctx->immediate_idx) { 841c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* need to generate a new immediate: */ 842c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou swiz = i % 4; 843c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou idx = i / 4; 844c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou neg = 0; 845c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->so->immediates[idx].val[swiz] = val; 846c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->so->immediates_count = idx + 1; 847c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->immediate_idx++; 848c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 849c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 850c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->File = TGSI_FILE_IMMEDIATE; 851c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->Indirect = 0; 852c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->Dimension = 0; 853c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->Index = idx; 854c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->Absolute = 0; 855c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->Negate = neg; 856c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->SwizzleX = swiz2tgsi[swiz]; 857c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->SwizzleY = swiz2tgsi[swiz]; 858c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->SwizzleZ = swiz2tgsi[swiz]; 859c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->SwizzleW = swiz2tgsi[swiz]; 860c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 861c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 862c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 863c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucreate_mov(struct ir3_compile_context *ctx, struct tgsi_dst_register *dst, 864c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src) 865c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 866c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou type_t type_mov = get_ftype(ctx); 867c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned i; 868c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 869c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < 4; i++) { 870c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* move to destination: */ 871c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (dst->WriteMask & (1 << i)) { 872c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 873c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 874c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (src->Absolute || src->Negate) { 875c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* can't have abs or neg on a mov instr, so use 876c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * absneg.f instead to handle these cases: 877c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 878c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ABSNEG_F); 879c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 880c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 881c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = type_mov; 882c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = type_mov; 883c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 884c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 885c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg(ctx, instr, dst, i); 8863e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton add_src_reg(ctx, instr, src, src_swiz(src, i)); 887c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 888c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 889c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 890c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 891c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 892c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucreate_clamp(struct ir3_compile_context *ctx, 893c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst, struct tgsi_src_register *val, 8943e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_src_register *minval, struct tgsi_src_register *maxval) 895c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 896c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 897c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 898c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MAX_F); 899c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 2, val, 0, minval, 0); 900c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 901c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MIN_F); 902c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 2, val, 0, maxval, 0); 903c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 904c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 905c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 906c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucreate_clamp_imm(struct ir3_compile_context *ctx, 907c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst, 908c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou uint32_t minval, uint32_t maxval) 909c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 910c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register minconst, maxconst; 911c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register src; 912c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 913c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src_from_dst(&src, dst); 914c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 915c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou get_immediate(ctx, &minconst, minval); 916c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou get_immediate(ctx, &maxconst, maxval); 91710dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum 91810dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum create_clamp(ctx, dst, &src, &minconst, &maxconst); 9193e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton} 9203e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 921d6f3bc2aaea467ceba2c390bba48210da55069d4Guido van Rossumstatic struct tgsi_dst_register * 922d6f3bc2aaea467ceba2c390bba48210da55069d4Guido van Rossumget_dst(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst) 9233e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton{ 9243e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_dst_register *dst = &inst->Dst[0].Register; 9253e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton unsigned i; 926c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 927c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, !ctx->using_tmp_dst); 928c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->using_tmp_dst = true; 929c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 930c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { 931c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src = &inst->Src[i].Register; 932c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if ((src->File == dst->File) && (src->Index == dst->Index)) { 933c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if ((dst->WriteMask == TGSI_WRITEMASK_XYZW) && 934c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (src->SwizzleX == TGSI_SWIZZLE_X) && 935c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (src->SwizzleY == TGSI_SWIZZLE_Y) && 936c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (src->SwizzleZ == TGSI_SWIZZLE_Z) && 937c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (src->SwizzleW == TGSI_SWIZZLE_W)) 938c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou continue; 939c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->tmp_src = get_internal_temp(ctx, &ctx->tmp_dst); 94010dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum ctx->tmp_dst.WriteMask = dst->WriteMask; 94110dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum dst = &ctx->tmp_dst; 9423e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton break; 9433e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 9443e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 945c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return dst; 946c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 9477791165fb36ecca2398ac81e9b6bc0248821262cVictor Stinner 9487791165fb36ecca2398ac81e9b6bc0248821262cVictor Stinnerstatic void 949c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouput_dst(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst, 950c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst) 951c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 952c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, ctx->using_tmp_dst); 953c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->using_tmp_dst = false; 954c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 955c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* if necessary, add mov back into original dst: */ 956c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (dst != &inst->Dst[0].Register) { 957c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou create_mov(ctx, &inst->Dst[0].Register, ctx->tmp_src); 958c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 959c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 960c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 961c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* helper to generate the necessary repeat and/or additional instructions 962c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * to turn a scalar instruction into a vector operation: 963c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 964c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 965c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouvectorize(struct ir3_compile_context *ctx, struct ir3_instruction *instr, 966c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst, int nsrcs, ...) 967c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 968c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou va_list ap; 969c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou int i, j, n = 0; 970c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 9714bad92cc8a452bad690f8bbdddbb2421b0361360Guido van Rossum instr_atomic_start(ctx); 9724bad92cc8a452bad690f8bbdddbb2421b0361360Guido van Rossum 9733e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton add_dst_reg(ctx, instr, dst, TGSI_SWIZZLE_X); 9743e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 975c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou va_start(ap, nsrcs); 9763e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton for (j = 0; j < nsrcs; j++) { 9773e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_src_register *src = 9783e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton va_arg(ap, struct tgsi_src_register *); 979a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou unsigned flags = va_arg(ap, unsigned); 9803e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3_register *reg; 9813e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (flags & IR3_REG_IMMED) { 982376e63d5cdb7388b5787ab10f7d82ba24257e742Jeremy Hylton reg = ir3_reg_create(instr, 0, IR3_REG_IMMED); 9833e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* this is an ugly cast.. should have put flags first! */ 9843e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton reg->iim_val = *(int *)&src; 985c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 9863e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton reg = add_src_reg(ctx, instr, src, TGSI_SWIZZLE_X); 9873e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 9883e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton reg->flags |= flags & ~IR3_REG_NEGATE; 9893e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (flags & IR3_REG_NEGATE) 990a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou reg->flags ^= IR3_REG_NEGATE; 9913e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 9923e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton va_end(ap); 9933e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 994a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou for (i = 0; i < 4; i++) { 9953e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (dst->WriteMask & (1 << i)) { 9963e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3_instruction *cur; 9973e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 9983e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (n++ == 0) { 9993e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton cur = instr; 1000376e63d5cdb7388b5787ab10f7d82ba24257e742Jeremy Hylton } else { 1001376e63d5cdb7388b5787ab10f7d82ba24257e742Jeremy Hylton cur = instr_clone(ctx, instr); 10024ca6c9db81ded166c95ce3f829ac4642d02f934dGuido van Rossum } 10033e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 10044ca6c9db81ded166c95ce3f829ac4642d02f934dGuido van Rossum ssa_dst(ctx, cur, dst, i); 1005c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1006c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* fix-up dst register component: */ 1007c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou cur->regs[0]->num = regid(cur->regs[0]->num >> 2, i); 1008c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1009c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* fix-up src register component: */ 1010c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou va_start(ap, nsrcs); 1011c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (j = 0; j < nsrcs; j++) { 1012c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_register *reg = cur->regs[j+1]; 1013c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src = 1014c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou va_arg(ap, struct tgsi_src_register *); 1015c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned flags = va_arg(ap, unsigned); 10164ca6c9db81ded166c95ce3f829ac4642d02f934dGuido van Rossum if (reg->flags & IR3_REG_SSA) { 10174ca6c9db81ded166c95ce3f829ac4642d02f934dGuido van Rossum ssa_src(ctx, reg, src, src_swiz(src, i)); 10183e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } else if (!(flags & IR3_REG_IMMED)) { 10193e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton reg->num = regid(reg->num >> 2, src_swiz(src, i)); 1020c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter } 1021c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1022c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou va_end(ap); 1023c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1024c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1025c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1026c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr_atomic_end(ctx); 1027c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1028c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1029c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 1030c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * Handlers for TGSI instructions which do not have a 1:1 mapping to 1031c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * native instructions: 1032c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1033c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1034c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1035c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_clamp(const struct instr_translater *t, 1036c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1037c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1038c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1039c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 1040c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src0 = &inst->Src[0].Register; 1041c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src1 = &inst->Src[1].Register; 10423e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_src_register *src2 = &inst->Src[2].Register; 10433e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 10443e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton create_clamp(ctx, dst, src0, src1, src2); 1045c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter 1046f733a013b2d1546e58dd6d4d3cdcb083e2176beaNeal Norwitz put_dst(ctx, inst, dst); 1047f733a013b2d1546e58dd6d4d3cdcb083e2176beaNeal Norwitz} 10483e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 10493e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton/* ARL(x) = x, but mova from hrN.x to a0.. */ 10503e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonstatic void 10513e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltontrans_arl(const struct instr_translater *t, 1052c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1053c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1054c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter{ 1055c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter struct ir3_instruction *instr; 10563e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_dst_register tmp_dst; 1057c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *tmp_src; 1058c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = &inst->Dst[0].Register; 1059c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter struct tgsi_src_register *src = &inst->Src[0].Register; 1060c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter unsigned chan = src->SwizzleX; 10613e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 1062c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, dst->File == TGSI_FILE_ADDRESS); 1063c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 10643e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* NOTE: we allocate a temporary from a flat register 10650ccff074cd806bc7e963a1e0ff6ce25e0d11cce9Michael W. Hudson * namespace (ignoring half vs full). It turns out 1066b6fc9df8fc34271a881ab954b843872834f5f112Neal Norwitz * not to really matter since registers get reassigned 1067c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * later in ir3_ra which (hopefully!) can deal a bit 1068c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * better with mixed half and full precision. 1069c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1070c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_src = get_internal_temp(ctx, &tmp_dst); 1071b6fc9df8fc34271a881ab954b843872834f5f112Neal Norwitz 1072b6fc9df8fc34271a881ab954b843872834f5f112Neal Norwitz /* cov.{u,f}{32,16}s16 Rtmp, Rsrc */ 10733e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr = instr_create(ctx, 1, 0); 1074c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = (t->tgsi_opc == TGSI_OPCODE_ARL) ? 1075c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou get_ftype(ctx) : get_utype(ctx); 10763e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr->cat1.dst_type = TYPE_S16; 10770ccff074cd806bc7e963a1e0ff6ce25e0d11cce9Michael W. Hudson add_dst_reg(ctx, instr, &tmp_dst, chan)->flags |= IR3_REG_HALF; 10783e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton add_src_reg(ctx, instr, src, chan); 1079c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1080c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* shl.b Rtmp, Rtmp, 2 */ 10813e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr = instr_create(ctx, 2, OPC_SHL_B); 1082c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter add_dst_reg(ctx, instr, &tmp_dst, chan)->flags |= IR3_REG_HALF; 10833e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton add_src_reg(ctx, instr, tmp_src, chan)->flags |= IR3_REG_HALF; 1084c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 2; 1085c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1086c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter /* mova a0, Rtmp */ 1087c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter instr = instr_create(ctx, 1, 0); 10883e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr->cat1.src_type = TYPE_S16; 1089c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = TYPE_S16; 1090c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg(ctx, instr, dst, 0)->flags |= IR3_REG_HALF; 10913e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton add_src_reg(ctx, instr, tmp_src, chan)->flags |= IR3_REG_HALF; 1092c2a5a636545a88f349dbe3e452ffb4494b68e534Anthony Baxter} 10933e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 1094c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 1095c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * texture fetch/sample instructions: 10963e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton */ 10970ccff074cd806bc7e963a1e0ff6ce25e0d11cce9Michael W. Hudson 10983e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonstruct tex_info { 10993e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton int8_t order[4]; 11003e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton int8_t args; 11010ccff074cd806bc7e963a1e0ff6ce25e0d11cce9Michael W. Hudson unsigned src_wrmask, flags; 11023e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton}; 1103c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1104c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustruct target_info { 11053e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton uint8_t dims; 11060ccff074cd806bc7e963a1e0ff6ce25e0d11cce9Michael W. Hudson uint8_t cube; 1107b6fc9df8fc34271a881ab954b843872834f5f112Neal Norwitz uint8_t array; 1108c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou uint8_t shadow; 1109c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou}; 1110c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1111c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic const struct target_info tex_targets[] = { 1112b6fc9df8fc34271a881ab954b843872834f5f112Neal Norwitz [TGSI_TEXTURE_1D] = { 1, 0, 0, 0 }, 1113b6fc9df8fc34271a881ab954b843872834f5f112Neal Norwitz [TGSI_TEXTURE_2D] = { 2, 0, 0, 0 }, 11143e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton [TGSI_TEXTURE_3D] = { 3, 0, 0, 0 }, 1115c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_CUBE] = { 3, 1, 0, 0 }, 1116c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_RECT] = { 2, 0, 0, 0 }, 111710dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum [TGSI_TEXTURE_SHADOW1D] = { 1, 0, 0, 1 }, 111810dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum [TGSI_TEXTURE_SHADOW2D] = { 2, 0, 0, 1 }, 11193e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton [TGSI_TEXTURE_SHADOWRECT] = { 2, 0, 0, 1 }, 1120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_1D_ARRAY] = { 1, 0, 1, 0 }, 1121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_2D_ARRAY] = { 2, 0, 1, 0 }, 1122c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_SHADOW1D_ARRAY] = { 1, 0, 1, 1 }, 1123c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_SHADOW2D_ARRAY] = { 2, 0, 1, 1 }, 1124c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_SHADOWCUBE] = { 3, 1, 0, 1 }, 1125c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_2D_MSAA] = { 2, 0, 0, 0 }, 1126c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_TEXTURE_2D_ARRAY_MSAA] = { 2, 0, 1, 0 }, 11277b782b61c597a989a21a22c15ee95decf997429fAnthony Baxter [TGSI_TEXTURE_CUBE_ARRAY] = { 3, 1, 1, 0 }, 11287b782b61c597a989a21a22c15ee95decf997429fAnthony Baxter [TGSI_TEXTURE_SHADOWCUBE_ARRAY] = { 3, 1, 1, 1 }, 1129b6fc9df8fc34271a881ab954b843872834f5f112Neal Norwitz}; 1130c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1131c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1132c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroufill_tex_info(struct ir3_compile_context *ctx, 1133c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst, 1134c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tex_info *info) 1135c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1136c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct target_info *tgt = &tex_targets[inst->Texture.Texture]; 1137c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1138c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tgt->dims == 3) 11397b782b61c597a989a21a22c15ee95decf997429fAnthony Baxter info->flags |= IR3_INSTR_3D; 11407b782b61c597a989a21a22c15ee95decf997429fAnthony Baxter if (tgt->array) 11413e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton info->flags |= IR3_INSTR_A; 11423e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (tgt->shadow) 1143c5e96291d00adac4f977060fc7f8d79a42322f72Guido van Rossum info->flags |= IR3_INSTR_S; 11443e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 1145a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou switch (inst->Instruction.Opcode) { 11463e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case TGSI_OPCODE_TXB: 1147c5e96291d00adac4f977060fc7f8d79a42322f72Guido van Rossum case TGSI_OPCODE_TXB2: 1148c5e96291d00adac4f977060fc7f8d79a42322f72Guido van Rossum case TGSI_OPCODE_TXL: 11493e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case TGSI_OPCODE_TXF: 11503e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton info->args = 2; 11513e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton break; 11523e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case TGSI_OPCODE_TXP: 115310dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum info->flags |= IR3_INSTR_P; 1154c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* fallthrough */ 1155c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_TEX: 1156c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_TXD: 1157c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou info->args = 1; 1158c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1159c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1160c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1161c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* 1162c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * lay out the first argument in the proper order: 1163c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * - actual coordinates first 1164c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * - array index 1165c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * - shadow reference 1166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * - projection w 1167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1168c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * bias/lod go into the second arg 1169c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 117010dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum int arg, pos = 0; 117110dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum for (arg = 0; arg < tgt->dims; arg++) 11723e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton info->order[arg] = pos++; 11733e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (tgt->dims == 1) 117410dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum info->order[pos++] = -1; 1175c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tgt->shadow) 1176c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou info->order[pos++] = MAX2(arg + tgt->array, 2); 1177c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tgt->array) 1178c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou info->order[pos++] = arg++; 1179c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (info->flags & IR3_INSTR_P) 1180c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou info->order[pos++] = 3; 1181c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1182c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou info->src_wrmask = (1 << pos) - 1; 1183c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1184c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (; pos < 4; pos++) 1185c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou info->order[pos] = -1; 1186c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1187c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou assert(pos <= 4); 1188c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1189c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1190c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic bool check_swiz(struct tgsi_src_register *src, const int8_t order[4]) 1191c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned i; 1193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 1; (i < 4) && order[i] >= 0; i++) 1194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (src_swiz(src, i) != (src_swiz(src, 0) + order[i])) 1195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return false; 1196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return true; 1197c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1198c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1199c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic bool is_1d(unsigned tex) 1200c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1201c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return tex_targets[tex].dims == 1; 1202c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1203c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct tgsi_src_register * 1205c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouget_tex_coord(struct ir3_compile_context *ctx, 1206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst, 1207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct tex_info *tinf) 1208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *coord = &inst->Src[0].Register; 1210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 1211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned tex = inst->Texture.Texture; 1212c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bool needs_mov = false; 1213c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1214c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cat5 instruction cannot seem to handle const or relative: */ 121510dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum if (is_rel_or_const(coord)) 121610dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum needs_mov = true; 12173e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 12183e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* 1D textures we fix up w/ 0.5 as 2nd coord: */ 12193e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (is_1d(tex)) 12203e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton needs_mov = true; 122110dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum 12223e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* The texture sample instructions need to coord in successive 12233e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * registers/components (ie. src.xy but not src.yx). And TXP 12243e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * needs the .w component in .z for 2D.. so in some cases we 1225c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * might need to emit some mov instructions to shuffle things 1226c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * around: 1227c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1228c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!needs_mov) 1229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou needs_mov = !check_swiz(coord, tinf->order); 1230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (needs_mov) { 1232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register tmp_dst; 1233a86c091a736020d823f1676acec7319bc5493f2cSerhiy Storchaka struct tgsi_src_register *tmp_src; 1234c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned j; 1235a86c091a736020d823f1676acec7319bc5493f2cSerhiy Storchaka 1236a86c091a736020d823f1676acec7319bc5493f2cSerhiy Storchaka type_t type_mov = get_ftype(ctx); 1237a86c091a736020d823f1676acec7319bc5493f2cSerhiy Storchaka 1238c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* need to move things around: */ 1239c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_src = get_internal_temp(ctx, &tmp_dst); 1240c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 12413e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton for (j = 0; j < 4; j++) { 1242c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tinf->order[j] < 0) 124310dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum continue; 124410dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum instr = instr_create(ctx, 1, 0); /* mov */ 12453e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr->cat1.src_type = type_mov; 12463e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr->cat1.dst_type = type_mov; 124710dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum add_dst_reg(ctx, instr, &tmp_dst, j); 12483e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton add_src_reg(ctx, instr, coord, 12497791165fb36ecca2398ac81e9b6bc0248821262cVictor Stinner src_swiz(coord, tinf->order[j])); 12503e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 1251a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou 12523e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* fix up .y coord: */ 12533715c3e576a182692cf2ad2d390732126f11780dNeal Norwitz if (is_1d(tex)) { 12543e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3_register *imm; 1255a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou instr = instr_create(ctx, 1, 0); /* mov */ 12563e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr->cat1.src_type = type_mov; 125710dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum instr->cat1.dst_type = type_mov; 125810dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum add_dst_reg(ctx, instr, &tmp_dst, 1); /* .y */ 12593e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton imm = ir3_reg_create(instr, 0, IR3_REG_IMMED); 12603e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) 126149d6dc4123173ab77ac220c3298a6db621fd6d4eGuido van Rossum imm->iim_val = 0; 1262c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou else 1263c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou imm->fim_val = 0.5; 1264c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1265c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1266c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou coord = tmp_src; 1267c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1268c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1269c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return coord; 1270c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1271c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1272c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1273c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_samp(const struct instr_translater *t, 1274c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1275c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1276c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1277c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr, *collect; 1278c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_register *reg; 1279c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = &inst->Dst[0].Register; 1280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *orig, *coord, *samp, *offset, *dpdx, *dpdy; 1281c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register zero; 1282c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct target_info *tgt = &tex_targets[inst->Texture.Texture]; 1283c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tex_info tinf; 1284c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou int i; 1285c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1286c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou memset(&tinf, 0, sizeof(tinf)); 1287c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou fill_tex_info(ctx, inst, &tinf); 1288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou coord = get_tex_coord(ctx, inst, &tinf); 1289a86c091a736020d823f1676acec7319bc5493f2cSerhiy Storchaka get_immediate(ctx, &zero, 0); 1290c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1291c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (inst->Instruction.Opcode) { 1292c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_TXB2: 1293a86c091a736020d823f1676acec7319bc5493f2cSerhiy Storchaka orig = &inst->Src[1].Register; 1294c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou samp = &inst->Src[2].Register; 1295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1296c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_TXD: 1297c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou orig = &inst->Src[0].Register; 1298c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou dpdx = &inst->Src[1].Register; 1299c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou dpdy = &inst->Src[2].Register; 1300c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou samp = &inst->Src[3].Register; 1301c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_rel_or_const(dpdx)) 130249d6dc4123173ab77ac220c3298a6db621fd6d4eGuido van Rossum dpdx = get_unconst(ctx, dpdx); 130349d6dc4123173ab77ac220c3298a6db621fd6d4eGuido van Rossum if (is_rel_or_const(dpdy)) 13043e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton dpdy = get_unconst(ctx, dpdy); 13053e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton break; 130610dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum default: 1307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou orig = &inst->Src[0].Register; 130810dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum samp = &inst->Src[1].Register; 1309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1310c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 131110dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum if (tinf.args > 1 && is_rel_or_const(orig)) 1312c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou orig = get_unconst(ctx, orig); 1313c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1314c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* scale up integer coords for TXF based on the LOD */ 1315c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) { 131610dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum struct tgsi_dst_register tmp_dst; 131710dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum struct tgsi_src_register *tmp_src; 13183e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton type_t type_mov = get_utype(ctx); 13193e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 132012d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum tmp_src = get_internal_temp(ctx, &tmp_dst); 1321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < tgt->dims; i++) { 1322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_SHL_B); 1323c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg(ctx, instr, &tmp_dst, i); 1324c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg(ctx, instr, coord, src_swiz(coord, i)); 1325c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg(ctx, instr, orig, orig->SwizzleW); 1326c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1327c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tgt->dims < 2) { 1328c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 1329c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = type_mov; 1330c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = type_mov; 1331c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg(ctx, instr, &tmp_dst, i); 1332c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg(ctx, instr, &zero, 0); 1333c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou i++; 1334c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1335c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tgt->array) { 1336c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 1337c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = type_mov; 1338c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = type_mov; 1339c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg(ctx, instr, &tmp_dst, i); 134012d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum add_src_reg(ctx, instr, coord, src_swiz(coord, i)); 134112d12c5faf4d770160b7975b54e8f9b12694e012Guido van Rossum } 13423e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton coord = tmp_src; 13433e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 13441f4fa501766ad79beb0602685dc0f69f9389fc5dGuido van Rossum 1345c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (inst->Texture.NumOffsets) { 1346c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_texture_offset *tex_offset = &inst->TexOffsets[0]; 1347c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register offset_src = {0}; 1348c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou offset_src.File = tex_offset->File; 1350c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou offset_src.Index = tex_offset->Index; 1351c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou offset_src.SwizzleX = tex_offset->SwizzleX; 1352c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou offset_src.SwizzleY = tex_offset->SwizzleY; 1353c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou offset_src.SwizzleZ = tex_offset->SwizzleZ; 1354c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou offset = get_unconst(ctx, &offset_src); 1355c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tinf.flags |= IR3_INSTR_O; 1356c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1357c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1358c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 5, t->opc); 1359c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat5.type = get_ftype(ctx); 1360c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat5.samp = samp->Index; 1361c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat5.tex = samp->Index; 1362c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->flags |= tinf.flags; 1363c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1364c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask); 1365c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1366c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg = ir3_reg_create(instr, 0, IR3_REG_SSA); 1367c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1368c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou collect = ir3_instr_create(ctx->block, -1, OPC_META_FI); 1369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(collect, 0, 0); 1370c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < 4; i++) 1371c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tinf.src_wrmask & (1 << i)) 1372c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), 1373c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou coord, src_swiz(coord, i)); 1374c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou else if (tinf.src_wrmask & ~((1 << i) - 1)) 1375c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(collect, 0, 0); 1376c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1377c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* Attach derivatives onto the end of the fan-in. Derivatives start after 1378c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * the 4th argument, so make sure that fi is padded up to 4 first. 1379c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1380c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) { 1381c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou while (collect->regs_count < 5) 1382c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), &zero, 0); 1383c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < tgt->dims; i++) 1384c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), dpdx, i); 1385c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tgt->dims < 2) 1386c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), &zero, 0); 1387c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < tgt->dims; i++) 1388c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), dpdy, i); 1389c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tgt->dims < 2) 1390c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), &zero, 0); 1391c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tinf.src_wrmask |= ((1 << (2 * MAX2(tgt->dims, 2))) - 1) << 4; 1392c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1393c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1394354433a59dd1701985ec8463ced25a967cade3c1Raymond Hettinger reg->instr = collect; 1395354433a59dd1701985ec8463ced25a967cade3c1Raymond Hettinger reg->wrmask = tinf.src_wrmask; 13963e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 13973e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* The second argument contains the offsets, followed by the lod/bias 139810dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum * argument. This is constructed more manually due to the dynamic nature. 1399c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1400c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (inst->Texture.NumOffsets == 0 && tinf.args == 1) 1401c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return; 1402c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1403c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg = ir3_reg_create(instr, 0, IR3_REG_SSA); 1404c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1405c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou collect = ir3_instr_create(ctx->block, -1, OPC_META_FI); 1406c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(collect, 0, 0); 1407c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1408c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (inst->Texture.NumOffsets) { 1409c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < tgt->dims; i++) 1410c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), 1411c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou offset, i); 1412c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (tgt->dims < 2) 1413c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), &zero, 0); 1414c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (inst->Instruction.Opcode == TGSI_OPCODE_TXB2) 1416c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), 14175951f2300f43d75d344d542e171daed47a0382a6Serhiy Storchaka orig, orig->SwizzleX); 1418bc62af1bbe118aa678cb6fa4ecad40f7250b56deSerhiy Storchaka else if (tinf.args > 1) 1419c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA), 1420c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou orig, orig->SwizzleW); 1421c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1422c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->instr = collect; 1423c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou reg->wrmask = (1 << (collect->regs_count - 1)) - 1; 1424c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1427c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_txq(const struct instr_translater *t, 1428c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1429c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1430c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1431c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 1432c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = &inst->Dst[0].Register; 1433c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *level = &inst->Src[0].Register; 1434c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *samp = &inst->Src[1].Register; 1435c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tex_info tinf; 1436c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1437c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou memset(&tinf, 0, sizeof(tinf)); 1438c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou fill_tex_info(ctx, inst, &tinf); 1439c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_rel_or_const(level)) 1440c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou level = get_unconst(ctx, level); 1441c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1442c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 5, OPC_GETSIZE); 1443c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat5.type = get_utype(ctx); 1444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat5.samp = samp->Index; 1445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat5.tex = samp->Index; 1446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->flags |= tinf.flags; 1447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask); 1449c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg_wrmask(ctx, instr, level, level->SwizzleX, 0x1); 1450c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1451c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1452c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* DDX/DDY */ 1453c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_deriv(const struct instr_translater *t, 1455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1456c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1457c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1458c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 145910dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum struct tgsi_dst_register *dst = &inst->Dst[0].Register; 146010dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum struct tgsi_src_register *src = &inst->Src[0].Register; 14613e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton static const int8_t order[4] = {0, 1, 2, 3}; 1462dca3b9c797f6dd4b08d590fa2aa1031e22ab598eThomas Wouters 1463dca3b9c797f6dd4b08d590fa2aa1031e22ab598eThomas Wouters if (!check_swiz(src, order)) { 1464c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register tmp_dst; 1465c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *tmp_src; 1466c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1467c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_src = get_internal_temp(ctx, &tmp_dst); 1468c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou create_mov(ctx, &tmp_dst, src); 1469c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1470c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src = tmp_src; 1471c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1472c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1473c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* This might be a workaround for hw bug? Blob compiler always 1474c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * seems to work two components at a time for dsy/dsx. It does 1475c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * actually seem to work in some cases (or at least some piglit 1476c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * tests) for four components at a time. But seems more reliable 1477c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * to split this into two instructions like the blob compiler 1478c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * does: 1479c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1480c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1481dca3b9c797f6dd4b08d590fa2aa1031e22ab598eThomas Wouters instr = instr_create(ctx, 5, t->opc); 1482dca3b9c797f6dd4b08d590fa2aa1031e22ab598eThomas Wouters instr->cat5.type = get_ftype(ctx); 1483dca3b9c797f6dd4b08d590fa2aa1031e22ab598eThomas Wouters add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask & 0x3); 14843e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton add_src_reg_wrmask(ctx, instr, src, 0, dst->WriteMask & 0x3); 148564949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton 1486c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 5, t->opc); 1487c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat5.type = get_ftype(ctx); 1488c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg_wrmask(ctx, instr, dst, 2, (dst->WriteMask >> 2) & 0x3); 1489c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg_wrmask(ctx, instr, src, 2, (dst->WriteMask >> 2) & 0x3); 1490c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1491c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1492c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 1493c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * SEQ(a,b) = (a == b) ? 1.0 : 0.0 1494c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.f.eq tmp0, a, b 1495c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cov.u16f16 dst, tmp0 1496c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1497c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * SNE(a,b) = (a != b) ? 1.0 : 0.0 1498c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.f.ne tmp0, a, b 1499c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cov.u16f16 dst, tmp0 1500c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1501c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * SGE(a,b) = (a >= b) ? 1.0 : 0.0 1502c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.f.ge tmp0, a, b 1503c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cov.u16f16 dst, tmp0 1504c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1505c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * SLE(a,b) = (a <= b) ? 1.0 : 0.0 1506c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.f.le tmp0, a, b 1507c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cov.u16f16 dst, tmp0 1508c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1509c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * SGT(a,b) = (a > b) ? 1.0 : 0.0 1510c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.f.gt tmp0, a, b 1511c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cov.u16f16 dst, tmp0 1512c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1513c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * SLT(a,b) = (a < b) ? 1.0 : 0.0 1514c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.f.lt tmp0, a, b 1515c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cov.u16f16 dst, tmp0 1516c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1517c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * CMP(a,b,c) = (a < 0.0) ? b : c 1518c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.f.lt tmp0, a, {0.0} 1519c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * sel.b16 dst, b, tmp0, c 1520c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1521c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1522c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_cmp(const struct instr_translater *t, 1523c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1524c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1525c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1526c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 15279f324e964e06c79f9c47501afa12b1af4cb1a75fJeremy Hylton struct tgsi_dst_register tmp_dst; 15289f324e964e06c79f9c47501afa12b1af4cb1a75fJeremy Hylton struct tgsi_src_register *tmp_src; 15293e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_src_register constval0; 15303e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* final instruction for CMP() uses orig src1 and src2: */ 15313e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_dst_register *dst = get_dst(ctx, inst); 1532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *a0, *a1, *a2; 1533c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned condition; 1534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1535c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_src = get_internal_temp(ctx, &tmp_dst); 1536c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1537c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a0 = &inst->Src[0].Register; /* a */ 1538c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a1 = &inst->Src[1].Register; /* b */ 1539c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1540c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (t->tgsi_opc) { 1541c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SEQ: 1542c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_FSEQ: 1543c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_EQ; 1544c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1545c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SNE: 1546c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_FSNE: 1547c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_NE; 1548c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1549c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SGE: 1550c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_FSGE: 1551c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_GE; 1552c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1553c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SLT: 1554c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_FSLT: 1555c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_LT; 1556c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1557c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SLE: 1558c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_LE; 1559c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1560c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SGT: 1561c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_GT; 1562c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1563c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_CMP: 15648ff077b0949791c6b699cb179749d929a9fdc98aGuido van Rossum get_immediate(ctx, &constval0, fui(0.0)); 15658ff077b0949791c6b699cb179749d929a9fdc98aGuido van Rossum a0 = &inst->Src[0].Register; /* a */ 15663e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton a1 = &constval0; /* {0.0} */ 15673e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton condition = IR3_COND_LT; 15684b38da664c107bc08768235a66621429beef5444Jeremy Hylton break; 1569c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou default: 1570c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, 0); 1571c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return; 1572c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1573c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1574c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_const(a0) && is_const(a1)) 1575c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a0 = get_unconst(ctx, a0); 1576c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1577c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cmps.f.<cond> tmp, a0, a1 */ 1578c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_CMPS_F); 1579c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat2.condition = condition; 1580c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &tmp_dst, 2, a0, 0, a1, 0); 1581c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1582c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (t->tgsi_opc) { 1583c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SEQ: 1584c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SGE: 1585c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SLE: 1586c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SNE: 1587c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SGT: 1588c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SLT: 1589c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cov.u16f16 dst, tmp0 */ 1590c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 1591c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = get_utype(ctx); 1592c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = get_ftype(ctx); 1593c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 1, tmp_src, 0); 1594c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1595c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_FSEQ: 1596c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_FSGE: 1597c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_FSNE: 1598c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_FSLT: 1599c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* absneg.s dst, (neg)tmp0 */ 1600c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ABSNEG_S); 1601c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 1, tmp_src, IR3_REG_NEGATE); 1602c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1603c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_CMP: 16044b38da664c107bc08768235a66621429beef5444Jeremy Hylton a1 = &inst->Src[1].Register; 16054b38da664c107bc08768235a66621429beef5444Jeremy Hylton a2 = &inst->Src[2].Register; 16063e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* sel.{b32,b16} dst, src2, tmp, src1 */ 16073e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr = instr_create(ctx, 3, OPC_SEL_B32); 16088ff077b0949791c6b699cb179749d929a9fdc98aGuido van Rossum vectorize(ctx, instr, dst, 3, a1, 0, tmp_src, 0, a2, 0); 1609c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1610c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1611c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1612c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1613c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 1614c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1615c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1616c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 1617c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * USNE(a,b) = (a != b) ? ~0 : 0 1618c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.u32.ne dst, a, b 1619c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1620c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * USEQ(a,b) = (a == b) ? ~0 : 0 1621c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.u32.eq dst, a, b 1622c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1623c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * ISGE(a,b) = (a > b) ? ~0 : 0 1624c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.s32.ge dst, a, b 1625c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1626c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * USGE(a,b) = (a > b) ? ~0 : 0 1627c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.u32.ge dst, a, b 1628c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 1629c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * ISLT(a,b) = (a < b) ? ~0 : 0 1630c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.s32.lt dst, a, b 1631c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 16328ff077b0949791c6b699cb179749d929a9fdc98aGuido van Rossum * USLT(a,b) = (a < b) ? ~0 : 0 16338ff077b0949791c6b699cb179749d929a9fdc98aGuido van Rossum * cmps.u32.lt dst, a, b 16343e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * 16353e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton */ 16368ff077b0949791c6b699cb179749d929a9fdc98aGuido van Rossumstatic void 1637c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_icmp(const struct instr_translater *t, 1638c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1639c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1640c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1641c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 1642c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 1643c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register tmp_dst; 1644c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *tmp_src; 1645c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *a0, *a1; 1646c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned condition; 1647c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1648c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a0 = &inst->Src[0].Register; /* a */ 1649c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a1 = &inst->Src[1].Register; /* b */ 1650c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1651c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (t->tgsi_opc) { 1652c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_USNE: 1653c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_NE; 1654c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1655c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_USEQ: 1656c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_EQ; 1657c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1658c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_ISGE: 1659c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_USGE: 1660c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_GE; 1661c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1662c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_ISLT: 1663c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_USLT: 1664c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou condition = IR3_COND_LT; 1665c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 1666c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1667c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou default: 1668c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, 0); 1669c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return; 1670c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1671c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1672c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_const(a0) && is_const(a1)) 1673c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a0 = get_unconst(ctx, a0); 1674c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1675c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_src = get_internal_temp(ctx, &tmp_dst); 1676c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cmps.{u32,s32}.<cond> tmp, a0, a1 */ 16777a6a97352d9a99e83e6beca729d14bb6ca542d12Benjamin Peterson instr = instr_create(ctx, 2, t->opc); 1678c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat2.condition = condition; 16797a6a97352d9a99e83e6beca729d14bb6ca542d12Benjamin Peterson vectorize(ctx, instr, &tmp_dst, 2, a0, 0, a1, 0); 1680c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1681c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* absneg.s dst, (neg)tmp */ 1682c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ABSNEG_S); 1683c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 1, tmp_src, IR3_REG_NEGATE); 1684c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1685c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 168610dc2e8097e7a431367e72f46ddba91be93aa159Guido van Rossum} 1687da4eb5c3b55df9b7d6957ddd0458313102f0a92eGuido van Rossum 16883e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton/* 16893e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * UCMP(a,b,c) = a ? b : c 1690da4eb5c3b55df9b7d6957ddd0458313102f0a92eGuido van Rossum * sel.b16 dst, b, a, c 1691c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1692c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1693c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_ucmp(const struct instr_translater *t, 1694c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1695c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1696c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1697c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 1698c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 1699c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *a0, *a1, *a2; 1700c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1701c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a0 = &inst->Src[0].Register; /* a */ 1702c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a1 = &inst->Src[1].Register; /* b */ 1703c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a2 = &inst->Src[2].Register; /* c */ 1704c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1705c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_rel_or_const(a0)) 1706c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a0 = get_unconst(ctx, a0); 1707c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1708c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* sel.{b32,b16} dst, b, a, c */ 1709c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_SEL_B32); 1710c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 3, a1, 0, a0, 0, a2, 0); 1711c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 1712c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1713c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1714c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 1715c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * ISSG(a) = a < 0 ? -1 : a > 0 ? 1 : 0 1716c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.s.lt tmp_neg, a, 0 # 1 if a is negative 1717c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * cmps.s.gt tmp_pos, a, 0 # 1 if a is positive 1718c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * sub.u dst, tmp_pos, tmp_neg 1719c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1720da4eb5c3b55df9b7d6957ddd0458313102f0a92eGuido van Rossumstatic void 1721e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hyltontrans_issg(const struct instr_translater *t, 17223e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3_compile_context *ctx, 1723c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1724c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1725c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 1726c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 1727c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *a = &inst->Src[0].Register; 1728c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register neg_dst, pos_dst; 1729c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *neg_src, *pos_src; 1730c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 17313e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton neg_src = get_internal_temp(ctx, &neg_dst); 17323e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton pos_src = get_internal_temp(ctx, &pos_dst); 17333e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 17343e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* cmps.s.lt neg, a, 0 */ 1735c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_CMPS_S); 17363e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr->cat2.condition = IR3_COND_LT; 1737c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &neg_dst, 2, a, 0, 0, IR3_REG_IMMED); 1738c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 17393e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* cmps.s.gt pos, a, 0 */ 1740c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_CMPS_S); 1741c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat2.condition = IR3_COND_GT; 1742c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &pos_dst, 2, a, 0, 0, IR3_REG_IMMED); 17433e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 1744c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* sub.u dst, pos, neg */ 1745c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_SUB_U); 1746c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 2, pos_src, 0, neg_src, 0); 1747c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 17483e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton put_dst(ctx, inst, dst); 17493e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton} 17503e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 17513e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 17523e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 175364949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton/* 1754e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton * Conditional / Flow control 1755e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton */ 17563e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 1757e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hyltonstatic void 1758c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroupush_branch(struct ir3_compile_context *ctx, bool inv, 1759c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr, struct ir3_instruction *cond) 1760c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1761c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned int idx = ctx->branch_count++; 1762c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, idx < ARRAY_SIZE(ctx->branch)); 1763c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->branch[idx].instr = instr; 1764c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->branch[idx].inv = inv; 1765c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* else side of branch has same condition: */ 1766c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!inv) 1767c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->branch[idx].cond = cond; 1768c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1769c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1770c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 17711abf610b154cc727f219fd52b2c1f868584a6e7bJeremy Hyltonpop_branch(struct ir3_compile_context *ctx) 1772c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1773c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned int idx = --ctx->branch_count; 1774c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return ctx->branch[idx].instr; 1775c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1776c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1777c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1778c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_if(const struct instr_translater *t, 17793e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3_compile_context *ctx, 1780c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1781e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton{ 1782e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton struct ir3_instruction *instr, *cond; 17833e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_src_register *src = &inst->Src[0].Register; 17843e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_dst_register tmp_dst; 17853e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_src_register *tmp_src; 17863e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_src_register constval; 17873e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 1788c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou get_immediate(ctx, &constval, fui(0.0)); 1789c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp_src = get_internal_temp(ctx, &tmp_dst); 1790c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1791c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_const(src)) 1792c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src = get_unconst(ctx, src); 1793c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1794c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cmps.{f,u}.ne tmp0, b, {0.0} */ 1795c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, t->opc); 1796c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg(ctx, instr, &tmp_dst, 0); 1797c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg(ctx, instr, src, src->SwizzleX); 1798c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg(ctx, instr, &constval, constval.SwizzleX); 1799c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat2.condition = IR3_COND_NE; 1800c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1801c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, instr->regs[1]->flags & IR3_REG_SSA); /* because get_unconst() */ 1802c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou cond = instr->regs[1]->instr; 1803c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1804c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* meta:flow tmp0 */ 1805c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, -1, OPC_META_FLOW); 18063e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ir3_reg_create(instr, 0, 0); /* dummy dst */ 1807ee34ac124a92d98590d2949feaa91c99e228143cGuido van Rossum add_src_reg(ctx, instr, tmp_src, TGSI_SWIZZLE_X); 1808c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1809c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou push_branch(ctx, false, instr, cond); 1810c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->flow.if_block = push_block(ctx); 1811c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 18123e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 18133e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hyltonstatic void 18144419ac1a97d445f3fadacbf7b25c4cfc258c733bJeremy Hyltontrans_else(const struct instr_translater *t, 18153e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3_compile_context *ctx, 1816ee34ac124a92d98590d2949feaa91c99e228143cGuido van Rossum struct tgsi_full_instruction *inst) 1817c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1818c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 1819c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1820c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou pop_block(ctx); 1821c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1822c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = pop_branch(ctx); 1823c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1824c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, (instr->category == -1) && 1825c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (instr->opc == OPC_META_FLOW)); 1826c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1827c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou push_branch(ctx, true, instr, NULL); 1828c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->flow.else_block = push_block(ctx); 1829c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1830c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1831c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 1832c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroufind_temporary(struct ir3_block *block, unsigned n) 1833c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1834c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (block->parent && !block->temporaries[n]) 1835c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return find_temporary(block->parent, n); 1836c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return block->temporaries[n]; 1837c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1838c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1839c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 1840c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroufind_output(struct ir3_block *block, unsigned n) 1841c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1842c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (block->parent && !block->outputs[n]) 1843c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return find_output(block->parent, n); 1844c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return block->outputs[n]; 1845c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1846c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1847c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 1848c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucreate_phi(struct ir3_compile_context *ctx, struct ir3_instruction *cond, 1849c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *a, struct ir3_instruction *b) 1850c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1851c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *phi; 1852c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1853c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, cond); 1854c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1855c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* Either side of the condition could be null.. which 1856c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * indicates a variable written on only one side of the 1857c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * branch. Normally this should only be variables not 1858c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * used outside of that side of the branch. So we could 1859c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * just 'return a ? a : b;' in that case. But for better 1860c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * defined undefined behavior we just stick in imm{0.0}. 1861c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * In the common case of a value only used within the 1862c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * one side of the branch, the PHI instruction will not 1863c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * get scheduled 1864c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1865c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!a) 1866c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a = create_immed(ctx, 0.0); 1867c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!b) 1868c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou b = create_immed(ctx, 0.0); 1869207fda61a5ee3d4ab0bac3e9d0415c73a9d6e4d0Guido van Rossum 1870207fda61a5ee3d4ab0bac3e9d0415c73a9d6e4d0Guido van Rossum phi = instr_create(ctx, -1, OPC_META_PHI); 1871207fda61a5ee3d4ab0bac3e9d0415c73a9d6e4d0Guido van Rossum ir3_reg_create(phi, 0, 0); /* dummy dst */ 18723e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ir3_reg_create(phi, 0, IR3_REG_SSA)->instr = cond; 1873207fda61a5ee3d4ab0bac3e9d0415c73a9d6e4d0Guido van Rossum ir3_reg_create(phi, 0, IR3_REG_SSA)->instr = a; 1874c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(phi, 0, IR3_REG_SSA)->instr = b; 1875c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1876c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return phi; 1877c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1878c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1879c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1880c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_endif(const struct instr_translater *t, 1881c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1882c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 1883c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 1884c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 1885c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_block *ifb, *elseb; 1886c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction **ifout, **elseout; 1887c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned i, ifnout = 0, elsenout = 0; 1888c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1889c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou pop_block(ctx); 1890c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1891c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = pop_branch(ctx); 189234cb3f026b0be1360ae438f82faa8ade126b8debSerhiy Storchaka 1893c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, (instr->category == -1) && 1894c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (instr->opc == OPC_META_FLOW)); 1895c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1896c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ifb = instr->flow.if_block; 1897c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou elseb = instr->flow.else_block; 1898c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* if there is no else block, the parent block is used for the 1899ee34ac124a92d98590d2949feaa91c99e228143cGuido van Rossum * branch-not-taken src of the PHI instructions: 1900ee34ac124a92d98590d2949feaa91c99e228143cGuido van Rossum */ 19013e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (!elseb) 19023e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton elseb = ifb->parent; 19033e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 1904c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* worst case sizes: */ 1905c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ifnout = ifb->ntemporaries + ifb->noutputs; 1906c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou elsenout = elseb->ntemporaries + elseb->noutputs; 1907c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1908c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ifout = ir3_alloc(ctx->ir, sizeof(ifb->outputs[0]) * ifnout); 1909c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (elseb != ifb->parent) 1910c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou elseout = ir3_alloc(ctx->ir, sizeof(ifb->outputs[0]) * elsenout); 1911c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1912c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ifnout = 0; 1913c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou elsenout = 0; 1914c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1915c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* generate PHI instructions for any temporaries written: */ 1916c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < ifb->ntemporaries; i++) { 1917c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *a = ifb->temporaries[i]; 1918c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *b = elseb->temporaries[i]; 1919c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1920c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* if temporary written in if-block, or if else block 1921c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * is present and temporary written in else-block: 1922c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1923c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (a || ((elseb != ifb->parent) && b)) { 1924c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *phi; 1925c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1926c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* if only written on one side, find the closest 1927c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * enclosing update on other side: 1928c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1929c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!a) 1930c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a = find_temporary(ifb, i); 1931c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!b) 1932c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou b = find_temporary(elseb, i); 1933c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1934c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ifout[ifnout] = a; 1935c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a = create_output(ifb, a, ifnout++); 1936c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1937c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (elseb != ifb->parent) { 1938c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou elseout[elsenout] = b; 1939c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou b = create_output(elseb, b, elsenout++); 19400287f2f7cbeee90491b24f24da871c981074ac00Benjamin Peterson } 1941c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1942c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou phi = create_phi(ctx, instr, a, b); 19430287f2f7cbeee90491b24f24da871c981074ac00Benjamin Peterson ctx->block->temporaries[i] = phi; 19440287f2f7cbeee90491b24f24da871c981074ac00Benjamin Peterson } 19450287f2f7cbeee90491b24f24da871c981074ac00Benjamin Peterson } 1946c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1947c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, ifb->noutputs == elseb->noutputs); 1948c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1949c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* .. and any outputs written: */ 1950c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < ifb->noutputs; i++) { 1951c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *a = ifb->outputs[i]; 1952c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *b = elseb->outputs[i]; 1953c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1954c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* if output written in if-block, or if else block 1955e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton * is present and output written in else-block: 1956e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton */ 1957e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton if (a || ((elseb != ifb->parent) && b)) { 19583e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct ir3_instruction *phi; 1959e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton 1960c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* if only written on one side, find the closest 1961c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * enclosing update on other side: 1962c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1963c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!a) 1964c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a = find_output(ifb, i); 1965c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!b) 1966c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou b = find_output(elseb, i); 1967c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1968c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ifout[ifnout] = a; 1969c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a = create_output(ifb, a, ifnout++); 1970c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1971c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (elseb != ifb->parent) { 1972c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou elseout[elsenout] = b; 1973c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou b = create_output(elseb, b, elsenout++); 1974c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1975c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1976c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou phi = create_phi(ctx, instr, a, b); 1977c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->block->outputs[i] = phi; 1978c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1979c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1980c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1981c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ifb->noutputs = ifnout; 1982c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ifb->outputs = ifout; 1983c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1984c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (elseb != ifb->parent) { 1985c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou elseb->noutputs = elsenout; 1986c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou elseb->outputs = elseout; 1987c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 1988c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1989c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou // TODO maybe we want to compact block->inputs? 1990c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 1991c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1992c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 1993c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * Kill 1994c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 1995c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 1996c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 1997c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_kill(const struct instr_translater *t, 1998c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 1999c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 2000c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2001c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr, *immed, *cond = NULL; 2002c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bool inv = false; 2003c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2004c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (t->tgsi_opc) { 2005c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_KILL: 2006c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* unconditional kill, use enclosing if condition: */ 2007c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx->branch_count > 0) { 2008c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned int idx = ctx->branch_count - 1; 2009c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou cond = ctx->branch[idx].cond; 2010c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou inv = ctx->branch[idx].inv; 2011c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 2012c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou cond = create_immed(ctx, 1.0); 2013c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2014c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2015c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2016c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2017c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2018c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, cond); 2019c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2020c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou immed = create_immed(ctx, 0.0); 2021c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2022c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cmps.f.ne p0.x, cond, {0.0} */ 2023c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_CMPS_F); 2024c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat2.condition = IR3_COND_NE; 2025c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid(REG_P0, 0), 0); 2026c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = cond; 2027c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = immed; 2028c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou cond = instr; 2029c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2030c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* kill p0.x */ 2031c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 0, OPC_KILL); 2032c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat0.inv = inv; 2033c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, 0); /* dummy dst */ 203429906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = cond; 203529906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton 203629906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton ctx->kill[ctx->kill_count++] = instr; 20373e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton} 203829906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton 2039c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 2040c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * Kill-If 2041c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2042c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2043c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2044c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_killif(const struct instr_translater *t, 2045c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 2046c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 2047c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2048c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src = &inst->Src[0].Register; 2049c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr, *immed, *cond = NULL; 2050c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bool inv = false; 2051c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2052c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou immed = create_immed(ctx, 0.0); 2053c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2054c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cmps.f.ne p0.x, cond, {0.0} */ 2055c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_CMPS_F); 2056c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat2.condition = IR3_COND_NE; 2057c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid(REG_P0, 0), 0); 2058c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = immed; 2059c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg(ctx, instr, src, src->SwizzleX); 2060c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2061c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou cond = instr; 2062c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2063c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* kill p0.x */ 2064c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 0, OPC_KILL); 20650c0d7560987a4a9c7290f44f4a22806d9d04a4d5Benjamin Peterson instr->cat0.inv = inv; 2066c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, 0); /* dummy dst */ 20670c0d7560987a4a9c7290f44f4a22806d9d04a4d5Benjamin Peterson ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = cond; 2068c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2069c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->kill[ctx->kill_count++] = instr; 207029906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton 207129906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton} 2072220ae7c0bf2054ad01f58e1cf669ac069eb9a574Jeremy Hylton/* 20733e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * I2F / U2F / F2I / F2U 20743e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton */ 2075c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2076c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2077c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_cov(const struct instr_translater *t, 2078c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 2079c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 2080c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2081c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 2082c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 2083c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src = &inst->Src[0].Register; 2084c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2085c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou // cov.f32s32 dst, tmp0 / 2086c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 2087c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (t->tgsi_opc) { 2088c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_U2F: 2089c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = TYPE_U32; 2090c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = TYPE_F32; 2091c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2092c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_I2F: 2093c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = TYPE_S32; 2094c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = TYPE_F32; 2095c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2096c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_F2U: 2097c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = TYPE_F32; 2098c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = TYPE_U32; 2099c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2100c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_F2I: 2101c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = TYPE_F32; 2102c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = TYPE_S32; 2103c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2104c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2105c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2106c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 1, src, 0); 2107c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 2108c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2109c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2110c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 2111c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * UMUL / UMAD 2112c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2113c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * There is no 32-bit multiply instruction, so splitting a and b into high and 2114c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * low components, we get that 2115c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2116c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * dst = al * bl + ah * bl << 16 + al * bh << 16 2117c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2118c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * mull.u tmp0, a, b (mul low, i.e. al * bl) 2119c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * madsh.m16 tmp1, a, b, tmp0 (mul-add shift high mix, i.e. ah * bl << 16) 2120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * madsh.m16 dst, b, a, tmp1 (i.e. al * bh << 16) 2121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2122c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * For UMAD, replace first mull.u with mad.u16. 2123c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2124c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2125c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_umul(const struct instr_translater *t, 2126c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 2127c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 2128c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2129c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 2130c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 2131c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *a = &inst->Src[0].Register; 2132c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *b = &inst->Src[1].Register; 2133c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2134c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register tmp0_dst, tmp1_dst; 2135c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *tmp0_src, *tmp1_src; 2136c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2137c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp0_src = get_internal_temp(ctx, &tmp0_dst); 2138c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tmp1_src = get_internal_temp(ctx, &tmp1_dst); 2139c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2140c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_rel_or_const(a)) 2141c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a = get_unconst(ctx, a); 2142c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_rel_or_const(b)) 2143c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou b = get_unconst(ctx, b); 2144c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2145c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (t->tgsi_opc == TGSI_OPCODE_UMUL) { 2146c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mull.u tmp0, a, b */ 2147c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MULL_U); 2148c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &tmp0_dst, 2, a, 0, b, 0); 2149c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 2150c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *c = &inst->Src[2].Register; 2151c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2152c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mad.u16 tmp0, a, b, c */ 2153c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_MAD_U16); 2154c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &tmp0_dst, 3, a, 0, b, 0, c, 0); 2155c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2156c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2157c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* madsh.m16 tmp1, a, b, tmp0 */ 2158c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_MADSH_M16); 2159c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &tmp1_dst, 3, a, 0, b, 0, tmp0_src, 0); 2160c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2161c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* madsh.m16 dst, b, a, tmp1 */ 2162c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_MADSH_M16); 2163c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 3, b, 0, a, 0, tmp1_src, 0); 2164c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 2165c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 2168c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * IDIV / UDIV / MOD / UMOD 2169c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2170c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * See NV50LegalizeSSA::handleDIV for the origin of this implementation. For 2171c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * MOD/UMOD, it becomes a - [IU]DIV(a, modulus) * modulus. 2172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2173c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2174c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroutrans_idiv(const struct instr_translater *t, 2175c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 2176c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 2177c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2178c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 2179c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst), *premod_dst = dst; 2180c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *a = &inst->Src[0].Register; 2181c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *b = &inst->Src[1].Register; 2182c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2183c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register af_dst, bf_dst, q_dst, r_dst, a_dst, b_dst; 2184c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *af_src, *bf_src, *q_src, *r_src, *a_src, *b_src; 2185c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2186220ae7c0bf2054ad01f58e1cf669ac069eb9a574Jeremy Hylton struct tgsi_src_register negative_2, thirty_one; 2187220ae7c0bf2054ad01f58e1cf669ac069eb9a574Jeremy Hylton type_t src_type; 218829906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton 21893e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (t->tgsi_opc == TGSI_OPCODE_IDIV || t->tgsi_opc == TGSI_OPCODE_MOD) 21903e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton src_type = get_stype(ctx); 2191c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou else 2192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src_type = get_utype(ctx); 2193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou af_src = get_internal_temp(ctx, &af_dst); 2195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bf_src = get_internal_temp(ctx, &bf_dst); 2196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou q_src = get_internal_temp(ctx, &q_dst); 2197c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou r_src = get_internal_temp(ctx, &r_dst); 2198c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a_src = get_internal_temp(ctx, &a_dst); 2199c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou b_src = get_internal_temp(ctx, &b_dst); 2200c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2201c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou get_immediate(ctx, &negative_2, -2); 2202c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou get_immediate(ctx, &thirty_one, 31); 2203c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (t->tgsi_opc == TGSI_OPCODE_MOD || t->tgsi_opc == TGSI_OPCODE_UMOD) 220529906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton premod_dst = &q_dst; 220629906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton 220729906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton /* cov.[us]32f32 af, numerator */ 22083e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr = instr_create(ctx, 1, 0); 22093e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr->cat1.src_type = src_type; 2210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = get_ftype(ctx); 2211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &af_dst, 1, a, 0); 2212c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2213c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cov.[us]32f32 bf, denominator */ 2214c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 2215c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = src_type; 2216c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = get_ftype(ctx); 2217c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &bf_dst, 1, b, 0); 2218c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2219c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* Get the absolute values for IDIV */ 2220c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (type_sint(src_type)) { 2221c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* absneg.f af, (abs)af */ 2222c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ABSNEG_F); 2223c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &af_dst, 1, af_src, IR3_REG_ABS); 2224c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2225c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* absneg.f bf, (abs)bf */ 2226c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ABSNEG_F); 2227c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &bf_dst, 1, bf_src, IR3_REG_ABS); 2228c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* absneg.s a, (abs)numerator */ 2230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ABSNEG_S); 2231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &a_dst, 1, a, IR3_REG_ABS); 2232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2233c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* absneg.s b, (abs)denominator */ 2234c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ABSNEG_S); 2235c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &b_dst, 1, b, IR3_REG_ABS); 2236c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 2237c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mov.u32u32 a, numerator */ 2238c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 2239c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = src_type; 2240c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = src_type; 2241c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &a_dst, 1, a, 0); 2242c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 22434419ac1a97d445f3fadacbf7b25c4cfc258c733bJeremy Hylton /* mov.u32u32 b, denominator */ 22444419ac1a97d445f3fadacbf7b25c4cfc258c733bJeremy Hylton instr = instr_create(ctx, 1, 0); 22454419ac1a97d445f3fadacbf7b25c4cfc258c733bJeremy Hylton instr->cat1.src_type = src_type; 22463e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr->cat1.dst_type = src_type; 22473e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton vectorize(ctx, instr, &b_dst, 1, b, 0); 2248c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2249c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2250c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* rcp.f bf, bf */ 2251c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 4, OPC_RCP); 2252c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &bf_dst, 1, bf_src, 0); 2253c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2254c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* That's right, subtract 2 as an integer from the float */ 2255c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* add.u bf, bf, -2 */ 2256c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ADD_U); 2257c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &bf_dst, 2, bf_src, 0, &negative_2, 0); 2258c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2259c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mul.f q, af, bf */ 2260c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MUL_F); 2261c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &q_dst, 2, af_src, 0, bf_src, 0); 2262c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2263c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cov.f32[us]32 q, q */ 2264c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 2265c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = get_ftype(ctx); 2266c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = src_type; 2267c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &q_dst, 1, q_src, 0); 2268c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2269c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* integer multiply q by b */ 2270c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mull.u r, q, b */ 2271c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MULL_U); 227229906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton vectorize(ctx, instr, &r_dst, 2, q_src, 0, b_src, 0); 227329906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton 227429906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton /* madsh.m16 r, q, b, r */ 22753e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr = instr_create(ctx, 3, OPC_MADSH_M16); 22763e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton vectorize(ctx, instr, &r_dst, 3, q_src, 0, b_src, 0, r_src, 0); 2277c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2278c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* madsh.m16, r, b, q, r */ 2279c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_MADSH_M16); 2280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 3, b_src, 0, q_src, 0, r_src, 0); 2281c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2282c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* sub.u r, a, r */ 2283c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_SUB_U); 2284c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 2, a_src, 0, r_src, 0); 2285c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2286c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cov.u32f32, r, r */ 2287c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 2288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = get_utype(ctx); 2289c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = get_ftype(ctx); 2290c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 1, r_src, 0); 2291c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2292c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mul.f r, r, bf */ 2293c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MUL_F); 2294c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 2, r_src, 0, bf_src, 0); 2295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2296c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cov.f32u32 r, r */ 2297c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 2298c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = get_ftype(ctx); 2299c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = get_utype(ctx); 2300c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 1, r_src, 0); 2301c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2302c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* add.u q, q, r */ 2303c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ADD_U); 2304c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &q_dst, 2, q_src, 0, r_src, 0); 2305c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2306c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mull.u r, q, b */ 2307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MULL_U); 2308c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 2, q_src, 0, b_src, 0); 2309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 23109832613beba817aa3d6abfde85eba40a9173fcdcJeremy Hylton /* madsh.m16 r, q, b, r */ 23119832613beba817aa3d6abfde85eba40a9173fcdcJeremy Hylton instr = instr_create(ctx, 3, OPC_MADSH_M16); 23129832613beba817aa3d6abfde85eba40a9173fcdcJeremy Hylton vectorize(ctx, instr, &r_dst, 3, q_src, 0, b_src, 0, r_src, 0); 23133e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 231429906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton /* madsh.m16 r, b, q, r */ 2315c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_MADSH_M16); 2316c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 3, b_src, 0, q_src, 0, r_src, 0); 2317c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2318c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* sub.u r, a, r */ 2319c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_SUB_U); 2320c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 2, a_src, 0, r_src, 0); 2321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* cmps.u.ge r, r, b */ 2323c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_CMPS_U); 2324c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat2.condition = IR3_COND_GE; 2325c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 2, r_src, 0, b_src, 0); 2326c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2327c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (type_uint(src_type)) { 2328c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* add.u dst, q, r */ 2329c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ADD_U); 2330c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, premod_dst, 2, q_src, 0, r_src, 0); 2331c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 2332c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* add.u q, q, r */ 2333c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ADD_U); 2334c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &q_dst, 2, q_src, 0, r_src, 0); 2335c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2336c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* negate result based on the original arguments */ 2337c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_const(a) && is_const(b)) 2338c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou a = get_unconst(ctx, a); 2339c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2340c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* xor.b r, numerator, denominator */ 2341c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_XOR_B); 2342c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 2, a, 0, b, 0); 2343c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2344c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* shr.b r, r, 31 */ 2345c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_SHR_B); 2346c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 2, r_src, 0, &thirty_one, 0); 2347c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2348c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* absneg.s b, (neg)q */ 2349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ABSNEG_S); 2350c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &b_dst, 1, q_src, IR3_REG_NEGATE); 2351c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2352c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* sel.b dst, b, r, q */ 2353c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_SEL_B32); 2354c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, premod_dst, 3, b_src, 0, r_src, 0, q_src, 0); 2355c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2356c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2357c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (t->tgsi_opc == TGSI_OPCODE_MOD || t->tgsi_opc == TGSI_OPCODE_UMOD) { 2358c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* The division result will have ended up in q. */ 2359c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2360c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mull.u r, q, b */ 2361c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MULL_U); 2362c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 2, q_src, 0, b, 0); 2363c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2364c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* madsh.m16 r, q, b, r */ 2365c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_MADSH_M16); 2366c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 3, q_src, 0, b, 0, r_src, 0); 2367c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2368c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* madsh.m16 r, b, q, r */ 2369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, OPC_MADSH_M16); 2370c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, &r_dst, 3, b, 0, q_src, 0, r_src, 0); 2371c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2372c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* sub.u dst, a, r */ 2373c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_SUB_U); 2374c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 2, a, 0, r_src, 0); 2375c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2376c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2377c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 2378c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2379c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2380c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* 2381c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * Handlers for TGSI instructions which do have 1:1 mapping to native 2382c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * instructions: 2383c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2384c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2385c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2386c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouinstr_cat0(const struct instr_translater *t, 2387c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 2388c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 2389c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2390c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr_create(ctx, 0, t->opc); 2391c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2392c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2393c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2394c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouinstr_cat1(const struct instr_translater *t, 2395c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 2396c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 2397c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2398c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 2399c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src = &inst->Src[0].Register; 2400c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou create_mov(ctx, dst, src); 2401c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 2402c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2403c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2404c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2405c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouinstr_cat2(const struct instr_translater *t, 2406c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context *ctx, 2407c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst) 2408c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2409c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 2410c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src0 = &inst->Src[0].Register; 2411c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src1 = &inst->Src[1].Register; 2412c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 2413c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned src0_flags = 0, src1_flags = 0; 2414c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (t->tgsi_opc) { 2416c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_ABS: 2417c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_IABS: 2418c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src0_flags = IR3_REG_ABS; 2419c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2420c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_INEG: 2421c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src0_flags = IR3_REG_NEGATE; 2422c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2423c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_OPCODE_SUB: 2424c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src1_flags = IR3_REG_NEGATE; 2425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2427c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2428c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (t->opc) { 2429c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_ABSNEG_F: 2430c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_ABSNEG_S: 2431c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_CLZ_B: 2432c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_CLZ_S: 2433c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_SIGN_F: 2434c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_FLOOR_F: 2435e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton case OPC_CEIL_F: 2436e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton case OPC_RNDNE_F: 2437e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton case OPC_RNDAZ_F: 24383e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case OPC_TRUNC_F: 243964949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton case OPC_NOT_B: 2440c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_BFREV_B: 2441c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_SETRM: 2442c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case OPC_CBITS_B: 2443c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* these only have one src reg */ 2444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, t->opc); 2445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 1, src0, src0_flags); 2446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou default: 2448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_const(src0) && is_const(src1)) 2449c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src0 = get_unconst(ctx, src0); 2450c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2451c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, t->opc); 2452c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 2, src0, src0_flags, 2453c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src1, src1_flags); 2454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2456c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2457c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 2458c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2459c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2460c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2461c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouinstr_cat3(const struct instr_translater *t, 246264949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton struct ir3_compile_context *ctx, 246364949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton struct tgsi_full_instruction *inst) 246464949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton{ 24653e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_dst_register *dst = get_dst(ctx, inst); 2466e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton struct tgsi_src_register *src0 = &inst->Src[0].Register; 2467c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src1 = &inst->Src[1].Register; 2468c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 2469c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2470c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* in particular, can't handle const for src1 for cat3.. 2471c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * for mad, we can swap first two src's if needed: 2472c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2473c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_rel_or_const(src1)) { 2474c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_mad(t->opc) && !is_rel_or_const(src0)) { 2475c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *tmp; 247664949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton tmp = src0; 247764949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton src0 = src1; 247864949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton src1 = tmp; 24793e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } else { 248064949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton src1 = get_unconst(ctx, src1); 2481c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2482c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2483c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2484c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 3, t->opc); 2485c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou vectorize(ctx, instr, dst, 3, src0, 0, src1, 0, 2486c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou &inst->Src[2].Register, 0); 2487c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 2488c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2489c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 249064949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hyltonstatic void 249164949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hyltoninstr_cat4(const struct instr_translater *t, 249264949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton struct ir3_compile_context *ctx, 24933e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton struct tgsi_full_instruction *inst) 24943e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton{ 2495c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_dst_register *dst = get_dst(ctx, inst); 2496c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_src_register *src = &inst->Src[0].Register; 2497c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 2498c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned i; 2499c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2500c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* seems like blob compiler avoids const as src.. */ 2501c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (is_const(src)) 2502c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src = get_unconst(ctx, src); 2503c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2504c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* we need to replicate into each component: */ 2505c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < 4; i++) { 2506c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (dst->WriteMask & (1 << i)) { 2507c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 4, t->opc); 2508c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_dst_reg(ctx, instr, dst, i); 2509c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou add_src_reg(ctx, instr, src, src->SwizzleX); 2510c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2511c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2512c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2513c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou put_dst(ctx, inst, dst); 2514c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2515c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2516c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic const struct instr_translater translaters[TGSI_OPCODE_LAST] = { 2517c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define INSTR(n, f, ...) \ 2518c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou [TGSI_OPCODE_ ## n] = { .fxn = (f), .tgsi_opc = TGSI_OPCODE_ ## n, ##__VA_ARGS__ } 2519c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2520c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(MOV, instr_cat1), 2521c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(RCP, instr_cat4, .opc = OPC_RCP), 2522c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(RSQ, instr_cat4, .opc = OPC_RSQ), 2523c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SQRT, instr_cat4, .opc = OPC_SQRT), 2524c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(MUL, instr_cat2, .opc = OPC_MUL_F), 2525c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ADD, instr_cat2, .opc = OPC_ADD_F), 2526c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SUB, instr_cat2, .opc = OPC_ADD_F), 2527c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(MIN, instr_cat2, .opc = OPC_MIN_F), 2528c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(MAX, instr_cat2, .opc = OPC_MAX_F), 2529c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(UADD, instr_cat2, .opc = OPC_ADD_U), 2530c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(IMIN, instr_cat2, .opc = OPC_MIN_S), 2531c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(UMIN, instr_cat2, .opc = OPC_MIN_U), 2532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(IMAX, instr_cat2, .opc = OPC_MAX_S), 2533c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(UMAX, instr_cat2, .opc = OPC_MAX_U), 2534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(AND, instr_cat2, .opc = OPC_AND_B), 253564949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton INSTR(OR, instr_cat2, .opc = OPC_OR_B), 253664949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton INSTR(NOT, instr_cat2, .opc = OPC_NOT_B), 25373e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton INSTR(XOR, instr_cat2, .opc = OPC_XOR_B), 25383e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton INSTR(UMUL, trans_umul), 253964949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton INSTR(UMAD, trans_umul), 2540c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(UDIV, trans_idiv), 2541c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(IDIV, trans_idiv), 2542c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(MOD, trans_idiv), 2543c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(UMOD, trans_idiv), 2544c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SHL, instr_cat2, .opc = OPC_SHL_B), 2545c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(USHR, instr_cat2, .opc = OPC_SHR_B), 2546c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ISHR, instr_cat2, .opc = OPC_ASHR_B), 2547c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(IABS, instr_cat2, .opc = OPC_ABSNEG_S), 2548c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(INEG, instr_cat2, .opc = OPC_ABSNEG_S), 2549c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(AND, instr_cat2, .opc = OPC_AND_B), 2550c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(MAD, instr_cat3, .opc = OPC_MAD_F32, .hopc = OPC_MAD_F16), 2551c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TRUNC, instr_cat2, .opc = OPC_TRUNC_F), 2552c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(CLAMP, trans_clamp), 2553c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(FLR, instr_cat2, .opc = OPC_FLOOR_F), 2554c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ROUND, instr_cat2, .opc = OPC_RNDNE_F), 2555c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SSG, instr_cat2, .opc = OPC_SIGN_F), 2556c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(CEIL, instr_cat2, .opc = OPC_CEIL_F), 2557c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ARL, trans_arl), 2558c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(UARL, trans_arl), 2559c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(EX2, instr_cat4, .opc = OPC_EXP2), 2560c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(LG2, instr_cat4, .opc = OPC_LOG2), 2561c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ABS, instr_cat2, .opc = OPC_ABSNEG_F), 2562c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(COS, instr_cat4, .opc = OPC_COS), 2563c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SIN, instr_cat4, .opc = OPC_SIN), 2564c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TEX, trans_samp, .opc = OPC_SAM, .arg = TGSI_OPCODE_TEX), 2565c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TXP, trans_samp, .opc = OPC_SAM, .arg = TGSI_OPCODE_TXP), 2566c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TXB, trans_samp, .opc = OPC_SAMB, .arg = TGSI_OPCODE_TXB), 2567c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TXB2, trans_samp, .opc = OPC_SAMB, .arg = TGSI_OPCODE_TXB2), 2568c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TXL, trans_samp, .opc = OPC_SAML, .arg = TGSI_OPCODE_TXL), 2569c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TXD, trans_samp, .opc = OPC_SAMGQ, .arg = TGSI_OPCODE_TXD), 2570c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TXF, trans_samp, .opc = OPC_ISAML, .arg = TGSI_OPCODE_TXF), 2571c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(TXQ, trans_txq), 2572e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton INSTR(DDX, trans_deriv, .opc = OPC_DSX), 2573e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton INSTR(DDY, trans_deriv, .opc = OPC_DSY), 2574e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton INSTR(SGT, trans_cmp), 2575d0c3515bc5b31a19d00bfc685d7657ad7d79fa94Antoine Pitrou INSTR(SLT, trans_cmp), 2576c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(FSLT, trans_cmp), 2577c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SGE, trans_cmp), 2578c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(FSGE, trans_cmp), 2579c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SLE, trans_cmp), 2580c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SNE, trans_cmp), 2581c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(FSNE, trans_cmp), 2582c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(SEQ, trans_cmp), 2583c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(FSEQ, trans_cmp), 2584c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(CMP, trans_cmp), 2585c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(USNE, trans_icmp, .opc = OPC_CMPS_U), 2586c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(USEQ, trans_icmp, .opc = OPC_CMPS_U), 2587c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ISGE, trans_icmp, .opc = OPC_CMPS_S), 2588c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(USGE, trans_icmp, .opc = OPC_CMPS_U), 2589c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ISLT, trans_icmp, .opc = OPC_CMPS_S), 2590c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(USLT, trans_icmp, .opc = OPC_CMPS_U), 2591c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(UCMP, trans_ucmp), 2592c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ISSG, trans_issg), 2593c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(IF, trans_if, .opc = OPC_CMPS_F), 2594c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(UIF, trans_if, .opc = OPC_CMPS_U), 2595c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ELSE, trans_else), 2596c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(ENDIF, trans_endif), 2597c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(END, instr_cat0, .opc = OPC_END), 2598c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(KILL, trans_kill, .opc = OPC_KILL), 2599c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(KILL_IF, trans_killif, .opc = OPC_KILL), 2600c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(I2F, trans_cov), 2601c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(U2F, trans_cov), 2602c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(F2I, trans_cov), 2603c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou INSTR(F2U, trans_cov), 2604c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou}; 2605c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2606c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic ir3_semantic 2607c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroudecl_semantic(const struct tgsi_declaration_semantic *sem) 2608c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2609c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return ir3_semantic_name(sem->Name, sem->Index); 2610c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2611c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2612c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 2613c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroudecl_in_frag_bary(struct ir3_compile_context *ctx, unsigned regid, 2614c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned j, unsigned inloc) 2615c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2616c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 2617c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_register *src; 2618c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2619c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* bary.f dst, #inloc, r0.x */ 2620c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_BARY_F); 2621c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid, 0); /* dummy dst */ 2622c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = inloc; 2623c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src = ir3_reg_create(instr, 0, IR3_REG_SSA); 2624c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->wrmask = 0x3; 2625c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src->instr = ctx->frag_pos; 2626c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 262729906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton return instr; 262829906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton} 262929906eef3a56c43a4cd68a8706c75844b2384e59Jeremy Hylton 26303e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton/* TGSI_SEMANTIC_POSITION 26313e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton * """""""""""""""""""""" 2632c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2633c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * For fragment shaders, TGSI_SEMANTIC_POSITION is used to indicate that 2634c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * fragment shader input contains the fragment's window position. The X 2635c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * component starts at zero and always increases from left to right. 263664949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton * The Y component starts at zero and always increases but Y=0 may either 263764949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton * indicate the top of the window or the bottom depending on the fragment 2638b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti * coordinate origin convention (see TGSI_PROPERTY_FS_COORD_ORIGIN). 2639b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti * The Z coordinate ranges from 0 to 1 to represent depth from the front 2640b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti * to the back of the Z buffer. The W component contains the reciprocol 2641b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti * of the interpolated vertex position W component. 2642b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti */ 2643b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalottistatic struct ir3_instruction * 2644b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalottidecl_in_frag_coord(struct ir3_compile_context *ctx, unsigned regid, 2645b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti unsigned j) 2646b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti{ 2647b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti struct ir3_instruction *instr, *src; 2648b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti 2649b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti compile_assert(ctx, !ctx->frag_coord[j]); 2650b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti 2651b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti ctx->frag_coord[j] = create_input(ctx->block, NULL, 0); 2652b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti 265364949cb753f206c0ca1d83f55d07afd3c179b81aJeremy Hylton 2654c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (j) { 2655c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 0: /* .x */ 2656c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 1: /* .y */ 2657c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* for frag_coord, we get unsigned values.. we need 2658c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * to subtract (integer) 8 and divide by 16 (right- 2659c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * shift by 4) then convert to float: 2660c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2661c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2662c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* add.s tmp, src, -8 */ 2663c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ADD_S); 2664c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid, 0); /* dummy dst */ 2665c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = ctx->frag_coord[j]; 2666c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = -8; 2667c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src = instr; 2668c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2669c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* shr.b tmp, tmp, 4 */ 2670c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_SHR_B); 2671c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid, 0); /* dummy dst */ 2672c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src; 2673c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 4; 2674c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src = instr; 2675c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2676c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* mov.u32f32 dst, tmp */ 2677c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); 2678c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = TYPE_U32; 2679c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = TYPE_F32; 2680c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid, 0); /* dummy dst */ 2681c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src; 2682c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2683c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2684c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 2: /* .z */ 2685c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 3: /* .w */ 2686c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* seems that we can use these as-is: */ 2687c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = ctx->frag_coord[j]; 2688c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2689c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou default: 2690c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_error(ctx, "invalid channel\n"); 2691c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = create_immed(ctx, 0.0); 2692c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2693c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2694c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2695c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return instr; 2696c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2697c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2698c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou/* TGSI_SEMANTIC_FACE 2699c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * """""""""""""""""" 2700c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2701c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * This label applies to fragment shader inputs only and indicates that 2702c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * the register contains front/back-face information of the form (F, 0, 2703c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 0, 1). The first component will be positive when the fragment belongs 2704c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * to a front-facing polygon, and negative when the fragment belongs to a 2705c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * back-facing polygon. 2706c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2707c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic struct ir3_instruction * 2708c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroudecl_in_frag_face(struct ir3_compile_context *ctx, unsigned regid, 2709c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned j) 2710c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2711c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr, *src; 2712c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2713c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (j) { 2714c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 0: /* .x */ 2715c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, !ctx->frag_face); 2716c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2717c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->frag_face = create_input(ctx->block, NULL, 0); 2718c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2719c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* for faceness, we always get -1 or 0 (int).. but TGSI expects 2720c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * positive vs negative float.. and piglit further seems to 2721c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * expect -1.0 or 1.0: 2722c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2723c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * mul.s tmp, hr0.x, 2 2724c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * add.s tmp, tmp, 1 2725c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * mov.s16f32, dst, tmp 2726c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * 2727c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2728c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2729c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_MUL_S); 2730c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid, 0); /* dummy dst */ 2731c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = ctx->frag_face; 2732c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 2; 2733c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou src = instr; 2734c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2735c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 2, OPC_ADD_S); 2736c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid, 0); /* dummy dst */ 27373e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src; 2738e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 1; 2739b6c3ceae79f193e4361651fea61dfb2528bc2746Tim Peters src = instr; 2740b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti 2741c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = instr_create(ctx, 1, 0); /* mov */ 2742c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.src_type = TYPE_S32; 2743c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->cat1.dst_type = TYPE_F32; 2744c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, regid, 0); /* dummy dst */ 2745c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src; 2746c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2747c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2748c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 1: /* .y */ 2749c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 2: /* .z */ 2750c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = create_immed(ctx, 0.0); 2751c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2752c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case 3: /* .w */ 2753c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = create_immed(ctx, 1.0); 2754c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2755c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou default: 2756c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_error(ctx, "invalid channel\n"); 2757c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = create_immed(ctx, 0.0); 2758c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2759c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2760c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2761c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return instr; 2762c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2763c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2764c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2765c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroudecl_in(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl) 2766c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2767c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_shader_variant *so = ctx->so; 2768c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned name = decl->Semantic.Name; 2769c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned i; 2770c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2771c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* I don't think we should get frag shader input without 2772c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * semantic info? Otherwise how do inputs get linked to 2773c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * vert outputs? 2774c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2775c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, (ctx->type == TGSI_PROCESSOR_VERTEX) || 2776c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou decl->Declaration.Semantic); 2777c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2778c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = decl->Range.First; i <= decl->Range.Last; i++) { 2779c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned n = so->inputs_count++; 2780c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned r = regid(i, 0); 2781c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned ncomp, j; 2782c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2783c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* we'll figure out the actual components used after scheduling */ 2784c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ncomp = 4; 2785c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2786c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou DBG("decl in -> r%d", i); 2787c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2788c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, n < ARRAY_SIZE(so->inputs)); 2789c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2790c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[n].semantic = decl_semantic(&decl->Semantic); 2791b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti so->inputs[n].compmask = (1 << ncomp) - 1; 2792c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[n].regid = r; 2793b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti so->inputs[n].inloc = ctx->next_inloc; 2794c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[n].interpolate = decl->Interp.Interpolate; 2795c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2796b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti for (j = 0; j < ncomp; j++) { 2797b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti struct ir3_instruction *instr = NULL; 2798b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti 2799b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti if (ctx->type == TGSI_PROCESSOR_FRAGMENT) { 2800b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti /* for fragment shaders, POSITION and FACE are handled 2801c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * specially, not using normal varying / bary.f 2802c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2803c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (name == TGSI_SEMANTIC_POSITION) { 2804c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[n].bary = false; 2805c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->frag_coord = true; 2806c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = decl_in_frag_coord(ctx, r + j, j); 2807c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else if (name == TGSI_SEMANTIC_FACE) { 2808c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[n].bary = false; 2809c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->frag_face = true; 2810c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = decl_in_frag_face(ctx, r + j, j); 2811b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti } else { 2812b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti so->inputs[n].bary = true; 2813b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti instr = decl_in_frag_bary(ctx, r + j, j, 2814b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti so->inputs[n].inloc + j - 8); 2815b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti } 2816c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 2817c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = create_input(ctx->block, NULL, (i * 4) + j); 2818c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2819c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2820c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->block->inputs[(i * 4) + j] = instr; 2821c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2822c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2823c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (so->inputs[n].bary || (ctx->type == TGSI_PROCESSOR_VERTEX)) { 2824c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->next_inloc += ncomp; 2825c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->total_in += ncomp; 2826b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti } 2827b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti } 2828b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti} 2829b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalotti 2830b646547bb45fe1df6abefd94f892c633798d91d2Alexandre Vassalottistatic void 2831c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroudecl_out(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl) 2832c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2833c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_shader_variant *so = ctx->so; 2834c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned comp = 0; 2835c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned name = decl->Semantic.Name; 2836c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned i; 2837c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2838c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, decl->Declaration.Semantic); 2839c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2840c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou DBG("decl out[%d] -> r%d", name, decl->Range.First); 28413e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 2842b6c3ceae79f193e4361651fea61dfb2528bc2746Tim Peters if (ctx->type == TGSI_PROCESSOR_VERTEX) { 28433e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton switch (name) { 28443e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case TGSI_SEMANTIC_POSITION: 2845e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton so->writes_pos = true; 2846c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2847c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_SEMANTIC_PSIZE: 2848c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->writes_psize = true; 28493e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton break; 2850e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton case TGSI_SEMANTIC_COLOR: 2851c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_SEMANTIC_BCOLOR: 28523e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case TGSI_SEMANTIC_GENERIC: 28533e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case TGSI_SEMANTIC_FOG: 28543e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton case TGSI_SEMANTIC_TEXCOORD: 28553e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton break; 2856483638c9a865d504b1131c098f010590103415ddJeremy Hylton default: 28573e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton compile_error(ctx, "unknown VS semantic name: %s\n", 28583e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton tgsi_semantic_names[name]); 28593e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 2860c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 2861c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (name) { 2862c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_SEMANTIC_POSITION: 2863c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou comp = 2; /* tgsi will write to .z component */ 2864c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->writes_pos = true; 2865c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2866c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_SEMANTIC_COLOR: 2867c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2868c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou default: 2869c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_error(ctx, "unknown FS semantic name: %s\n", 2870c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tgsi_semantic_names[name]); 2871c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2872c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2873c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2874c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = decl->Range.First; i <= decl->Range.Last; i++) { 28753e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton unsigned n = so->outputs_count++; 28763e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton unsigned ncomp, j; 2877c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 2878c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ncomp = 4; 2879c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 2880c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, n < ARRAY_SIZE(so->outputs)); 2881c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 2882c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum so->outputs[n].semantic = decl_semantic(&decl->Semantic); 2883c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum so->outputs[n].regid = regid(i, comp); 2884c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2885c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum /* avoid undefined outputs, stick a dummy mov from imm{0.0}, 2886c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * which if the output is actually assigned will be over- 2887da5b701aeef755f2317a41e36cc950cfdc0c95cbGuido van Rossum * written 2888c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum */ 2889c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum for (j = 0; j < ncomp; j++) 2890c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->block->outputs[(i * 4) + j] = create_immed(ctx, 0.0); 2891c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum } 2892c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum} 2893c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 2894c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum/* from TGSI perspective, we actually have inputs. But most of the "inputs" 2895f0aa88f6e856710c4cf5bdb23a81817a841c4553Serhiy Storchaka * for a fragment shader are just bary.f instructions. The *actual* inputs 2896c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum * from the hw perspective are the frag_pos and optionally frag_coord and 2897f0aa88f6e856710c4cf5bdb23a81817a841c4553Serhiy Storchaka * frag_face. 2898c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum */ 2899c2e20744b2b7811632030470971c31630f0975e2Guido van Rossumstatic void 2900c2e20744b2b7811632030470971c31630f0975e2Guido van Rossumfixup_frag_inputs(struct ir3_compile_context *ctx) 2901c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum{ 2902c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum struct ir3_shader_variant *so = ctx->so; 2903c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum struct ir3_block *block = ctx->block; 2904c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum struct ir3_instruction **inputs; 2905c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum struct ir3_instruction *instr; 2906c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum int n, regid = 0; 2907c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 2908c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum block->ninputs = 0; 2909c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 2910a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou n = 4; /* always have frag_pos */ 2911c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum n += COND(so->frag_face, 4); 2912da5b701aeef755f2317a41e36cc950cfdc0c95cbGuido van Rossum n += COND(so->frag_coord, 4); 2913c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 29141880d8b8231d0085700d5d3c03ee9b16c619720dBenjamin Peterson inputs = ir3_alloc(ctx->ir, n * (sizeof(struct ir3_instruction *))); 2915c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 29161880d8b8231d0085700d5d3c03ee9b16c619720dBenjamin Peterson if (so->frag_face) { 2917c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum /* this ultimately gets assigned to hr0.x so doesn't conflict 2918565d78586babda2b62cbe4f89c2dd3cace79c0faBenjamin Peterson * with frag_coord/frag_pos.. 2919565d78586babda2b62cbe4f89c2dd3cace79c0faBenjamin Peterson */ 2920565d78586babda2b62cbe4f89c2dd3cace79c0faBenjamin Peterson inputs[block->ninputs++] = ctx->frag_face; 2921c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->frag_face->regs[0]->num = 0; 2922a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou 2923c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum /* remaining channels not used, but let's avoid confusing 2924c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum * other parts that expect inputs to come in groups of vec4 2925c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum */ 2926a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou inputs[block->ninputs++] = NULL; 29271880d8b8231d0085700d5d3c03ee9b16c619720dBenjamin Peterson inputs[block->ninputs++] = NULL; 29281880d8b8231d0085700d5d3c03ee9b16c619720dBenjamin Peterson inputs[block->ninputs++] = NULL; 2929c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2930a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou 2931c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum /* since we don't know where to set the regid for frag_coord, 2932c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum * we have to use r0.x for it. But we don't want to *always* 2933c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum * use r1.x for frag_pos as that could increase the register 29342c33fc77feedd3766f8e732b2e1879d03420aad3Anthony Baxter * footprint on simple shaders: 2935c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum */ 2936c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum if (so->frag_coord) { 2937c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->frag_coord[0]->regs[0]->num = regid++; 2938c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->frag_coord[1]->regs[0]->num = regid++; 2939c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->frag_coord[2]->regs[0]->num = regid++; 2940c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->frag_coord[3]->regs[0]->num = regid++; 2941c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 2942c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum inputs[block->ninputs++] = ctx->frag_coord[0]; 2943a4d36a9572b283166ebcd152446c707ca08fc681Antoine Pitrou inputs[block->ninputs++] = ctx->frag_coord[1]; 2944c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum inputs[block->ninputs++] = ctx->frag_coord[2]; 29457af53be66f8c074902e0e7e7c452a280538582bcNick Coghlan inputs[block->ninputs++] = ctx->frag_coord[3]; 29467af53be66f8c074902e0e7e7c452a280538582bcNick Coghlan } 29477af53be66f8c074902e0e7e7c452a280538582bcNick Coghlan 2948c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum /* we always have frag_pos: */ 2949c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum so->pos_regid = regid; 2950c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum 2951c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum /* r0.x */ 2952c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum instr = create_input(block, NULL, block->ninputs); 2953c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum instr->regs[0]->num = regid++; 2954c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum inputs[block->ninputs++] = instr; 2955c2e20744b2b7811632030470971c31630f0975e2Guido van Rossum ctx->frag_pos->regs[1]->instr = instr; 29563e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 29573e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton /* r0.y */ 29583e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton instr = create_input(block, NULL, block->ninputs); 2959c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr->regs[0]->num = regid++; 2960c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou inputs[block->ninputs++] = instr; 2961c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->frag_pos->regs[2]->instr = instr; 2962c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2963c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->inputs = inputs; 2964c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 2965c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2966c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 2967c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucompile_instructions(struct ir3_compile_context *ctx) 2968c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 2969c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou push_block(ctx); 2970c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2971c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* for fragment shader, we have a single input register (usually 2972c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * r0.xy) which is used as the base for bary.f varying fetch instrs: 2973c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 2974c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx->type == TGSI_PROCESSOR_FRAGMENT) { 2975c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *instr; 2976c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr = ir3_instr_create(ctx->block, -1, OPC_META_FI); 2977c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, 0); 2978c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA); /* r0.x */ 2979c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_reg_create(instr, 0, IR3_REG_SSA); /* r0.y */ 2980c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->frag_pos = instr; 2981c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2982c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2983c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou while (!tgsi_parse_end_of_tokens(&ctx->parser)) { 2984c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tgsi_parse_token(&ctx->parser); 2985c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 2986c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (ctx->parser.FullToken.Token.Type) { 2987c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_TOKEN_TYPE_DECLARATION: { 2988c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_declaration *decl = 2989c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou &ctx->parser.FullToken.FullDeclaration; 2990c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (decl->Declaration.File == TGSI_FILE_OUTPUT) { 2991c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou decl_out(ctx, decl); 2992c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else if (decl->Declaration.File == TGSI_FILE_INPUT) { 2993c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou decl_in(ctx, decl); 2994c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2995c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 2996c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 2997c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_TOKEN_TYPE_IMMEDIATE: { 2998c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* TODO: if we know the immediate is small enough, and only 2999c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * used with instructions that can embed an immediate, we 3000c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * can skip this: 3001c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 3002c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_immediate *imm = 3003c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou &ctx->parser.FullToken.FullImmediate; 3004c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned n = ctx->so->immediates_count++; 3005c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, n < ARRAY_SIZE(ctx->so->immediates)); 3006c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou memcpy(ctx->so->immediates[n].val, imm->u, 16); 3007c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 3008c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3009c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_TOKEN_TYPE_INSTRUCTION: { 3010c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct tgsi_full_instruction *inst = 3011c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou &ctx->parser.FullToken.FullInstruction; 3012c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned opc = inst->Instruction.Opcode; 3013c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct instr_translater *t = &translaters[opc]; 3014c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3015c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (t->fxn) { 3016c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou t->fxn(t, ctx, inst); 3017c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ctx->num_internal_temps = 0; 3018c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3019c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_assert(ctx, !ctx->using_tmp_dst); 3020c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } else { 3021c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_error(ctx, "unknown TGSI opc: %s\n", 3022c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou tgsi_get_opcode_name(opc)); 3023c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3024c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3025c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou switch (inst->Instruction.Saturate) { 3026c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_SAT_ZERO_ONE: 3027c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou create_clamp_imm(ctx, &inst->Dst[0].Register, 3028c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou fui(0.0), fui(1.0)); 3029c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 3030c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou case TGSI_SAT_MINUS_PLUS_ONE: 3031c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou create_clamp_imm(ctx, &inst->Dst[0].Register, 3032c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou fui(-1.0), fui(1.0)); 3033c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 3034c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3035c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3036c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou instr_finish(ctx); 3037c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3038c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 3039c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3040c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou default: 3041c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou break; 3042c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3043c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3044c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 3045c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3046c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic void 3047c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroucompile_dump(struct ir3_compile_context *ctx) 3048c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 3049c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const char *name = (ctx->so->type == SHADER_VERTEX) ? "vert" : "frag"; 3050c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou static unsigned n = 0; 3051c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou char fname[16]; 3052c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou FILE *f; 3053c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou snprintf(fname, sizeof(fname), "%s-%04u.dot", name, n++); 3054c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou f = fopen(fname, "w"); 3055c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (!f) 3056c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou return; 3057c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_block_depth(ctx->block); 3058c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_dump(ctx->ir, name, ctx->block, f); 3059c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou fclose(f); 3060c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 3061c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3062c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouint 3063c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouir3_compile_shader(struct ir3_shader_variant *so, 3064c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou const struct tgsi_token *tokens, struct ir3_shader_key key, 3065c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou bool cp) 3066c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{ 3067c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_compile_context ctx; 3068c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_block *block; 3069c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction **inputs; 3070c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned i, j, actual_in; 3071c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou int ret = 0; 3072c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3073c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou assert(!so->ir); 3074c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3075c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->ir = ir3_create(); 3076c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3077c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou assert(so->ir); 3078c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3079c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (compile_init(&ctx, so, tokens) != TGSI_PARSE_OK) { 3080c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou DBG("INIT failed!"); 3081c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ret = -1; 3082c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou goto out; 3083c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3084c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3085c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_instructions(&ctx); 3086c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3087c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block = ctx.block; 3088c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3089c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* keep track of the inputs from TGSI perspective.. */ 3090c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou inputs = block->inputs; 3091c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3092c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* but fixup actual inputs for frag shader: */ 3093c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx.type == TGSI_PROCESSOR_FRAGMENT) 3094c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou fixup_frag_inputs(&ctx); 3095c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3096c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* at this point, for binning pass, throw away unneeded outputs: */ 30973e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (key.binning_pass) { 30983e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton for (i = 0, j = 0; i < so->outputs_count; i++) { 30993e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton unsigned name = sem2name(so->outputs[i].semantic); 31003e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton unsigned idx = sem2name(so->outputs[i].semantic); 31013e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 3102c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* throw away everything but first position/psize */ 3103c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if ((idx == 0) && ((name == TGSI_SEMANTIC_POSITION) || 3104c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (name == TGSI_SEMANTIC_PSIZE))) { 3105c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (i != j) { 3106c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->outputs[j] = so->outputs[i]; 3107c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[(j*4)+0] = block->outputs[(i*4)+0]; 3108c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[(j*4)+1] = block->outputs[(i*4)+1]; 3109c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[(j*4)+2] = block->outputs[(i*4)+2]; 3110c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[(j*4)+3] = block->outputs[(i*4)+3]; 3111c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3112c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou j++; 3113c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3114c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3115c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->outputs_count = j; 3116c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->noutputs = j * 4; 3117c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3118c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3119c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* for rendering to alpha format, we only need the .w component, 3120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * and we need it to be in the .x position: 3121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 3122c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (key.alpha) { 3123c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0, j = 0; i < so->outputs_count; i++) { 3124c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned name = sem2name(so->outputs[i].semantic); 3125c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3126c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* move .w component to .x and discard others: */ 3127c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (name == TGSI_SEMANTIC_COLOR) { 3128c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[(i*4)+0] = block->outputs[(i*4)+3]; 3129c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[(i*4)+1] = NULL; 3130c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[(i*4)+2] = NULL; 3131c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[(i*4)+3] = NULL; 3132c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3133c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3134c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3135c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3136c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* at this point, we want the kill's in the outputs array too, 3137c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * so that they get scheduled (since they have no dst).. we've 3138c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * already ensured that the array is big enough in push_block(): 3139c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 3140c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ctx.type == TGSI_PROCESSOR_FRAGMENT) { 3141c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < ctx.kill_count; i++) 3142c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou block->outputs[block->noutputs++] = ctx.kill[i]; 3143e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton } 3144e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton 31453e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (fd_mesa_debug & FD_DBG_OPTDUMP) 31463e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton compile_dump(&ctx); 3147e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton 3148c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ret = ir3_block_flatten(block); 3149c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ret < 0) { 31506c4fa70da66d7efbf838a93bc69c7bdf2dda65f8Benjamin Peterson DBG("FLATTEN failed!"); 3151c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou goto out; 3152c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3153c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if ((ret > 0) && (fd_mesa_debug & FD_DBG_OPTDUMP)) 3154c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_dump(&ctx); 3155c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3156c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (fd_mesa_debug & FD_DBG_OPTMSGS) { 3157c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou printf("BEFORE CP:\n"); 3158e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton ir3_dump_instr_list(block->head); 3159e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton } 31603e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 31613e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (cp) 31623e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ir3_block_cp(block); 3163c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3164c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (fd_mesa_debug & FD_DBG_OPTDUMP) 3165c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compile_dump(&ctx); 3166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_block_depth(block); 31683e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 3169e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton if (fd_mesa_debug & FD_DBG_OPTMSGS) { 317082271f13e7eab69b909d538556e4781e971f7584Jeremy Hylton printf("AFTER DEPTH:\n"); 317182271f13e7eab69b909d538556e4781e971f7584Jeremy Hylton ir3_dump_instr_list(block->head); 3172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3173c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3174c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ret = ir3_block_sched(block); 3175c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ret) { 3176c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou DBG("SCHED failed!"); 3177c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou goto out; 3178c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 317982271f13e7eab69b909d538556e4781e971f7584Jeremy Hylton 31803e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if (fd_mesa_debug & FD_DBG_OPTMSGS) { 31813e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton printf("AFTER SCHED:\n"); 3182e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton ir3_dump_instr_list(block->head); 3183e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton } 31843e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 31853e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton ret = ir3_block_ra(block, so->type, key.half_precision, 3186e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton so->frag_coord, so->frag_face, &so->has_samp); 3187c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ret) { 3188c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou DBG("RA failed!"); 3189c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou goto out; 3190c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3191c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (fd_mesa_debug & FD_DBG_OPTMSGS) { 3193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou printf("AFTER RA:\n"); 3194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_dump_instr_list(block->head); 3195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3197c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* fixup input/outputs: */ 3198c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < so->outputs_count; i++) { 3199c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->outputs[i].regid = block->outputs[i*4]->regs[0]->num; 3200c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* preserve hack for depth output.. tgsi writes depth to .z, 3201c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * but what we give the hw is the scalar register: 3202c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 32033e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton if ((ctx.type == TGSI_PROCESSOR_FRAGMENT) && 3204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou (sem2name(so->outputs[i].semantic) == TGSI_SEMANTIC_POSITION)) 3205c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->outputs[i].regid += 2; 3206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* Note that some or all channels of an input may be unused: */ 3208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou actual_in = 0; 3209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (i = 0; i < so->inputs_count; i++) { 3210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou unsigned j, regid = ~0, compmask = 0; 3211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[i].ncomp = 0; 3212c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou for (j = 0; j < 4; j++) { 3213c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou struct ir3_instruction *in = inputs[(i*4) + j]; 3214c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (in) { 3215c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou compmask |= (1 << j); 3216c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou regid = in->regs[0]->num - j; 3217c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou actual_in++; 3218c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[i].ncomp++; 3219c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3220c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3221c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[i].regid = regid; 3222c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->inputs[i].compmask = compmask; 3223c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou } 3224c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3225c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou /* fragment shader always gets full vec4's even if it doesn't 3226c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * fetch all components, but vertex shader we need to update 3227c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * with the actual number of components fetch, otherwise thing 3228c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * will hang due to mismaptch between VFD_DECODE's and 3229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou * TOTALATTRTOVS 3230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou */ 3231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (so->type == SHADER_VERTEX) 3232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou so->total_in = actual_in; 3233c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou 3234c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrouout: 3235c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou if (ret) { 3236c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou ir3_destroy(so->ir); 32373e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton so->ir = NULL; 32383e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton } 32393e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton compile_free(&ctx); 32403e0055f8c65c407e74ce476b8e2b1fb889723514Jeremy Hylton 3241e36f77814e83bd2b3dc84a4e0bfb0b8dc0da9965Jeremy Hylton return ret; 3242c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou} 3243c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou