• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2015-2019 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 /** @file
25  *
26  * This file implements a pass that validates shader assembly.
27  *
28  * The restrictions implemented herein are intended to verify that instructions
29  * in shader assembly do not violate restrictions documented in the graphics
30  * programming reference manuals.
31  *
32  * The restrictions are difficult for humans to quickly verify due to their
33  * complexity and abundance.
34  *
35  * It is critical that this code is thoroughly unit tested because false
36  * results will lead developers astray, which is worse than having no validator
37  * at all. Functional changes to this file without corresponding unit tests (in
38  * test_eu_validate.cpp) will be rejected.
39  */
40 
41 #include <stdlib.h>
42 #include "brw_eu.h"
43 #include "brw_disasm_info.h"
44 
45 enum brw_hw_instr_format {
46    FORMAT_BASIC,
47    FORMAT_BASIC_THREE_SRC,
48    FORMAT_DPAS_THREE_SRC,
49    FORMAT_SEND,
50    FORMAT_BRANCH,
51    FORMAT_ILLEGAL,
52    FORMAT_NOP,
53 };
54 
55 typedef struct brw_hw_decoded_inst {
56    const brw_eu_inst *raw;
57 
58    enum brw_hw_instr_format format;
59 
60    enum opcode opcode;
61 
62    unsigned exec_size;
63    unsigned access_mode;
64 
65    enum brw_conditional_mod cond_modifier;
66    enum brw_predicate pred_control;
67    bool saturate;
68 
69    bool has_dst;
70    struct {
71       enum brw_reg_file file;
72       enum brw_reg_type type;
73       unsigned address_mode;
74 
75       /* These are already physical register numbers. */
76       unsigned nr;
77       unsigned subnr;
78 
79       unsigned hstride;
80    } dst;
81 
82    unsigned num_sources;
83    struct {
84       enum brw_reg_file file;
85       enum brw_reg_type type;
86       unsigned address_mode;
87       bool negate;
88       bool abs;
89 
90       /* These are already physical register numbers. */
91       unsigned nr;
92       unsigned subnr;
93 
94       unsigned vstride;
95       unsigned width;
96       unsigned hstride;
97    } src[3];
98 } brw_hw_decoded_inst;
99 
100 /* We're going to do lots of string concatenation, so this should help. */
101 struct string {
102    char *str;
103    size_t len;
104 };
105 
106 static void
cat(struct string * dest,const struct string src)107 cat(struct string *dest, const struct string src)
108 {
109    dest->str = realloc(dest->str, dest->len + src.len + 1);
110    memcpy(dest->str + dest->len, src.str, src.len);
111    dest->str[dest->len + src.len] = '\0';
112    dest->len = dest->len + src.len;
113 }
114 #define CAT(dest, src) cat(&dest, (struct string){src, strlen(src)})
115 
116 static bool
contains(const struct string haystack,const struct string needle)117 contains(const struct string haystack, const struct string needle)
118 {
119    return haystack.str && memmem(haystack.str, haystack.len,
120                                  needle.str, needle.len) != NULL;
121 }
122 #define CONTAINS(haystack, needle) \
123    contains(haystack, (struct string){needle, strlen(needle)})
124 
125 #define error(str)   "\tERROR: " str "\n"
126 #define ERROR_INDENT "\t       "
127 
128 #define ERROR(msg) ERROR_IF(true, msg)
129 #define ERROR_IF(cond, msg)                             \
130    do {                                                 \
131       if ((cond) && !CONTAINS(error_msg, error(msg))) { \
132          CAT(error_msg, error(msg));                    \
133       }                                                 \
134    } while(0)
135 
136 #define RETURN_ERROR(msg) RETURN_ERROR_IF(true, msg)
137 #define RETURN_ERROR_IF(cond, msg)                      \
138    do {                                                 \
139       if ((cond) && !CONTAINS(error_msg, error(msg))) { \
140          CAT(error_msg, error(msg));                    \
141          return error_msg;                              \
142       }                                                 \
143    } while(0)
144 
145 #define STRIDE(stride) (stride != 0 ? 1 << ((stride) - 1) : 0)
146 #define WIDTH(width)   (1 << (width))
147 
148 static bool
inst_is_send(const brw_hw_decoded_inst * inst)149 inst_is_send(const brw_hw_decoded_inst *inst)
150 {
151    switch (inst->opcode) {
152    case BRW_OPCODE_SEND:
153    case BRW_OPCODE_SENDC:
154    case BRW_OPCODE_SENDS:
155    case BRW_OPCODE_SENDSC:
156       return true;
157    default:
158       return false;
159    }
160 }
161 
162 static bool
inst_is_split_send(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)163 inst_is_split_send(const struct brw_isa_info *isa, const brw_hw_decoded_inst *inst)
164 {
165    const struct intel_device_info *devinfo = isa->devinfo;
166 
167    if (devinfo->ver >= 12) {
168       return inst_is_send(inst);
169    } else {
170       switch (inst->opcode) {
171       case BRW_OPCODE_SENDS:
172       case BRW_OPCODE_SENDSC:
173          return true;
174       default:
175          return false;
176       }
177    }
178 }
179 
180 static unsigned
signed_type(unsigned type)181 signed_type(unsigned type)
182 {
183    return brw_type_is_uint(type) ? (type | BRW_TYPE_BASE_SINT) : type;
184 }
185 
186 static bool
inst_is_raw_move(const brw_hw_decoded_inst * inst)187 inst_is_raw_move(const brw_hw_decoded_inst *inst)
188 {
189    unsigned dst_type = signed_type(inst->dst.type);
190    unsigned src_type = signed_type(inst->src[0].type);
191 
192    if (inst->src[0].file == IMM) {
193       /* FIXME: not strictly true */
194       if (brw_type_is_vector_imm(inst->src[0].type))
195          return false;
196    } else if (inst->src[0].negate || inst->src[0].abs) {
197       return false;
198    }
199 
200    return inst->opcode == BRW_OPCODE_MOV &&
201           !inst->saturate &&
202           dst_type == src_type;
203 }
204 
205 static bool
dst_is_null(const brw_hw_decoded_inst * inst)206 dst_is_null(const brw_hw_decoded_inst *inst)
207 {
208    return inst->dst.file == ARF && inst->dst.nr == BRW_ARF_NULL;
209 }
210 
211 static bool
src0_is_null(const brw_hw_decoded_inst * inst)212 src0_is_null(const brw_hw_decoded_inst *inst)
213 {
214    return inst->src[0].address_mode == BRW_ADDRESS_DIRECT &&
215           inst->src[0].file == ARF &&
216           inst->src[0].nr == BRW_ARF_NULL;
217 }
218 
219 static bool
src1_is_null(const brw_hw_decoded_inst * inst)220 src1_is_null(const brw_hw_decoded_inst *inst)
221 {
222    assert(inst->src[1].address_mode == BRW_ADDRESS_DIRECT);
223    return inst->src[1].file == ARF &&
224           inst->src[1].nr == BRW_ARF_NULL;
225 }
226 
227 static bool
src0_is_acc(const brw_hw_decoded_inst * inst)228 src0_is_acc(const brw_hw_decoded_inst *inst)
229 {
230    return inst->src[0].address_mode == BRW_ADDRESS_DIRECT &&
231           inst->src[0].file == ARF &&
232           (inst->src[0].nr & 0xF0) == BRW_ARF_ACCUMULATOR;
233 }
234 
235 static bool
src1_is_acc(const brw_hw_decoded_inst * inst)236 src1_is_acc(const brw_hw_decoded_inst *inst)
237 {
238    assert(inst->src[1].address_mode == BRW_ADDRESS_DIRECT);
239    return inst->src[1].file == ARF &&
240           (inst->src[1].nr & 0xF0) == BRW_ARF_ACCUMULATOR;
241 }
242 
243 static bool
src_has_scalar_region(const brw_hw_decoded_inst * inst,int src)244 src_has_scalar_region(const brw_hw_decoded_inst *inst, int src)
245 {
246    return inst->src[src].vstride == 0 &&
247           inst->src[src].width == 1 &&
248           inst->src[src].hstride == 0;
249 }
250 
251 static struct string
invalid_values(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)252 invalid_values(const struct brw_isa_info *isa, const brw_hw_decoded_inst *inst)
253 {
254    const struct intel_device_info *devinfo = isa->devinfo;
255 
256    struct string error_msg = { .str = NULL, .len = 0 };
257 
258    if (devinfo->ver >= 12) {
259       unsigned qtr_ctrl = brw_eu_inst_qtr_control(devinfo, inst->raw);
260       unsigned nib_ctrl =
261          devinfo->ver == 12 ? brw_eu_inst_nib_control(devinfo, inst->raw) : 0;
262 
263       unsigned chan_off = (qtr_ctrl * 2 + nib_ctrl) << 2;
264       ERROR_IF(chan_off % inst->exec_size != 0,
265                "The execution size must be a factor of the chosen offset");
266    }
267 
268    return error_msg;
269 }
270 
271 static struct string
sources_not_null(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)272 sources_not_null(const struct brw_isa_info *isa,
273                  const brw_hw_decoded_inst *inst)
274 {
275    struct string error_msg = { .str = NULL, .len = 0 };
276 
277    /* Nothing to test. 3-src instructions can only have GRF sources, and
278     * there's no bit to control the file.
279     */
280    if (inst->num_sources == 3)
281       return (struct string){};
282 
283    /* Nothing to test.  Split sends can only encode a file in sources that are
284     * allowed to be NULL.
285     */
286    if (inst_is_split_send(isa, inst))
287       return (struct string){};
288 
289    if (inst->num_sources >= 1 && inst->opcode != BRW_OPCODE_SYNC)
290       ERROR_IF(src0_is_null(inst), "src0 is null");
291 
292    if (inst->num_sources == 2)
293       ERROR_IF(src1_is_null(inst), "src1 is null");
294 
295    return error_msg;
296 }
297 
298 static bool
inst_uses_src_acc(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)299 inst_uses_src_acc(const struct brw_isa_info *isa,
300                   const brw_hw_decoded_inst *inst)
301 {
302    /* Check instructions that use implicit accumulator sources */
303    switch (inst->opcode) {
304    case BRW_OPCODE_MAC:
305    case BRW_OPCODE_MACH:
306       return true;
307    default:
308       break;
309    }
310 
311    /* FIXME: support 3-src instructions */
312    assert(inst->num_sources < 3);
313 
314    return src0_is_acc(inst) || (inst->num_sources > 1 && src1_is_acc(inst));
315 }
316 
317 static struct string
send_restrictions(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)318 send_restrictions(const struct brw_isa_info *isa,
319                   const brw_hw_decoded_inst *inst)
320 {
321    const struct intel_device_info *devinfo = isa->devinfo;
322 
323    struct string error_msg = { .str = NULL, .len = 0 };
324 
325    if (inst_is_split_send(isa, inst)) {
326       ERROR_IF(inst->src[1].file == ARF &&
327                inst->src[1].nr != BRW_ARF_NULL,
328                "src1 of split send must be a GRF or NULL");
329 
330       if (devinfo->ver < 30) {
331          ERROR_IF(brw_eu_inst_eot(devinfo, inst->raw) &&
332                   inst->src[0].nr < 112,
333                   "send with EOT must use g112-g127");
334          ERROR_IF(brw_eu_inst_eot(devinfo, inst->raw) &&
335                   inst->src[1].file == FIXED_GRF &&
336                   inst->src[1].nr < 112,
337                   "send with EOT must use g112-g127");
338       }
339 
340       if (inst->src[0].file == FIXED_GRF && inst->src[1].file == FIXED_GRF) {
341          /* Assume minimums if we don't know */
342          unsigned mlen = 1;
343          if (!brw_eu_inst_send_sel_reg32_desc(devinfo, inst->raw)) {
344             const uint32_t desc = brw_eu_inst_send_desc(devinfo, inst->raw);
345             mlen = brw_message_desc_mlen(devinfo, desc) / reg_unit(devinfo);
346          }
347 
348          unsigned ex_mlen = 1;
349          if (!brw_eu_inst_send_sel_reg32_ex_desc(devinfo, inst->raw)) {
350             const uint32_t ex_desc = brw_eu_inst_sends_ex_desc(devinfo, inst->raw, false);
351             ex_mlen = brw_message_ex_desc_ex_mlen(devinfo, ex_desc) /
352                       reg_unit(devinfo);
353          }
354          const unsigned src0_reg_nr = inst->src[0].nr;
355          const unsigned src1_reg_nr = inst->src[1].nr;
356          ERROR_IF((src0_reg_nr <= src1_reg_nr &&
357                    src1_reg_nr < src0_reg_nr + mlen) ||
358                   (src1_reg_nr <= src0_reg_nr &&
359                    src0_reg_nr < src1_reg_nr + ex_mlen),
360                    "split send payloads must not overlap");
361       }
362    } else if (inst_is_send(inst)) {
363       ERROR_IF(inst->src[0].address_mode != BRW_ADDRESS_DIRECT,
364                "send must use direct addressing");
365 
366       ERROR_IF(inst->src[0].file != FIXED_GRF,
367                "send from non-GRF");
368       ERROR_IF(brw_eu_inst_eot(devinfo, inst->raw) &&
369                inst->src[0].nr < 112,
370                "send with EOT must use g112-g127");
371 
372       ERROR_IF(!dst_is_null(inst) &&
373                (inst->dst.nr + brw_eu_inst_rlen(devinfo, inst->raw) > 127) &&
374                (inst->src[0].nr + brw_eu_inst_mlen(devinfo, inst->raw) > inst->dst.nr),
375                "r127 must not be used for return address when there is "
376                "a src and dest overlap");
377    }
378 
379    return error_msg;
380 }
381 
382 static bool
is_unsupported_inst(const struct brw_isa_info * isa,const brw_eu_inst * inst)383 is_unsupported_inst(const struct brw_isa_info *isa,
384                     const brw_eu_inst *inst)
385 {
386    return brw_eu_inst_opcode(isa, inst) == BRW_OPCODE_ILLEGAL;
387 }
388 
389 /**
390  * Returns whether a combination of two types would qualify as mixed float
391  * operation mode
392  */
393 static inline bool
types_are_mixed_float(enum brw_reg_type t0,enum brw_reg_type t1)394 types_are_mixed_float(enum brw_reg_type t0, enum brw_reg_type t1)
395 {
396    return (t0 == BRW_TYPE_F && t1 == BRW_TYPE_HF) ||
397           (t1 == BRW_TYPE_F && t0 == BRW_TYPE_HF);
398 }
399 
400 static enum brw_reg_type
execution_type_for_type(enum brw_reg_type type)401 execution_type_for_type(enum brw_reg_type type)
402 {
403    switch (type) {
404    case BRW_TYPE_DF:
405    case BRW_TYPE_F:
406    case BRW_TYPE_HF:
407       return type;
408 
409    case BRW_TYPE_VF:
410       return BRW_TYPE_F;
411 
412    case BRW_TYPE_Q:
413    case BRW_TYPE_UQ:
414       return BRW_TYPE_Q;
415 
416    case BRW_TYPE_D:
417    case BRW_TYPE_UD:
418       return BRW_TYPE_D;
419 
420    case BRW_TYPE_W:
421    case BRW_TYPE_UW:
422    case BRW_TYPE_B:
423    case BRW_TYPE_UB:
424    case BRW_TYPE_V:
425    case BRW_TYPE_UV:
426       return BRW_TYPE_W;
427    default:
428       unreachable("invalid type");
429    }
430 }
431 
432 /**
433  * Returns the execution type of an instruction \p inst
434  */
435 static enum brw_reg_type
execution_type(const brw_hw_decoded_inst * inst)436 execution_type(const brw_hw_decoded_inst *inst)
437 {
438    enum brw_reg_type src0_exec_type, src1_exec_type;
439 
440    /* Execution data type is independent of destination data type, except in
441     * mixed F/HF instructions.
442     */
443    enum brw_reg_type dst_exec_type = inst->dst.type;
444 
445    src0_exec_type = execution_type_for_type(inst->src[0].type);
446    if (inst->num_sources == 1) {
447       if (src0_exec_type == BRW_TYPE_HF)
448          return dst_exec_type;
449       return src0_exec_type;
450    }
451 
452    src1_exec_type = execution_type_for_type(inst->src[1].type);
453    if (types_are_mixed_float(src0_exec_type, src1_exec_type) ||
454        types_are_mixed_float(src0_exec_type, dst_exec_type) ||
455        types_are_mixed_float(src1_exec_type, dst_exec_type)) {
456       return BRW_TYPE_F;
457    }
458 
459    if (src0_exec_type == src1_exec_type)
460       return src0_exec_type;
461 
462    if (src0_exec_type == BRW_TYPE_Q ||
463        src1_exec_type == BRW_TYPE_Q)
464       return BRW_TYPE_Q;
465 
466    if (src0_exec_type == BRW_TYPE_D ||
467        src1_exec_type == BRW_TYPE_D)
468       return BRW_TYPE_D;
469 
470    if (src0_exec_type == BRW_TYPE_W ||
471        src1_exec_type == BRW_TYPE_W)
472       return BRW_TYPE_W;
473 
474    if (src0_exec_type == BRW_TYPE_DF ||
475        src1_exec_type == BRW_TYPE_DF)
476       return BRW_TYPE_DF;
477 
478    unreachable("not reached");
479 }
480 
481 /**
482  * Returns whether a region is packed
483  *
484  * A region is packed if its elements are adjacent in memory, with no
485  * intervening space, no overlap, and no replicated values.
486  */
487 static bool
is_packed(unsigned vstride,unsigned width,unsigned hstride)488 is_packed(unsigned vstride, unsigned width, unsigned hstride)
489 {
490    if (vstride == width) {
491       if (vstride == 1) {
492          return hstride == 0;
493       } else {
494          return hstride == 1;
495       }
496    }
497 
498    return false;
499 }
500 
501 /**
502  * Returns whether a region is linear
503  *
504  * A region is linear if its elements do not overlap and are not replicated.
505  * Unlike a packed region, intervening space (i.e. strided values) is allowed.
506  */
507 static bool
is_linear(unsigned vstride,unsigned width,unsigned hstride)508 is_linear(unsigned vstride, unsigned width, unsigned hstride)
509 {
510    return vstride == width * hstride ||
511           (hstride == 0 && width == 1);
512 }
513 
514 /**
515  * Returns whether an instruction is an explicit or implicit conversion
516  * to/from half-float.
517  */
518 static bool
is_half_float_conversion(const brw_hw_decoded_inst * inst)519 is_half_float_conversion(const brw_hw_decoded_inst *inst)
520 {
521    enum brw_reg_type dst_type = inst->dst.type;
522 
523    enum brw_reg_type src0_type = inst->src[0].type;
524 
525    if (dst_type != src0_type &&
526        (dst_type == BRW_TYPE_HF || src0_type == BRW_TYPE_HF)) {
527       return true;
528    } else if (inst->num_sources > 1) {
529       enum brw_reg_type src1_type = inst->src[1].type;
530       return dst_type != src1_type &&
531             (dst_type == BRW_TYPE_HF ||
532              src1_type == BRW_TYPE_HF);
533    }
534 
535    return false;
536 }
537 
538 /*
539  * Returns whether an instruction is using mixed float operation mode
540  */
541 static bool
is_mixed_float(const brw_hw_decoded_inst * inst)542 is_mixed_float(const brw_hw_decoded_inst *inst)
543 {
544    if (inst_is_send(inst))
545       return false;
546 
547    if (!inst->has_dst)
548       return false;
549 
550    /* FIXME: support 3-src instructions */
551    assert(inst->num_sources < 3);
552 
553    enum brw_reg_type dst_type = inst->dst.type;
554    enum brw_reg_type src0_type = inst->src[0].type;
555 
556    if (inst->num_sources == 1)
557       return types_are_mixed_float(src0_type, dst_type);
558 
559    enum brw_reg_type src1_type = inst->src[1].type;
560 
561    return types_are_mixed_float(src0_type, src1_type) ||
562           types_are_mixed_float(src0_type, dst_type) ||
563           types_are_mixed_float(src1_type, dst_type);
564 }
565 
566 /**
567  * Returns whether an instruction is an explicit or implicit conversion
568  * to/from byte.
569  */
570 static bool
is_byte_conversion(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)571 is_byte_conversion(const struct brw_isa_info *isa,
572                    const brw_hw_decoded_inst *inst)
573 {
574    enum brw_reg_type dst_type = inst->dst.type;
575 
576    enum brw_reg_type src0_type = inst->src[0].type;
577 
578    if (dst_type != src0_type &&
579        (brw_type_size_bytes(dst_type) == 1 ||
580         brw_type_size_bytes(src0_type) == 1)) {
581       return true;
582    } else if (inst->num_sources > 1) {
583       enum brw_reg_type src1_type = inst->src[1].type;
584       return dst_type != src1_type &&
585             (brw_type_size_bytes(dst_type) == 1 ||
586              brw_type_size_bytes(src1_type) == 1);
587    }
588 
589    return false;
590 }
591 
592 /**
593  * Checks restrictions listed in "General Restrictions Based on Operand Types"
594  * in the "Register Region Restrictions" section.
595  */
596 static struct string
general_restrictions_based_on_operand_types(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)597 general_restrictions_based_on_operand_types(const struct brw_isa_info *isa,
598                                             const brw_hw_decoded_inst *inst)
599 {
600    const struct intel_device_info *devinfo = isa->devinfo;
601 
602    struct string error_msg = { .str = NULL, .len = 0 };
603 
604    if (inst_is_send(inst))
605       return error_msg;
606 
607    if (devinfo->ver >= 11) {
608       /* A register type of B or UB for DPAS actually means 4 bytes packed into
609        * a D or UD, so it is allowed.
610        */
611       if (inst->num_sources == 3 && inst->opcode != BRW_OPCODE_DPAS) {
612          ERROR_IF(brw_type_size_bytes(inst->src[1].type) == 1 ||
613                   brw_type_size_bytes(inst->src[2].type) == 1,
614                   "Byte data type is not supported for src1/2 register regioning. This includes "
615                   "byte broadcast as well.");
616       }
617       if (inst->num_sources == 2) {
618          ERROR_IF(brw_type_size_bytes(inst->src[1].type) == 1,
619                   "Byte data type is not supported for src1 register regioning. This includes "
620                   "byte broadcast as well.");
621       }
622    }
623 
624    enum brw_reg_type dst_type = inst->dst.type;
625 
626    ERROR_IF(dst_type == BRW_TYPE_DF &&
627             !devinfo->has_64bit_float,
628             "64-bit float destination, but platform does not support it");
629 
630    ERROR_IF((dst_type == BRW_TYPE_Q ||
631              dst_type == BRW_TYPE_UQ) &&
632             !devinfo->has_64bit_int,
633             "64-bit int destination, but platform does not support it");
634 
635    for (unsigned s = 0; s < inst->num_sources; s++) {
636       enum brw_reg_type src_type = inst->src[s].type;
637 
638       ERROR_IF(src_type == BRW_TYPE_DF &&
639                !devinfo->has_64bit_float,
640                "64-bit float source, but platform does not support it");
641 
642       ERROR_IF((src_type == BRW_TYPE_Q ||
643                 src_type == BRW_TYPE_UQ) &&
644                !devinfo->has_64bit_int,
645                "64-bit int source, but platform does not support it");
646       if (inst->access_mode == BRW_ALIGN_16 &&
647           inst->num_sources == 3 && brw_type_size_bytes(src_type) > 4) {
648          /* From the Broadwell PRM, Volume 7 "3D Media GPGPU", page 944:
649           *
650           *    "This is applicable to 32b datatypes and 16b datatype. 64b
651           *    datatypes cannot use the replicate control."
652           */
653          switch (s) {
654          case 0:
655             ERROR_IF(brw_eu_inst_3src_a16_src0_rep_ctrl(devinfo, inst->raw),
656                      "RepCtrl must be zero for 64-bit source 0");
657             break;
658          case 1:
659             ERROR_IF(brw_eu_inst_3src_a16_src1_rep_ctrl(devinfo, inst->raw),
660                      "RepCtrl must be zero for 64-bit source 1");
661             break;
662          case 2:
663             ERROR_IF(brw_eu_inst_3src_a16_src2_rep_ctrl(devinfo, inst->raw),
664                      "RepCtrl must be zero for 64-bit source 2");
665             break;
666          default: unreachable("invalid src");
667          }
668       }
669    }
670 
671    if (inst->num_sources == 3)
672       return error_msg;
673 
674    if (inst->exec_size == 1)
675       return error_msg;
676 
677    if (!inst->has_dst)
678       return error_msg;
679 
680    if (inst->opcode == BRW_OPCODE_MATH &&
681        intel_needs_workaround(devinfo, 22016140776)) {
682       /* Wa_22016140776:
683        *
684        *    Scalar broadcast on HF math (packed or unpacked) must not be
685        *    used.  Compiler must use a mov instruction to expand the scalar
686        *    value to a vector before using in a HF (packed or unpacked)
687        *    math operation.
688        */
689       ERROR_IF(inst->src[0].type == BRW_TYPE_HF &&
690                src_has_scalar_region(inst, 0),
691                "Scalar broadcast on HF math (packed or unpacked) must not "
692                "be used.");
693 
694       if (inst->num_sources > 1) {
695          ERROR_IF(inst->src[1].type == BRW_TYPE_HF &&
696                   src_has_scalar_region(inst, 1),
697                   "Scalar broadcast on HF math (packed or unpacked) must not "
698                   "be used.");
699       }
700    }
701 
702    /* The PRMs say:
703     *
704     *    Where n is the largest element size in bytes for any source or
705     *    destination operand type, ExecSize * n must be <= 64.
706     *
707     * But we do not attempt to enforce it, because it is implied by other
708     * rules:
709     *
710     *    - that the destination stride must match the execution data type
711     *    - sources may not span more than two adjacent GRF registers
712     *    - destination may not span more than two adjacent GRF registers
713     *
714     * In fact, checking it would weaken testing of the other rules.
715     */
716 
717    unsigned dst_stride = inst->dst.hstride;
718    bool dst_type_is_byte =
719       inst->dst.type == BRW_TYPE_B ||
720       inst->dst.type == BRW_TYPE_UB;
721 
722    if (dst_type_is_byte) {
723       if (is_packed(inst->exec_size * dst_stride, inst->exec_size, dst_stride)) {
724          if (!inst_is_raw_move(inst))
725             ERROR("Only raw MOV supports a packed-byte destination");
726          return error_msg;
727       }
728    }
729 
730    unsigned exec_type = execution_type(inst);
731    unsigned exec_type_size = brw_type_size_bytes(exec_type);
732    unsigned dst_type_size = brw_type_size_bytes(dst_type);
733 
734    if (is_byte_conversion(isa, inst)) {
735       /* From the BDW+ PRM, Volume 2a, Command Reference, Instructions - MOV:
736        *
737        *    "There is no direct conversion from B/UB to DF or DF to B/UB.
738        *     There is no direct conversion from B/UB to Q/UQ or Q/UQ to B/UB."
739        *
740        * Even if these restrictions are listed for the MOV instruction, we
741        * validate this more generally, since there is the possibility
742        * of implicit conversions from other instructions.
743        */
744       enum brw_reg_type src0_type = inst->src[0].type;
745       enum brw_reg_type src1_type = inst->num_sources > 1 ?
746                                     inst->src[1].type : 0;
747 
748       ERROR_IF(brw_type_size_bytes(dst_type) == 1 &&
749                (brw_type_size_bytes(src0_type) == 8 ||
750                 (inst->num_sources > 1 && brw_type_size_bytes(src1_type) == 8)),
751                "There are no direct conversions between 64-bit types and B/UB");
752 
753       ERROR_IF(brw_type_size_bytes(dst_type) == 8 &&
754                (brw_type_size_bytes(src0_type) == 1 ||
755                 (inst->num_sources > 1 && brw_type_size_bytes(src1_type) == 1)),
756                "There are no direct conversions between 64-bit types and B/UB");
757    }
758 
759    if (is_half_float_conversion(inst)) {
760       /**
761        * A helper to validate used in the validation of the following restriction
762        * from the BDW+ PRM, Volume 2a, Command Reference, Instructions - MOV:
763        *
764        *    "There is no direct conversion from HF to DF or DF to HF.
765        *     There is no direct conversion from HF to Q/UQ or Q/UQ to HF."
766        *
767        * Even if these restrictions are listed for the MOV instruction, we
768        * validate this more generally, since there is the possibility
769        * of implicit conversions from other instructions, such us implicit
770        * conversion from integer to HF with the ADD instruction in SKL+.
771        */
772       enum brw_reg_type src0_type = inst->src[0].type;
773       enum brw_reg_type src1_type = inst->num_sources > 1 ?
774                                     inst->src[1].type : 0;
775       ERROR_IF(dst_type == BRW_TYPE_HF &&
776                (brw_type_size_bytes(src0_type) == 8 ||
777                 (inst->num_sources > 1 && brw_type_size_bytes(src1_type) == 8)),
778                "There are no direct conversions between 64-bit types and HF");
779 
780       ERROR_IF(brw_type_size_bytes(dst_type) == 8 &&
781                (src0_type == BRW_TYPE_HF ||
782                 (inst->num_sources > 1 && src1_type == BRW_TYPE_HF)),
783                "There are no direct conversions between 64-bit types and HF");
784 
785       /* From the BDW+ PRM:
786        *
787        *   "Conversion between Integer and HF (Half Float) must be
788        *    DWord-aligned and strided by a DWord on the destination."
789        *
790        * Also, the above restrictions seems to be expanded on CHV and SKL+ by:
791        *
792        *   "There is a relaxed alignment rule for word destinations. When
793        *    the destination type is word (UW, W, HF), destination data types
794        *    can be aligned to either the lowest word or the second lowest
795        *    word of the execution channel. This means the destination data
796        *    words can be either all in the even word locations or all in the
797        *    odd word locations."
798        *
799        * We do not implement the second rule as is though, since empirical
800        * testing shows inconsistencies:
801        *   - It suggests that packed 16-bit is not allowed, which is not true.
802        *   - It suggests that conversions from Q/DF to W (which need to be
803        *     64-bit aligned on the destination) are not possible, which is
804        *     not true.
805        *
806        * So from this rule we only validate the implication that conversions
807        * from F to HF need to be DWord strided (except in Align1 mixed
808        * float mode where packed fp16 destination is allowed so long as the
809        * destination is oword-aligned).
810        *
811        * Finally, we only validate this for Align1 because Align16 always
812        * requires packed destinations, so these restrictions can't possibly
813        * apply to Align16 mode.
814        */
815       if (inst->access_mode == BRW_ALIGN_1) {
816          if ((dst_type == BRW_TYPE_HF &&
817               (brw_type_is_int(src0_type) ||
818                (inst->num_sources > 1 && brw_type_is_int(src1_type)))) ||
819              (brw_type_is_int(dst_type) &&
820               (src0_type == BRW_TYPE_HF ||
821                (inst->num_sources > 1 && src1_type == BRW_TYPE_HF)))) {
822             ERROR_IF(dst_stride * dst_type_size != 4,
823                      "Conversions between integer and half-float must be "
824                      "strided by a DWord on the destination");
825 
826             ERROR_IF(inst->dst.subnr % 4 != 0,
827                      "Conversions between integer and half-float must be "
828                      "aligned to a DWord on the destination");
829          } else if (dst_type == BRW_TYPE_HF) {
830             ERROR_IF(dst_stride != 2 &&
831                      !(is_mixed_float(inst) &&
832                        dst_stride == 1 && inst->dst.subnr % 16 == 0),
833                      "Conversions to HF must have either all words in even "
834                      "word locations or all words in odd word locations or "
835                      "be mixed-float with Oword-aligned packed destination");
836          }
837       }
838    }
839 
840    /* There are special regioning rules for mixed-float mode in CHV and SKL that
841     * override the general rule for the ratio of sizes of the destination type
842     * and the execution type. We will add validation for those in a later patch.
843     */
844    bool validate_dst_size_and_exec_size_ratio = !is_mixed_float(inst);
845 
846    if (validate_dst_size_and_exec_size_ratio &&
847        exec_type_size > dst_type_size) {
848       if (!(dst_type_is_byte && inst_is_raw_move(inst))) {
849          ERROR_IF(dst_stride * dst_type_size != exec_type_size,
850                   "Destination stride must be equal to the ratio of the sizes "
851                   "of the execution data type to the destination type");
852       }
853 
854       unsigned subreg = inst->dst.subnr;
855 
856       if (inst->access_mode == BRW_ALIGN_1 &&
857           inst->dst.address_mode == BRW_ADDRESS_DIRECT) {
858          /* The i965 PRM says:
859           *
860           *    Implementation Restriction: The relaxed alignment rule for byte
861           *    destination (#10.5) is not supported.
862           */
863          if (dst_type_is_byte) {
864             ERROR_IF(subreg % exec_type_size != 0 &&
865                      subreg % exec_type_size != 1,
866                      "Destination subreg must be aligned to the size of the "
867                      "execution data type (or to the next lowest byte for byte "
868                      "destinations)");
869          } else {
870             ERROR_IF(subreg % exec_type_size != 0,
871                      "Destination subreg must be aligned to the size of the "
872                      "execution data type");
873          }
874       }
875    }
876 
877    return error_msg;
878 }
879 
880 /**
881  * Checks restrictions listed in "General Restrictions on Regioning Parameters"
882  * in the "Register Region Restrictions" section.
883  */
884 static struct string
general_restrictions_on_region_parameters(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)885 general_restrictions_on_region_parameters(const struct brw_isa_info *isa,
886                                           const brw_hw_decoded_inst *inst)
887 {
888    const struct intel_device_info *devinfo = isa->devinfo;
889 
890    struct string error_msg = { .str = NULL, .len = 0 };
891 
892    if (inst->num_sources == 3)
893       return (struct string){};
894 
895    /* Split sends don't have the bits in the instruction to encode regions so
896     * there's nothing to check.
897     */
898    if (inst_is_split_send(isa, inst))
899       return (struct string){};
900 
901    if (inst->access_mode == BRW_ALIGN_16) {
902       if (inst->has_dst && !dst_is_null(inst))
903          ERROR_IF(inst->dst.hstride != 1,
904                   "Destination Horizontal Stride must be 1");
905 
906       if (inst->num_sources >= 1) {
907          ERROR_IF(inst->src[0].file != IMM &&
908                   inst->src[0].vstride != 0 &&
909                   inst->src[0].vstride != 2 &&
910                   inst->src[0].vstride != 4,
911                   "In Align16 mode, only VertStride of 0, 2, or 4 is allowed");
912       }
913 
914       if (inst->num_sources == 2) {
915          ERROR_IF(inst->src[1].file != IMM &&
916                   inst->src[1].vstride != 0 &&
917                   inst->src[1].vstride != 2 &&
918                   inst->src[1].vstride != 4,
919                   "In Align16 mode, only VertStride of 0, 2, or 4 is allowed");
920       }
921 
922       return error_msg;
923    }
924 
925    for (unsigned i = 0; i < inst->num_sources; i++) {
926       if (inst->src[i].file == IMM)
927          continue;
928 
929       enum brw_reg_type type = inst->src[i].type;
930       unsigned element_size = brw_type_size_bytes(type);
931       unsigned subreg = inst->src[i].subnr;
932       unsigned vstride = inst->src[i].vstride;
933       unsigned width = inst->src[i].width;
934       unsigned hstride = inst->src[i].hstride;
935 
936       /* ExecSize must be greater than or equal to Width. */
937       ERROR_IF(inst->exec_size < width, "ExecSize must be greater than or equal "
938                                         "to Width");
939 
940       /* If Width = 1, HorzStride must be 0 regardless of the values of
941        * ExecSize and VertStride.
942        */
943       if (width == 1) {
944          ERROR_IF(hstride != 0,
945                   "If Width = 1, HorzStride must be 0 regardless "
946                   "of the values of ExecSize and VertStride");
947       }
948 
949       if (vstride == STRIDE(BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL))
950          continue;
951 
952       /* If ExecSize = Width and HorzStride ≠ 0,
953        * VertStride must be set to Width * HorzStride.
954        */
955       if (inst->exec_size == width && hstride != 0) {
956          ERROR_IF(vstride != width * hstride,
957                   "If ExecSize = Width and HorzStride ≠ 0, "
958                   "VertStride must be set to Width * HorzStride");
959       }
960 
961       /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
962       if (inst->exec_size == 1 && width == 1) {
963          ERROR_IF(vstride != 0 || hstride != 0,
964                   "If ExecSize = Width = 1, both VertStride "
965                   "and HorzStride must be 0");
966       }
967 
968       /* If VertStride = HorzStride = 0, Width must be 1 regardless of the
969        * value of ExecSize.
970        */
971       if (vstride == 0 && hstride == 0) {
972          ERROR_IF(width != 1,
973                   "If VertStride = HorzStride = 0, Width must be "
974                   "1 regardless of the value of ExecSize");
975       }
976 
977       /* VertStride must be used to cross GRF register boundaries. This rule
978        * implies that elements within a 'Width' cannot cross GRF boundaries.
979        */
980       if (inst->src[i].file == FIXED_GRF) {
981          unsigned rowbase = subreg;
982          assert(util_is_power_of_two_nonzero(reg_unit(devinfo)));
983          unsigned grf_size_shift = ffs(REG_SIZE * reg_unit(devinfo)) - 1;
984 
985          for (int y = 0; y < inst->exec_size / width; y++) {
986             bool spans_grfs = false;
987             unsigned offset = rowbase;
988             unsigned first_grf = offset >> grf_size_shift;
989 
990             for (int x = 0; x < width; x++) {
991                const unsigned end_byte = offset + (element_size - 1);
992                const unsigned end_grf = end_byte >> grf_size_shift;
993                spans_grfs = end_grf != first_grf;
994                if (spans_grfs)
995                   break;
996                offset += hstride * element_size;
997             }
998 
999             rowbase += vstride * element_size;
1000 
1001             if (spans_grfs) {
1002                ERROR("VertStride must be used to cross GRF register boundaries");
1003                break;
1004             }
1005          }
1006       }
1007    }
1008 
1009    /* Dst.HorzStride must not be 0. */
1010    if (inst->has_dst && !dst_is_null(inst)) {
1011       ERROR_IF(inst->dst.hstride == 0,
1012                "Destination Horizontal Stride must not be 0");
1013    }
1014 
1015    return error_msg;
1016 }
1017 
1018 static struct string
special_restrictions_for_mixed_float_mode(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)1019 special_restrictions_for_mixed_float_mode(const struct brw_isa_info *isa,
1020                                           const brw_hw_decoded_inst *inst)
1021 {
1022    const struct intel_device_info *devinfo = isa->devinfo;
1023 
1024    struct string error_msg = { .str = NULL, .len = 0 };
1025 
1026    const unsigned opcode = inst->opcode;
1027    if (inst->num_sources >= 3)
1028       return error_msg;
1029 
1030    if (!is_mixed_float(inst))
1031       return error_msg;
1032 
1033    bool is_align16 = inst->access_mode == BRW_ALIGN_16;
1034 
1035    enum brw_reg_type src0_type = inst->src[0].type;
1036    enum brw_reg_type src1_type = inst->num_sources > 1 ?
1037                                  inst->src[1].type : 0;
1038    enum brw_reg_type dst_type = inst->dst.type;
1039 
1040    unsigned dst_stride = inst->dst.hstride;
1041    bool dst_is_packed = is_packed(inst->exec_size * dst_stride, inst->exec_size, dst_stride);
1042 
1043    /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1044     * Float Operations:
1045     *
1046     *    "Indirect addressing on source is not supported when source and
1047     *     destination data types are mixed float."
1048     */
1049    ERROR_IF(inst->src[0].address_mode != BRW_ADDRESS_DIRECT ||
1050             (inst->num_sources > 1 &&
1051              inst->src[1].address_mode != BRW_ADDRESS_DIRECT),
1052             "Indirect addressing on source is not supported when source and "
1053             "destination data types are mixed float");
1054 
1055    /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1056     * Float Operations:
1057     *
1058     *    "No SIMD16 in mixed mode when destination is f32. Instruction
1059     *     execution size must be no more than 8."
1060     */
1061    ERROR_IF(inst->exec_size > 8 && devinfo->ver < 20 &&
1062             dst_type == BRW_TYPE_F &&
1063             opcode != BRW_OPCODE_MOV,
1064             "Mixed float mode with 32-bit float destination is limited "
1065             "to SIMD8");
1066 
1067    if (is_align16) {
1068       /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1069        * Float Operations:
1070        *
1071        *   "In Align16 mode, when half float and float data types are mixed
1072        *    between source operands OR between source and destination operands,
1073        *    the register content are assumed to be packed."
1074        *
1075        * Since Align16 doesn't have a concept of horizontal stride (or width),
1076        * it means that vertical stride must always be 4, since 0 and 2 would
1077        * lead to replicated data, and any other value is disallowed in Align16.
1078        */
1079       ERROR_IF(inst->src[0].vstride != 4,
1080                "Align16 mixed float mode assumes packed data (vstride must be 4");
1081 
1082       ERROR_IF(inst->num_sources >= 2 &&
1083                inst->src[1].vstride != 4,
1084                "Align16 mixed float mode assumes packed data (vstride must be 4");
1085 
1086       /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1087        * Float Operations:
1088        *
1089        *   "For Align16 mixed mode, both input and output packed f16 data
1090        *    must be oword aligned, no oword crossing in packed f16."
1091        *
1092        * The previous rule requires that Align16 operands are always packed,
1093        * and since there is only one bit for Align16 subnr, which represents
1094        * offsets 0B and 16B, this rule is always enforced and we don't need to
1095        * validate it.
1096        */
1097 
1098       /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1099        * Float Operations:
1100        *
1101        *    "No SIMD16 in mixed mode when destination is packed f16 for both
1102        *     Align1 and Align16."
1103        *
1104        * And:
1105        *
1106        *   "In Align16 mode, when half float and float data types are mixed
1107        *    between source operands OR between source and destination operands,
1108        *    the register content are assumed to be packed."
1109        *
1110        * Which implies that SIMD16 is not available in Align16. This is further
1111        * confirmed by:
1112        *
1113        *    "For Align16 mixed mode, both input and output packed f16 data
1114        *     must be oword aligned, no oword crossing in packed f16"
1115        *
1116        * Since oword-aligned packed f16 data would cross oword boundaries when
1117        * the execution size is larger than 8.
1118        */
1119       ERROR_IF(inst->exec_size > 8, "Align16 mixed float mode is limited to SIMD8");
1120 
1121       /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1122        * Float Operations:
1123        *
1124        *    "No accumulator read access for Align16 mixed float."
1125        */
1126       ERROR_IF(inst_uses_src_acc(isa, inst),
1127                "No accumulator read access for Align16 mixed float");
1128    } else {
1129       assert(!is_align16);
1130 
1131       /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1132        * Float Operations:
1133        *
1134        *    "No SIMD16 in mixed mode when destination is packed f16 for both
1135        *     Align1 and Align16."
1136        */
1137       ERROR_IF(inst->exec_size > 8 && dst_is_packed &&
1138                dst_type == BRW_TYPE_HF &&
1139                opcode != BRW_OPCODE_MOV,
1140                "Align1 mixed float mode is limited to SIMD8 when destination "
1141                "is packed half-float");
1142 
1143       /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1144        * Float Operations:
1145        *
1146        *    "Math operations for mixed mode:
1147        *     - In Align1, f16 inputs need to be strided"
1148        */
1149       if (opcode == BRW_OPCODE_MATH) {
1150          if (src0_type == BRW_TYPE_HF) {
1151             ERROR_IF(inst->src[0].hstride <= 1,
1152                      "Align1 mixed mode math needs strided half-float inputs");
1153          }
1154 
1155          if (inst->num_sources >= 2 && src1_type == BRW_TYPE_HF) {
1156             ERROR_IF(inst->src[1].hstride <= 1,
1157                      "Align1 mixed mode math needs strided half-float inputs");
1158          }
1159       }
1160 
1161       if (dst_type == BRW_TYPE_HF && dst_stride == 1) {
1162          /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1163           * Float Operations:
1164           *
1165           *    "In Align1, destination stride can be smaller than execution
1166           *     type. When destination is stride of 1, 16 bit packed data is
1167           *     updated on the destination. However, output packed f16 data
1168           *     must be oword aligned, no oword crossing in packed f16."
1169           *
1170           * The requirement of not crossing oword boundaries for 16-bit oword
1171           * aligned data means that execution size is limited to 8.
1172           */
1173          ERROR_IF(inst->dst.subnr % 16 != 0,
1174                   "Align1 mixed mode packed half-float output must be "
1175                   "oword aligned");
1176          ERROR_IF(inst->exec_size > 8,
1177                   "Align1 mixed mode packed half-float output must not "
1178                   "cross oword boundaries (max exec size is 8)");
1179 
1180          /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1181           * Float Operations:
1182           *
1183           *    "When source is float or half float from accumulator register and
1184           *     destination is half float with a stride of 1, the source must
1185           *     register aligned. i.e., source must have offset zero."
1186           *
1187           * Align16 mixed float mode doesn't allow accumulator access on sources,
1188           * so we only need to check this for Align1.
1189           */
1190          if (src0_is_acc(inst) &&
1191              (src0_type == BRW_TYPE_F ||
1192               src0_type == BRW_TYPE_HF)) {
1193             ERROR_IF(inst->src[0].subnr != 0,
1194                      "Mixed float mode requires register-aligned accumulator "
1195                      "source reads when destination is packed half-float");
1196 
1197          }
1198 
1199          if (inst->num_sources > 1 &&
1200              src1_is_acc(inst) &&
1201              (src1_type == BRW_TYPE_F ||
1202               src1_type == BRW_TYPE_HF)) {
1203             ERROR_IF(inst->src[1].subnr != 0,
1204                      "Mixed float mode requires register-aligned accumulator "
1205                      "source reads when destination is packed half-float");
1206          }
1207       }
1208 
1209       /* From the SKL PRM, Special Restrictions for Handling Mixed Mode
1210        * Float Operations:
1211        *
1212        *    "No swizzle is allowed when an accumulator is used as an implicit
1213        *     source or an explicit source in an instruction. i.e. when
1214        *     destination is half float with an implicit accumulator source,
1215        *     destination stride needs to be 2."
1216        *
1217        * FIXME: it is not quite clear what the first sentence actually means
1218        *        or its link to the implication described after it, so we only
1219        *        validate the explicit implication, which is clearly described.
1220        */
1221       if (dst_type == BRW_TYPE_HF &&
1222           inst_uses_src_acc(isa, inst)) {
1223          ERROR_IF(dst_stride != 2,
1224                   "Mixed float mode with implicit/explicit accumulator "
1225                   "source and half-float destination requires a stride "
1226                   "of 2 on the destination");
1227       }
1228    }
1229 
1230    return error_msg;
1231 }
1232 
1233 /**
1234  * Creates a \p grf_access_mask for an \p exec_size, \p element_size, and a
1235  * region
1236  *
1237  * A \p grf_access_mask is a 32-element array of uint8_t, where each uint8_t
1238  * is a bitmask of grfs accessed by the region.
1239  *
1240  * For instance the access mask of the source gX.1<4,2,2>F in an exec_size = 4
1241  * instruction would be
1242  *
1243  *    access_mask[0] = 0x01 (bytes 7-4 of the 1st grf)
1244  *    access_mask[1] = 0x01 (bytes 15-12 of the 1st grf)
1245  *    access_mask[2] = 0x01 (bytes 23-20 of the 1st grf)
1246  *    access_mask[3] = 0x01 (bytes 31-28 of the 1st grf)
1247  *    access_mask[4-31] = 0
1248  *
1249  * Before Xe2, gX<1,1,0>F in an exec_size == 16 would yield:
1250  *
1251  *    access_mask[0] = 0x01 (bytes 3-0 of the 1st grf)
1252  *    access_mask[1] = 0x01 (bytes 7-4 of the 1st grf)
1253  *      ...
1254  *    access_mask[7] = 0x01 (bytes 31-28 of the 1st grf)
1255  *    access_mask[8] = 0x02 (bytes 3-0 of the 2nd grf)
1256  *      ...
1257  *    access_mask[15] = 0x02 (bytes 31-28 of the 2nd grf)
1258  *    access_mask[16-31] = 0
1259  *
1260  * Whereas on Xe2, gX<1,1,0>F in an exec_size of 16 would yield:
1261  *
1262  *    access_mask[0] = 0x01 (bytes 3-0 of the 1st grf)
1263  *    access_mask[1] = 0x01 (bytes 7-4 of the 1st grf)
1264  *      ...
1265  *    access_mask[7] = 0x01 (bytes 31-28 of the 1st grf)
1266  *    access_mask[8] = 0x01 (bytes 35-32 of the 1st grf)
1267  *      ...
1268  *    access_mask[15] = 0x01 (bytes 63-60 of the 1st grf)
1269  *    access_mask[4-31] = 0
1270  *
1271  */
1272 static void
grfs_accessed(const struct intel_device_info * devinfo,uint8_t grf_access_mask[static32],unsigned exec_size,unsigned element_size,unsigned subreg,unsigned vstride,unsigned width,unsigned hstride)1273 grfs_accessed(const struct intel_device_info *devinfo,
1274               uint8_t grf_access_mask[static 32],
1275               unsigned exec_size, unsigned element_size, unsigned subreg,
1276               unsigned vstride, unsigned width, unsigned hstride)
1277 {
1278    unsigned rowbase = subreg;
1279    unsigned element = 0;
1280    assert(util_is_power_of_two_nonzero(reg_unit(devinfo)));
1281    unsigned grf_size_shift = (5 - 1) + ffs(reg_unit(devinfo));
1282 
1283    for (int y = 0; y < exec_size / width; y++) {
1284       unsigned offset = rowbase;
1285 
1286       for (int x = 0; x < width; x++) {
1287          const unsigned start_grf = (offset >> grf_size_shift) % 8;
1288          const unsigned end_byte = offset + (element_size - 1);
1289          const unsigned end_grf = (end_byte >> grf_size_shift) % 8;
1290          grf_access_mask[element++] = (1 << start_grf) | (1 << end_grf);
1291          offset += hstride * element_size;
1292       }
1293 
1294       rowbase += vstride * element_size;
1295    }
1296 
1297    assert(element == 0 || element == exec_size);
1298 }
1299 
1300 /**
1301  * Returns the number of registers accessed according to the \p access_mask
1302  */
1303 static int
registers_read(const uint8_t grfs_accessed[static32])1304 registers_read(const uint8_t grfs_accessed[static 32])
1305 {
1306    uint8_t all_read = 0;
1307 
1308    for (unsigned i = 0; i < 32; i++)
1309       all_read |= grfs_accessed[i];
1310 
1311    return util_bitcount(all_read);
1312 }
1313 
1314 /**
1315  * Checks restrictions listed in "Region Alignment Rules" in the "Register
1316  * Region Restrictions" section.
1317  */
1318 static struct string
region_alignment_rules(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)1319 region_alignment_rules(const struct brw_isa_info *isa,
1320                        const brw_hw_decoded_inst *inst)
1321 {
1322    const struct intel_device_info *devinfo = isa->devinfo;
1323    uint8_t dst_access_mask[32] = {}, src_access_mask[2][32] = {};
1324    struct string error_msg = { .str = NULL, .len = 0 };
1325 
1326    if (inst->num_sources == 3)
1327       return (struct string){};
1328 
1329    if (inst->access_mode == BRW_ALIGN_16)
1330       return (struct string){};
1331 
1332    if (inst_is_send(inst))
1333       return (struct string){};
1334 
1335    for (unsigned i = 0; i < inst->num_sources; i++) {
1336       /* In Direct Addressing mode, a source cannot span more than 2 adjacent
1337        * GRF registers.
1338        */
1339       if (inst->src[i].file != FIXED_GRF ||
1340           inst->src[i].address_mode != BRW_ADDRESS_DIRECT)
1341          continue;
1342 
1343       enum brw_reg_type type = inst->src[i].type;
1344       unsigned element_size = brw_type_size_bytes(type);
1345       unsigned subreg = inst->src[i].subnr;
1346       unsigned vstride = inst->src[i].vstride;
1347       unsigned width = inst->src[i].width;
1348       unsigned hstride = inst->src[i].hstride;
1349 
1350       grfs_accessed(devinfo, src_access_mask[i],
1351                     inst->exec_size, element_size, subreg,
1352                     vstride, width, hstride);
1353 
1354       unsigned num_vstride = inst->exec_size / width;
1355       unsigned num_hstride = width;
1356       unsigned vstride_elements = (num_vstride - 1) * vstride;
1357       unsigned hstride_elements = (num_hstride - 1) * hstride;
1358       unsigned offset = (vstride_elements + hstride_elements) * element_size +
1359                         subreg;
1360       ERROR_IF(offset >= 64 * reg_unit(devinfo),
1361                "A source cannot span more than 2 adjacent GRF registers");
1362    }
1363 
1364    if (!inst->has_dst || dst_is_null(inst))
1365       return error_msg;
1366 
1367    unsigned stride = inst->dst.hstride;
1368    enum brw_reg_type dst_type = inst->dst.type;
1369    unsigned element_size = brw_type_size_bytes(dst_type);
1370    unsigned subreg = inst->dst.subnr;
1371    unsigned offset = ((inst->exec_size - 1) * stride * element_size) + subreg;
1372    ERROR_IF(offset >= 64 * reg_unit(devinfo),
1373             "A destination cannot span more than 2 adjacent GRF registers");
1374 
1375    if (error_msg.str)
1376       return error_msg;
1377 
1378    grfs_accessed(devinfo, dst_access_mask, inst->exec_size, element_size, subreg,
1379                  inst->exec_size == 1 ? 0 : inst->exec_size * stride,
1380                  inst->exec_size == 1 ? 1 : inst->exec_size,
1381                  inst->exec_size == 1 ? 0 : stride);
1382 
1383    unsigned dst_regs = registers_read(dst_access_mask);
1384 
1385    /* The SKL PRM says:
1386     *
1387     *    When destination of MATH instruction spans two registers, the
1388     *    destination elements must be evenly split between the two registers.
1389     *
1390     * It is not known whether this restriction applies to KBL other Gens after
1391     * SKL.
1392     */
1393    if (inst->opcode == BRW_OPCODE_MATH) {
1394       if (dst_regs == 2) {
1395          unsigned upper_reg_writes = 0, lower_reg_writes = 0;
1396 
1397          for (unsigned i = 0; i < inst->exec_size; i++) {
1398             if (dst_access_mask[i] == 2) {
1399                upper_reg_writes++;
1400             } else {
1401                assert(dst_access_mask[i] == 1);
1402                lower_reg_writes++;
1403             }
1404          }
1405 
1406          ERROR_IF(upper_reg_writes != lower_reg_writes,
1407                   "Writes must be evenly split between the two "
1408                   "destination registers");
1409       }
1410    }
1411 
1412    return error_msg;
1413 }
1414 
1415 static struct string
vector_immediate_restrictions(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)1416 vector_immediate_restrictions(const struct brw_isa_info *isa,
1417                               const brw_hw_decoded_inst *inst)
1418 {
1419    const struct intel_device_info *devinfo = isa->devinfo;
1420 
1421    struct string error_msg = { .str = NULL, .len = 0 };
1422 
1423    if (inst->num_sources == 3 || inst->num_sources == 0 ||
1424        (devinfo->ver >= 12 && inst_is_send(inst)))
1425       return (struct string){};
1426 
1427    unsigned file = inst->src[inst->num_sources == 1 ? 0 : 1].file;
1428    if (file != IMM)
1429       return (struct string){};
1430 
1431    enum brw_reg_type dst_type = inst->dst.type;
1432    unsigned dst_type_size = brw_type_size_bytes(dst_type);
1433    unsigned dst_subreg = inst->dst.subnr;
1434    unsigned dst_stride = inst->dst.hstride;
1435    enum brw_reg_type type = inst->src[inst->num_sources == 1 ? 0 : 1].type;
1436 
1437    /* The PRMs say:
1438     *
1439     *    When an immediate vector is used in an instruction, the destination
1440     *    must be 128-bit aligned with destination horizontal stride equivalent
1441     *    to a word for an immediate integer vector (v) and equivalent to a
1442     *    DWord for an immediate float vector (vf).
1443     *
1444     * The text has not been updated for the addition of the immediate unsigned
1445     * integer vector type (uv) on SNB, but presumably the same restriction
1446     * applies.
1447     */
1448    switch (type) {
1449    case BRW_TYPE_V:
1450    case BRW_TYPE_UV:
1451    case BRW_TYPE_VF:
1452       ERROR_IF(dst_subreg % (128 / 8) != 0,
1453                "Destination must be 128-bit aligned in order to use immediate "
1454                "vector types");
1455 
1456       if (type == BRW_TYPE_VF) {
1457          ERROR_IF(dst_type_size * dst_stride != 4,
1458                   "Destination must have stride equivalent to dword in order "
1459                   "to use the VF type");
1460       } else {
1461          ERROR_IF(dst_type_size * dst_stride != 2,
1462                   "Destination must have stride equivalent to word in order "
1463                   "to use the V or UV type");
1464       }
1465       break;
1466    default:
1467       break;
1468    }
1469 
1470    return error_msg;
1471 }
1472 
1473 static struct string
special_requirements_for_handling_double_precision_data_types(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)1474 special_requirements_for_handling_double_precision_data_types(
1475                                        const struct brw_isa_info *isa,
1476                                        const brw_hw_decoded_inst *inst)
1477 {
1478    const struct intel_device_info *devinfo = isa->devinfo;
1479 
1480    struct string error_msg = { .str = NULL, .len = 0 };
1481 
1482    if (inst->num_sources == 3 || inst->num_sources == 0)
1483       return (struct string){};
1484 
1485    /* Split sends don't have types so there's no doubles there. */
1486    if (inst_is_split_send(isa, inst))
1487       return (struct string){};
1488 
1489    enum brw_reg_type exec_type = execution_type(inst);
1490    unsigned exec_type_size = brw_type_size_bytes(exec_type);
1491 
1492    enum brw_reg_type dst_type = inst->dst.type;
1493    unsigned dst_type_size = brw_type_size_bytes(dst_type);
1494    unsigned dst_hstride = inst->dst.hstride;
1495    unsigned dst_reg = inst->dst.nr;
1496    unsigned dst_subreg = inst->dst.subnr;
1497    unsigned dst_address_mode = inst->dst.address_mode;
1498 
1499    bool is_integer_dword_multiply =
1500       inst->opcode == BRW_OPCODE_MUL &&
1501       (inst->src[0].type == BRW_TYPE_D || inst->src[0].type == BRW_TYPE_UD) &&
1502       (inst->src[1].type == BRW_TYPE_D || inst->src[1].type == BRW_TYPE_UD);
1503 
1504    const bool is_double_precision =
1505       dst_type_size == 8 || exec_type_size == 8 || is_integer_dword_multiply;
1506 
1507    for (unsigned i = 0; i < inst->num_sources; i++) {
1508       enum brw_reg_file file = inst->src[i].file;
1509       if (file == IMM)
1510          continue;
1511 
1512       enum brw_reg_type type = inst->src[i].type;
1513       unsigned type_size = brw_type_size_bytes(type);
1514       unsigned address_mode = inst->src[i].address_mode;
1515       unsigned reg = inst->src[i].nr;
1516       unsigned subreg = inst->src[i].subnr;
1517       bool is_scalar_region = src_has_scalar_region(inst, i);
1518       unsigned vstride = inst->src[i].vstride;
1519       unsigned width = inst->src[i].width;
1520       unsigned hstride = inst->src[i].hstride;
1521 
1522       const unsigned src_stride = (hstride ? hstride : vstride) * type_size;
1523       const unsigned dst_stride = dst_hstride * dst_type_size;
1524 
1525       /* The PRMs say that for CHV, BXT:
1526        *
1527        *    When source or destination datatype is 64b or operation is integer
1528        *    DWord multiply, regioning in Align1 must follow these rules:
1529        *
1530        *    1. Source and Destination horizontal stride must be aligned to the
1531        *       same qword.
1532        *    2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride.
1533        *    3. Source and Destination offset must be the same, except the case
1534        *       of scalar source.
1535        *
1536        * We assume that the restriction applies to GLK as well.
1537        */
1538       if (is_double_precision &&
1539           inst->access_mode == BRW_ALIGN_1 &&
1540           intel_device_info_is_9lp(devinfo)) {
1541          ERROR_IF(!is_scalar_region &&
1542                   (src_stride % 8 != 0 ||
1543                    dst_stride % 8 != 0 ||
1544                    src_stride != dst_stride),
1545                   "Source and destination horizontal stride must equal and a "
1546                   "multiple of a qword when the execution type is 64-bit");
1547 
1548          ERROR_IF(vstride != width * hstride,
1549                   "Vstride must be Width * Hstride when the execution type is "
1550                   "64-bit");
1551 
1552          ERROR_IF(!is_scalar_region && dst_subreg != subreg,
1553                   "Source and destination offset must be the same when the "
1554                   "execution type is 64-bit");
1555       }
1556 
1557       /* The PRMs say that for CHV, BXT:
1558        *
1559        *    When source or destination datatype is 64b or operation is integer
1560        *    DWord multiply, indirect addressing must not be used.
1561        *
1562        * We assume that the restriction applies to GLK as well.
1563        */
1564       if (is_double_precision &&
1565           intel_device_info_is_9lp(devinfo)) {
1566          ERROR_IF(BRW_ADDRESS_REGISTER_INDIRECT_REGISTER == address_mode ||
1567                   BRW_ADDRESS_REGISTER_INDIRECT_REGISTER == dst_address_mode,
1568                   "Indirect addressing is not allowed when the execution type "
1569                   "is 64-bit");
1570       }
1571 
1572       /* The PRMs say that for CHV, BXT:
1573        *
1574        *    ARF registers must never be used with 64b datatype or when
1575        *    operation is integer DWord multiply.
1576        *
1577        * We assume that the restriction applies to GLK as well.
1578        *
1579        * We assume that the restriction does not apply to the null register.
1580        */
1581       if (is_double_precision &&
1582           intel_device_info_is_9lp(devinfo)) {
1583          ERROR_IF(inst->opcode == BRW_OPCODE_MAC ||
1584                   brw_eu_inst_acc_wr_control(devinfo, inst->raw) ||
1585                   (ARF == file &&
1586                    reg != BRW_ARF_NULL) ||
1587                   (ARF == inst->dst.file &&
1588                    dst_reg != BRW_ARF_NULL),
1589                   "Architecture registers cannot be used when the execution "
1590                   "type is 64-bit");
1591       }
1592 
1593       /* From the hardware spec section "Register Region Restrictions":
1594        *
1595        * There are two rules:
1596        *
1597        * "In case of all floating point data types used in destination:" and
1598        *
1599        * "In case where source or destination datatype is 64b or operation is
1600        *  integer DWord multiply:"
1601        *
1602        * both of which list the same restrictions:
1603        *
1604        *  "1. Register Regioning patterns where register data bit location
1605        *      of the LSB of the channels are changed between source and
1606        *      destination are not supported on Src0 and Src1 except for
1607        *      broadcast of a scalar.
1608        *
1609        *   2. Explicit ARF registers except null and accumulator must not be
1610        *      used."
1611        */
1612       if (devinfo->verx10 >= 125 &&
1613           (brw_type_is_float(dst_type) ||
1614            is_double_precision)) {
1615          ERROR_IF(!is_scalar_region &&
1616                   BRW_ADDRESS_REGISTER_INDIRECT_REGISTER != address_mode &&
1617                   (!is_linear(vstride, width, hstride) ||
1618                    src_stride != dst_stride ||
1619                    subreg != dst_subreg),
1620                   "Register Regioning patterns where register data bit "
1621                   "location of the LSB of the channels are changed between "
1622                   "source and destination are not supported except for "
1623                   "broadcast of a scalar.");
1624 
1625          /* NOTE: Expanded this to include Scalar.  See documentation issue
1626           * open in https://gfxspecs.intel.com/Predator/Home/Index/56640.
1627           */
1628          ERROR_IF((address_mode == BRW_ADDRESS_DIRECT && file == ARF &&
1629                    reg != BRW_ARF_SCALAR &&
1630                    reg != BRW_ARF_NULL && !(reg >= BRW_ARF_ACCUMULATOR && reg < BRW_ARF_FLAG)) ||
1631                   (inst->dst.file == ARF &&
1632                    dst_reg != BRW_ARF_SCALAR &&
1633                    dst_reg != BRW_ARF_NULL && (dst_reg & 0xF0) != BRW_ARF_ACCUMULATOR),
1634                   "Explicit ARF registers except null, accumulator, and scalar must not "
1635                   "be used.");
1636       }
1637 
1638       /* From the hardware spec section "Register Region Restrictions":
1639        *
1640        * "Vx1 and VxH indirect addressing for Float, Half-Float, Double-Float and
1641        *  Quad-Word data must not be used."
1642        */
1643       if (devinfo->verx10 >= 125 &&
1644           (brw_type_is_float(type) || brw_type_size_bytes(type) == 8)) {
1645          ERROR_IF(address_mode == BRW_ADDRESS_REGISTER_INDIRECT_REGISTER &&
1646                   vstride == BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL,
1647                   "Vx1 and VxH indirect addressing for Float, Half-Float, "
1648                   "Double-Float and Quad-Word data must not be used");
1649       }
1650    }
1651 
1652    /* The PRMs say that for BDW, SKL:
1653     *
1654     *    If Align16 is required for an operation with QW destination and non-QW
1655     *    source datatypes, the execution size cannot exceed 2.
1656     *
1657     * We assume that the restriction applies to all Gfx8+ parts.
1658     */
1659    if (is_double_precision) {
1660       enum brw_reg_type src0_type = inst->src[0].type;
1661       enum brw_reg_type src1_type =
1662          inst->num_sources > 1 ? inst->src[1].type : src0_type;
1663       unsigned src0_type_size = brw_type_size_bytes(src0_type);
1664       unsigned src1_type_size = brw_type_size_bytes(src1_type);
1665 
1666       ERROR_IF(inst->access_mode == BRW_ALIGN_16 &&
1667                dst_type_size == 8 &&
1668                (src0_type_size != 8 || src1_type_size != 8) &&
1669                inst->exec_size > 2,
1670                "In Align16 exec size cannot exceed 2 with a QWord destination "
1671                "and a non-QWord source");
1672    }
1673 
1674    /* The PRMs say that for CHV, BXT:
1675     *
1676     *    When source or destination datatype is 64b or operation is integer
1677     *    DWord multiply, DepCtrl must not be used.
1678     *
1679     * We assume that the restriction applies to GLK as well.
1680     */
1681    if (is_double_precision &&
1682        intel_device_info_is_9lp(devinfo)) {
1683       ERROR_IF(brw_eu_inst_no_dd_check(devinfo, inst->raw) ||
1684                brw_eu_inst_no_dd_clear(devinfo, inst->raw),
1685                "DepCtrl is not allowed when the execution type is 64-bit");
1686    }
1687 
1688    return error_msg;
1689 }
1690 
1691 static struct string
instruction_restrictions(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)1692 instruction_restrictions(const struct brw_isa_info *isa,
1693                          const brw_hw_decoded_inst *inst)
1694 {
1695    const struct intel_device_info *devinfo = isa->devinfo;
1696    struct string error_msg = { .str = NULL, .len = 0 };
1697 
1698    /* From Wa_1604601757:
1699     *
1700     * "When multiplying a DW and any lower precision integer, source modifier
1701     *  is not supported."
1702     */
1703    if (devinfo->ver >= 12 &&
1704        inst->opcode == BRW_OPCODE_MUL) {
1705       enum brw_reg_type exec_type = execution_type(inst);
1706       const bool src0_valid =
1707          brw_type_size_bytes(inst->src[0].type) == 4 ||
1708          inst->src[0].file == IMM ||
1709          !(inst->src[0].negate || inst->src[0].abs);
1710       const bool src1_valid =
1711          brw_type_size_bytes(inst->src[1].type) == 4 ||
1712          inst->src[1].file == IMM ||
1713          !(inst->src[1].negate || inst->src[1].abs);
1714 
1715       ERROR_IF(!brw_type_is_float(exec_type) &&
1716                brw_type_size_bytes(exec_type) == 4 &&
1717                !(src0_valid && src1_valid),
1718                "When multiplying a DW and any lower precision integer, source "
1719                "modifier is not supported.");
1720    }
1721 
1722    if (inst->opcode == BRW_OPCODE_CMP ||
1723        inst->opcode == BRW_OPCODE_CMPN) {
1724       ERROR_IF(inst->cond_modifier == BRW_CONDITIONAL_NONE,
1725                "CMP (or CMPN) must have a condition.");
1726    }
1727 
1728    if (inst->opcode == BRW_OPCODE_SEL) {
1729       ERROR_IF((inst->cond_modifier != BRW_CONDITIONAL_NONE) ==
1730                (inst->pred_control != BRW_PREDICATE_NONE),
1731                "SEL must either be predicated or have a condition modifiers");
1732    }
1733 
1734    if (inst->opcode == BRW_OPCODE_MUL) {
1735       const enum brw_reg_type src0_type = inst->src[0].type;
1736       const enum brw_reg_type src1_type = inst->src[1].type;
1737       const enum brw_reg_type dst_type = inst->dst.type;
1738 
1739       /* Page 966 (page 982 of the PDF) of Broadwell PRM volume 2a says:
1740        *
1741        *    When multiplying a DW and any lower precision integer, the DW
1742        *    operand must on src0.
1743        *
1744        * Ivy Bridge, Haswell, Skylake, and Ice Lake PRMs contain the same
1745        * text.
1746        */
1747       ERROR_IF(brw_type_is_int(src1_type) &&
1748                brw_type_size_bytes(src0_type) < 4 &&
1749                brw_type_size_bytes(src1_type) == 4,
1750                "When multiplying a DW and any lower precision integer, the "
1751                "DW operand must be src0.");
1752 
1753       /* Page 971 (page 987 of the PDF), section "Accumulator
1754        * Restrictions," of the Broadwell PRM volume 7 says:
1755        *
1756        *    Integer source operands cannot be accumulators.
1757        *
1758        * The Skylake and Ice Lake PRMs contain the same text.
1759        */
1760       ERROR_IF((src0_is_acc(inst) &&
1761                 brw_type_is_int(src0_type)) ||
1762                (src1_is_acc(inst) &&
1763                 brw_type_is_int(src1_type)),
1764                "Integer source operands cannot be accumulators.");
1765 
1766       /* Page 935 (page 951 of the PDF) of the Ice Lake PRM volume 2a says:
1767        *
1768        *    When multiplying integer data types, if one of the sources is a
1769        *    DW, the resulting full precision data is stored in the
1770        *    accumulator. However, if the destination data type is either W or
1771        *    DW, the low bits of the result are written to the destination
1772        *    register and the remaining high bits are discarded. This results
1773        *    in undefined Overflow and Sign flags. Therefore, conditional
1774        *    modifiers and saturation (.sat) cannot be used in this case.
1775        *
1776        * Similar text appears in every version of the PRM.
1777        *
1778        * The wording of the last sentence is not very clear.  It could either
1779        * be interpreted as "conditional modifiers combined with saturation
1780        * cannot be used" or "neither conditional modifiers nor saturation can
1781        * be used."  I have interpreted it as the latter primarily because that
1782        * is the more restrictive interpretation.
1783        */
1784       ERROR_IF((src0_type == BRW_TYPE_UD ||
1785                 src0_type == BRW_TYPE_D ||
1786                 src1_type == BRW_TYPE_UD ||
1787                 src1_type == BRW_TYPE_D) &&
1788                (dst_type == BRW_TYPE_UD ||
1789                 dst_type == BRW_TYPE_D ||
1790                 dst_type == BRW_TYPE_UW ||
1791                 dst_type == BRW_TYPE_W) &&
1792                (inst->saturate || inst->cond_modifier != BRW_CONDITIONAL_NONE),
1793                "Neither Saturate nor conditional modifier allowed with DW "
1794                "integer multiply.");
1795    }
1796 
1797    if (inst->opcode == BRW_OPCODE_MATH) {
1798       unsigned math_function = brw_eu_inst_math_function(devinfo, inst->raw);
1799       switch (math_function) {
1800       case BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER:
1801       case BRW_MATH_FUNCTION_INT_DIV_QUOTIENT:
1802       case BRW_MATH_FUNCTION_INT_DIV_REMAINDER: {
1803          /* Page 442 of the Broadwell PRM Volume 2a "Extended Math Function" says:
1804           *    INT DIV function does not support source modifiers.
1805           * Bspec 6647 extends it back to Ivy Bridge.
1806           */
1807          bool src0_valid = !inst->src[0].negate && !inst->src[0].abs;
1808          bool src1_valid = !inst->src[1].negate && !inst->src[1].abs;
1809          ERROR_IF(!src0_valid || !src1_valid,
1810                   "INT DIV function does not support source modifiers.");
1811          break;
1812       }
1813       default:
1814          break;
1815       }
1816    }
1817 
1818    if (inst->opcode == BRW_OPCODE_DP4A) {
1819       /* Page 396 (page 412 of the PDF) of the DG1 PRM volume 2a says:
1820        *
1821        *    Only one of src0 or src1 operand may be an the (sic) accumulator
1822        *    register (acc#).
1823        */
1824       ERROR_IF(src0_is_acc(inst) && src1_is_acc(inst),
1825                "Only one of src0 or src1 operand may be an accumulator "
1826                "register (acc#).");
1827 
1828    }
1829 
1830    if (inst->opcode == BRW_OPCODE_ADD3) {
1831       const enum brw_reg_type dst_type = inst->dst.type;
1832 
1833       ERROR_IF(dst_type != BRW_TYPE_D &&
1834                dst_type != BRW_TYPE_UD &&
1835                dst_type != BRW_TYPE_W &&
1836                dst_type != BRW_TYPE_UW,
1837                "Destination must be integer D, UD, W, or UW type.");
1838 
1839       for (unsigned i = 0; i < 3; i++) {
1840          enum brw_reg_type src_type = inst->src[i].type;
1841 
1842          ERROR_IF(src_type != BRW_TYPE_D &&
1843                   src_type != BRW_TYPE_UD &&
1844                   src_type != BRW_TYPE_W &&
1845                   src_type != BRW_TYPE_UW,
1846                   "Source must be integer D, UD, W, or UW type.");
1847 
1848          ERROR_IF(inst->src[i].file == IMM &&
1849                   src_type != BRW_TYPE_W &&
1850                   src_type != BRW_TYPE_UW,
1851                   "Immediate source must be integer W or UW type.");
1852       }
1853    }
1854 
1855    if (inst->opcode == BRW_OPCODE_OR ||
1856        inst->opcode == BRW_OPCODE_AND ||
1857        inst->opcode == BRW_OPCODE_XOR ||
1858        inst->opcode == BRW_OPCODE_NOT) {
1859       /* While the behavior of the negate source modifier is defined as
1860        * logical not, the behavior of abs source modifier is not
1861        * defined. Disallow it to be safe.
1862        */
1863       ERROR_IF(inst->src[0].abs,
1864                "Behavior of abs source modifier in logic ops is undefined.");
1865       ERROR_IF(inst->opcode != BRW_OPCODE_NOT &&
1866                inst->src[1].file != IMM &&
1867                inst->src[1].abs,
1868                "Behavior of abs source modifier in logic ops is undefined.");
1869 
1870       /* Page 479 (page 495 of the PDF) of the Broadwell PRM volume 2a says:
1871        *
1872        *    Source modifier is not allowed if source is an accumulator.
1873        *
1874        * The same text also appears for OR, NOT, and XOR instructions.
1875        */
1876       ERROR_IF((inst->src[0].abs || inst->src[0].negate) &&
1877                src0_is_acc(inst),
1878                "Source modifier is not allowed if source is an accumulator.");
1879       ERROR_IF(inst->num_sources > 1 &&
1880                (inst->src[1].abs || inst->src[1].negate) &&
1881                src1_is_acc(inst),
1882                "Source modifier is not allowed if source is an accumulator.");
1883 
1884       /* Page 479 (page 495 of the PDF) of the Broadwell PRM volume 2a says:
1885        *
1886        *    This operation does not produce sign or overflow conditions. Only
1887        *    the .e/.z or .ne/.nz conditional modifiers should be used.
1888        *
1889        * The same text also appears for OR, NOT, and XOR instructions.
1890        *
1891        * Per the comment around nir_op_imod in brw_fs_nir.cpp, we have
1892        * determined this to not be true. The only conditions that seem
1893        * absolutely sketchy are O, R, and U.  Some OpenGL shaders from Doom
1894        * 2016 have been observed to generate and.g and operate correctly.
1895        */
1896       const enum brw_conditional_mod cmod = inst->cond_modifier;
1897       ERROR_IF(cmod == BRW_CONDITIONAL_O ||
1898                cmod == BRW_CONDITIONAL_R ||
1899                cmod == BRW_CONDITIONAL_U,
1900                "O, R, and U conditional modifiers should not be used.");
1901    }
1902 
1903    if (inst->opcode == BRW_OPCODE_BFI2) {
1904       ERROR_IF(inst->cond_modifier != BRW_CONDITIONAL_NONE,
1905                "BFI2 cannot have conditional modifier");
1906 
1907       ERROR_IF(inst->saturate,
1908                "BFI2 cannot have saturate modifier");
1909 
1910       enum brw_reg_type dst_type = inst->dst.type;
1911 
1912       ERROR_IF(dst_type != BRW_TYPE_D &&
1913                dst_type != BRW_TYPE_UD,
1914                "BFI2 destination type must be D or UD");
1915 
1916       for (unsigned s = 0; s < 3; s++) {
1917          enum brw_reg_type src_type = inst->src[s].type;
1918 
1919          ERROR_IF(src_type != dst_type,
1920                   "BFI2 source type must match destination type");
1921       }
1922    }
1923 
1924    if (inst->opcode == BRW_OPCODE_CSEL) {
1925       ERROR_IF(inst->pred_control != BRW_PREDICATE_NONE,
1926                "CSEL cannot be predicated");
1927 
1928       /* CSEL is CMP and SEL fused into one. The condition modifier, which
1929        * does not actually modify the flags, controls the built-in comparison.
1930        */
1931       ERROR_IF(inst->cond_modifier == BRW_CONDITIONAL_NONE,
1932                "CSEL must have a condition.");
1933 
1934       enum brw_reg_type dst_type = inst->dst.type;
1935 
1936       if (devinfo->ver == 9) {
1937          ERROR_IF(dst_type != BRW_TYPE_F,
1938                   "CSEL destination type must be F");
1939       } else {
1940          ERROR_IF(dst_type != BRW_TYPE_F &&
1941                   dst_type != BRW_TYPE_HF &&
1942                   dst_type != BRW_TYPE_D &&
1943                   dst_type != BRW_TYPE_W &&
1944                   dst_type != BRW_TYPE_UD &&
1945                   dst_type != BRW_TYPE_UW,
1946                   "CSEL destination type must be F, HF, *D, or *W");
1947       }
1948 
1949       for (unsigned s = 0; s < 3; s++) {
1950          enum brw_reg_type src_type = inst->src[s].type;
1951 
1952          if (devinfo->ver == 9) {
1953             ERROR_IF(src_type != BRW_TYPE_F,
1954                      "CSEL source type must be F");
1955          } else {
1956             ERROR_IF(src_type != BRW_TYPE_F && src_type != BRW_TYPE_HF &&
1957                      src_type != BRW_TYPE_D && src_type != BRW_TYPE_UD &&
1958                      src_type != BRW_TYPE_W && src_type != BRW_TYPE_UW,
1959                      "CSEL source type must be F, HF, *D, or *W");
1960 
1961             ERROR_IF(brw_type_is_float(src_type) != brw_type_is_float(dst_type),
1962                      "CSEL cannot mix float and integer types.");
1963 
1964             ERROR_IF(brw_type_size_bytes(src_type) !=
1965                      brw_type_size_bytes(dst_type),
1966                      "CSEL cannot mix different type sizes.");
1967          }
1968       }
1969    }
1970 
1971    if (inst->opcode == BRW_OPCODE_DPAS) {
1972       ERROR_IF(brw_eu_inst_dpas_3src_sdepth(devinfo, inst->raw) != BRW_SYSTOLIC_DEPTH_8,
1973                "Systolic depth must be 8.");
1974 
1975       const unsigned sdepth = 8;
1976 
1977       const enum brw_reg_type dst_type = inst->dst.type;
1978       const enum brw_reg_type src0_type = inst->src[0].type;
1979       const enum brw_reg_type src1_type = inst->src[1].type;
1980       const enum brw_reg_type src2_type = inst->src[2].type;
1981 
1982       const enum gfx12_sub_byte_precision src1_sub_byte =
1983          brw_eu_inst_dpas_3src_src1_subbyte(devinfo, inst->raw);
1984 
1985       if (src1_type != BRW_TYPE_B && src1_type != BRW_TYPE_UB) {
1986          ERROR_IF(src1_sub_byte != BRW_SUB_BYTE_PRECISION_NONE,
1987                   "Sub-byte precision must be None for source type larger than Byte.");
1988       } else {
1989          ERROR_IF(src1_sub_byte != BRW_SUB_BYTE_PRECISION_NONE &&
1990                   src1_sub_byte != BRW_SUB_BYTE_PRECISION_4BIT &&
1991                   src1_sub_byte != BRW_SUB_BYTE_PRECISION_2BIT,
1992                   "Invalid sub-byte precision.");
1993       }
1994 
1995       const enum gfx12_sub_byte_precision src2_sub_byte =
1996          brw_eu_inst_dpas_3src_src2_subbyte(devinfo, inst->raw);
1997 
1998       if (src2_type != BRW_TYPE_B && src2_type != BRW_TYPE_UB) {
1999          ERROR_IF(src2_sub_byte != BRW_SUB_BYTE_PRECISION_NONE,
2000                   "Sub-byte precision must be None.");
2001       } else {
2002          ERROR_IF(src2_sub_byte != BRW_SUB_BYTE_PRECISION_NONE &&
2003                   src2_sub_byte != BRW_SUB_BYTE_PRECISION_4BIT &&
2004                   src2_sub_byte != BRW_SUB_BYTE_PRECISION_2BIT,
2005                   "Invalid sub-byte precision.");
2006       }
2007 
2008       const unsigned src1_bits_per_element =
2009          brw_type_size_bits(src1_type) >>
2010          brw_eu_inst_dpas_3src_src1_subbyte(devinfo, inst->raw);
2011 
2012       const unsigned src2_bits_per_element =
2013          brw_type_size_bits(src2_type) >>
2014          brw_eu_inst_dpas_3src_src2_subbyte(devinfo, inst->raw);
2015 
2016       /* The MAX2(1, ...) is just to prevent possible division by 0 later. */
2017       const unsigned ops_per_chan =
2018          MAX2(1, 32 / MAX2(src1_bits_per_element, src2_bits_per_element));
2019 
2020       if (devinfo->ver < 20) {
2021          ERROR_IF(inst->exec_size != 8, "DPAS execution size must be 8.");
2022       } else {
2023          ERROR_IF(inst->exec_size != 16, "DPAS execution size must be 16.");
2024       }
2025 
2026       const unsigned dst_subnr  = inst->dst.subnr;
2027       const unsigned src0_subnr = inst->src[0].subnr;
2028       const unsigned src1_subnr = inst->src[1].subnr;
2029       const unsigned src2_subnr = inst->src[2].subnr;
2030 
2031       /* Until HF is supported as dst type, this is effectively subnr == 0. */
2032       ERROR_IF(dst_subnr % inst->exec_size != 0,
2033                "Destination subregister offset must be a multiple of ExecSize.");
2034 
2035       /* Until HF is supported as src0 type, this is effectively subnr == 0. */
2036       ERROR_IF(src0_subnr % inst->exec_size != 0,
2037                "Src0 subregister offset must be a multiple of ExecSize.");
2038 
2039       ERROR_IF(src1_subnr != 0,
2040                "Src1 subregister offsets must be 0.");
2041 
2042       /* In nearly all cases, this effectively requires that src2.subnr be
2043        * 0. It is only when src1 is 8 bits and src2 is 2 or 4 bits that the
2044        * ops_per_chan value can allow non-zero src2.subnr.
2045        */
2046       ERROR_IF(src2_subnr % (sdepth * ops_per_chan) != 0,
2047                "Src2 subregister offset must be a multiple of SystolicDepth "
2048                "times OPS_PER_CHAN.");
2049 
2050       ERROR_IF(dst_subnr * brw_type_size_bytes(dst_type) >= REG_SIZE,
2051                "Destination subregister specifies next register.");
2052 
2053       ERROR_IF(src0_subnr * brw_type_size_bytes(src0_type) >= REG_SIZE,
2054                "Src0 subregister specifies next register.");
2055 
2056       ERROR_IF((src1_subnr * brw_type_size_bytes(src1_type) * src1_bits_per_element) / 8 >= REG_SIZE,
2057                "Src1 subregister specifies next register.");
2058 
2059       ERROR_IF((src2_subnr * brw_type_size_bytes(src2_type) * src2_bits_per_element) / 8 >= REG_SIZE,
2060                "Src2 subregister specifies next register.");
2061 
2062       if (brw_eu_inst_3src_atomic_control(devinfo, inst->raw)) {
2063          /* FINISHME: When we start emitting DPAS with Atomic set, figure out
2064           * a way to validate it. Also add a test in test_eu_validate.cpp.
2065           */
2066          ERROR_IF(true,
2067                   "When instruction option Atomic is used it must be follwed by a "
2068                   "DPAS instruction.");
2069       }
2070 
2071       if (brw_eu_inst_dpas_3src_exec_type(devinfo, inst->raw) ==
2072           BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT) {
2073          ERROR_IF(dst_type != BRW_TYPE_F,
2074                   "DPAS destination type must be F.");
2075          ERROR_IF(src0_type != BRW_TYPE_F,
2076                   "DPAS src0 type must be F.");
2077          ERROR_IF(src1_type != BRW_TYPE_HF,
2078                   "DPAS src1 type must be HF.");
2079          ERROR_IF(src2_type != BRW_TYPE_HF,
2080                   "DPAS src2 type must be HF.");
2081       } else {
2082          ERROR_IF(dst_type != BRW_TYPE_D &&
2083                   dst_type != BRW_TYPE_UD,
2084                   "DPAS destination type must be D or UD.");
2085          ERROR_IF(src0_type != BRW_TYPE_D &&
2086                   src0_type != BRW_TYPE_UD,
2087                   "DPAS src0 type must be D or UD.");
2088          ERROR_IF(src1_type != BRW_TYPE_B &&
2089                   src1_type != BRW_TYPE_UB,
2090                   "DPAS src1 base type must be B or UB.");
2091          ERROR_IF(src2_type != BRW_TYPE_B &&
2092                   src2_type != BRW_TYPE_UB,
2093                   "DPAS src2 base type must be B or UB.");
2094 
2095          if (brw_type_is_uint(dst_type)) {
2096             ERROR_IF(!brw_type_is_uint(src0_type) ||
2097                      !brw_type_is_uint(src1_type) ||
2098                      !brw_type_is_uint(src2_type),
2099                      "If any source datatype is signed, destination datatype "
2100                      "must be signed.");
2101          }
2102       }
2103 
2104       /* FINISHME: Additional restrictions mentioned in the Bspec that are not
2105        * yet enforced here:
2106        *
2107        *    - General Accumulator registers access is not supported. This is
2108        *      currently enforced in brw_dpas_three_src (brw_eu_emit.c).
2109        *
2110        *    - Given any combination of datatypes in the sources of a DPAS
2111        *      instructions, the boundaries of a register should not be crossed.
2112        */
2113    }
2114 
2115    return error_msg;
2116 }
2117 
2118 static struct string
send_descriptor_restrictions(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)2119 send_descriptor_restrictions(const struct brw_isa_info *isa,
2120                              const brw_hw_decoded_inst *inst)
2121 {
2122    const struct intel_device_info *devinfo = isa->devinfo;
2123    struct string error_msg = { .str = NULL, .len = 0 };
2124 
2125    if (inst_is_split_send(isa, inst)) {
2126       /* We can only validate immediate descriptors */
2127       if (brw_eu_inst_send_sel_reg32_desc(devinfo, inst->raw))
2128          return error_msg;
2129    } else if (inst_is_send(inst)) {
2130       /* We can only validate immediate descriptors */
2131       if (inst->src[1].file != IMM)
2132          return error_msg;
2133    } else {
2134       return error_msg;
2135    }
2136 
2137    const uint32_t desc = brw_eu_inst_send_desc(devinfo, inst->raw);
2138 
2139    switch (brw_eu_inst_sfid(devinfo, inst->raw)) {
2140    case BRW_SFID_URB:
2141       if (devinfo->ver < 20)
2142          break;
2143       FALLTHROUGH;
2144    case GFX12_SFID_TGM:
2145    case GFX12_SFID_SLM:
2146    case GFX12_SFID_UGM:
2147       ERROR_IF(!devinfo->has_lsc, "Platform does not support LSC");
2148 
2149       ERROR_IF(lsc_opcode_has_transpose(lsc_msg_desc_opcode(devinfo, desc)) &&
2150                lsc_msg_desc_transpose(devinfo, desc) &&
2151                inst->exec_size != 1,
2152                "Transposed vectors are restricted to Exec_Mask = 1.");
2153       break;
2154 
2155    default:
2156       break;
2157    }
2158 
2159    if (brw_eu_inst_sfid(devinfo, inst->raw) == BRW_SFID_URB && devinfo->ver < 20) {
2160       ERROR_IF(!brw_eu_inst_header_present(devinfo, inst->raw),
2161                "Header must be present for all URB messages.");
2162 
2163       switch (brw_eu_inst_urb_opcode(devinfo, inst->raw)) {
2164       case GFX7_URB_OPCODE_ATOMIC_INC:
2165       case GFX7_URB_OPCODE_ATOMIC_MOV:
2166       case GFX8_URB_OPCODE_ATOMIC_ADD:
2167       case GFX8_URB_OPCODE_SIMD8_WRITE:
2168          break;
2169 
2170       case GFX8_URB_OPCODE_SIMD8_READ:
2171          ERROR_IF(brw_eu_inst_rlen(devinfo, inst->raw) == 0,
2172                   "URB SIMD8 read message must read some data.");
2173          break;
2174 
2175       case GFX125_URB_OPCODE_FENCE:
2176          ERROR_IF(devinfo->verx10 < 125,
2177                   "URB fence message only valid on gfx >= 12.5");
2178          break;
2179 
2180       default:
2181          ERROR_IF(true, "Invalid URB message");
2182          break;
2183       }
2184    }
2185 
2186    return error_msg;
2187 }
2188 
2189 static struct string
register_region_special_restrictions(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)2190 register_region_special_restrictions(const struct brw_isa_info *isa,
2191                                      const brw_hw_decoded_inst *inst)
2192 {
2193    const struct intel_device_info *devinfo = isa->devinfo;
2194    struct string error_msg = { .str = NULL, .len = 0 };
2195 
2196    bool format_uses_regions = inst->format == FORMAT_BASIC ||
2197                               inst->format == FORMAT_BASIC_THREE_SRC;
2198 
2199    /* "Src0 Restrictions" in "Special Restrictions" in Bspec 56640 (r57070). */
2200    if (devinfo->ver >= 20 &&
2201        format_uses_regions &&
2202        inst->num_sources > 0 &&
2203        inst->src[0].file == FIXED_GRF) {
2204       const unsigned v = inst->src[0].vstride;
2205       const unsigned w = inst->src[0].width;
2206       const unsigned h = inst->src[0].hstride;
2207 
2208       const bool multi_indirect =
2209          inst->src[0].address_mode == BRW_ADDRESS_REGISTER_INDIRECT_REGISTER &&
2210          inst->src[0].vstride == STRIDE(BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL);
2211       const bool is_Vx1 = multi_indirect && w != 1;
2212       const bool is_VxH = multi_indirect && w == 1;
2213 
2214       const unsigned src0_stride         = w == 1 ? v : h;
2215       const unsigned src0_uniform_stride = (w == 1) || (h * w == v) || is_Vx1;
2216       const unsigned dst_stride          = inst->dst.hstride;
2217 
2218       const unsigned src0_size  = brw_type_size_bytes(inst->src[0].type);
2219       const unsigned dst_size   = brw_type_size_bytes(inst->dst.type);
2220       const unsigned src0_subnr = inst->src[0].subnr / src0_size;
2221       const unsigned dst_subnr  = inst->dst.subnr / dst_size;
2222 
2223       const bool dst_dword_aligned = (dst_size >= 4) ||
2224                                      (dst_size == 2 && (dst_subnr % 2 == 0)) ||
2225                                      (dst_size == 1 && (dst_subnr % 4 == 0));
2226 
2227       /* The section below follows the pseudo-code in the spec to make
2228        * easier to verify.
2229        */
2230       bool allowed = false;
2231       if ((dst_size >= 4) ||
2232           (src0_size >= 4) ||
2233           (dst_size == 2 && dst_stride > 1) ||
2234           (dst_size == 1 && dst_stride > 2) ||
2235           is_VxH) {
2236          /* One element per DWord channel. */
2237          allowed = true;
2238 
2239       } else if (src0_uniform_stride || dst_dword_aligned) {
2240          if (src0_size == 2 && dst_size == 2) {
2241             if ((src0_stride < 2) ||
2242                 (src0_stride == 2 && src0_uniform_stride && (dst_subnr % 16 == src0_subnr / 2)))
2243                allowed = true;
2244 
2245          } else if (src0_size == 2 && dst_size == 1 && dst_stride == 2) {
2246             if ((src0_stride < 2) ||
2247                 (src0_stride == 2 && src0_uniform_stride && (dst_subnr % 32 == src0_subnr)))
2248                allowed = true;
2249 
2250          } else if (src0_size == 1 && dst_size == 2) {
2251             if ((src0_stride < 4) ||
2252                 (src0_stride == 4 && src0_uniform_stride && ((2 * dst_subnr) % 16 == src0_subnr / 2)) ||
2253                 (src0_stride == 8 && src0_uniform_stride && ((2 * dst_subnr) % 8 == src0_subnr / 4)))
2254                allowed = true;
2255 
2256          } else if (src0_size == 1 && dst_size == 1 && dst_stride == 2) {
2257             if ((src0_stride < 4) ||
2258                 (src0_stride == 4 && src0_uniform_stride && (dst_subnr % 32 == src0_subnr / 2)) ||
2259                 (src0_stride == 8 && src0_uniform_stride && (dst_subnr % 16 == src0_subnr / 4)))
2260                allowed = true;
2261 
2262          } else if (src0_size == 1 && dst_size == 1 && dst_stride == 1 && w != 2) {
2263             if ((src0_stride < 2) ||
2264                 (src0_stride == 2 && src0_uniform_stride && (dst_subnr % 32 == src0_subnr / 2)) ||
2265                 (src0_stride == 4 && src0_uniform_stride && (dst_subnr % 16 == src0_subnr / 4)))
2266                allowed = true;
2267 
2268          } else if (src0_size == 1 && dst_size == 1 && dst_stride == 1 && w == 2) {
2269             if ((h == 0 && v < 4) ||
2270                 (h == 1 && v < 4) ||
2271                 (h == 2 && v < 2) ||
2272                 (h == 1 && v == 4 && (dst_subnr % 32 == 2 * (src0_subnr / 4)) && (src0_subnr % 2 == 0)) ||
2273                 (h == 2 && v == 4 && (dst_subnr % 32 == src0_subnr / 2)) ||
2274                 (h == 4 && v == 8 && (dst_subnr % 32 == src0_subnr / 4)))
2275                allowed = true;
2276          }
2277       }
2278 
2279       ERROR_IF(!allowed,
2280                "Invalid register region for source 0.  See special restrictions section.");
2281    }
2282 
2283    /* "Src1 Restrictions" in "Special Restrictions" in Bspec 56640 (r57070). */
2284    if (devinfo->ver >= 20 &&
2285        format_uses_regions &&
2286        inst->num_sources > 1 &&
2287        inst->src[1].file == FIXED_GRF) {
2288       const unsigned v = inst->src[1].vstride;
2289       const unsigned w = inst->src[1].width;
2290       const unsigned h = inst->src[1].hstride;
2291 
2292       const bool multi_indirect =
2293          inst->src[1].address_mode == BRW_ADDRESS_REGISTER_INDIRECT_REGISTER &&
2294          inst->src[1].vstride == STRIDE(BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL);
2295       const bool is_Vx1 = multi_indirect && w != 1;
2296 
2297       const unsigned src1_stride         = w == 1 ? v : h;
2298       const unsigned src1_uniform_stride = (w == 1) || (h * w == v) || is_Vx1;
2299       const unsigned dst_stride          = inst->dst.hstride;
2300 
2301       const unsigned src1_size  = brw_type_size_bytes(inst->src[1].type);
2302       const unsigned dst_size   = brw_type_size_bytes(inst->dst.type);
2303       const unsigned src1_subnr = inst->src[1].subnr / src1_size;
2304       const unsigned dst_subnr  = inst->dst.subnr / dst_size;
2305 
2306       const bool dst_dword_aligned = (dst_size >= 4) ||
2307                                      (dst_size == 2 && (dst_subnr % 2 == 0)) ||
2308                                      (dst_size == 1 && (dst_subnr % 4 == 0));
2309 
2310       /* The section below follows the pseudo-code in the spec to make
2311        * easier to verify.
2312        */
2313       bool allowed = false;
2314       if ((dst_size >= 4) ||
2315           (src1_size >= 4) ||
2316           (dst_size == 2 && dst_stride > 1) ||
2317           (dst_size == 1 && dst_stride > 2)) {
2318          /* One element per DWord channel. */
2319          allowed = true;
2320 
2321       } else if (src1_uniform_stride || dst_dword_aligned) {
2322          if (src1_size == 2 && dst_size == 2) {
2323             if ((src1_stride < 2) ||
2324                 (src1_stride == 2 && src1_uniform_stride && (dst_subnr % 16 == src1_subnr / 2)))
2325                allowed = true;
2326 
2327          } else if (src1_size == 2 && dst_size == 1 && dst_stride == 2) {
2328             if ((src1_stride < 2) ||
2329                 (src1_stride == 2 && src1_uniform_stride && (dst_subnr % 32 == src1_subnr)))
2330                allowed = true;
2331          }
2332       }
2333 
2334       ERROR_IF(!allowed,
2335                "Invalid register region for source 1.  See special restrictions section.");
2336    }
2337 
2338    return error_msg;
2339 }
2340 
2341 static struct string
scalar_register_restrictions(const struct brw_isa_info * isa,const brw_hw_decoded_inst * inst)2342 scalar_register_restrictions(const struct brw_isa_info *isa,
2343                              const brw_hw_decoded_inst *inst)
2344 {
2345    const struct intel_device_info *devinfo = isa->devinfo;
2346    struct string error_msg = { .str = NULL, .len = 0 };
2347 
2348    /* Restrictions from BSpec 71168 (r55736). */
2349 
2350    if (devinfo->ver >= 30) {
2351       if (inst->dst.file == ARF && inst->dst.nr == BRW_ARF_SCALAR) {
2352          switch (inst->opcode) {
2353          case BRW_OPCODE_MOV: {
2354             unsigned dst_size_bits = brw_type_size_bits(inst->dst.type);
2355             ERROR_IF(inst->dst.type != inst->src[0].type,
2356                      "When destination is scalar register, "
2357                      "source and destination data-types must be the same.");
2358             ERROR_IF(!brw_type_is_int(inst->dst.type) || (dst_size_bits != 16 &&
2359                                                           dst_size_bits != 32 &&
2360                                                           dst_size_bits != 64),
2361                      "When destination is scalar register, "
2362                      "it must be an integer with size 16, 32, or 64 bits.");
2363             if (inst->src[0].file == IMM) {
2364                ERROR_IF(inst->exec_size != 1,
2365                         "When destination is scalar register with immediate source, "
2366                         "execution size must be 1.");
2367                ERROR_IF(inst->cond_modifier != BRW_CONDITIONAL_NONE,
2368                         "When destination is scalar register with immediate source, "
2369                         "conditional modifier must not be used.");
2370             }
2371             ERROR_IF((inst->dst.subnr / 32) != ((inst->dst.subnr + brw_type_size_bytes(inst->dst.type)) / 32),
2372                      "When destination is scalar register, it must not span across "
2373                      "the lower to upper 8 dword boundary of the register.");
2374             break;
2375          }
2376 
2377          default:
2378             ERROR("When destination is scalar register, opcode must be MOV.");
2379             break;
2380          }
2381       }
2382 
2383       if (inst->src[0].file == ARF && inst->src[0].nr == BRW_ARF_SCALAR) {
2384          switch (inst->opcode) {
2385          case BRW_OPCODE_MOV: {
2386             ERROR_IF(inst->dst.file == ARF && inst->dst.nr == BRW_ARF_SCALAR,
2387                      "When source is a scalar register, destination must not be a scalar register.");
2388             ERROR_IF(!src_has_scalar_region(inst, 0),
2389                      "When source is a scalar register and opcode is MOV, the scalar (broadcast) regioning must be used.");
2390             break;
2391          }
2392 
2393          case BRW_OPCODE_SEND:
2394          case BRW_OPCODE_SENDC: {
2395             ERROR_IF(!src1_is_null(inst),
2396                      "When source is a scalar and opcode is a SEND or SENDC, Src1 must be NULL.");
2397             break;
2398          }
2399 
2400          default:
2401             ERROR("When source is a scalar register, opcode must be MOV, SEND, or SENDC.");
2402             break;
2403          }
2404       }
2405 
2406       if ((inst->src[1].file == ARF && inst->src[1].nr == BRW_ARF_SCALAR) ||
2407           (inst->src[2].file == ARF && inst->src[2].nr == BRW_ARF_SCALAR)) {
2408          ERROR("When source is a scalar register, it must be on Source 0.");
2409       }
2410    } else {
2411       assert(devinfo->ver < 30);
2412       if ((inst->dst.file == ARF && inst->dst.nr == BRW_ARF_SCALAR) ||
2413           (inst->src[0].file == ARF && inst->src[0].nr == BRW_ARF_SCALAR) ||
2414           (inst->src[1].file == ARF && inst->src[1].nr == BRW_ARF_SCALAR) ||
2415           (inst->src[2].file == ARF && inst->src[2].nr == BRW_ARF_SCALAR))
2416          ERROR("Scalar register not available before Gfx30.");
2417    }
2418 
2419    return error_msg;
2420 }
2421 
2422 static unsigned
VSTRIDE_3SRC(unsigned vstride)2423 VSTRIDE_3SRC(unsigned vstride)
2424 {
2425    switch (vstride) {
2426    case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_0: return 0;
2427    case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_1: return 1;
2428    case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_4: return 4;
2429    case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_8: return 8;
2430    }
2431    unreachable("invalid vstride");
2432 }
2433 
2434 static struct string
brw_hw_decode_inst(const struct brw_isa_info * isa,brw_hw_decoded_inst * inst,const brw_eu_inst * raw)2435 brw_hw_decode_inst(const struct brw_isa_info *isa,
2436                    brw_hw_decoded_inst *inst,
2437                    const brw_eu_inst *raw)
2438 {
2439    const struct intel_device_info *devinfo = isa->devinfo;
2440    struct string error_msg = { .str = NULL, .len = 0 };
2441 
2442    inst->raw = raw;
2443    inst->opcode = brw_eu_inst_opcode(isa, raw);
2444    inst->num_sources = brw_num_sources_from_inst(isa, raw);
2445 
2446    const struct opcode_desc *desc = brw_opcode_desc(isa, inst->opcode);
2447    assert(desc->ndst == 0 || desc->ndst == 1);
2448    inst->has_dst = desc->ndst == 1;
2449 
2450    enum brw_execution_size exec_size = brw_eu_inst_exec_size(devinfo, raw);
2451    switch (exec_size) {
2452    case BRW_EXECUTE_1:
2453    case BRW_EXECUTE_2:
2454    case BRW_EXECUTE_4:
2455    case BRW_EXECUTE_8:
2456    case BRW_EXECUTE_16:
2457    case BRW_EXECUTE_32:
2458       inst->exec_size = 1 << exec_size;
2459       break;
2460    default:
2461       RETURN_ERROR("invalid execution size");
2462       break;
2463    }
2464 
2465    inst->access_mode = brw_eu_inst_access_mode(devinfo, raw);
2466    inst->pred_control = brw_eu_inst_pred_control(devinfo, raw);
2467 
2468    RETURN_ERROR_IF(inst->num_sources == 3 && inst->access_mode == BRW_ALIGN_1 && devinfo->ver == 9,
2469                    "Align1 mode not allowed on Gfx9 for 3-src instructions");
2470 
2471    RETURN_ERROR_IF(inst->access_mode == BRW_ALIGN_16 && devinfo->ver >= 11,
2472                    "Align16 mode doesn't exist on Gfx11+");
2473 
2474    switch (inst->opcode) {
2475    case BRW_OPCODE_DPAS:
2476       inst->format = FORMAT_DPAS_THREE_SRC;
2477       break;
2478 
2479    case BRW_OPCODE_SEND:
2480    case BRW_OPCODE_SENDC:
2481       inst->format = devinfo->ver >= 12 ? FORMAT_SEND : FORMAT_BASIC;
2482       break;
2483 
2484    case BRW_OPCODE_SENDS:
2485    case BRW_OPCODE_SENDSC:
2486       inst->format = FORMAT_SEND;
2487       break;
2488 
2489    case BRW_OPCODE_DO:
2490    case BRW_OPCODE_WHILE:
2491    case BRW_OPCODE_IF:
2492    case BRW_OPCODE_ELSE:
2493    case BRW_OPCODE_ENDIF:
2494    case BRW_OPCODE_BREAK:
2495    case BRW_OPCODE_CONTINUE:
2496    case BRW_OPCODE_JMPI:
2497    case BRW_OPCODE_BRD:
2498    case BRW_OPCODE_BRC:
2499    case BRW_OPCODE_HALT:
2500    case BRW_OPCODE_CALLA:
2501    case BRW_OPCODE_CALL:
2502    case BRW_OPCODE_GOTO:
2503       inst->format = FORMAT_BRANCH;
2504       break;
2505 
2506    case BRW_OPCODE_NOP:
2507       inst->format = FORMAT_NOP;
2508       break;
2509 
2510    case BRW_OPCODE_ILLEGAL:
2511       inst->format = FORMAT_ILLEGAL;
2512       break;
2513 
2514    default:
2515       if (inst->num_sources == 3) {
2516          inst->format = FORMAT_BASIC_THREE_SRC;
2517       } else {
2518          inst->format = FORMAT_BASIC;
2519       }
2520       break;
2521    }
2522 
2523    switch (inst->format) {
2524    case FORMAT_BASIC: {
2525       assert(inst->num_sources == 1 ||
2526              inst->num_sources == 2 ||
2527              inst->opcode == BRW_OPCODE_WAIT);
2528       assert(inst->has_dst ||
2529              inst->opcode == BRW_OPCODE_SYNC);
2530 
2531       if (inst->has_dst) {
2532          inst->dst.file = brw_eu_inst_dst_reg_file(devinfo, raw);
2533          inst->dst.type = brw_eu_inst_dst_type(devinfo, raw);
2534          inst->dst.address_mode = brw_eu_inst_dst_address_mode(devinfo, raw);
2535          if (inst->dst.address_mode == BRW_ADDRESS_DIRECT) {
2536             inst->dst.nr = brw_eu_inst_dst_da_reg_nr(devinfo, raw);
2537             if (inst->access_mode == BRW_ALIGN_1) {
2538                inst->dst.subnr = brw_eu_inst_dst_da1_subreg_nr(devinfo, raw);
2539             } else {
2540                inst->dst.subnr = brw_eu_inst_dst_da16_subreg_nr(devinfo, raw);
2541             }
2542          } else {
2543             inst->dst.subnr = brw_eu_inst_dst_ia_subreg_nr(devinfo, raw);
2544          }
2545          inst->dst.hstride = STRIDE(brw_eu_inst_dst_hstride(devinfo, raw));
2546       }
2547 
2548       inst->src[0].file = brw_eu_inst_src0_reg_file(devinfo, raw);
2549       inst->src[0].type = brw_eu_inst_src0_type(devinfo, raw);
2550       inst->src[0].address_mode = brw_eu_inst_src0_address_mode(devinfo, raw);
2551       inst->src[0].negate = brw_eu_inst_src0_negate(devinfo, raw);
2552       inst->src[0].abs = brw_eu_inst_src0_abs(devinfo, raw);
2553       if (inst->src[0].file != IMM) {
2554          if (inst->src[0].address_mode == BRW_ADDRESS_DIRECT) {
2555             inst->src[0].nr = brw_eu_inst_src0_da_reg_nr(devinfo, raw);
2556             if (inst->access_mode == BRW_ALIGN_1) {
2557                inst->src[0].subnr = brw_eu_inst_src0_da1_subreg_nr(devinfo, raw);
2558             } else {
2559                inst->src[0].subnr = brw_eu_inst_src0_da16_subreg_nr(devinfo, raw) * 16;
2560             }
2561          } else {
2562             inst->src[0].subnr = brw_eu_inst_src0_ia_subreg_nr(devinfo, raw);
2563          }
2564 
2565          inst->src[0].vstride = STRIDE(brw_eu_inst_src0_vstride(devinfo, raw));
2566          if (inst->access_mode == BRW_ALIGN_1) {
2567             inst->src[0].width = WIDTH(brw_eu_inst_src0_width(devinfo, raw));
2568             inst->src[0].hstride = STRIDE(brw_eu_inst_src0_hstride(devinfo, raw));
2569          }
2570       }
2571 
2572       if (inst->num_sources > 1) {
2573          inst->src[1].file = brw_eu_inst_src1_reg_file(devinfo, raw);
2574          inst->src[1].type = brw_eu_inst_src1_type(devinfo, raw);
2575          inst->src[1].negate = brw_eu_inst_src1_negate(devinfo, raw);
2576          inst->src[1].abs = brw_eu_inst_src1_abs(devinfo, raw);
2577          if (inst->src[1].file != IMM) {
2578             if (inst->src[1].address_mode == BRW_ADDRESS_DIRECT) {
2579                inst->src[1].nr = brw_eu_inst_src1_da_reg_nr(devinfo, raw);
2580                if (inst->access_mode == BRW_ALIGN_1) {
2581                   inst->src[1].subnr = brw_eu_inst_src1_da1_subreg_nr(devinfo, raw);
2582                } else {
2583                   inst->src[1].subnr = brw_eu_inst_src1_da16_subreg_nr(devinfo, raw) * 16;
2584                }
2585             } else {
2586                inst->src[1].subnr = brw_eu_inst_src1_ia_subreg_nr(devinfo, raw);
2587             }
2588 
2589             inst->src[1].vstride = STRIDE(brw_eu_inst_src1_vstride(devinfo, raw));
2590             if (inst->access_mode == BRW_ALIGN_1) {
2591                inst->src[1].width = WIDTH(brw_eu_inst_src1_width(devinfo, raw));
2592                inst->src[1].hstride = STRIDE(brw_eu_inst_src1_hstride(devinfo, raw));
2593             }
2594          }
2595       }
2596 
2597       break;
2598    }
2599 
2600    case FORMAT_BASIC_THREE_SRC: {
2601       assert(inst->num_sources == 3);
2602       assert(inst->has_dst);
2603 
2604       if (inst->access_mode == BRW_ALIGN_1) {
2605          inst->dst.file = brw_eu_inst_3src_a1_dst_reg_file(devinfo, raw);
2606          inst->dst.type = brw_eu_inst_3src_a1_dst_type(devinfo, raw);
2607          inst->dst.nr = brw_eu_inst_3src_dst_reg_nr(devinfo, raw);
2608          inst->dst.subnr = brw_eu_inst_3src_a1_dst_subreg_nr(devinfo, raw) * 8;
2609          inst->dst.hstride = STRIDE(brw_eu_inst_3src_a1_dst_hstride(devinfo, raw));
2610 
2611          inst->src[0].file = brw_eu_inst_3src_a1_src0_reg_file(devinfo, raw);
2612          inst->src[0].type = brw_eu_inst_3src_a1_src0_type(devinfo, raw);
2613          inst->src[0].negate = brw_eu_inst_3src_src0_negate(devinfo, raw);
2614          inst->src[0].abs = brw_eu_inst_3src_src0_abs(devinfo, raw);
2615          if (inst->src[0].file != IMM) {
2616             inst->src[0].nr = brw_eu_inst_3src_src0_reg_nr(devinfo, raw);
2617             inst->src[0].subnr = brw_eu_inst_3src_a1_src0_subreg_nr(devinfo, raw);
2618             inst->src[0].vstride = VSTRIDE_3SRC(brw_eu_inst_3src_a1_src0_vstride(devinfo, raw));
2619             inst->src[0].hstride = STRIDE(brw_eu_inst_3src_a1_src0_hstride(devinfo, raw));
2620          }
2621 
2622          inst->src[1].file = brw_eu_inst_3src_a1_src1_reg_file(devinfo, raw);
2623          inst->src[1].type = brw_eu_inst_3src_a1_src1_type(devinfo, raw);
2624          inst->src[1].negate = brw_eu_inst_3src_src1_negate(devinfo, raw);
2625          inst->src[1].abs = brw_eu_inst_3src_src1_abs(devinfo, raw);
2626          inst->src[1].nr = brw_eu_inst_3src_src1_reg_nr(devinfo, raw);
2627          inst->src[1].subnr = brw_eu_inst_3src_a1_src1_subreg_nr(devinfo, raw);
2628          inst->src[1].vstride = VSTRIDE_3SRC(brw_eu_inst_3src_a1_src1_vstride(devinfo, raw));
2629          inst->src[1].hstride = STRIDE(brw_eu_inst_3src_a1_src1_hstride(devinfo, raw));
2630 
2631          inst->src[2].file = brw_eu_inst_3src_a1_src2_reg_file(devinfo, raw);
2632          inst->src[2].type = brw_eu_inst_3src_a1_src2_type(devinfo, raw);
2633          inst->src[2].negate = brw_eu_inst_3src_src2_negate(devinfo, raw);
2634          inst->src[2].abs = brw_eu_inst_3src_src2_abs(devinfo, raw);
2635          if (inst->src[2].file != IMM) {
2636             inst->src[2].nr = brw_eu_inst_3src_src2_reg_nr(devinfo, raw);
2637             inst->src[2].subnr = brw_eu_inst_3src_a1_src2_subreg_nr(devinfo, raw);
2638             inst->src[2].hstride = STRIDE(brw_eu_inst_3src_a1_src2_hstride(devinfo, raw));
2639          }
2640 
2641       } else {
2642          inst->dst.file = FIXED_GRF;
2643          inst->dst.type = brw_eu_inst_3src_a16_dst_type(devinfo, raw);
2644          inst->dst.nr = brw_eu_inst_3src_dst_reg_nr(devinfo, raw);
2645          inst->dst.subnr = brw_eu_inst_3src_a16_dst_subreg_nr(devinfo, raw) * 4;
2646 
2647          enum brw_reg_type src_type = brw_eu_inst_3src_a16_src_type(devinfo, raw);
2648 
2649          inst->src[0].file = FIXED_GRF;
2650          inst->src[0].type = src_type;
2651          inst->src[0].nr = brw_eu_inst_3src_src0_reg_nr(devinfo, raw);
2652          inst->src[0].subnr = brw_eu_inst_3src_a16_src0_subreg_nr(devinfo, raw) * 4;
2653 
2654          inst->src[1].file = FIXED_GRF;
2655          inst->src[1].type = src_type;
2656          inst->src[1].nr = brw_eu_inst_3src_src1_reg_nr(devinfo, raw);
2657          inst->src[1].subnr = brw_eu_inst_3src_a16_src1_subreg_nr(devinfo, raw) * 4;
2658 
2659          inst->src[2].file = FIXED_GRF;
2660          inst->src[2].type = src_type;
2661          inst->src[2].nr = brw_eu_inst_3src_src2_reg_nr(devinfo, raw);
2662          inst->src[2].subnr = brw_eu_inst_3src_a16_src2_subreg_nr(devinfo, raw) * 4;
2663       }
2664       break;
2665    }
2666 
2667    case FORMAT_DPAS_THREE_SRC: {
2668       assert(inst->num_sources == 3);
2669       assert(inst->has_dst);
2670 
2671       inst->dst.file = brw_eu_inst_dpas_3src_dst_reg_file(devinfo, raw);
2672       inst->dst.type = brw_eu_inst_dpas_3src_dst_type(devinfo, raw);
2673       inst->dst.nr = brw_eu_inst_dpas_3src_dst_reg_nr(devinfo, raw);
2674       inst->dst.subnr = brw_eu_inst_dpas_3src_dst_subreg_nr(devinfo, raw);
2675 
2676       inst->src[0].file = brw_eu_inst_dpas_3src_src0_reg_file(devinfo, raw);
2677       inst->src[0].type = brw_eu_inst_dpas_3src_src0_type(devinfo, raw);
2678       inst->src[0].nr = brw_eu_inst_dpas_3src_src0_reg_nr(devinfo, raw);
2679       inst->src[0].subnr = brw_eu_inst_dpas_3src_src0_subreg_nr(devinfo, raw);
2680 
2681       inst->src[1].file = brw_eu_inst_dpas_3src_src1_reg_file(devinfo, raw);
2682       inst->src[1].type = brw_eu_inst_dpas_3src_src1_type(devinfo, raw);
2683       inst->src[1].nr = brw_eu_inst_dpas_3src_src1_reg_nr(devinfo, raw);
2684       inst->src[1].subnr = brw_eu_inst_dpas_3src_src1_subreg_nr(devinfo, raw);
2685 
2686       inst->src[2].file = brw_eu_inst_dpas_3src_src2_reg_file(devinfo, raw);
2687       inst->src[2].type = brw_eu_inst_dpas_3src_src2_type(devinfo, raw);
2688       inst->src[2].nr = brw_eu_inst_dpas_3src_src2_reg_nr(devinfo, raw);
2689       inst->src[2].subnr = brw_eu_inst_dpas_3src_src2_subreg_nr(devinfo, raw);
2690       break;
2691    }
2692 
2693    case FORMAT_SEND: {
2694       if (inst->opcode == BRW_OPCODE_SENDS || inst->opcode == BRW_OPCODE_SENDSC) {
2695          assert(devinfo->ver < 12);
2696 
2697          inst->dst.file = brw_eu_inst_send_dst_reg_file(devinfo, raw);
2698          inst->dst.type = BRW_TYPE_D;
2699          inst->dst.nr = brw_eu_inst_dst_da_reg_nr(devinfo, raw);
2700          inst->dst.subnr = brw_eu_inst_dst_da16_subreg_nr(devinfo, raw) * 16;
2701 
2702          inst->src[0].file = FIXED_GRF;
2703          inst->src[0].type = BRW_TYPE_D;
2704          inst->src[0].nr = brw_eu_inst_src0_da_reg_nr(devinfo, raw);
2705          inst->src[0].subnr = brw_eu_inst_src0_da16_subreg_nr(devinfo, raw) * 16;
2706 
2707          if (inst->num_sources > 1) {
2708             inst->src[1].file = brw_eu_inst_send_src1_reg_file(devinfo, raw);
2709             inst->src[1].type = BRW_TYPE_D;
2710             inst->src[1].nr = brw_eu_inst_send_src1_reg_nr(devinfo, raw);
2711          }
2712       } else {
2713          assert(devinfo->ver >= 12);
2714 
2715          inst->dst.file = brw_eu_inst_dst_reg_file(devinfo, raw);
2716          inst->dst.type = BRW_TYPE_D;
2717          inst->dst.nr = brw_eu_inst_dst_da_reg_nr(devinfo, raw);
2718 
2719          inst->src[0].file = brw_eu_inst_send_src0_reg_file(devinfo, raw);
2720          inst->src[0].type = BRW_TYPE_D;
2721          inst->src[0].nr = brw_eu_inst_src0_da_reg_nr(devinfo, raw);
2722 
2723          if (inst->num_sources > 1) {
2724             inst->src[1].file = brw_eu_inst_send_src1_reg_file(devinfo, raw);
2725             inst->src[1].type = BRW_TYPE_D;
2726             inst->src[1].nr = brw_eu_inst_send_src1_reg_nr(devinfo, raw);
2727          }
2728       }
2729       break;
2730    }
2731 
2732    case FORMAT_BRANCH: {
2733       assert(!inst->has_dst);
2734       break;
2735    }
2736 
2737    case FORMAT_ILLEGAL:
2738    case FORMAT_NOP: {
2739       assert(!inst->has_dst);
2740       assert(inst->num_sources == 0);
2741       break;
2742    }
2743    }
2744 
2745    if (inst->has_dst) {
2746       ERROR_IF(inst->dst.type == BRW_TYPE_INVALID,
2747                "Invalid destination register type encoding.");
2748    }
2749 
2750    for (unsigned i = 0; i < inst->num_sources; i++) {
2751       ERROR_IF(inst->src[i].type == BRW_TYPE_INVALID,
2752                "Invalid source register type encoding.");
2753    }
2754 
2755    if ((inst->format == FORMAT_BASIC ||
2756         inst->format == FORMAT_BASIC_THREE_SRC ||
2757         inst->format == FORMAT_DPAS_THREE_SRC) &&
2758        !inst_is_send(inst)) {
2759       inst->saturate = brw_eu_inst_saturate(devinfo, raw);
2760 
2761       if (inst->num_sources > 1 ||
2762           devinfo->ver < 12 ||
2763           inst->src[0].file != IMM  ||
2764           brw_type_size_bytes(inst->src[0].type) < 8) {
2765          inst->cond_modifier = brw_eu_inst_cond_modifier(devinfo, raw);
2766       }
2767    }
2768 
2769    return error_msg;
2770 }
2771 
2772 bool
brw_validate_instruction(const struct brw_isa_info * isa,const brw_eu_inst * inst,int offset,unsigned inst_size,struct disasm_info * disasm)2773 brw_validate_instruction(const struct brw_isa_info *isa,
2774                          const brw_eu_inst *inst, int offset,
2775                          unsigned inst_size,
2776                          struct disasm_info *disasm)
2777 {
2778    struct string error_msg = { .str = NULL, .len = 0 };
2779 
2780    if (is_unsupported_inst(isa, inst)) {
2781       ERROR("Instruction not supported on this Gen");
2782    } else {
2783       brw_hw_decoded_inst decoded = {};
2784       error_msg = brw_hw_decode_inst(isa, &decoded, inst);
2785 
2786 #define CHECK(func, args...)                             \
2787    do {                                                  \
2788       struct string __msg = func(isa, &decoded, ##args); \
2789       if (__msg.str) {                                   \
2790          cat(&error_msg, __msg);                         \
2791          free(__msg.str);                                \
2792       }                                                  \
2793    } while (0)
2794 
2795       if (error_msg.str == NULL)
2796          CHECK(invalid_values);
2797 
2798       if (error_msg.str == NULL) {
2799          CHECK(sources_not_null);
2800          CHECK(send_restrictions);
2801          CHECK(general_restrictions_based_on_operand_types);
2802          CHECK(general_restrictions_on_region_parameters);
2803          CHECK(special_restrictions_for_mixed_float_mode);
2804          CHECK(region_alignment_rules);
2805          CHECK(vector_immediate_restrictions);
2806          CHECK(special_requirements_for_handling_double_precision_data_types);
2807          CHECK(instruction_restrictions);
2808          CHECK(send_descriptor_restrictions);
2809          CHECK(register_region_special_restrictions);
2810          CHECK(scalar_register_restrictions);
2811       }
2812 
2813 #undef CHECK
2814    }
2815 
2816    if (error_msg.str && disasm) {
2817       disasm_insert_error(disasm, offset, inst_size, error_msg.str);
2818    }
2819    free(error_msg.str);
2820 
2821    return error_msg.len == 0;
2822 }
2823 
2824 bool
brw_validate_instructions(const struct brw_isa_info * isa,const void * assembly,int start_offset,int end_offset,struct disasm_info * disasm)2825 brw_validate_instructions(const struct brw_isa_info *isa,
2826                           const void *assembly, int start_offset, int end_offset,
2827                           struct disasm_info *disasm)
2828 {
2829    const struct intel_device_info *devinfo = isa->devinfo;
2830    bool valid = true;
2831 
2832    for (int src_offset = start_offset; src_offset < end_offset;) {
2833       const brw_eu_inst *inst = assembly + src_offset;
2834       bool is_compact = brw_eu_inst_cmpt_control(devinfo, inst);
2835       unsigned inst_size = is_compact ? sizeof(brw_eu_compact_inst)
2836                                       : sizeof(brw_eu_inst);
2837       brw_eu_inst uncompacted;
2838 
2839       if (is_compact) {
2840          brw_eu_compact_inst *compacted = (void *)inst;
2841          brw_uncompact_instruction(isa, &uncompacted, compacted);
2842          inst = &uncompacted;
2843       }
2844 
2845       bool v = brw_validate_instruction(isa, inst, src_offset,
2846                                         inst_size, disasm);
2847       valid = valid && v;
2848 
2849       src_offset += inst_size;
2850    }
2851 
2852    return valid;
2853 }
2854