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