i965: Make can_do_source_mods() a member of the instruction classes.
[mesa.git] / src / mesa / drivers / dri / i965 / gen8_generator.h
1 /*
2 * Copyright © 2012 Intel Corporation
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 /**
25 * @file gen8_generator.h
26 *
27 * Code generation for Gen8+ hardware, replacing the brw_eu_emit.c layer.
28 */
29
30 #pragma once
31
32 extern "C" {
33 #include "main/macros.h"
34 } /* extern "C" */
35
36 #include "gen8_instruction.h"
37
38 class gen8_generator {
39 public:
40 gen8_generator(struct brw_context *brw,
41 struct gl_shader_program *shader_prog,
42 struct gl_program *prog,
43 void *mem_ctx);
44 ~gen8_generator();
45
46 /**
47 * Instruction emitters.
48 * @{
49 */
50 #define ALU1(OP) \
51 gen8_instruction *OP(struct brw_reg dst, struct brw_reg src);
52 #define ALU2(OP) \
53 gen8_instruction *OP(struct brw_reg d, struct brw_reg, struct brw_reg);
54 #define ALU3(OP) \
55 gen8_instruction *OP(struct brw_reg d, \
56 struct brw_reg, struct brw_reg, struct brw_reg);
57 ALU2(ADD)
58 ALU2(AND)
59 ALU2(ASR)
60 ALU3(BFE)
61 ALU2(BFI1)
62 ALU3(BFI2)
63 ALU1(F32TO16)
64 ALU1(F16TO32)
65 ALU1(BFREV)
66 ALU1(CBIT)
67 ALU2(ADDC)
68 ALU2(SUBB)
69 ALU2(DP2)
70 ALU2(DP3)
71 ALU2(DP4)
72 ALU2(DPH)
73 ALU1(FBH)
74 ALU1(FBL)
75 ALU1(FRC)
76 ALU2(LINE)
77 ALU3(LRP)
78 ALU2(MAC)
79 ALU2(MACH)
80 ALU3(MAD)
81 ALU2(MUL)
82 ALU1(MOV)
83 ALU1(MOV_RAW)
84 ALU1(NOT)
85 ALU2(OR)
86 ALU2(PLN)
87 ALU1(RNDD)
88 ALU1(RNDE)
89 ALU1(RNDZ)
90 ALU2(SEL)
91 ALU2(SHL)
92 ALU2(SHR)
93 ALU2(XOR)
94 #undef ALU1
95 #undef ALU2
96 #undef ALU3
97
98 gen8_instruction *CMP(struct brw_reg dst, unsigned conditional,
99 struct brw_reg src0, struct brw_reg src1);
100 gen8_instruction *IF(unsigned predicate);
101 gen8_instruction *ELSE();
102 gen8_instruction *ENDIF();
103 void DO();
104 gen8_instruction *BREAK();
105 gen8_instruction *CONTINUE();
106 gen8_instruction *WHILE();
107
108 gen8_instruction *HALT();
109
110 gen8_instruction *MATH(unsigned math_function,
111 struct brw_reg dst,
112 struct brw_reg src0);
113 gen8_instruction *MATH(unsigned math_function,
114 struct brw_reg dst,
115 struct brw_reg src0,
116 struct brw_reg src1);
117 gen8_instruction *NOP();
118 /** @} */
119
120 protected:
121 gen8_instruction *alu3(unsigned opcode,
122 struct brw_reg dst,
123 struct brw_reg src0,
124 struct brw_reg src1,
125 struct brw_reg src2);
126
127 gen8_instruction *math(unsigned math_function,
128 struct brw_reg dst,
129 struct brw_reg src0);
130
131 gen8_instruction *next_inst(unsigned opcode);
132
133 struct gl_shader_program *shader_prog;
134 struct gl_program *prog;
135
136 struct brw_context *brw;
137 struct intel_context *intel;
138 struct gl_context *ctx;
139
140 gen8_instruction *store;
141 unsigned store_size;
142 unsigned nr_inst;
143 unsigned next_inst_offset;
144
145 /**
146 * Control flow stacks:
147 *
148 * if_stack contains IF and ELSE instructions which must be patched with
149 * the final jump offsets (and popped) once the matching ENDIF is encountered.
150 *
151 * We actually store an array index into the store, rather than pointers
152 * to the instructions. This is necessary since we may realloc the store.
153 *
154 * @{
155 */
156 int *if_stack;
157 int if_stack_depth;
158 int if_stack_array_size;
159
160 int *loop_stack;
161 int loop_stack_depth;
162 int loop_stack_array_size;
163
164 int if_depth_in_loop;
165
166 void push_if_stack(gen8_instruction *inst);
167 gen8_instruction *pop_if_stack();
168 /** @} */
169
170 void patch_IF_ELSE(gen8_instruction *if_inst,
171 gen8_instruction *else_inst,
172 gen8_instruction *endif_inst);
173
174 unsigned next_ip(unsigned ip) const;
175 unsigned find_next_block_end(unsigned start_ip) const;
176 unsigned find_loop_end(unsigned start) const;
177
178 void patch_jump_targets();
179
180 /**
181 * Default state for new instructions.
182 */
183 struct {
184 unsigned exec_size;
185 unsigned access_mode;
186 unsigned mask_control;
187 unsigned qtr_control;
188 unsigned flag_subreg_nr;
189 unsigned conditional_mod;
190 unsigned predicate;
191 bool predicate_inverse;
192 bool saturate;
193 } default_state;
194
195 void *mem_ctx;
196 };
197
198 extern "C" void
199 gen8_disassemble(struct brw_context *brw, void *assembly,
200 int start, int end, FILE *out);