1/*
2 * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#ifndef IR2_H_
25#define IR2_H_
26
27#include <stdint.h>
28#include <stdbool.h>
29
30#include "instr-a2xx.h"
31
32/* low level intermediate representation of an adreno a2xx shader program */
33
34struct ir2_shader;
35
36struct ir2_shader_info {
37	uint16_t sizedwords;
38	int8_t   max_reg;   /* highest GPR # used by shader */
39	uint8_t  max_input_reg;
40	uint64_t regs_written;
41};
42
43struct ir2_register {
44	enum {
45		IR2_REG_CONST  = 0x1,
46		IR2_REG_EXPORT = 0x2,
47		IR2_REG_NEGATE = 0x4,
48		IR2_REG_ABS    = 0x8,
49	} flags;
50	int num;
51	char *swizzle;
52};
53
54enum ir2_pred {
55	IR2_PRED_NONE = 0,
56	IR2_PRED_EQ = 1,
57	IR2_PRED_NE = 2,
58};
59
60struct ir2_instruction {
61	struct ir2_shader *shader;
62	enum {
63		IR2_FETCH,
64		IR2_ALU,
65	} instr_type;
66	enum ir2_pred pred;
67	int sync;
68	unsigned regs_count;
69	struct ir2_register *regs[5];
70	union {
71		/* FETCH specific: */
72		struct {
73			instr_fetch_opc_t opc;
74			unsigned const_idx;
75			/* texture fetch specific: */
76			bool is_cube : 1;
77			/* vertex fetch specific: */
78			unsigned const_idx_sel;
79			enum a2xx_sq_surfaceformat fmt;
80			bool is_signed : 1;
81			bool is_normalized : 1;
82			uint32_t stride;
83			uint32_t offset;
84		} fetch;
85		/* ALU specific: */
86		struct {
87			instr_vector_opc_t vector_opc;
88			instr_scalar_opc_t scalar_opc;
89			bool vector_clamp : 1;
90			bool scalar_clamp : 1;
91		} alu;
92	};
93};
94
95struct ir2_cf {
96	struct ir2_shader *shader;
97	instr_cf_opc_t cf_type;
98
99	union {
100		/* EXEC/EXEC_END specific: */
101		struct {
102			unsigned instrs_count;
103			struct ir2_instruction *instrs[6];
104			uint32_t addr, cnt, sequence;
105		} exec;
106		/* ALLOC specific: */
107		struct {
108			instr_alloc_type_t type;   /* SQ_POSITION or SQ_PARAMETER_PIXEL */
109			int size;
110		} alloc;
111	};
112};
113
114struct ir2_shader {
115	unsigned cfs_count;
116	struct ir2_cf *cfs[0x56];
117	uint32_t heap[100 * 4096];
118	unsigned heap_idx;
119
120	enum ir2_pred pred;  /* pred inherited by newly created instrs */
121};
122
123struct ir2_shader * ir2_shader_create(void);
124void ir2_shader_destroy(struct ir2_shader *shader);
125void * ir2_shader_assemble(struct ir2_shader *shader,
126		struct ir2_shader_info *info);
127
128struct ir2_cf * ir2_cf_create(struct ir2_shader *shader, instr_cf_opc_t cf_type);
129
130struct ir2_instruction * ir2_instr_create(struct ir2_cf *cf, int instr_type);
131
132struct ir2_register * ir2_reg_create(struct ir2_instruction *instr,
133		int num, const char *swizzle, int flags);
134
135/* some helper fxns: */
136
137static inline struct ir2_cf *
138ir2_cf_create_alloc(struct ir2_shader *shader, instr_alloc_type_t type, int size)
139{
140	struct ir2_cf *cf = ir2_cf_create(shader, ALLOC);
141	if (!cf)
142		return cf;
143	cf->alloc.type = type;
144	cf->alloc.size = size;
145	return cf;
146}
147static inline struct ir2_instruction *
148ir2_instr_create_alu(struct ir2_cf *cf, instr_vector_opc_t vop, instr_scalar_opc_t sop)
149{
150	struct ir2_instruction *instr = ir2_instr_create(cf, IR2_ALU);
151	if (!instr)
152		return instr;
153	instr->alu.vector_opc = vop;
154	instr->alu.scalar_opc = sop;
155	return instr;
156}
157static inline struct ir2_instruction *
158ir2_instr_create_vtx_fetch(struct ir2_cf *cf, int ci, int cis,
159		enum a2xx_sq_surfaceformat fmt, bool is_signed, int stride)
160{
161	struct ir2_instruction *instr = ir2_instr_create(cf, IR2_FETCH);
162	instr->fetch.opc = VTX_FETCH;
163	instr->fetch.const_idx = ci;
164	instr->fetch.const_idx_sel = cis;
165	instr->fetch.fmt = fmt;
166	instr->fetch.is_signed = is_signed;
167	instr->fetch.stride = stride;
168	return instr;
169}
170static inline struct ir2_instruction *
171ir2_instr_create_tex_fetch(struct ir2_cf *cf, int ci)
172{
173	struct ir2_instruction *instr = ir2_instr_create(cf, IR2_FETCH);
174	instr->fetch.opc = TEX_FETCH;
175	instr->fetch.const_idx = ci;
176	return instr;
177}
178
179
180#endif /* IR2_H_ */
181