utests: replace the nodistriutable picture.
[contrib/beignet.git] / backend / src / backend / gen / gen_mesa_disasm.c
1 /*
2  * Copyright © 2012 Intel Corporation
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Author: Benjamin Segovia <benjamin.segovia@intel.com>
18  */
19
20 /*
21  * Copyright © 2008 Keith Packard
22  *
23  * Permission to use, copy, modify, distribute, and sell this software and its
24  * documentation for any purpose is hereby granted without fee, provided that
25  * the above copyright notice appear in all copies and that both that copyright
26  * notice and this permission notice appear in supporting documentation, and
27  * that the name of the copyright holders not be used in advertising or
28  * publicity pertaining to distribution of the software without specific,
29  * written prior permission.  The copyright holders make no representations
30  * about the suitability of this software for any purpose.  It is provided "as
31  * is" without express or implied warranty.
32  *
33  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
34  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
35  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
36  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
37  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
39  * OF THIS SOFTWARE.
40  */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <getopt.h>
46 #include <unistd.h>
47 #include <stdarg.h>
48 #include <stdint.h>
49 #include <assert.h>
50
51 #include "backend/gen_defs.hpp"
52 #include "backend/gen7_instruction.hpp"
53 #include "src/cl_device_data.h"
54
55 static const struct {
56   const char    *name;
57   int       nsrc;
58   int       ndst;
59 } opcode[128] = {
60   [GEN_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1 },
61   [GEN_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1 },
62   [GEN_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1 },
63   [GEN_OPCODE_RNDD] = { .name = "rndd", .nsrc = 1, .ndst = 1 },
64   [GEN_OPCODE_RNDE] = { .name = "rnde", .nsrc = 1, .ndst = 1 },
65   [GEN_OPCODE_RNDZ] = { .name = "rndz", .nsrc = 1, .ndst = 1 },
66   [GEN_OPCODE_NOT] = { .name = "not", .nsrc = 1, .ndst = 1 },
67   [GEN_OPCODE_LZD] = { .name = "lzd", .nsrc = 1, .ndst = 1 },
68   [GEN_OPCODE_FBH] = { .name = "fbh", .nsrc = 1, .ndst = 1 },
69   [GEN_OPCODE_FBL] = { .name = "fbl", .nsrc = 1, .ndst = 1 },
70   [GEN_OPCODE_F16TO32] = { .name = "f16to32", .nsrc = 1, .ndst = 1 },
71   [GEN_OPCODE_F32TO16] = { .name = "f32to16", .nsrc = 1, .ndst = 1 },
72
73   [GEN_OPCODE_MUL] = { .name = "mul", .nsrc = 2, .ndst = 1 },
74   [GEN_OPCODE_MAC] = { .name = "mac", .nsrc = 2, .ndst = 1 },
75   [GEN_OPCODE_MACH] = { .name = "mach", .nsrc = 2, .ndst = 1 },
76   [GEN_OPCODE_LINE] = { .name = "line", .nsrc = 2, .ndst = 1 },
77   [GEN_OPCODE_PLN] = { .name = "pln", .nsrc = 2, .ndst = 1 },
78   [GEN_OPCODE_MAD] = { .name = "mad", .nsrc = 3, .ndst = 1 },
79   [GEN_OPCODE_SAD2] = { .name = "sad2", .nsrc = 2, .ndst = 1 },
80   [GEN_OPCODE_SADA2] = { .name = "sada2", .nsrc = 2, .ndst = 1 },
81   [GEN_OPCODE_DP4] = { .name = "dp4", .nsrc = 2, .ndst = 1 },
82   [GEN_OPCODE_DPH] = { .name = "dph", .nsrc = 2, .ndst = 1 },
83   [GEN_OPCODE_DP3] = { .name = "dp3", .nsrc = 2, .ndst = 1 },
84   [GEN_OPCODE_DP2] = { .name = "dp2", .nsrc = 2, .ndst = 1 },
85   [GEN_OPCODE_MATH] = { .name = "math", .nsrc = 2, .ndst = 1 },
86
87   [GEN_OPCODE_AVG] = { .name = "avg", .nsrc = 2, .ndst = 1 },
88   [GEN_OPCODE_ADD] = { .name = "add", .nsrc = 2, .ndst = 1 },
89   [GEN_OPCODE_ADDC] = { .name = "addc", .nsrc = 2, .ndst = 1 },
90   [GEN_OPCODE_SUBB] = { .name = "subb", .nsrc = 2, .ndst = 1 },
91   [GEN_OPCODE_SEL] = { .name = "sel", .nsrc = 2, .ndst = 1 },
92   [GEN_OPCODE_AND] = { .name = "and", .nsrc = 2, .ndst = 1 },
93   [GEN_OPCODE_OR] = { .name = "or", .nsrc = 2, .ndst = 1 },
94   [GEN_OPCODE_XOR] = { .name = "xor", .nsrc = 2, .ndst = 1 },
95   [GEN_OPCODE_SHR] = { .name = "shr", .nsrc = 2, .ndst = 1 },
96   [GEN_OPCODE_SHL] = { .name = "shl", .nsrc = 2, .ndst = 1 },
97   [GEN_OPCODE_ASR] = { .name = "asr", .nsrc = 2, .ndst = 1 },
98   [GEN_OPCODE_CMP] = { .name = "cmp", .nsrc = 2, .ndst = 1 },
99   [GEN_OPCODE_CMPN] = { .name = "cmpn", .nsrc = 2, .ndst = 1 },
100
101   [GEN_OPCODE_SEND] = { .name = "send", .nsrc = 1, .ndst = 1 },
102   [GEN_OPCODE_SENDC] = { .name = "sendc", .nsrc = 1, .ndst = 1 },
103   [GEN_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 },
104   [GEN_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 0, .ndst = 0 },
105   [GEN_OPCODE_BRD] = { .name = "brd", .nsrc = 0, .ndst = 0 },
106   [GEN_OPCODE_IF] = { .name = "if", .nsrc = 0, .ndst = 0 },
107   [GEN_OPCODE_BRC] = { .name = "brc", .nsrc = 0, .ndst = 0 },
108   [GEN_OPCODE_WHILE] = { .name = "while", .nsrc = 0, .ndst = 0 },
109   [GEN_OPCODE_ELSE] = { .name = "else", .nsrc = 0, .ndst = 0 },
110   [GEN_OPCODE_BREAK] = { .name = "break", .nsrc = 0, .ndst = 0 },
111   [GEN_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 0, .ndst = 0 },
112   [GEN_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 },
113   [GEN_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 },
114   [GEN_OPCODE_PUSH] = { .name = "push", .nsrc = 1, .ndst = 1 },
115   [GEN_OPCODE_MRESTORE] = { .name = "mrest", .nsrc = 1, .ndst = 1 },
116   [GEN_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 },
117   [GEN_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 },
118   [GEN_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 },
119   [GEN_OPCODE_ENDIF] = { .name = "endif", .nsrc = 1, .ndst = 0 },
120 };
121
122 static const char *conditional_modifier[16] = {
123   [GEN_CONDITIONAL_NONE] = "",
124   [GEN_CONDITIONAL_Z] = ".e",
125   [GEN_CONDITIONAL_NZ] = ".ne",
126   [GEN_CONDITIONAL_G] = ".g",
127   [GEN_CONDITIONAL_GE] = ".ge",
128   [GEN_CONDITIONAL_L] = ".l",
129   [GEN_CONDITIONAL_LE] = ".le",
130   [GEN_CONDITIONAL_R] = ".r",
131   [GEN_CONDITIONAL_O] = ".o",
132   [GEN_CONDITIONAL_U] = ".u",
133 };
134
135 static const char *negate[2] = {
136   [0] = "",
137   [1] = "-",
138 };
139
140 static const char *_abs[2] = {
141   [0] = "",
142   [1] = "(abs)",
143 };
144
145 static const char *vert_stride_gen7[16] = {
146   [0] = "0",
147   [1] = "1",
148   [2] = "2",
149   [3] = "4",
150   [4] = "8",
151   [5] = "16",
152   [6] = "32",
153   [15] = "VxH",
154 };
155 static const char *vert_stride_gen8[16] = {
156   [0] = "0",
157   [1] = "1",
158   [2] = "2",
159   [3] = "4",
160   [4] = "8",
161   [5] = "16",
162   [6] = "32",
163 };
164
165 static const char *width[8] = {
166   [0] = "1",
167   [1] = "2",
168   [2] = "4",
169   [3] = "8",
170   [4] = "16",
171 };
172
173 static const char *horiz_stride[4] = {
174   [0] = "0",
175   [1] = "1",
176   [2] = "2",
177   [3] = "4"
178 };
179
180 static const char *chan_sel[4] = {
181   [0] = "x",
182   [1] = "y",
183   [2] = "z",
184   [3] = "w",
185 };
186
187 static const char *debug_ctrl[2] = {
188   [0] = "",
189   [1] = ".breakpoint"
190 };
191
192 static const char *saturate[2] = {
193   [0] = "",
194   [1] = ".sat"
195 };
196
197 static const char *accwr[2] = {
198   [0] = "",
199   [1] = "AccWrEnable"
200 };
201
202 static const char *wectrl[2] = {
203   [0] = "WE_normal",
204   [1] = "WE_all"
205 };
206
207 static const char *exec_size[8] = {
208   [0] = "1",
209   [1] = "2",
210   [2] = "4",
211   [3] = "8",
212   [4] = "16",
213   [5] = "32"
214 };
215
216 static const char *pred_inv[2] = {
217   [0] = "+",
218   [1] = "-"
219 };
220
221 static const char *pred_ctrl_align16[16] = {
222   [1] = "",
223   [2] = ".x",
224   [3] = ".y",
225   [4] = ".z",
226   [5] = ".w",
227   [6] = ".any4h",
228   [7] = ".all4h",
229 };
230
231 static const char *pred_ctrl_align1[16] = {
232   [1] = "",
233   [2] = ".anyv",
234   [3] = ".allv",
235   [4] = ".any2h",
236   [5] = ".all2h",
237   [6] = ".any4h",
238   [7] = ".all4h",
239   [8] = ".any8h",
240   [9] = ".all8h",
241   [10] = ".any16h",
242   [11] = ".all16h",
243 };
244
245 static const char *thread_ctrl_gen7[4] = {
246   [0] = "",
247   [2] = "switch"
248 };
249 static const char *thread_ctrl_gen8[4] = {
250   [0] = "",
251   [1] = "atomic",
252   [2] = "switch"
253 };
254
255
256 static const char *dep_ctrl[4] = {
257   [0] = "",
258   [1] = "NoDDClr",
259   [2] = "NoDDChk",
260   [3] = "NoDDClr,NoDDChk",
261 };
262
263 static const char *access_mode[2] = {
264   [0] = "align1",
265   [1] = "align16",
266 };
267
268 static const char *reg_encoding[8] = {
269   [0] = ":UD",
270   [1] = ":D",
271   [2] = ":UW",
272   [3] = ":W",
273   [4] = ":UB",
274   [5] = ":B",
275   [6] = ":DF",
276   [7] = ":F"
277 };
278
279 int reg_type_size[8] = {
280   [0] = 4,
281   [1] = 4,
282   [2] = 2,
283   [3] = 2,
284   [4] = 1,
285   [5] = 1,
286   [6] = 8,
287   [7] = 4
288 };
289
290 static const char *reg_file[4] = {
291   [0] = "A",
292   [1] = "g",
293   [2] = "m",
294   [3] = "imm",
295 };
296
297 static const char *writemask[16] = {
298   [0x0] = ".",
299   [0x1] = ".x",
300   [0x2] = ".y",
301   [0x3] = ".xy",
302   [0x4] = ".z",
303   [0x5] = ".xz",
304   [0x6] = ".yz",
305   [0x7] = ".xyz",
306   [0x8] = ".w",
307   [0x9] = ".xw",
308   [0xa] = ".yw",
309   [0xb] = ".xyw",
310   [0xc] = ".zw",
311   [0xd] = ".xzw",
312   [0xe] = ".yzw",
313   [0xf] = "",
314 };
315
316 static const char *end_of_thread[2] = {
317   [0] = "",
318   [1] = "EOT"
319 };
320
321 static const char *target_function_gen7[16] = {
322   [GEN_SFID_NULL] = "null",
323   [GEN_SFID_RESERVED] = NULL,
324   [GEN_SFID_SAMPLER] = "sampler",
325   [GEN_SFID_MESSAGE_GATEWAY] = "gateway",
326   [GEN_SFID_DATAPORT_SAMPLER] = "dataport_sampler",
327   [GEN_SFID_DATAPORT_RENDER] = "render",
328   [GEN_SFID_URB] = "urb",
329   [GEN_SFID_THREAD_SPAWNER] = "thread_spawner",
330   [GEN_SFID_VIDEO_MOTION_EST] = "video_motion_estimation",
331   [GEN_SFID_DATAPORT_CONSTANT] = "const",
332   [GEN_SFID_DATAPORT_DATA] = "data",
333   [GEN_SFID_PIXEL_INTERPOLATOR] = "pix_interpolator",
334 };
335
336 static const char *target_function_gen75[16] = {
337   [GEN_SFID_NULL] = "null",
338   [GEN_SFID_RESERVED] = NULL,
339   [GEN_SFID_SAMPLER] = "sampler",
340   [GEN_SFID_MESSAGE_GATEWAY] = "gateway",
341   [GEN_SFID_DATAPORT_SAMPLER] = "dataport_sampler",
342   [GEN_SFID_DATAPORT_RENDER] = "render",
343   [GEN_SFID_URB] = "urb",
344   [GEN_SFID_THREAD_SPAWNER] = "thread_spawner",
345   [GEN_SFID_VIDEO_MOTION_EST] = "video_motion_estimation",
346   [GEN_SFID_DATAPORT_CONSTANT] = "const",
347   [GEN_SFID_DATAPORT_DATA] = "data (0)",
348   [GEN_SFID_PIXEL_INTERPOLATOR] = "pix_interpolator",
349   [GEN_SFID_DATAPORT1_DATA] = "data (1)",
350 };
351
352 static const char *gateway_sub_function[8] = {
353   [0] = "open gateway",
354   [1] = "close gateway",
355   [2] = "forward gateway",
356   [3] = "get time stamp",
357   [4] = "barrier",
358   [5] = "update gateway state",
359   [6] = "MMIO R/W",
360   [7] = "reserved"
361 };
362
363 static const char *math_function_gen7[16] = {
364   [GEN_MATH_FUNCTION_INV] = "inv",
365   [GEN_MATH_FUNCTION_LOG] = "log",
366   [GEN_MATH_FUNCTION_EXP] = "exp",
367   [GEN_MATH_FUNCTION_SQRT] = "sqrt",
368   [GEN_MATH_FUNCTION_RSQ] = "rsq",
369   [GEN_MATH_FUNCTION_SIN] = "sin",
370   [GEN_MATH_FUNCTION_COS] = "cos",
371   [GEN_MATH_FUNCTION_FDIV] = "fdiv",
372   [GEN_MATH_FUNCTION_POW] = "pow",
373   [GEN_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
374   [GEN_MATH_FUNCTION_INT_DIV_QUOTIENT] = "intdiv",
375   [GEN_MATH_FUNCTION_INT_DIV_REMAINDER] = "intmod",
376 };
377 static const char *math_function_gen8[16] = {
378   [GEN_MATH_FUNCTION_INV] = "inv",
379   [GEN_MATH_FUNCTION_LOG] = "log",
380   [GEN_MATH_FUNCTION_EXP] = "exp",
381   [GEN_MATH_FUNCTION_SQRT] = "sqrt",
382   [GEN_MATH_FUNCTION_RSQ] = "rsq",
383   [GEN_MATH_FUNCTION_SIN] = "sin",
384   [GEN_MATH_FUNCTION_COS] = "cos",
385   [GEN_MATH_FUNCTION_FDIV] = "fdiv",
386   [GEN_MATH_FUNCTION_POW] = "pow",
387   [GEN_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
388   [GEN8_MATH_FUNCTION_INVM] = "invm",
389   [GEN8_MATH_FUNCTION_RSQRTM] = "rsqrtm",
390 };
391
392 static const char *math_saturate[2] = {
393   [0] = "",
394   [1] = "sat"
395 };
396
397 static const char *math_signed[2] = {
398   [0] = "",
399   [1] = "signed"
400 };
401
402 static const char *math_scalar[2] = {
403   [0] = "",
404   [1] = "scalar"
405 };
406
407 static const char *math_precision[2] = {
408   [0] = "",
409   [1] = "partial_precision"
410 };
411
412 static const char *data_port_data_cache_simd_mode[] = {
413   "SIMD4x2",
414   "SIMD16",
415   "SIMD8",
416 };
417
418 static const char *data_port_data_cache_category[] = {
419   "legacy",
420   "scratch",
421 };
422
423 static const char *data_port_scratch_block_size[] = {
424   "1 register",
425   "2 registers",
426   "Reserve",
427   "4 registers",
428 };
429
430 static const char *data_port_scratch_invalidate[] = {
431   "no invalidate",
432   "invalidate cache line",
433 };
434
435 static const char *data_port_scratch_channel_mode[] = {
436   "Oword",
437   "Dword",
438 };
439
440 static const char *data_port_scratch_msg_type[] = {
441   "Scratch Read",
442   "Scratch Write",
443 };
444
445 static const char *data_port_data_cache_msg_type[] = {
446   [0] = "OWord Block Read",
447   [1] = "Unaligned OWord Block Read",
448   [2] = "OWord Dual Block Read",
449   [3] = "DWord Scattered Read",
450   [4] = "Byte Scattered Read",
451   [5] = "Untyped Surface Read",
452   [6] = "Untyped Atomic Operation",
453   [7] = "Memory Fence",
454   [8] = "OWord Block Write",
455   [10] = "OWord Dual Block Write",
456   [11] = "DWord Scattered Write",
457   [12] = "Byte Scattered Write",
458   [13] = "Untyped Surface Write",
459 };
460
461 static const char *data_port1_data_cache_msg_type[] = {
462   [1] = "Untyped Surface Read",
463   [2] = "Untyped Atomic Operation",
464   [3] = "Untyped Atomic Operation SIMD4x2",
465   [4] = "Media Block Read",
466   [5] = "Typed Surface Read",
467   [6] = "Typed Atomic Operation",
468   [7] = "Typed Atomic Operation SIMD4x2",
469   [9] = "Untyped Surface Write",
470   [10] = "Media Block Write",
471   [11] = "Atomic Counter Operation",
472   [12] = "Atomic Counter Operation 4X2",
473   [13] = "Typed Surface Write",
474 };
475
476 static int column;
477
478 static int gen_version;
479
480 #define GEN_BITS_FIELD(inst, gen)                               \
481   ({                                                            \
482     int bits;                                                   \
483     if (gen_version < 80)                                       \
484       bits = ((const union Gen7NativeInstruction *)inst)->gen;  \
485     else                                                        \
486       bits = ((const union Gen8NativeInstruction *)inst)->gen;  \
487     bits;                                                       \
488   })
489
490 #define GEN_BITS_FIELD2(inst, gen7, gen8)                       \
491   ({                                                            \
492     int bits;                                                   \
493     if (gen_version < 80)                                       \
494       bits = ((const union Gen7NativeInstruction *)inst)->gen7; \
495     else                                                        \
496       bits = ((const union Gen8NativeInstruction *)inst)->gen8; \
497     bits;                                                       \
498   })
499
500 #define PRED_CTRL(inst)            GEN_BITS_FIELD(inst, header.predicate_control)
501 #define PRED_INV(inst)             GEN_BITS_FIELD(inst, header.predicate_inverse)
502 #define FLAG_REG_NR(inst)          GEN_BITS_FIELD2(inst, bits2.da1.flag_reg_nr, bits1.da1.flag_reg_nr)
503 #define FLAG_SUB_REG_NR(inst)      GEN_BITS_FIELD2(inst, bits2.da1.flag_sub_reg_nr, bits1.da1.flag_sub_reg_nr)
504 #define ACCESS_MODE(inst)          GEN_BITS_FIELD(inst, header.access_mode)
505 #define MASK_CONTROL(inst)         GEN_BITS_FIELD2(inst, header.mask_control, bits1.da1.mask_control)
506 #define DEPENDENCY_CONTROL(inst)   GEN_BITS_FIELD(inst, header.dependency_control)
507 #define THREAD_CONTROL(inst)       GEN_BITS_FIELD(inst, header.thread_control)
508 #define ACC_WR_CONTROL(inst)       GEN_BITS_FIELD(inst, header.acc_wr_control)
509 #define QUARTER_CONTROL(inst)      GEN_BITS_FIELD(inst, header.quarter_control)
510 #define END_OF_THREAD(inst)        GEN_BITS_FIELD(inst, bits3.generic_gen5.end_of_thread)
511 #define OPCODE(inst)               GEN_BITS_FIELD(inst, header.opcode)
512 #define SATURATE(inst)             GEN_BITS_FIELD(inst, header.saturate)
513 #define DEBUG_CONTROL(inst)        GEN_BITS_FIELD(inst, header.debug_control)
514 #define MATH_FUNCTION(inst)        GEN_BITS_FIELD(inst, header.destreg_or_condmod)
515 #define MATH_SATURATE(inst)        GEN_BITS_FIELD(inst, bits3.math_gen5.saturate)
516 #define MATH_SIGNED(inst)          GEN_BITS_FIELD(inst, bits3.math_gen5.int_type)
517 #define MATH_SCALAR(inst)          GEN_BITS_FIELD(inst, bits3.math_gen5.data_type)
518 #define MATH_PRECISION(inst)       GEN_BITS_FIELD(inst, bits3.math_gen5.precision)
519 #define COND_DST_OR_MODIFIER(inst) GEN_BITS_FIELD(inst, header.destreg_or_condmod)
520 #define EXECUTION_SIZE(inst)       GEN_BITS_FIELD(inst, header.execution_size)
521 #define BRANCH_JIP(inst)           GEN_BITS_FIELD2(inst, bits3.gen7_branch.jip, bits3.gen8_branch.jip/8)
522 #define BRANCH_UIP(inst)           GEN_BITS_FIELD2(inst, bits3.gen7_branch.uip, bits2.gen8_branch.uip/8)
523 #define SAMPLE_BTI(inst)           GEN_BITS_FIELD(inst, bits3.sampler_gen7.bti)
524 #define SAMPLER(inst)              GEN_BITS_FIELD(inst, bits3.sampler_gen7.sampler)
525 #define SAMPLER_MSG_TYPE(inst)     GEN_BITS_FIELD(inst, bits3.sampler_gen7.msg_type)
526 #define SAMPLER_SIMD_MODE(inst)    GEN_BITS_FIELD(inst, bits3.sampler_gen7.simd_mode)
527 #define UNTYPED_RW_BTI(inst)       GEN_BITS_FIELD(inst, bits3.gen7_untyped_rw.bti)
528 #define UNTYPED_RW_RGBA(inst)      GEN_BITS_FIELD(inst, bits3.gen7_untyped_rw.rgba)
529 #define UNTYPED_RW_SIMD_MODE(inst) GEN_BITS_FIELD(inst, bits3.gen7_untyped_rw.simd_mode)
530 #define UNTYPED_RW_CATEGORY(inst)  GEN_BITS_FIELD(inst, bits3.gen7_untyped_rw.category)
531 #define UNTYPED_RW_MSG_TYPE(inst)  GEN_BITS_FIELD(inst, bits3.gen7_untyped_rw.msg_type)
532 #define SCRATCH_RW_OFFSET(inst)    GEN_BITS_FIELD(inst, bits3.gen7_scratch_rw.offset)
533 #define SCRATCH_RW_BLOCK_SIZE(inst) GEN_BITS_FIELD(inst, bits3.gen7_scratch_rw.block_size)
534 #define SCRATCH_RW_INVALIDATE_AFTER_READ(inst) GEN_BITS_FIELD(inst, bits3.gen7_scratch_rw.invalidate_after_read)
535 #define SCRATCH_RW_BLOCK_SIZE(inst) GEN_BITS_FIELD(inst, bits3.gen7_scratch_rw.block_size)
536 #define SCRATCH_RW_CHANNEL_MODE(inst) GEN_BITS_FIELD(inst, bits3.gen7_scratch_rw.channel_mode)
537 #define SCRATCH_RW_MSG_TYPE(inst)  GEN_BITS_FIELD(inst, bits3.gen7_scratch_rw.msg_type)
538 #define DWORD_RW_BTI(inst)         GEN_BITS_FIELD(inst, bits3.gen7_dword_rw.msg_type)
539 #define DWORD_RW_MSG_TYPE(inst)    GEN_BITS_FIELD(inst, bits3.gen7_dword_rw.bti)
540 #define MSG_GW_SUBFUNC(inst)       GEN_BITS_FIELD(inst, bits3.gen7_msg_gw.subfunc)
541 #define MSG_GW_NOTIFY(inst)        GEN_BITS_FIELD(inst, bits3.gen7_msg_gw.notify)
542 #define MSG_GW_ACKREQ(inst)        GEN_BITS_FIELD(inst, bits3.gen7_msg_gw.ackreq)
543 #define GENERIC_MSG_LENGTH(inst)   GEN_BITS_FIELD(inst, bits3.generic_gen5.msg_length)
544 #define GENERIC_RESPONSE_LENGTH(inst) GEN_BITS_FIELD(inst, bits3.generic_gen5.response_length)
545
546 static int string(FILE *file, const char *string)
547 {
548   fputs (string, file);
549   column += strlen (string);
550   return 0;
551 }
552
553 static int format(FILE *f, const char *format, ...)
554 {
555   char    buf[1024];
556   va_list       args;
557   va_start (args, format);
558
559   vsnprintf (buf, sizeof (buf) - 1, format, args);
560   va_end (args);
561   string(f, buf);
562   return 0;
563 }
564
565 static int newline(FILE *f)
566 {
567   putc ('\n', f);
568   column = 0;
569   return 0;
570 }
571
572 static int pad(FILE *f, int c)
573 {
574   do
575     string(f, " ");
576   while (column < c);
577   return 0;
578 }
579
580 static int flag_reg(FILE *file, const int flag_nr, const int flag_sub_reg_nr)
581 {
582   if (flag_nr || flag_sub_reg_nr)
583     return format(file, ".f%d.%d", flag_nr, flag_sub_reg_nr);
584   return 0;
585 }
586
587 static int control(FILE *file, const char *name, const char *ctrl[], uint32_t id, int *space)
588 {
589   if (!ctrl[id]) {
590     fprintf (file, "*** invalid %s value %d ",
591              name, id);
592     return 1;
593   }
594   if (ctrl[id][0]) {
595     if (space && *space)
596       string(file, " ");
597     string(file, ctrl[id]);
598     if (space)
599       *space = 1;
600   }
601   return 0;
602 }
603
604 static int print_opcode(FILE *file, int id)
605 {
606   if (!opcode[id].name) {
607     format(file, "*** invalid opcode value %d ", id);
608     return 1;
609   }
610   string(file, opcode[id].name);
611   return 0;
612 }
613
614 static int reg(FILE *file, uint32_t _reg_file, uint32_t _reg_nr)
615 {
616   int err = 0;
617
618   if (_reg_file == GEN_ARCHITECTURE_REGISTER_FILE) {
619     switch (_reg_nr & 0xf0) {
620       case GEN_ARF_NULL:
621         string(file, "null");
622         return -1;
623       case GEN_ARF_ADDRESS:
624         format(file, "a%d", _reg_nr & 0x0f);
625         break;
626       case GEN_ARF_ACCUMULATOR:
627         format(file, "acc%d", _reg_nr & 0x0f);
628         break;
629       case GEN_ARF_FLAG:
630         format(file, "f%d", _reg_nr & 0x0f);
631         break;
632       case GEN_ARF_MASK:
633         format(file, "mask%d", _reg_nr & 0x0f);
634         break;
635       case GEN_ARF_MASK_STACK:
636         format(file, "msd%d", _reg_nr & 0x0f);
637         break;
638       case GEN_ARF_STATE:
639         format(file, "sr%d", _reg_nr & 0x0f);
640         break;
641       case GEN_ARF_CONTROL:
642         format(file, "cr%d", _reg_nr & 0x0f);
643         break;
644       case GEN_ARF_NOTIFICATION_COUNT:
645         format(file, "n%d", _reg_nr & 0x0f);
646         break;
647       case GEN_ARF_IP:
648         string(file, "ip");
649         return -1;
650         break;
651       case GEN_ARF_TM:
652         format(file, "tm%d", _reg_nr & 0x0f);
653         break;
654       default:
655         format(file, "ARF%d", _reg_nr);
656         break;
657     }
658   } else {
659     err |= control(file, "src reg file", reg_file, _reg_file, NULL);
660     format(file, "%d", _reg_nr);
661   }
662   return err;
663 }
664
665 static int dest(FILE *file, const void* inst)
666 {
667   int err = 0;
668
669   if (ACCESS_MODE(inst) == GEN_ALIGN_1) {
670     if (GEN_BITS_FIELD(inst, bits1.da1.dest_address_mode) == GEN_ADDRESS_DIRECT) {
671       err |= reg(file, GEN_BITS_FIELD(inst, bits1.da1.dest_reg_file),
672                  GEN_BITS_FIELD(inst, bits1.da1.dest_reg_nr));
673       if (err == -1) {
674         control(file, "dest reg encoding", reg_encoding, GEN_BITS_FIELD(inst, bits1.da1.dest_reg_type), NULL);
675         return 0;
676       }
677       if (GEN_BITS_FIELD(inst, bits1.da1.dest_subreg_nr))
678         format(file, ".%d", GEN_BITS_FIELD(inst, bits1.da1.dest_subreg_nr) /
679                reg_type_size[GEN_BITS_FIELD(inst, bits1.da1.dest_reg_type)]);
680       format(file, "<%s>", horiz_stride[GEN_BITS_FIELD(inst, bits1.da1.dest_horiz_stride)]);
681       err |= control(file, "dest reg encoding", reg_encoding, GEN_BITS_FIELD(inst, bits1.da1.dest_reg_type), NULL);
682     } else {
683       string(file, "g[a0");
684       if (GEN_BITS_FIELD(inst, bits1.ia1.dest_subreg_nr))
685         format(file, ".%d", GEN_BITS_FIELD(inst, bits1.ia1.dest_subreg_nr) /
686                reg_type_size[GEN_BITS_FIELD(inst, bits1.ia1.dest_reg_type)]);
687       if (GEN_BITS_FIELD(inst, bits1.ia1.dest_indirect_offset))
688         format(file, " %d", GEN_BITS_FIELD(inst, bits1.ia1.dest_indirect_offset));
689       string(file, "]");
690       format(file, "<%s>", horiz_stride[GEN_BITS_FIELD(inst, bits1.ia1.dest_horiz_stride)]);
691       err |= control(file, "dest reg encoding", reg_encoding, GEN_BITS_FIELD(inst, bits1.ia1.dest_reg_type), NULL);
692     }
693   } else {
694     if (GEN_BITS_FIELD(inst, bits1.da16.dest_address_mode) == GEN_ADDRESS_DIRECT) {
695       err |= reg(file, GEN_BITS_FIELD(inst, bits1.da16.dest_reg_file), GEN_BITS_FIELD(inst, bits1.da16.dest_reg_nr));
696       if (err == -1)
697         return 0;
698       if (GEN_BITS_FIELD(inst, bits1.da16.dest_subreg_nr))
699         format(file, ".%d", GEN_BITS_FIELD(inst, bits1.da16.dest_subreg_nr) /
700                reg_type_size[GEN_BITS_FIELD(inst, bits1.da16.dest_reg_type)]);
701       string(file, "<1>");
702       err |= control(file, "writemask", writemask, GEN_BITS_FIELD(inst, bits1.da16.dest_writemask), NULL);
703       err |= control(file, "dest reg encoding", reg_encoding, GEN_BITS_FIELD(inst, bits1.da16.dest_reg_type), NULL);
704     } else {
705       err = 1;
706       string(file, "Indirect align16 address mode not supported");
707     }
708   }
709
710   return 0;
711 }
712
713 static int dest_3src(FILE *file, const void *inst)
714 {
715   int err = 0;
716   const uint32_t reg_file = GEN_GENERAL_REGISTER_FILE;
717
718   err |= reg(file, reg_file, GEN_BITS_FIELD(inst, bits1.da3src.dest_reg_nr));
719   if (err == -1)
720     return 0;
721   if (GEN_BITS_FIELD(inst, bits1.da3src.dest_subreg_nr))
722     format(file, ".%d", GEN_BITS_FIELD(inst, bits1.da3src.dest_subreg_nr));
723   string(file, "<1>");
724   err |= control(file, "writemask", writemask, GEN_BITS_FIELD(inst, bits1.da3src.dest_writemask), NULL);
725   err |= control(file, "dest reg encoding", reg_encoding, GEN_TYPE_F, NULL);
726
727   return 0;
728 }
729
730 static int src_align1_region(FILE *file,
731                              uint32_t _vert_stride, uint32_t _width, uint32_t _horiz_stride)
732 {
733   int err = 0;
734   string(file, "<");
735   if (gen_version < 80) {
736     err |= control(file, "vert stride", vert_stride_gen7, _vert_stride, NULL);
737   } else {
738     err |= control(file, "vert stride", vert_stride_gen8, _vert_stride, NULL);
739   }
740   string(file, ",");
741   err |= control(file, "width", width, _width, NULL);
742   string(file, ",");
743   err |= control(file, "horiz_stride", horiz_stride, _horiz_stride, NULL);
744   string(file, ">");
745   return err;
746 }
747
748 static int src_da1(FILE *file, uint32_t type, uint32_t _reg_file,
749                    uint32_t _vert_stride, uint32_t _width, uint32_t _horiz_stride,
750                    uint32_t reg_num, uint32_t sub_reg_num, uint32_t __abs, uint32_t _negate)
751 {
752   int err = 0;
753   err |= control(file, "negate", negate, _negate, NULL);
754   err |= control(file, "abs", _abs, __abs, NULL);
755
756   err |= reg(file, _reg_file, reg_num);
757   if (err == -1)
758     return 0;
759   if (sub_reg_num)
760     format(file, ".%d", sub_reg_num / reg_type_size[type]); /* use formal style like spec */
761   src_align1_region(file, _vert_stride, _width, _horiz_stride);
762   err |= control(file, "src reg encoding", reg_encoding, type, NULL);
763   return err;
764 }
765
766 static int src_ia1(FILE *file,
767                    uint32_t type,
768                    uint32_t _reg_file,
769                    int32_t _addr_imm,
770                    uint32_t _addr_subreg_nr,
771                    uint32_t _negate,
772                    uint32_t __abs,
773                    uint32_t _addr_mode,
774                    uint32_t _horiz_stride,
775                    uint32_t _width,
776                    uint32_t _vert_stride)
777 {
778   int err = 0;
779   err |= control(file, "negate", negate, _negate, NULL);
780   err |= control(file, "abs", _abs, __abs, NULL);
781
782   string(file, "g[a0");
783   if (_addr_subreg_nr)
784     format(file, ".%d", _addr_subreg_nr);
785   if (_addr_imm)
786     format(file, " %d", _addr_imm);
787   string(file, "]");
788   src_align1_region(file, _vert_stride, _width, _horiz_stride);
789   err |= control(file, "src reg encoding", reg_encoding, type, NULL);
790   return err;
791 }
792
793 static int src_da16(FILE *file,
794                     uint32_t _reg_type,
795                     uint32_t _reg_file,
796                     uint32_t _vert_stride,
797                     uint32_t _reg_nr,
798                     uint32_t _subreg_nr,
799                     uint32_t __abs,
800                     uint32_t _negate,
801                     uint32_t swz_x,
802                     uint32_t swz_y,
803                     uint32_t swz_z,
804                     uint32_t swz_w)
805 {
806   int err = 0;
807   err |= control(file, "negate", negate, _negate, NULL);
808   err |= control(file, "abs", _abs, __abs, NULL);
809
810   err |= reg(file, _reg_file, _reg_nr);
811   if (err == -1)
812     return 0;
813   if (_subreg_nr)
814     /* bit4 for subreg number byte addressing. Make this same meaning as
815        in da1 case, so output looks consistent. */
816     format(file, ".%d", 16 / reg_type_size[_reg_type]);
817   string(file, "<");
818
819   if (gen_version < 80) {
820     err |= control(file, "vert stride", vert_stride_gen7, _vert_stride, NULL);
821   } else {
822     err |= control(file, "vert stride", vert_stride_gen8, _vert_stride, NULL);
823   }
824   string(file, ",4,1>");
825   /*
826    * Three kinds of swizzle display:
827    *  identity - nothing printed
828    *  1->all     - print the single channel
829    *  1->1     - print the mapping
830    */
831   if (swz_x == GEN_CHANNEL_X &&
832       swz_y == GEN_CHANNEL_Y &&
833       swz_z == GEN_CHANNEL_Z &&
834       swz_w == GEN_CHANNEL_W) {
835     ;
836   } else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w) {
837     string(file, ".");
838     err |= control(file, "channel select", chan_sel, swz_x, NULL);
839   } else {
840     string(file, ".");
841     err |= control(file, "channel select", chan_sel, swz_x, NULL);
842     err |= control(file, "channel select", chan_sel, swz_y, NULL);
843     err |= control(file, "channel select", chan_sel, swz_z, NULL);
844     err |= control(file, "channel select", chan_sel, swz_w, NULL);
845   }
846   err |= control(file, "src da16 reg type", reg_encoding, _reg_type, NULL);
847   return err;
848 }
849
850 static int src0_3src(FILE *file, const void* inst)
851 {
852   int err = 0;
853   uint32_t swz_x = (GEN_BITS_FIELD(inst, bits2.da3src.src0_swizzle) >> 0) & 0x3;
854   uint32_t swz_y = (GEN_BITS_FIELD(inst, bits2.da3src.src0_swizzle) >> 2) & 0x3;
855   uint32_t swz_z = (GEN_BITS_FIELD(inst, bits2.da3src.src0_swizzle) >> 4) & 0x3;
856   uint32_t swz_w = (GEN_BITS_FIELD(inst, bits2.da3src.src0_swizzle) >> 6) & 0x3;
857
858   err |= control(file, "negate", negate, GEN_BITS_FIELD(inst, bits1.da3src.src0_negate), NULL);
859   err |= control(file, "abs", _abs, GEN_BITS_FIELD(inst, bits1.da3src.src0_abs), NULL);
860
861   err |= reg(file, GEN_GENERAL_REGISTER_FILE, GEN_BITS_FIELD(inst, bits2.da3src.src0_reg_nr));
862   if (err == -1)
863     return 0;
864   if (GEN_BITS_FIELD(inst, bits2.da3src.src0_subreg_nr))
865     format(file, ".%d", GEN_BITS_FIELD(inst, bits2.da3src.src0_subreg_nr));
866   string(file, "<4,1,1>");
867   err |= control(file, "src da16 reg type", reg_encoding,
868                  GEN_TYPE_F, NULL);
869   /*
870    * Three kinds of swizzle display:
871    *  identity - nothing printed
872    *  1->all     - print the single channel
873    *  1->1     - print the mapping
874    */
875   if (swz_x == GEN_CHANNEL_X &&
876       swz_y == GEN_CHANNEL_Y &&
877       swz_z == GEN_CHANNEL_Z &&
878       swz_w == GEN_CHANNEL_W) {
879     ;
880   } else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w) {
881     string(file, ".");
882     err |= control(file, "channel select", chan_sel, swz_x, NULL);
883   } else {
884     string(file, ".");
885     err |= control(file, "channel select", chan_sel, swz_x, NULL);
886     err |= control(file, "channel select", chan_sel, swz_y, NULL);
887     err |= control(file, "channel select", chan_sel, swz_z, NULL);
888     err |= control(file, "channel select", chan_sel, swz_w, NULL);
889   }
890   return err;
891 }
892
893 static int src1_3src(FILE *file, const void* inst)
894 {
895   int err = 0;
896   uint32_t swz_x = (GEN_BITS_FIELD(inst, bits2.da3src.src1_swizzle) >> 0) & 0x3;
897   uint32_t swz_y = (GEN_BITS_FIELD(inst, bits2.da3src.src1_swizzle) >> 2) & 0x3;
898   uint32_t swz_z = (GEN_BITS_FIELD(inst, bits2.da3src.src1_swizzle) >> 4) & 0x3;
899   uint32_t swz_w = (GEN_BITS_FIELD(inst, bits2.da3src.src1_swizzle) >> 6) & 0x3;
900   uint32_t src1_subreg_nr = (GEN_BITS_FIELD(inst, bits2.da3src.src1_subreg_nr_low) |
901                              (GEN_BITS_FIELD(inst, bits3.da3src.src1_subreg_nr_high) << 2));
902
903   err |= control(file, "negate", negate, GEN_BITS_FIELD(inst, bits1.da3src.src1_negate), NULL);
904   err |= control(file, "abs", _abs, GEN_BITS_FIELD(inst, bits1.da3src.src1_abs), NULL);
905
906   err |= reg(file, GEN_GENERAL_REGISTER_FILE, GEN_BITS_FIELD(inst, bits3.da3src.src1_reg_nr));
907   if (err == -1)
908     return 0;
909   if (src1_subreg_nr)
910     format(file, ".%d", src1_subreg_nr);
911   string(file, "<4,1,1>");
912   err |= control(file, "src da16 reg type", reg_encoding,
913                  GEN_TYPE_F, NULL);
914   /*
915    * Three kinds of swizzle display:
916    *  identity - nothing printed
917    *  1->all     - print the single channel
918    *  1->1     - print the mapping
919    */
920   if (swz_x == GEN_CHANNEL_X &&
921       swz_y == GEN_CHANNEL_Y &&
922       swz_z == GEN_CHANNEL_Z &&
923       swz_w == GEN_CHANNEL_W) {
924     ;
925   } else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w) {
926     string(file, ".");
927     err |= control(file, "channel select", chan_sel, swz_x, NULL);
928   } else {
929     string(file, ".");
930     err |= control(file, "channel select", chan_sel, swz_x, NULL);
931     err |= control(file, "channel select", chan_sel, swz_y, NULL);
932     err |= control(file, "channel select", chan_sel, swz_z, NULL);
933     err |= control(file, "channel select", chan_sel, swz_w, NULL);
934   }
935   return err;
936 }
937
938 static int src2_3src(FILE *file, const void* inst)
939 {
940   int err = 0;
941   uint32_t swz_x = (GEN_BITS_FIELD(inst, bits3.da3src.src2_swizzle) >> 0) & 0x3;
942   uint32_t swz_y = (GEN_BITS_FIELD(inst, bits3.da3src.src2_swizzle) >> 2) & 0x3;
943   uint32_t swz_z = (GEN_BITS_FIELD(inst, bits3.da3src.src2_swizzle) >> 4) & 0x3;
944   uint32_t swz_w = (GEN_BITS_FIELD(inst, bits3.da3src.src2_swizzle) >> 6) & 0x3;
945
946   err |= control(file, "negate", negate, GEN_BITS_FIELD(inst, bits1.da3src.src2_negate), NULL);
947   err |= control(file, "abs", _abs, GEN_BITS_FIELD(inst, bits1.da3src.src2_abs), NULL);
948   err |= reg(file, GEN_GENERAL_REGISTER_FILE, GEN_BITS_FIELD(inst, bits3.da3src.src2_reg_nr));
949   if (err == -1)
950     return 0;
951   if (GEN_BITS_FIELD(inst, bits3.da3src.src2_subreg_nr))
952     format(file, ".%d", GEN_BITS_FIELD(inst, bits3.da3src.src2_subreg_nr));
953   string(file, "<4,1,1>");
954   err |= control(file, "src da16 reg type", reg_encoding,
955                  GEN_TYPE_F, NULL);
956   /*
957    * Three kinds of swizzle display:
958    *  identity - nothing printed
959    *  1->all     - print the single channel
960    *  1->1     - print the mapping
961    */
962   if (swz_x == GEN_CHANNEL_X &&
963       swz_y == GEN_CHANNEL_Y &&
964       swz_z == GEN_CHANNEL_Z &&
965       swz_w == GEN_CHANNEL_W) {
966     ;
967   } else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w) {
968     string(file, ".");
969     err |= control(file, "channel select", chan_sel, swz_x, NULL);
970   } else {
971     string(file, ".");
972     err |= control(file, "channel select", chan_sel, swz_x, NULL);
973     err |= control(file, "channel select", chan_sel, swz_y, NULL);
974     err |= control(file, "channel select", chan_sel, swz_z, NULL);
975     err |= control(file, "channel select", chan_sel, swz_w, NULL);
976   }
977   return err;
978 }
979
980 static int imm(FILE *file, uint32_t type, const void* inst)
981 {
982   switch (type) {
983     case GEN_TYPE_UD:
984       format(file, "0x%xUD", GEN_BITS_FIELD(inst, bits3.ud));
985       break;
986     case GEN_TYPE_D:
987       format(file, "%dD", GEN_BITS_FIELD(inst, bits3.d));
988       break;
989     case GEN_TYPE_UW:
990       format(file, "0x%xUW", (uint16_t) GEN_BITS_FIELD(inst, bits3.ud));
991       break;
992     case GEN_TYPE_W:
993       format(file, "%dW", (int16_t) GEN_BITS_FIELD(inst, bits3.d));
994       break;
995     case GEN_TYPE_UB:
996       format(file, "0x%xUB", (int8_t) GEN_BITS_FIELD(inst, bits3.ud));
997       break;
998     case GEN_TYPE_VF:
999       format(file, "Vector Float");
1000       break;
1001     case GEN_TYPE_V:
1002       format(file, "0x%xV", GEN_BITS_FIELD(inst, bits3.ud));
1003       break;
1004     case GEN_TYPE_F:
1005       format(file, "%-gF", GEN_BITS_FIELD(inst, bits3.f));
1006   }
1007   return 0;
1008 }
1009
1010 static int src0(FILE *file, const void* inst)
1011 {
1012   if (GEN_BITS_FIELD(inst, bits1.da1.src0_reg_file) == GEN_IMMEDIATE_VALUE)
1013     return imm(file, GEN_BITS_FIELD(inst, bits1.da1.src0_reg_type), inst);
1014   else if (ACCESS_MODE(inst) == GEN_ALIGN_1) {
1015     if (GEN_BITS_FIELD(inst, bits2.da1.src0_address_mode) == GEN_ADDRESS_DIRECT) {
1016       return src_da1(file,
1017                      GEN_BITS_FIELD(inst, bits1.da1.src0_reg_type),
1018                      GEN_BITS_FIELD(inst, bits1.da1.src0_reg_file),
1019                      GEN_BITS_FIELD(inst, bits2.da1.src0_vert_stride),
1020                      GEN_BITS_FIELD(inst, bits2.da1.src0_width),
1021                      GEN_BITS_FIELD(inst, bits2.da1.src0_horiz_stride),
1022                      GEN_BITS_FIELD(inst, bits2.da1.src0_reg_nr),
1023                      GEN_BITS_FIELD(inst, bits2.da1.src0_subreg_nr),
1024                      GEN_BITS_FIELD(inst, bits2.da1.src0_abs),
1025                      GEN_BITS_FIELD(inst, bits2.da1.src0_negate));
1026     } else {
1027       return src_ia1(file,
1028                      GEN_BITS_FIELD(inst, bits1.ia1.src0_reg_type),
1029                      GEN_BITS_FIELD(inst, bits1.ia1.src0_reg_file),
1030                      GEN_BITS_FIELD(inst, bits2.ia1.src0_indirect_offset),
1031                      GEN_BITS_FIELD(inst, bits2.ia1.src0_subreg_nr),
1032                      GEN_BITS_FIELD(inst, bits2.ia1.src0_negate),
1033                      GEN_BITS_FIELD(inst, bits2.ia1.src0_abs),
1034                      GEN_BITS_FIELD(inst, bits2.ia1.src0_address_mode),
1035                      GEN_BITS_FIELD(inst, bits2.ia1.src0_horiz_stride),
1036                      GEN_BITS_FIELD(inst, bits2.ia1.src0_width),
1037                      GEN_BITS_FIELD(inst, bits2.ia1.src0_vert_stride));
1038     }
1039   } else {
1040     if (GEN_BITS_FIELD(inst, bits2.da16.src0_address_mode) == GEN_ADDRESS_DIRECT) {
1041       return src_da16(file,
1042                       GEN_BITS_FIELD(inst, bits1.da16.src0_reg_type),
1043                       GEN_BITS_FIELD(inst, bits1.da16.src0_reg_file),
1044                       GEN_BITS_FIELD(inst, bits2.da16.src0_vert_stride),
1045                       GEN_BITS_FIELD(inst, bits2.da16.src0_reg_nr),
1046                       GEN_BITS_FIELD(inst, bits2.da16.src0_subreg_nr),
1047                       GEN_BITS_FIELD(inst, bits2.da16.src0_abs),
1048                       GEN_BITS_FIELD(inst, bits2.da16.src0_negate),
1049                       GEN_BITS_FIELD(inst, bits2.da16.src0_swz_x),
1050                       GEN_BITS_FIELD(inst, bits2.da16.src0_swz_y),
1051                       GEN_BITS_FIELD(inst, bits2.da16.src0_swz_z),
1052                       GEN_BITS_FIELD(inst, bits2.da16.src0_swz_w));
1053     } else {
1054       string(file, "Indirect align16 address mode not supported");
1055       return 1;
1056     }
1057   }
1058 }
1059
1060 static int src1(FILE *file, const void* inst)
1061 {
1062   if (GEN_BITS_FIELD2(inst, bits1.da1.src1_reg_file, bits2.da1.src1_reg_file) == GEN_IMMEDIATE_VALUE)
1063     return imm(file, GEN_BITS_FIELD2(inst, bits1.da1.src1_reg_type, bits2.da1.src1_reg_type),
1064                inst);
1065   else if (ACCESS_MODE(inst) == GEN_ALIGN_1) {
1066     if (GEN_BITS_FIELD(inst, bits3.da1.src1_address_mode) == GEN_ADDRESS_DIRECT) {
1067       return src_da1(file,
1068                      GEN_BITS_FIELD2(inst, bits1.da1.src1_reg_type, bits2.da1.src1_reg_type),
1069                      GEN_BITS_FIELD2(inst, bits1.da1.src1_reg_file, bits2.da1.src1_reg_file),
1070                      GEN_BITS_FIELD(inst, bits3.da1.src1_vert_stride),
1071                      GEN_BITS_FIELD(inst, bits3.da1.src1_width),
1072                      GEN_BITS_FIELD(inst, bits3.da1.src1_horiz_stride),
1073                      GEN_BITS_FIELD(inst, bits3.da1.src1_reg_nr),
1074                      GEN_BITS_FIELD(inst, bits3.da1.src1_subreg_nr),
1075                      GEN_BITS_FIELD(inst, bits3.da1.src1_abs),
1076                      GEN_BITS_FIELD(inst, bits3.da1.src1_negate));
1077     } else {
1078       return src_ia1(file,
1079                      GEN_BITS_FIELD2(inst, bits1.ia1.src1_reg_type, bits2.ia1.src1_reg_type),
1080                      GEN_BITS_FIELD2(inst, bits1.ia1.src1_reg_file, bits2.ia1.src1_reg_file),
1081                      GEN_BITS_FIELD(inst, bits3.ia1.src1_indirect_offset),
1082                      GEN_BITS_FIELD(inst, bits3.ia1.src1_subreg_nr),
1083                      GEN_BITS_FIELD(inst, bits3.ia1.src1_negate),
1084                      GEN_BITS_FIELD(inst, bits3.ia1.src1_abs),
1085                      GEN_BITS_FIELD(inst, bits3.ia1.src1_address_mode),
1086                      GEN_BITS_FIELD(inst, bits3.ia1.src1_horiz_stride),
1087                      GEN_BITS_FIELD(inst, bits3.ia1.src1_width),
1088                      GEN_BITS_FIELD(inst, bits3.ia1.src1_vert_stride));
1089     }
1090   } else {
1091     if (GEN_BITS_FIELD(inst, bits3.da16.src1_address_mode) == GEN_ADDRESS_DIRECT) {
1092       return src_da16(file,
1093                       GEN_BITS_FIELD2(inst, bits1.da16.src1_reg_type, bits2.da16.src1_reg_type),
1094                       GEN_BITS_FIELD2(inst, bits1.da16.src1_reg_file, bits2.da16.src1_reg_file),
1095                       GEN_BITS_FIELD(inst, bits3.da16.src1_vert_stride),
1096                       GEN_BITS_FIELD(inst, bits3.da16.src1_reg_nr),
1097                       GEN_BITS_FIELD(inst, bits3.da16.src1_subreg_nr),
1098                       GEN_BITS_FIELD(inst, bits3.da16.src1_abs),
1099                       GEN_BITS_FIELD(inst, bits3.da16.src1_negate),
1100                       GEN_BITS_FIELD(inst, bits3.da16.src1_swz_x),
1101                       GEN_BITS_FIELD(inst, bits3.da16.src1_swz_y),
1102                       GEN_BITS_FIELD(inst, bits3.da16.src1_swz_z),
1103                       GEN_BITS_FIELD(inst, bits3.da16.src1_swz_w));
1104     } else {
1105       string(file, "Indirect align16 address mode not supported");
1106       return 1;
1107     }
1108   }
1109 }
1110
1111 static const int esize[6] = {
1112   [0] = 1,
1113   [1] = 2,
1114   [2] = 4,
1115   [3] = 8,
1116   [4] = 16,
1117   [5] = 32,
1118 };
1119
1120 static int qtr_ctrl(FILE *file, const void* inst)
1121 {
1122   int qtr_ctl = QUARTER_CONTROL(inst);
1123   int exec_size = esize[EXECUTION_SIZE(inst)];
1124
1125   if (exec_size == 8) {
1126     switch (qtr_ctl) {
1127       case 0:
1128         string(file, " 1Q");
1129         break;
1130       case 1:
1131         string(file, " 2Q");
1132         break;
1133       case 2:
1134         string(file, " 3Q");
1135         break;
1136       case 3:
1137         string(file, " 4Q");
1138         break;
1139     }
1140   } else if (exec_size == 16) {
1141     if (qtr_ctl < 2)
1142       string(file, " 1H");
1143     else
1144       string(file, " 2H");
1145   }
1146   return 0;
1147 }
1148
1149 int gen_disasm (FILE *file, const void *inst, uint32_t deviceID, uint32_t compacted)
1150 {
1151   int err = 0;
1152   int space = 0;
1153   if (IS_IVYBRIDGE(deviceID)) {
1154     gen_version = 70;
1155   } else if (IS_HASWELL(deviceID)) {
1156     gen_version = 75;
1157   } else if (IS_BROADWELL(deviceID)) {
1158     gen_version = 80;
1159   }
1160
1161   if (PRED_CTRL(inst)) {
1162     string(file, "(");
1163     err |= control(file, "predicate inverse", pred_inv, PRED_INV(inst), NULL);
1164     format(file, "f%d", FLAG_REG_NR(inst));
1165     if (FLAG_SUB_REG_NR(inst))
1166       format(file, ".%d", FLAG_SUB_REG_NR(inst));
1167     if (ACCESS_MODE(inst) == GEN_ALIGN_1)
1168       err |= control(file, "predicate control align1", pred_ctrl_align1,
1169                      PRED_CTRL(inst), NULL);
1170     else
1171       err |= control(file, "predicate control align16", pred_ctrl_align16,
1172                      PRED_CTRL(inst), NULL);
1173     string(file, ") ");
1174   }
1175
1176   err |= print_opcode(file, OPCODE(inst));
1177   err |= control(file, "saturate", saturate, SATURATE(inst), NULL);
1178   err |= control(file, "debug control", debug_ctrl, DEBUG_CONTROL(inst), NULL);
1179
1180   if (OPCODE(inst) == GEN_OPCODE_MATH) {
1181     string(file, " ");
1182     if (gen_version < 80) {
1183       err |= control(file, "function", math_function_gen7,
1184                      MATH_FUNCTION(inst), &space);
1185     } else {
1186       err |= control(file, "function", math_function_gen8,
1187                      MATH_FUNCTION(inst), &space);
1188     }
1189
1190     err |= control(file, "math saturate", math_saturate,
1191                    MATH_SATURATE(inst), &space);
1192     err |= control(file, "math signed", math_signed,
1193                    MATH_SIGNED(inst), &space);
1194     err |= control(file, "math scalar", math_scalar,
1195                    MATH_SCALAR(inst), &space);
1196     err |= control(file, "math precision", math_precision,
1197                    MATH_PRECISION(inst), &space);
1198   } else if (OPCODE(inst) != GEN_OPCODE_SEND &&
1199              OPCODE(inst) != GEN_OPCODE_SENDC) {
1200     err |= control(file, "conditional modifier", conditional_modifier,
1201                    COND_DST_OR_MODIFIER(inst), NULL);
1202     if (COND_DST_OR_MODIFIER(inst))
1203       err |= flag_reg(file,
1204                       FLAG_REG_NR(inst),
1205                       FLAG_SUB_REG_NR(inst));
1206   }
1207
1208   if (OPCODE(inst) != GEN_OPCODE_NOP) {
1209     string(file, "(");
1210     err |= control(file, "execution size", exec_size, EXECUTION_SIZE(inst), NULL);
1211     string(file, ")");
1212   }
1213
1214   if (opcode[OPCODE(inst)].nsrc == 3) {
1215     pad(file, 16);
1216     err |= dest_3src(file, inst);
1217
1218     pad(file, 32);
1219     err |= src0_3src(file, inst);
1220
1221     pad(file, 48);
1222     err |= src1_3src(file, inst);
1223
1224     pad(file, 64);
1225     err |= src2_3src(file, inst);
1226   } else {
1227     if (opcode[OPCODE(inst)].ndst > 0) {
1228       pad(file, 16);
1229       err |= dest(file, inst);
1230     } else if (OPCODE(inst) == GEN_OPCODE_IF ||
1231                OPCODE(inst) == GEN_OPCODE_ELSE ||
1232                OPCODE(inst) == GEN_OPCODE_ENDIF ||
1233                OPCODE(inst) == GEN_OPCODE_WHILE ||
1234                OPCODE(inst) == GEN_OPCODE_BRD ||
1235                OPCODE(inst) == GEN_OPCODE_JMPI) {
1236       format(file, " %d", (int16_t)BRANCH_JIP(inst));
1237     } else if (OPCODE(inst) == GEN_OPCODE_BREAK ||
1238                OPCODE(inst) == GEN_OPCODE_CONTINUE ||
1239                OPCODE(inst) == GEN_OPCODE_HALT ||
1240                OPCODE(inst) == GEN_OPCODE_BRC) {
1241       format(file, " %d %d", BRANCH_JIP(inst), BRANCH_UIP(inst));
1242     }/* else if (inst->header.opcode == GEN_OPCODE_JMPI) {
1243       format(file, " %d", inst->bits3.d);
1244     }*/
1245
1246     if (opcode[OPCODE(inst)].nsrc > 0) {
1247       pad(file, 32);
1248       err |= src0(file, inst);
1249     }
1250     if (opcode[OPCODE(inst)].nsrc > 1) {
1251       pad(file, 48);
1252       err |= src1(file, inst);
1253     }
1254   }
1255
1256   if (OPCODE(inst) == GEN_OPCODE_SEND ||
1257       OPCODE(inst) == GEN_OPCODE_SENDC) {
1258     enum GenMessageTarget target = COND_DST_OR_MODIFIER(inst);
1259
1260     newline(file);
1261     pad(file, 16);
1262     space = 0;
1263
1264     if(gen_version >= 75) {
1265       err |= control(file, "target function", target_function_gen75,
1266                      target, &space);
1267     } else {
1268       err |= control(file, "target function", target_function_gen7,
1269                      target, &space);
1270     }
1271
1272     switch (target) {
1273       case GEN_SFID_SAMPLER:
1274         format(file, " (%d, %d, %d, %d)",
1275                SAMPLE_BTI(inst),
1276                SAMPLER(inst),
1277                SAMPLER_MSG_TYPE(inst),
1278                SAMPLER_SIMD_MODE(inst));
1279         break;
1280       case GEN_SFID_DATAPORT_DATA:
1281         if(UNTYPED_RW_CATEGORY(inst) == 0) {
1282           format(file, " (bti: %d, rgba: %d, %s, %s, %s)",
1283                  UNTYPED_RW_BTI(inst),
1284                  UNTYPED_RW_RGBA(inst),
1285                  data_port_data_cache_simd_mode[UNTYPED_RW_SIMD_MODE(inst)],
1286                  data_port_data_cache_category[UNTYPED_RW_CATEGORY(inst)],
1287                  data_port_data_cache_msg_type[UNTYPED_RW_MSG_TYPE(inst)]);
1288         } else {
1289           format(file, " (addr: %d, blocks: %s, %s, mode: %s, %s)",
1290                  SCRATCH_RW_OFFSET(inst),
1291                  data_port_scratch_block_size[SCRATCH_RW_BLOCK_SIZE(inst)],
1292                  data_port_scratch_invalidate[SCRATCH_RW_INVALIDATE_AFTER_READ(inst)],
1293                  data_port_scratch_channel_mode[SCRATCH_RW_CHANNEL_MODE(inst)],
1294                  data_port_scratch_msg_type[SCRATCH_RW_MSG_TYPE(inst)]);
1295         }
1296         break;
1297       case GEN_SFID_DATAPORT1_DATA:
1298         format(file, " (bti: %d, rgba: %d, %s, %s, %s)",
1299                UNTYPED_RW_BTI(inst),
1300                UNTYPED_RW_RGBA(inst),
1301                data_port_data_cache_simd_mode[UNTYPED_RW_SIMD_MODE(inst)],
1302                data_port_data_cache_category[UNTYPED_RW_CATEGORY(inst)],
1303                data_port1_data_cache_msg_type[UNTYPED_RW_MSG_TYPE(inst)]);
1304         break;
1305       case GEN_SFID_DATAPORT_CONSTANT:
1306         format(file, " (bti: %d, %s)",
1307                DWORD_RW_BTI(inst),
1308                data_port_data_cache_msg_type[DWORD_RW_MSG_TYPE(inst)]);
1309         break;
1310       case GEN_SFID_MESSAGE_GATEWAY:
1311         format(file, " (subfunc: %s, notify: %d, ackreq: %d)",
1312                gateway_sub_function[MSG_GW_SUBFUNC(inst)],
1313                MSG_GW_NOTIFY(inst),
1314                MSG_GW_ACKREQ(inst));
1315         break;
1316
1317       default:
1318         format(file, "unsupported target %d", target);
1319         break;
1320     }
1321     if (space)
1322       string(file, " ");
1323     format(file, "mlen %d", GENERIC_MSG_LENGTH(inst));
1324     format(file, " rlen %d", GENERIC_RESPONSE_LENGTH(inst));
1325   }
1326   pad(file, 64);
1327   if (OPCODE(inst) != GEN_OPCODE_NOP) {
1328     string(file, "{");
1329     space = 1;
1330     err |= control(file, "access mode", access_mode, ACCESS_MODE(inst), &space);
1331     err |= control(file, "write enable control", wectrl, MASK_CONTROL(inst), &space);
1332     err |= control(file, "dependency control", dep_ctrl, DEPENDENCY_CONTROL(inst), &space);
1333
1334     err |= qtr_ctrl(file, inst);
1335     if (gen_version < 80) {
1336       err |= control(file, "thread control", thread_ctrl_gen7, THREAD_CONTROL(inst), &space);
1337     } else {
1338       err |= control(file, "thread control", thread_ctrl_gen8, THREAD_CONTROL(inst), &space);
1339     }
1340     err |= control(file, "acc write control", accwr, ACC_WR_CONTROL(inst), &space);
1341     if (OPCODE(inst) == GEN_OPCODE_SEND ||
1342         OPCODE(inst) == GEN_OPCODE_SENDC)
1343       err |= control(file, "end of thread", end_of_thread,
1344                      END_OF_THREAD(inst), &space);
1345
1346     if(compacted) {
1347       string(file, " Compacted");
1348     }
1349     if (space)
1350       string(file, " ");
1351     string(file, "}");
1352   }
1353   string(file, ";");
1354   newline(file);
1355   return err;
1356 }
1357