1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 %{
10 #include <stdio.h>
11 #include <math.h>
12 #include <string>
13 #include <vector>
14 
15 #include "visa_igc_common_header.h"
16 #include "Common_ISA.h"
17 #include "Common_ISA_util.h"
18 #include "Common_ISA_framework.h"
19 #include "JitterDataStruct.h"
20 #include "VISAKernel.h"
21 
22 static int lscCheckExecSize(
23     LSC_SFID sfid,
24     LSC_OP op,
25     LSC_DATA_ORDER data_order,
26     int exec_size);
27 
28 //VISA_Type variable_declaration_and_type_check(char *var, Common_ISA_Var_Class type);
29 void CISAerror(CISA_IR_Builder* builder, char const* msg);
30 int yylex(CISA_IR_Builder *pBuilder);
31 extern int CISAlineno;
32 
33 
34 static bool ParseAlign(CISA_IR_Builder* pBuilder, const char *sym, VISA_Align &value);
35 static VISA_Align AlignBytesToVisaAlignment(int bytes);
36 static int DataTypeSizeOf(VISA_Type type);
37 static bool ParseEMask(CISA_IR_Builder* pBuilder, const char* sym, VISA_EMask_Ctrl &emask);
38 
39 
40 
41 
42 //
43 // check if the cond is true.
44 // if cond is false, then print errorMessage (syntax error) and YYABORT
45 #define MUST_HOLD(cond, errorMessage) \
46   {if (!(cond)) {pBuilder->RecordParseError(CISAlineno, errorMessage); YYABORT;}}
47 #define PARSE_ERROR_AT(LINE,...)\
48   {pBuilder->RecordParseError(LINE, __VA_ARGS__); YYABORT;}
49 #define PARSE_ERROR(...)\
50     PARSE_ERROR_AT(CISAlineno, __VA_ARGS__)
51 
52 // Use this to wrap API calls that return false, nullptr, or 0 on failure
53 // It's assumed that the API call reported the parse error
54 #define ABORT_ON_FAIL(X) \
55     do \
56         if (!(X)) \
57             YYABORT;\
58     while (0)
59 #define TRACE(S) \
60     do { \
61       if (CISAout && pBuilder->debugParse()) \
62           fprintf(CISAout, "line %d: %s", CISAlineno, S); \
63     } while (0)
64 
65 std::deque<const char*> switchLabels;
66 char * switch_label_array[32];
67 std::vector<VISA_opnd*> RTRWOperands;
68 int num_parameters;
69 
70 VISA_RawOpnd* rawOperandArray[16];
71 
72 // global var for non-kernel attribute option.
73 // The var needs to be cleared before each use.
74 std::vector<attr_gen_struct*> AttrOptVar;
75 
76 #ifdef _MSC_VER
77 #pragma warning(disable:4065; disable:4267)
78 #endif
79 
80 %}
81 
82 %param {CISA_IR_Builder* pBuilder}
83 
84 //////////////////////////////////////////////////////////////////////////
85 // This asserts that the parser is (nearly?) free of shift-reduce and reduce-reduce
86 // conflicts.  This is usually pretty easy to keep at the moment.
87 //   FIXME: c.f. CmpInstruction:
88 %expect 1
89 
90 %define parse.error verbose
91 
92 %union
93 {
94     int64_t                intval;
95     double                 fltval;
96 
97     struct strlitbuf_struct {
98         char      decoded[4096];
99         size_t    len;
100     } strlit;
101     char *                 string;
102 
103     VISA_Type              type;
104     ISA_Opcode             opcode;
105     bool                   sat;
106 
107     VISA_Cond_Mod          cond_mod;
108 
109     VISA_opnd *            pred_reg;
110     VISA_PREDICATE_STATE   pred_sign;
111     VISA_PREDICATE_CONTROL pred_ctrl;
112 
113     // to tell call is fc_call or subroutine call
114     struct call_sub_or_fc {
115         ISA_Opcode opcode;
116         bool       is_fccall;
117     } cisa_call;
118 
119     struct {
120         VISA_Modifier mod;
121     } src_mod;
122 
123     struct {
124         unsigned int v_stride;
125         unsigned int h_stride;
126         unsigned int width;
127     } cisa_region;
128 
129     struct {
130         int                row;
131         int                elem;
132     } offset;
133 
134     struct {
135         Common_ISA_Operand_Class type;
136         VISA_opnd * cisa_gen_opnd;
137     } genOperand;
138 
139     struct {
140         char * var_name;
141         VISA_opnd * cisa_gen_opnd;
142         unsigned char streamMode;
143         unsigned char searchCtrl;
144     } vmeOpndIvb;
145 
146     struct {
147         VISA_opnd * cisa_fbrMbMode_opnd;
148         VISA_opnd * cisa_fbrSubMbShape_opnd;
149         VISA_opnd * cisa_fbrSubPredMode_opnd;
150     } vmeOpndFbr;
151 
152     struct {
153         int            row;
154         int            elem;
155         int            immOff;
156         VISA_opnd *    cisa_gen_opnd;
157         CISA_GEN_VAR * cisa_decl;
158     } regAccess;
159 
160     struct {
161         char *             aliasname;
162         int                offset;
163     } alias;
164 
165     VISA_opnd * RawVar;
166 
167     struct {
168         Common_ISA_State_Opnd type;
169         unsigned char offset;
170         VISA_opnd * cisa_gen_opnd;
171     } StateVar;
172 
173     struct {
174         VISA_EMask_Ctrl emask;
175         int exec_size;
176     } emask_exec_size;
177 
178     struct attr_gen_struct*  pattr_gen;
179 
180     struct dpas_info_struct {
181         ISA_Opcode    opcode;
182         GenPrecision  src2Precision;
183         GenPrecision  src1Precision;
184         uint8_t       depth;
185         uint8_t       count;
186     } dpas_info;
187 
188     struct bfn_op_struct {
189         uint8_t func_ctrl;
190     } bfn_info;
191 
192     ///////////////////////////////////////////////////////////////////////////
193     // Support for LSC instructions
194     LSC_OP                  lsc_subOpcode;
195     ISA_Opcode              lsc_opcode;
196     LSC_CACHE_OPTS          lsc_caching_opts;
197     LSC_CACHE_OPT           lsc_caching_opt; // for lexer to parser
198     LSC_FENCE_OP            lsc_fence_op;
199     LSC_SCOPE               lsc_scope;
200     LSC_SFID                lsc_sfid;
201 
202     struct {
203         VISA_opnd              *reg;
204         LSC_DATA_SHAPE          shape;
205     } lsc_data_operand;
206     LSC_DATA_SHAPE            lsc_data_shape;
207     struct {
208         VISA_opnd              *reg;
209         LSC_DATA_SHAPE_BLOCK2D  shape2D;
210     } lsc_data_operand2d;
211     LSC_DATA_SHAPE_BLOCK2D    lsc_data_shape2d;
212 
213     struct {
214         VISA_opnd               *surface;
215         // for UNTYPED
216         //  simple:  regs[0] = reg addr
217         //  strided: regs[0] = base; regs[1] = strided
218         //  block2d: regs = {surfBase,surfWidth,surfHeight,surfPitch,surfX,surfY}
219         //
220         // for TYPED: {U, V, R, LOD}
221         // for TYPED block2d: regs = {BlockStartX, BlockStartY}
222         VISA_opnd               *regs[6];
223         LSC_ADDR                 addr;
224     } lsc_addr_operand;
225     LSC_ADDR_SIZE              lsc_addr_size;
226     LSC_ADDR_TYPE              lsc_addr_type;
227     VISA_opnd                 *lsc_addr_surface_ident; // vec. opnd imm or reg
228     struct lsc_addr_model_struct {
229         LSC_ADDR_TYPE          type;
230         VISA_opnd             *surface; // can be imm or reg
231     } lsc_addr_model;
232 
233     // Align Support in Declaration
234     VISA_Align             align;
235 
236     VISAAtomicOps          atomic_op;
237     VISASampler3DSubOpCode sample3DOp;
238 
239     MEDIA_LD_mod           media_mode;
240     bool                   oword_mod;
241     VISAChannelMask        s_channel; // Cannot use ChannelMask here as it's a member of union where non-trivial constructor is not allowed.
242     CHANNEL_OUTPUT_FORMAT  s_channel_output;
243     VISA_EMask_Ctrl        emask;
244     OutputFormatControl    cntrl;
245     AVSExecMode            execMode;
246     unsigned char          fence_options;
247 
248     // Pixel null mask for sampler instructions.
249     bool                   pixel_null_mask;
250 
251     // CPS LOD compensation enable for 3d sample.
252     bool                   cps;
253     bool                   non_uniform_sampler;
254     bool                   flag;
255 
256     CISA_GEN_VAR*          vISADecl;
257 } // end of possible token types
258 
259 %start Listing
260 
261 %type <intval> ScopeStart
262 
263 
264 %token <align>     ALIGN_KEYWORD
265 %token <atomic_op> ATOMIC_SUB_OP
266 
267 // directives
268 %token          DIRECTIVE_DECL        // .decl
269 %token          DIRECTIVE_FUNC        // .function
270 %token          DIRECTIVE_FUNCDECL    // .funcdecl
271 %token          DIRECTIVE_GLOBAL_FUNC // .global_function
272 %token <string> DIRECTIVE_IMPLICIT    // .implicit*
273 %token          DIRECTIVE_INPUT       // .input
274 %token          DIRECTIVE_KERNEL      // .kernel
275 %token          DIRECTIVE_KERNEL_ATTR // .kernel_attr
276 %token          DIRECTIVE_PARAMETER   // .parameter
277 %token          DIRECTIVE_VERSION     // .verions
278 
279 // tokens to support .decl and .input
280 %token ALIAS_EQ             // .decl ... alias=...
281 %token ALIGN_EQ             // .decl ... align=...
282 %token ATTR_EQ              // .decl ... attr=...
283 %token OFFSET_EQ
284 %token NUM_ELTS_EQ
285 %token V_NAME_EQ
286 %token SIZE_EQ
287 %token V_TYPE_EQ_G // v_type=G
288 %token V_TYPE_EQ_P
289 %token V_TYPE_EQ_A
290 %token V_TYPE_EQ_S
291 %token V_TYPE_EQ_T
292 
293 
294 %token CPS                   // .cps
295 %token NON_UNIFORM_SAMPLER  // .divS
296 %token PIXEL_NULL_MASK      // .pixel_null_mask
297 %token RAW_SENDC_STRING     // raw_sendc
298 %token RAW_SENDSC_EOT_STRING // raw_sendsc_eot
299 %token RAW_SENDSC_STRING    // raw_sendsc
300 %token RAW_SENDS_EOT_STRING // raw_sends_eot
301 %token RAW_SENDS_STRING     // raw_sends
302 %token RAW_SEND_STRING      // raw_send
303 %token SAT                  // .sat
304 %token SRCMOD_ABS           // (abs)
305 %token SRCMOD_NEG           // (-)
306 %token SRCMOD_NEGABS        // (-abs)
307 %token SRCMOD_NOT           // (~)
308 %token BFN_OP
309 %token DPAS_OP
310 %token BF_CVT_OP
311 %token <opcode> NBARRIER_SIGNAL
312 %token <opcode> NBARRIER_WAIT
313 %token <type>   ITYPE
314 %token <type>   DECL_DATA_TYPE
315 %token <type>   DFTYPE         // :df
316 %token <type>   FTYPE          // :f
317 %token <type>   HFTYPE         // :hf
318 %token <type>   VTYPE          // :v and vf
319 %token <cond_mod> COND_MOD     // .ne .ge ...
320 
321 %token LANGLE          // <
322 %token RANGLE          // >
323 %token LBRACK          // [
324 %token RBRACK          // ]
325 %token IND_LBRACK      // r[
326 %token LPAREN          // (
327 %token RPAREN          // )
328 %token LBRACE          // {
329 %token RBRACE          // }
330 
331 %token DOT             // .
332 %token COMMA           // ,
333 %token SEMI            // ;
334 %token COLON           // :
335 %token SLASH           // /
336 %token PERCENT         // %
337 %token EQUALS          // =
338 %token PLUS            // +
339 %token MINUS           // -
340 %token TIMES           // *
341 %token AMP             // &
342 %token CIRC            // ^
343 %token PIPE            // |
344 %token TILDE           // ~
345 %token BANG            // !
346 %token QUESTION        // ?
347 %token LEQ             // relational operators
348 %token GEQ
349 %token EQ
350 %token NEQ
351 %token SHL             // shift operators
352 %token SHRS
353 %token SHRZ
354 
355 %token <string> LABEL
356 
357 %token <string> IDENT         // an identifier of some sort
358 %token <string> BUILTIN_NULL  // %null
359 %token <string> BUILTIN       // other builtins e.g. %r0, %cr0, ...
360 %token <string> STRING_LIT
361 
362 %token NEWLINE
363 
364 
365 %token <string>            RTWRITE_OPTION
366 %token <media_mode>        MEDIA_MODE
367 %token <oword_mod>         OWORD_MODIFIER
368 %token <s_channel>         SAMPLER_CHANNEL
369 %token <s_channel_output>  CHANNEL_OUTPUT
370 %token <execMode>          EXECMODE
371 %token <cntrl>             CNTRL
372 %token <fence_options>     FENCE_OPTIONS;
373 
374 // Instruction opcode tokens
375 %token <opcode> ADDR_ADD_OP
376 %token <opcode> UNARY_LOGIC_OP
377 %token <opcode> BINARY_LOGIC_OP
378 %token <opcode> TERNARY_LOGIC_OP
379 %token <opcode> QUATERNARY_LOGIC_OP
380 
381 %token <opcode> SEL_OP
382 %token <opcode> MIN_OP
383 %token <opcode> MAX_OP
384 %token <opcode> ANTI_TRIG_OP
385 %token <opcode> MATH2_OP
386 %token <opcode> MATH3_OP
387 %token <opcode> ARITH2_OP
388 %token <opcode> ARITH3_OP
389 %token <opcode> ARITH4_OP
390 %token <opcode> ARITH4_OP2
391 %token <opcode> CMP_OP
392 %token <opcode> SVM_OP
393 %token <opcode> SVM_SCATTER_OP
394 %token <opcode> SVM_GATHER4SCALED_OP
395 %token <opcode> SVM_SCATTER4SCALED_OP
396 %token <opcode> SVM_ATOMIC_OP
397 %token <opcode> OWORD_OP
398 %token <opcode> MEDIA_OP
399 %token <opcode> SCATTER_OP
400 %token <opcode> SCATTER_TYPED_OP
401 %token <opcode> SCATTER_SCALED_OP
402 %token <opcode> SCATTER4_SCALED_OP
403 %token <opcode> BARRIER_OP
404 %token <opcode> SBARRIER_SIGNAL
405 %token <opcode> SBARRIER_WAIT
406 %token <opcode> DWORD_ATOMIC_OP
407 %token <opcode> TYPED_ATOMIC_OP
408 %token <opcode> SAMPLE_OP
409 %token <opcode> SAMPLE_UNORM_OP
410 %token <opcode> VME_IME_OP
411 %token <opcode> VME_SIC_OP
412 %token <opcode> VME_FBR_OP
413 %token <opcode> BRANCH_OP
414 %token <opcode> RET_OP
415 %token <opcode> IFCALL
416 %token <opcode> FCALL
417 %token <opcode> FADDR
418 %token <opcode> SWITCHJMP_OP
419 %token <opcode> MOVS_OP
420 %token <opcode> SETP_OP
421 %token <opcode> MOV_OP
422 %token <opcode> FILE_OP
423 %token <opcode> LOC_OP
424 %token <opcode> CACHE_FLUSH_OP
425 %token <opcode> WAIT_OP
426 %token <opcode> FENCE_GLOBAL_OP
427 %token <opcode> FENCE_LOCAL_OP
428 %token <opcode> FENCE_SW_OP
429 %token <opcode> YIELD_OP
430 %token <sample3DOp> SAMPLE_3D_OP
431 %token <sample3DOp> LOAD_3D_OP
432 %token <sample3DOp> SAMPLE4_3D_OP
433 %token <opcode> RESINFO_OP_3D
434 %token <opcode> SAMPLEINFO_OP_3D
435 %token <opcode> RTWRITE_OP_3D
436 %token <opcode> URBWRITE_OP_3D
437 %token <opcode> LIFETIME_START_OP
438 %token <opcode> LIFETIME_END_OP
439 %token <opcode> AVS_OP
440 %token <cisa_call> CALL_OP
441 
442 %type <string> RTWriteModeOpt
443 
444 %type <intval> SwitchLabels
445 %type <intval> RTWriteOperandParse
446 
447 %type <pred_reg>   Predicate
448 %type <pred_sign>  PredSign
449 %type <pred_ctrl>  PredCtrlOpt
450 %token <pred_ctrl> PRED_CNTL   // .any or .all
451 
452 
453 %type <string> IdentOrStringLit
454 %type <string> Var
455 %type <string> VarNonNull
456 
457 %type <intval> MediaInstructionPlaneID
458 %type <intval> SIMDMode
459 %type <intval> DstRegion
460 
461 
462 %token <fltval> F32_LIT  // single-precision floating point value
463 %token <fltval> F64_LIT  // double-precision floating point value
464 %token <intval> DEC_LIT  // decimal (base 10) literal
465 %token <intval> HEX_LIT  // hexadecimal literal (e.g. 0x123)
466 
467 %type <intval> IntExp
468 %type <intval> IntExpCond
469 %type <intval> IntExpAND
470 %type <intval> IntExpXOR
471 %type <intval> IntExpOR
472 %type <intval> IntExpCmp
473 %type <intval> IntExpRel
474 %type <intval> IntExpNRA
475 %type <intval> IntExpShift
476 %type <intval> IntExpAdd
477 %type <intval> IntExpMul
478 %type <intval> IntExpUnr
479 %type <intval> IntExpPrim
480 
481 %token BUILTIN_SIZEOF
482 %token BUILTIN_DISPATCH_SIMD_SIZE
483 
484 %type <intval> ElemNum
485 %type <intval> InputOffset
486 %type <intval> InputSize
487 %type <string> VNameEqOpt
488 
489 %type <cond_mod> ConditionalModifier
490 
491 %type <genOperand> SrcGeneralOperand
492 %type <genOperand> SrcImmOperand
493 %type <fltval>     FloatLit
494 %type <fltval>     DoubleFloatLit
495 %type <genOperand> SrcIndirectOperand
496 %type <genOperand> SrcAddrOperand
497 %type <genOperand> SrcAddrOfOperand
498 %type <regAccess>  AddrOfVar
499 
500 // the scheme here is:
501 //   G - general;           e.g. VAR(0,2)
502 //   I - indirect           e.g. r[A0(0),0]<0;1,0>:f
503 //   IMM - immediate        e.g. 0x123:d or 3.141:f
504 //   A - address register   e.g. A(1)
505 //   AO - address of        e.g. &V127+0x10
506 %type <genOperand> VecSrcOperand_G
507 %type <genOperand> VecSrcOperand_G_A
508 %type <genOperand> VecSrcOperand_G_A_AO
509 %type <genOperand> VecSrcOperand_G_IMM
510 %type <genOperand> VecSrcOperand_G_IMM_AO
511 %type <genOperand> VecSrcOperand_G_I_IMM
512 %type <genOperand> VecSrcOperand_G_I_IMM_A
513 %type <genOperand> VecSrcOperand_G_I_IMM_A_AO
514 %type <genOperand> VecDstOperand_A
515 %type <genOperand> VecDstOperand_G
516 %type <genOperand> VecDstOperand_G_I
517 %type <genOperand> VecSrcOpndSimple
518 %type <genOperand> DstGeneralOperand
519 %type <genOperand> DstAddrOperand
520 %type <genOperand> DstIndirectOperand
521 
522 %type <cisa_region> SrcRegionDirect
523 %type <cisa_region> SrcRegionIndirect
524 
525 %type <regAccess>    IndirectVarAccess
526 %type <offset>       TwoDimOffset
527 %type <vISADecl>     PredVar
528 %type <regAccess>    AddrVarAccess
529 %type <regAccess>    AddrVarAccessWithWidth
530 // %type <vISADecl>     AddrVar
531 
532 %type <vmeOpndIvb> VMEOpndIME
533 %type <vmeOpndFbr> VMEOpndFBR
534 
535 %type <align>               Align
536 %type <align>               AlignAttrOpt
537 %type <emask_exec_size>     ExecSize
538 %type <intval>              ExecSizeInt
539 %type <type>                DataType
540 %type <type>                DataTypeIntOrVector
541 %type <src_mod>             SrcModifier
542 %type <sat>                 SatModOpt
543 %type <alias>               AliasAttrOpt
544 %type <oword_mod>           OwordModifier
545 %type <StateVar>            DstStateOperand
546 %type <StateVar>            SrcStateOperand
547 %type <RawVar>              RawOperand
548 %type <RawVar>              RawOperandNonNull
549 %type <intval>              RawOperandOffsetSuffix
550 %type <intval>              RawOperandArray
551 %type <pixel_null_mask>     PixelNullMaskEnableOpt
552 %type <cps>                 CPSEnableOpt
553 %type <non_uniform_sampler> NonUniformSamplerEnableOpt
554 %type <pattr_gen>           OneAttr
555 %type <intval>              AttrOpt
556 %type <intval>              GenAttrOpt
557 %type <flag>                Atomic16Opt
558 %type <intval>              AtomicBitwidthOpt
559 %type <dpas_info>           DPAS_OP
560 %type <bfn_info>            BFN_OP
561 %token <opcode>             QW_SCATTER_OP
562 // elements to support new LSC instructions
563 //
564 // cache options
565 %type  <lsc_caching_opts>      LscCacheOpts
566 %token <lsc_caching_opt>       LSC_CACHING_OPT
567 %type <RawVar>                 LscPayloadReg
568 %type <RawVar>                 LscPayloadNonNullReg
569 // address syntax; e.g. bss(S2)[V12]:a64
570 %type <lsc_addr_model>         LscAddrModelOpt
571 %type <lsc_addr_model>         LscRegAddrModel
572 %type <lsc_addr_operand>       LscUntypedAddrOperand
573 %type <lsc_addr_operand>       LscUntypedStridedAddrOperand
574 %type <lsc_addr_operand>       LscUntypedBlock2dAddrOperand
575 %type <lsc_addr_operand>       LscTypedAddrOperand
576 %token <lsc_addr_size>         LSC_ADDR_SIZE_TK
577 %type <lsc_addr_type>          LscRegAddrModelKind
578 %type <intval>                 LscAddrImmOffsetOpt
579 %type <intval>                 LscAddrImmScaleOpt
580 %type <lsc_addr_surface_ident> LscVectorOpRegOrImm
581 %type <lsc_addr_surface_ident> LscVectorOpReg
582 %type <lsc_addr_surface_ident> LscVectorOpImm
583 
584 // data syntax; e.g. V13:u32x4t
585 %type <lsc_data_operand>       LscDataOperand
586 %type <lsc_data_operand2d>     LscDataOperand2D
587 %token <lsc_data_shape>        LSC_DATA_SHAPE_TK
588 %token <lsc_data_shape>        LSC_DATA_SHAPE_TK_CHMASK
589 %token <lsc_data_shape2d>      LSC_DATA_SHAPE_TK_BLOCK2D
590 //
591 %token                         LSC_AM_FLAT
592 %token                         LSC_AM_BTI
593 %token                         LSC_AM_BSS
594 %token                         LSC_AM_SS
595 //
596 %token <lsc_fence_op>          LSC_FENCE_OP_TYPE
597 %token <lsc_scope>             LSC_FENCE_SCOPE
598 //
599 %type  <lsc_sfid>              LscSfid
600 %token <lsc_sfid>              LSC_SFID_UNTYPED_TOKEN
601 %token <lsc_sfid>              LSC_SFID_TYPED_TOKEN
602 ////////////////////////////////////////////////////////
603 // specific LSC ops
604 //
605 // load*/store*/atomic* are all subops of LSC_TYPED and LSC_UNTYPED.
606 // We infer which parent op based on the grammar (LSC_SFID).
607 %token <lsc_subOpcode>         LSC_LOAD_MNEMONIC
608 %token <lsc_subOpcode>         LSC_LOAD_STRIDED_MNEMONIC
609 %token <lsc_subOpcode>         LSC_LOAD_BLOCK2D_MNEMONIC
610 %token <lsc_subOpcode>         LSC_STORE_MNEMONIC
611 %token <lsc_subOpcode>         LSC_STORE_STRIDED_MNEMONIC
612 %token <lsc_subOpcode>         LSC_STORE_BLOCK2D_MNEMONIC
613 %token <lsc_subOpcode>         LSC_ATOMIC_MNEMONIC
614 %token <lsc_subOpcode>         LSC_READ_STATE_INFO_MNEMONIC
615 // fence is a top-level op (not a subop)
616 %token <lsc_opcode>            LSC_FENCE_MNEMONIC
617 %token <opcode>                FCVT_OP
618 
619 
620 
621 %%
622 Listing: NewlinesOpt ListingHeader NewlinesOpt Statements NewlinesOpt {
623         TRACE("** Listing Complete\n");
624         pBuilder->CISA_post_file_parse();
625     }
626 
627 ListingHeader: DirectiveVersion
628 
629 Statements: Statements Newlines Statement | Statement
630 
631 Newlines: Newlines NEWLINE | NEWLINE
632 NewlinesOpt: %empty | Newlines
633 
634 Statement:
635       DirectiveDecl
636     | DirectiveKernel
637     | DirectiveGlobalFunction
638     | DirectiveImplicitInput
639     | DirectiveInput
640     | DirectiveParameter
641     | DirectiveFunc
642     | DirectiveAttr
643     | Instruction
644     | Label
645     | Scope
646 
647 
648 // ------------- Scope -------------
649 Scope:
650       ScopeStart NewlinesOpt                        ScopeEnd
651     | ScopeStart NewlinesOpt Statements NewlinesOpt ScopeEnd
652     | ScopeStart error {
653         PARSE_ERROR_AT((int)$1, "unclosed scope");
654     }
655 ScopeStart:
656     LBRACE {
657         pBuilder->CISA_push_decl_scope();
658         $$ = CISAlineno;
659     }
660 ScopeEnd: RBRACE {pBuilder->CISA_pop_decl_scope();}
661 
662 // ------------- an identifier or string literal -------------
663 IdentOrStringLit: IDENT | STRING_LIT;
664 
665 // ---------------------------------------------------------------------
666 // ------------------------- directives --------------------------------
667 // ---------------------------------------------------------------------
668 
669 // ----- .kernel ------
670 DirectiveKernel: DIRECTIVE_KERNEL IdentOrStringLit
671     {
672         VISAKernel *cisa_kernel = NULL;
673         pBuilder->AddKernel(cisa_kernel, $2);
674     }
675 
676 
677 // ----- .global_function ------
678 DirectiveGlobalFunction: DIRECTIVE_GLOBAL_FUNC IdentOrStringLit
679   {
680       VISAFunction *cisa_kernel = NULL;
681       pBuilder->AddFunction(cisa_kernel, $2);
682   }
683 
684 
685 // ----- .version ------
686 DirectiveVersion : DIRECTIVE_VERSION DEC_LIT DOT DEC_LIT
687    {
688        pBuilder->CISA_IR_setVersion((unsigned char)$2, (unsigned char)$4);
689    }
690 
691 // ----- .decl -----
692 DirectiveDecl:
693       DeclVariable
694     | DeclAddress
695     | DeclPredicate
696     | DeclSampler
697     | DeclSurface
698     | DeclFunction
699 
700 DeclFunction: DIRECTIVE_FUNCDECL STRING_LIT
701     {
702         // do nothing as it's informational only
703     }
704 
705 DeclVariable:
706     //     1         2         3           4             5        6        7            8          9
707     DIRECTIVE_DECL IDENT V_TYPE_EQ_G DECL_DATA_TYPE NUM_ELTS_EQ IntExp AlignAttrOpt AliasAttrOpt GenAttrOpt
708     {
709        ABORT_ON_FAIL(pBuilder->CISA_general_variable_decl(
710            $2, (unsigned int)$6, $4, $7, $8.aliasname, $8.offset, AttrOptVar, CISAlineno));
711        AttrOptVar.clear();
712     }
713 
714                //     1       2        3         4         5        6
715 DeclAddress: DIRECTIVE_DECL IDENT V_TYPE_EQ_A NUM_ELTS_EQ IntExp GenAttrOpt
716    {
717        ABORT_ON_FAIL(
718            pBuilder->CISA_addr_variable_decl($2, (unsigned int)$5, ISA_TYPE_UW, AttrOptVar, CISAlineno));
719        AttrOptVar.clear();
720    }
721 
722                //     1         2         3        4          5       6
723 DeclPredicate: DIRECTIVE_DECL IDENT V_TYPE_EQ_P NUM_ELTS_EQ IntExp GenAttrOpt
724    {
725        ABORT_ON_FAIL(pBuilder->CISA_predicate_variable_decl($2, (unsigned int)$5, AttrOptVar, CISAlineno));
726        AttrOptVar.clear();
727    }
728 
729                //     1       2         3       4          5         6          7
730 DeclSampler: DIRECTIVE_DECL IDENT V_TYPE_EQ_S NUM_ELTS_EQ IntExp VNameEqOpt GenAttrOpt
731    {
732        ABORT_ON_FAIL(pBuilder->CISA_sampler_variable_decl($2, (int)$5, $6, CISAlineno));
733    }
734 VNameEqOpt: %empty  {$$ = "";} | V_NAME_EQ IDENT {$$ = $2;};
735 
736                //     1       2         3          4         5         6          7
737 DeclSurface: DIRECTIVE_DECL IDENT V_TYPE_EQ_T  NUM_ELTS_EQ IntExp  VNameEqOpt GenAttrOpt
738    {
739        ABORT_ON_FAIL(pBuilder->CISA_surface_variable_decl($2, (int)$5, $6, AttrOptVar, CISAlineno));
740        AttrOptVar.clear();
741    }
742 
743 // ----- .input ------
744 DirectiveInput:
745     DIRECTIVE_INPUT IDENT InputOffset InputSize
746     {
747         ABORT_ON_FAIL(pBuilder->CISA_input_directive($2, (short)$3, (unsigned short)$4, CISAlineno));
748     }
749     |
750     DIRECTIVE_INPUT IDENT InputOffset
751     {
752         int64_t size = 0;
753         ABORT_ON_FAIL(pBuilder->CISA_eval_sizeof_decl(CISAlineno, $2, size));
754         MUST_HOLD(size < 0x10000, "declaration size is too large");
755         ABORT_ON_FAIL(pBuilder->CISA_input_directive($2, (short)$3, (unsigned short)size, CISAlineno));
756     }
757 
758 ///////////////////////////////////////////////////////////
759 // ----- .implicit* inputs ------
760 DirectiveImplicitInput:
761     //  1                2        3        4        5
762     DIRECTIVE_IMPLICIT IDENT InputOffset InputSize GenAttrOpt
763     {
764         ABORT_ON_FAIL(pBuilder->CISA_implicit_input_directive(
765             $1, $2, (short)$3, (unsigned short)$4, CISAlineno));
766     }
767     |
768     //  1                2        3           4
769     DIRECTIVE_IMPLICIT IDENT InputOffset  GenAttrOpt
770     {
771         int64_t size = 0;
772         ABORT_ON_FAIL(pBuilder->CISA_eval_sizeof_decl(CISAlineno, $2, size));
773         MUST_HOLD(size < 0x10000, "declaration size is too large");
774         ABORT_ON_FAIL(pBuilder->CISA_input_directive($2, (short)$3, (unsigned short)size, CISAlineno));
775     }
776 
777 InputOffset: %empty {$$ = 0;} | OFFSET_EQ IntExp {$$ = $2;}
778 InputSize: SIZE_EQ IntExp {$$ = $2;}
779 
780 ///////////////////////////////////////////////////////////
781 // ----- .parameter ------
782 
783 DirectiveParameter:
784     //      1            2       3        4
785     DIRECTIVE_PARAMETER IDENT InputSize GenAttrOpt {
786         ABORT_ON_FAIL(pBuilder->CISA_input_directive($2, 0, (unsigned short)$3, CISAlineno));
787     }
788 // ----- .attribute ------
789 
790 DirectiveAttr:
791     DIRECTIVE_KERNEL_ATTR IDENT EQUALS STRING_LIT {
792         ABORT_ON_FAIL(pBuilder->CISA_attr_directive($2, $4, CISAlineno));
793     }
794     |
795     DIRECTIVE_KERNEL_ATTR IDENT EQUALS IntExp {
796         ABORT_ON_FAIL(pBuilder->CISA_attr_directiveNum($2, (uint32_t)$4, CISAlineno));
797     }
798     |
799     DIRECTIVE_KERNEL_ATTR IDENT {
800         ABORT_ON_FAIL(pBuilder->CISA_attr_directive($2, nullptr, CISAlineno));
801     }
802     |
803     DIRECTIVE_KERNEL_ATTR IDENT EQUALS {
804         ABORT_ON_FAIL(pBuilder->CISA_attr_directive($2, nullptr, CISAlineno));
805     }
806 
807 // ----- .function -----
808 DirectiveFunc: DIRECTIVE_FUNC IdentOrStringLit
809     {
810         ABORT_ON_FAIL(pBuilder->CISA_function_directive($2, CISAlineno));
811     }
812 
813 
814 AlignAttrOpt: %empty {$$ = ALIGN_BYTE;} | Align
815 Align:
816     ALIGN_EQ ALIGN_KEYWORD { // 2GRF, 32word, ...
817         $$ = $2;
818     }
819     |
820     ALIGN_EQ IDENT { // e.g. byte, word, dword, qword, GRF, GRFx2
821        if (!ParseAlign(pBuilder, $2, $$)) {
822            PARSE_ERROR($2, ": invalid align value");
823        }
824     }
825     |
826     ALIGN_EQ IntExp {
827         // e.g. %sizeof(GRF) or %sizeof(DECL)
828         $$ = AlignBytesToVisaAlignment((int)$2);
829         if ($$ == ALIGN_UNDEF) {
830             PARSE_ERROR("invalid align size (must be 1, 2, 4, 8, ..., 128)");
831         }
832     }
833     |
834     ALIGN_EQ error {
835         PARSE_ERROR("syntax error in align attribute");
836     }
837 
838 
839 AliasAttrOpt:
840     %empty
841     {
842        $$.aliasname = NULL;
843        $$.offset = 0;
844     }
845     | ALIAS_EQ LANGLE Var COMMA IntExpNRA RANGLE
846     {
847        $$.aliasname = $3;
848        $$.offset = (int)$5;
849     }
850     | ALIAS_EQ LANGLE error
851     {
852        PARSE_ERROR("syntax error in alias attribute");
853     }
854 
855 OneAttr:
856     IDENT EQUALS IntExpNRA
857     {
858       $$ = pBuilder->CISA_Create_Attr($1, $3, nullptr);
859     }
860     | IDENT EQUALS STRING_LIT
861     {
862       $$ = pBuilder->CISA_Create_Attr($1, 0, $3);
863     }
864     | IDENT
865     {
866       $$ = pBuilder->CISA_Create_Attr($1, 0, nullptr);
867     }
868 
869 AttrOpt:
870     AttrOpt COMMA OneAttr
871     {
872       AttrOptVar.push_back($3);
873     }
874     |
875     OneAttr
876     {
877       AttrOptVar.push_back($1);
878     }
879 
880 GenAttrOpt:
881     %empty
882     {
883         $$ = 0;
884     }
885     | ATTR_EQ LBRACE AttrOpt RBRACE
886     {
887         $$ = 1;
888     }
889 
890 // ----------------------------------------------------------
891 // --------------- Instructions -----------------------------
892 // ----------------------------------------------------------
893 
894 Instruction:
895           LogicInstruction
896         | SvmInstruction
897         | UnaryLogicInstruction
898         | MathInstruction_2OPND
899         | MathInstruction_3OPND
900         | ArithInstruction_2OPND
901         | ArithInstruction_3OPND
902         | ArithInstruction_4OPND
903         | AntiTrigInstruction
904         | AddrAddInstruction
905         | CmpInstruction
906         | MediaInstruction
907         | OwordInstruction
908         | ScatterInstruction
909         | ScatterTypedInstruction
910         | ScatterScaledInstruction
911         | Scatter4ScaledInstruction
912         | SynchronizationInstruction
913         | BranchInstruction
914         | DwordAtomicInstruction
915         | TypedAtomicInstruction
916         | SampleInstruction
917         | SampleUnormInstruction
918         | VMEInstruction
919         | AVSInstruction
920         | MovsInstruction
921         | MovInstruction
922         | SelInstruction
923         | MinInstruction
924         | MaxInstruction
925         | SetpInstruction
926         | FILE
927         | LOC
928         | RawSendInstruction
929         | RawSendsInstruction
930         | Sample3dInstruction
931         | Load3dInstruction
932         | Gather43dInstruction
933         | ResInfo3dInstruction
934         | SampleInfo3dInstruction
935         | RTWriteInstruction
936         | URBWriteInstruction
937         | LifetimeStartInst
938         | LifetimeEndInst
939         | NullaryInstruction
940         | DpasInstruction
941         | BfnInstruction
942         | QwScatterInstruction
943         | BF_CvtInstruction
944         | LscInstruction
945         | FCvtInstruction
946 
947 
948 Label: LABEL {pBuilder->CISA_create_label($1, CISAlineno);}
949 
950 
951 LogicInstruction:
952     Predicate BINARY_LOGIC_OP SatModOpt  ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
953     {
954         pBuilder->CISA_create_logic_instruction($1, $2, $3, $4.emask, $4.exec_size,
955             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, NULL, NULL, CISAlineno);
956     }
957     |
958     Predicate BINARY_LOGIC_OP SatModOpt  ExecSize PredVar           PredVar               PredVar
959     {
960         pBuilder->CISA_create_logic_instruction($2, $4.emask, $4.exec_size, $5, $6, $7, CISAlineno);
961     }
962     |
963     Predicate TERNARY_LOGIC_OP SatModOpt  ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
964     {
965         pBuilder->CISA_create_logic_instruction($1, $2, $3, $4.emask, $4.exec_size,
966             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, $8.cisa_gen_opnd, NULL, CISAlineno);
967     }
968     |
969     Predicate QUATERNARY_LOGIC_OP SatModOpt  ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
970     {
971         pBuilder->CISA_create_logic_instruction($1, $2, $3, $4.emask, $4.exec_size,
972             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, $8.cisa_gen_opnd, $9.cisa_gen_opnd, CISAlineno);
973     }
974 
975 
976 UnaryLogicInstruction:
977     Predicate UNARY_LOGIC_OP SatModOpt  ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM
978     {
979         pBuilder->CISA_create_logic_instruction($1, $2, $3, $4.emask, $4.exec_size,
980             $5.cisa_gen_opnd, $6.cisa_gen_opnd, NULL, NULL, NULL, CISAlineno);
981     }
982     |
983     Predicate UNARY_LOGIC_OP SatModOpt  ExecSize PredVar           PredVar
984     {
985         pBuilder->CISA_create_logic_instruction($2, $4.emask, $4.exec_size,
986             $5, $6, NULL, CISAlineno);
987     }
988 
989 MathInstruction_2OPND:
990     Predicate MATH2_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM
991     {
992         pBuilder->CISA_create_math_instruction($1, $2, $3, $4.emask, $4.exec_size,
993             $5.cisa_gen_opnd, $6.cisa_gen_opnd, NULL, CISAlineno);
994     }
995 
996 MathInstruction_3OPND:
997     Predicate MATH3_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
998     {
999         pBuilder->CISA_create_math_instruction($1, $2, $3, $4.emask, $4.exec_size,
1000             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, CISAlineno);
1001     }
1002 
1003 ArithInstruction_2OPND:
1004     Predicate ARITH2_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM
1005     {
1006         pBuilder->CISA_create_arith_instruction($1, $2, $3, $4.emask, $4.exec_size,
1007             $5.cisa_gen_opnd, $6.cisa_gen_opnd, NULL, NULL, CISAlineno);
1008     }
1009 
1010 ArithInstruction_3OPND:
1011     Predicate ARITH3_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
1012     {
1013         MUST_HOLD(!(($2 == ISA_LINE) && ($6.type == OPERAND_IMMEDIATE || $6.type == OPERAND_INDIRECT)),
1014             "wrong type of src0 operand");
1015         pBuilder->CISA_create_arith_instruction(
1016             $1, $2, $3, $4.emask, $4.exec_size,
1017             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, NULL, CISAlineno);
1018     }
1019 
1020 
1021 ArithInstruction_4OPND:
1022      //  1         2         3        4             5                    6                    7                     8
1023      Predicate ARITH4_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM  VecSrcOperand_G_I_IMM
1024      {
1025          pBuilder->CISA_create_arith_instruction($1, $2, $3, $4.emask, $4.exec_size,
1026             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, $8.cisa_gen_opnd, CISAlineno);
1027      }
1028      //  1          2                      3           4                   5                   6                   7
1029      |
1030      Predicate ARITH4_OP2             ExecSize VecDstOperand_G_I VecDstOperand_G_I VecSrcOperand_G_I_IMM  VecSrcOperand_G_I_IMM
1031      {
1032         pBuilder->CISA_create_arith_instruction2($1, $2, $3.emask, $3.exec_size,
1033             $4.cisa_gen_opnd, $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, CISAlineno);
1034      }
1035 
1036 
1037 DpasInstruction:
1038     // 1       2          3           4           5            6
1039     DPAS_OP ExecSize  RawOperand  RawOperand  RawOperand VecSrcOpndSimple
1040     {
1041         pBuilder->CISA_create_dpas_instruction(
1042             $1.opcode, $2.emask, $2.exec_size,
1043             $3, $4, $5, $6.cisa_gen_opnd,
1044             $1.src2Precision, $1.src1Precision, $1.depth, $1.count, CISAlineno);
1045     }
1046 
1047 BfnInstruction:
1048     // 1      2         3         4           5                 6                      7                       8
1049     Predicate BFN_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM  VecSrcOperand_G_I_IMM
1050     {
1051         pBuilder->CISA_create_bfn_instruction($1, $2.func_ctrl , $3, $4.emask, $4.exec_size,
1052             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, $8.cisa_gen_opnd, CISAlineno);
1053     }
1054 //                        1           2        3     4       5      6      7         8
1055 QwScatterInstruction: Predicate QW_SCATTER_OP DOT DEC_LIT ExecSize Var RawOperand RawOperand
1056     {
1057         ABORT_ON_FAIL(pBuilder->CISA_create_qword_scatter_instruction(
1058             $2, $1, $5.emask, $5.exec_size, (uint32_t)$4, $6, $7, $8, CISAlineno));
1059     }
1060 
1061                //    1         2           3              4
1062 BF_CvtInstruction: BF_CVT_OP ExecSize VecDstOperand_G VecSrcOperand_G_IMM
1063     {
1064         pBuilder->CISA_create_bf_cvt_instruction($2.emask, $2.exec_size, $3.cisa_gen_opnd, $4.cisa_gen_opnd, CISAlineno);
1065     }
1066 
1067                //   1        2            3            4
1068 FCvtInstruction: FCVT_OP ExecSize VecDstOperand_G VecSrcOperand_G_IMM
1069     {
1070         pBuilder->CISA_create_fcvt_instruction($2.emask, $2.exec_size, $3.cisa_gen_opnd, $4.cisa_gen_opnd, CISAlineno);
1071     }
1072 
1073                      //  1            2           3            4             5                6
1074 AntiTrigInstruction: Predicate ANTI_TRIG_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM
1075     {
1076         pBuilder->CISA_create_invtri_inst($1, $2, $3, $4.emask, $4.exec_size,
1077             $5.cisa_gen_opnd, $6.cisa_gen_opnd, CISAlineno);
1078     }
1079 
1080 
1081 AddrAddInstruction:
1082      //  1         2           3              4                    5
1083     ADDR_ADD_OP ExecSize VecDstOperand_A VecSrcOperand_G_A_AO VecSrcOperand_G_IMM_AO
1084     {
1085         // a grammatically problematic instruction
1086         //   addr_add (M1_NM, 1) A0(0)<1> &V127 - 0x10...
1087         //                                        ^^^^ next operand or V127 offset
1088         pBuilder->CISA_create_address_instruction($1, $2.emask, $2.exec_size,
1089             $3.cisa_gen_opnd, $4.cisa_gen_opnd, $5.cisa_gen_opnd, CISAlineno);
1090     }
1091 
1092                 //   1      2        3          4
1093 SetpInstruction: SETP_OP ExecSize PredVar VecSrcOperand_G_I_IMM
1094     {
1095         pBuilder->CISA_create_setp_instruction(
1096             $1, $2.emask, $2.exec_size, $3, $4.cisa_gen_opnd, CISAlineno);
1097     }
1098 
1099                 //   1       2       3         4          5                   6                   7
1100 SelInstruction: Predicate SEL_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
1101     {
1102         pBuilder->CISA_create_sel_instruction($2, $3, $1, $4.emask, $4.exec_size,
1103             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, CISAlineno);
1104     }
1105 
1106                 //   1      2        3        4           5                   6                   7
1107 MinInstruction: Predicate MIN_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
1108     {
1109         pBuilder->CISA_create_fminmax_instruction(0, ISA_FMINMAX, $3, $1, $4.emask, $4.exec_size,
1110             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, CISAlineno);
1111     }
1112 
1113 MaxInstruction:
1114     //   1      2         3       4          5                   6                     7
1115     Predicate MAX_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
1116     {
1117         pBuilder->CISA_create_fminmax_instruction(
1118             1, ISA_FMINMAX, $3, $1, $4.emask, $4.exec_size,
1119             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, CISAlineno);
1120     }
1121 
1122 MovInstruction:
1123     //  1       2       3          4         5                   6
1124     Predicate MOV_OP SatModOpt ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM_A_AO
1125     {
1126         pBuilder->CISA_create_mov_instruction(
1127             $1, $2, $4.emask, $4.exec_size, $3,
1128             $5.cisa_gen_opnd, $6.cisa_gen_opnd, CISAlineno);
1129     }
1130     |
1131     Predicate MOV_OP SatModOpt ExecSize VecDstOperand_G_I PredVar
1132     {
1133         ABORT_ON_FAIL(pBuilder->CISA_create_mov_instruction($5.cisa_gen_opnd, $6, CISAlineno));
1134     }
1135 
1136 MovsInstruction:
1137     MOVS_OP ExecSize DstStateOperand SrcStateOperand
1138     {
1139         pBuilder->CISA_create_movs_instruction($2.emask, ISA_MOVS, $2.exec_size,
1140             $3.cisa_gen_opnd, $4.cisa_gen_opnd, CISAlineno);
1141     }
1142     |
1143     MOVS_OP ExecSize VecDstOperand_G SrcStateOperand
1144     {
1145         pBuilder->CISA_create_movs_instruction($2.emask, ISA_MOVS, $2.exec_size,
1146             $3.cisa_gen_opnd, $4.cisa_gen_opnd, CISAlineno);
1147     }
1148     |
1149     MOVS_OP ExecSize DstStateOperand VecSrcOperand_G_I_IMM
1150     {
1151         pBuilder->CISA_create_movs_instruction($2.emask, ISA_MOVS, $2.exec_size,
1152             $3.cisa_gen_opnd, $4.cisa_gen_opnd, CISAlineno);
1153     }
1154 
1155 
1156 CmpInstruction:
1157     // FIXME: S/R conflict
1158     // DstGeneralOperand: Var . TwoDimOffset DstRegion
1159     //                  | Var . DstRegion
1160     // PredVar: Var .
1161     //
1162     // Given: ExecSize VAR with lookahead LPAREN
1163     // we cannot decide if we should shift LPAREN (we're looking at a DstOperand paren)
1164     // or reduce IDENT to PredVar
1165 
1166     // 1          2               3       4                       5                     6
1167     CMP_OP ConditionalModifier ExecSize PredVar           VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
1168     {
1169         pBuilder->CISA_create_cmp_instruction($2, $3.emask, $3.exec_size,
1170             $4, $5.cisa_gen_opnd, $6.cisa_gen_opnd, CISAlineno);
1171     }
1172     |
1173     //    1        2              3          4                   5                     6
1174     CMP_OP ConditionalModifier ExecSize VecDstOperand_G_I VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM
1175     {
1176         // NOTE: predication not permitted.  Apparently the vISA API doesn't allow for predicated compares
1177         pBuilder->CISA_create_cmp_instruction(
1178             $2, ISA_CMP, $3.emask, $3.exec_size,
1179             $4.cisa_gen_opnd, $5.cisa_gen_opnd, $6.cisa_gen_opnd, CISAlineno);
1180     }
1181 
1182 MediaInstruction:
1183     // 1       2          3           4              5                    6                    7                  8
1184     MEDIA_OP MEDIA_MODE TwoDimOffset Var MediaInstructionPlaneID VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM  RawOperand
1185     {
1186         ABORT_ON_FAIL(pBuilder->CISA_create_media_instruction(
1187             $1, $2, $3.row, $3.elem, (int)$5, $4,
1188             $6.cisa_gen_opnd, $7.cisa_gen_opnd, $8, CISAlineno));
1189     }
1190     |
1191     // 1       2          3           4                  5                    6                    7
1192     MEDIA_OP MEDIA_MODE TwoDimOffset Var         VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM  RawOperand
1193     {
1194         ABORT_ON_FAIL(pBuilder->CISA_create_media_instruction(
1195             $1, $2, $3.row, $3.elem, (int)0, $4,
1196             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7, CISAlineno));
1197     }
1198 
1199 MediaInstructionPlaneID: DEC_LIT {
1200         MUST_HOLD($1 <= 0xF, "PlaneID must less than 0xF");
1201         $$ = $1;
1202     }
1203 
1204 ScatterInstruction:
1205     //  1          2        3        4         5          6                7           8
1206     SCATTER_OP ElemNum ExecSize OwordModifier Var VecSrcOperand_G_I_IMM RawOperand RawOperand
1207     {
1208         ABORT_ON_FAIL(pBuilder->CISA_create_scatter_instruction(
1209             $1, (int)$2, $3.emask, $3.exec_size, $4, $5,
1210             $6.cisa_gen_opnd, $7, $8, CISAlineno));
1211     }
1212 
1213 ScatterTypedInstruction:
1214     //  1             2                 3             4       5         6           7             8           9            10
1215     Predicate   SCATTER_TYPED_OP  SAMPLER_CHANNEL  ExecSize  Var    RawOperand   RawOperand   RawOperand  RawOperand    RawOperand
1216     {
1217         ABORT_ON_FAIL(pBuilder->CISA_create_scatter4_typed_instruction(
1218             $2, $1, ChannelMask::createFromAPI($3), $4.emask, $4.exec_size, $5,
1219             $6, $7, $8, $9, $10, CISAlineno));
1220     }
1221 
1222 Scatter4ScaledInstruction:
1223     //  1           2               3                4      5          6                 7         8
1224     Predicate SCATTER4_SCALED_OP SAMPLER_CHANNEL  ExecSize Var VecSrcOperand_G_I_IMM RawOperand RawOperand
1225     {
1226         ABORT_ON_FAIL(pBuilder->CISA_create_scatter4_scaled_instruction(
1227             $2, $1, $4.emask, $4.exec_size, ChannelMask::createFromAPI($3), $5,
1228             $6.cisa_gen_opnd, $7, $8, CISAlineno));
1229     }
1230 
1231 ScatterScaledInstruction:
1232     // 1           2             3    4        5      6       7                   8          9
1233     Predicate SCATTER_SCALED_OP DOT DEC_LIT ExecSize Var VecSrcOperand_G_I_IMM RawOperand RawOperand
1234     {
1235         ABORT_ON_FAIL(pBuilder->CISA_create_scatter_scaled_instruction(
1236             $2, $1, $5.emask, $5.exec_size, (uint32_t) $4, $6,
1237             $7.cisa_gen_opnd, $8, $9, CISAlineno));
1238     }
1239 
1240 SynchronizationInstruction:
1241     BARRIER_OP {
1242         pBuilder->CISA_create_sync_instruction($1, CISAlineno);
1243     }
1244     | SBARRIER_SIGNAL {
1245         pBuilder->CISA_create_sbarrier_instruction(true, CISAlineno);
1246     }
1247     | SBARRIER_WAIT {
1248         pBuilder->CISA_create_sbarrier_instruction(false, CISAlineno);
1249     }
1250     | NBARRIER_SIGNAL VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM {
1251         pBuilder->CISA_create_nbarrier(false, $2.cisa_gen_opnd, $3.cisa_gen_opnd, CISAlineno);
1252     }
1253     | NBARRIER_WAIT VecSrcOperand_G_I_IMM {
1254         pBuilder->CISA_create_nbarrier(true, $2.cisa_gen_opnd, NULL, CISAlineno);
1255     }
1256 
1257 //                      1         2               3             4           5         6     7          8          9          10
1258 DwordAtomicInstruction: Predicate DWORD_ATOMIC_OP ATOMIC_SUB_OP Atomic16Opt ExecSize Var RawOperand RawOperand RawOperand RawOperand
1259     {
1260         ABORT_ON_FAIL(pBuilder->CISA_create_dword_atomic_instruction(
1261             $1, $3, $4, $5.emask, $5.exec_size, $6, $7, $8, $9, $10, CISAlineno));
1262     }
1263 
1264 //                      1         2               3             4           5        6   7          8          9          10         11         12         13
1265 TypedAtomicInstruction: Predicate TYPED_ATOMIC_OP ATOMIC_SUB_OP Atomic16Opt ExecSize Var RawOperand RawOperand RawOperand RawOperand RawOperand RawOperand RawOperand
1266     {
1267         ABORT_ON_FAIL(pBuilder->CISA_create_typed_atomic_instruction(
1268             $1, $3, $4, $5.emask, $5.exec_size, $6,
1269             $7, $8, $9, $10, $11, $12, $13, CISAlineno));
1270     }
1271 
1272 Atomic16Opt:
1273       %empty {$$ = false;}
1274     | DOT DEC_LIT { // .16
1275         MUST_HOLD(($2 == 16), "only supports 16");
1276         $$ = true;
1277     }
1278 
1279                  //            1               2               3        4   5             6                   7                      8                   9                10
1280 SampleUnormInstruction: SAMPLE_UNORM_OP SAMPLER_CHANNEL CHANNEL_OUTPUT Var Var VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM RawOperand
1281     {
1282         ABORT_ON_FAIL(pBuilder->CISA_create_sampleunorm_instruction(
1283             $1, ChannelMask::createFromAPI($2), $3, $4, $5,
1284             $6.cisa_gen_opnd, $7.cisa_gen_opnd, $8.cisa_gen_opnd, $9.cisa_gen_opnd, $10, CISAlineno));
1285     }
1286 
1287 SampleInstruction:
1288     // 1            2            3      4   5      6          7          8          9
1289     SAMPLE_OP SAMPLER_CHANNEL SIMDMode Var Var RawOperand RawOperand RawOperand RawOperand
1290     {
1291         ABORT_ON_FAIL(pBuilder->CISA_create_sample_instruction(
1292             $1, ChannelMask::createFromAPI($2), (int)$3, $4, $5,
1293             $6, $7, $8, $9, CISAlineno));
1294     }
1295    |
1296    // 1             2          3       4     5           6         7           8
1297    SAMPLE_OP SAMPLER_CHANNEL SIMDMode Var RawOperand RawOperand RawOperand RawOperand
1298    {
1299        ABORT_ON_FAIL(pBuilder->CISA_create_sample_instruction(
1300            $1, ChannelMask::createFromAPI($2), (int)$3, "", $4,
1301            $5, $6, $7, $8, CISAlineno));
1302    }
1303 
1304            //        1         2            3                      4            5                          6               7        8                     9   10  11
1305 Sample3dInstruction: Predicate SAMPLE_3D_OP PixelNullMaskEnableOpt CPSEnableOpt NonUniformSamplerEnableOpt SAMPLER_CHANNEL ExecSize VecSrcOperand_G_I_IMM Var Var RawOperand
1306            //        12
1307                      RawOperandArray
1308    {
1309        const bool success = pBuilder->create3DSampleInstruction(
1310            $1, $2, $3, $4, $5, ChannelMask::createFromAPI($6),
1311            $7.emask, $7.exec_size, $8.cisa_gen_opnd, $9, $10,
1312            $11, (unsigned int)$12, rawOperandArray, CISAlineno);
1313 
1314     ABORT_ON_FAIL(success);
1315    }
1316 
1317 CPSEnableOpt: %empty {$$ = false;} | CPS  {$$ = true;}
1318 
1319 NonUniformSamplerEnableOpt: %empty {$$ = false;} | NON_UNIFORM_SAMPLER {$$ = true;}
1320 
1321            //      1         2          3                      4               5        6                     7   8
1322 Load3dInstruction: Predicate LOAD_3D_OP PixelNullMaskEnableOpt SAMPLER_CHANNEL ExecSize VecSrcOperand_G_I_IMM Var RawOperand
1323            //      9
1324                    RawOperandArray
1325    {
1326        const bool success = pBuilder->create3DLoadInstruction(
1327            $1, $2, $3, ChannelMask::createFromAPI($4),
1328            $5.emask, $5.exec_size, $6.cisa_gen_opnd, $7,
1329            $8, (unsigned int)$9, rawOperandArray, CISAlineno);
1330 
1331     ABORT_ON_FAIL(success);
1332    }
1333 
1334            //         1         2             3                      4               5        6                     7   8   9
1335 Gather43dInstruction: Predicate SAMPLE4_3D_OP PixelNullMaskEnableOpt SAMPLER_CHANNEL ExecSize VecSrcOperand_G_I_IMM Var Var RawOperand
1336            //      10
1337                    RawOperandArray
1338    {
1339        const bool success = pBuilder->createSample4Instruction(
1340           $1, $2, $3, ChannelMask::createFromAPI($4), $5.emask, $5.exec_size,
1341           $6.cisa_gen_opnd, $7, $8,
1342           $9, (unsigned int)$10, rawOperandArray, CISAlineno);
1343 
1344     ABORT_ON_FAIL(success);
1345    }
1346 
1347 PixelNullMaskEnableOpt: %empty {$$ = false;} | PIXEL_NULL_MASK {$$ = true;}
1348 
1349             //          1                   2              3           4           5              6
1350 ResInfo3dInstruction: RESINFO_OP_3D   SAMPLER_CHANNEL  ExecSize       Var     RawOperand      RawOperand
1351    {
1352         ABORT_ON_FAIL(pBuilder->CISA_create_info_3d_instruction(
1353             VISA_3D_RESINFO, $3.emask, $3.exec_size,
1354             ChannelMask::createFromAPI($2), $4, $5, $6, CISAlineno));
1355    }
1356 
1357            //               1                    2              3         4          5
1358 SampleInfo3dInstruction: SAMPLEINFO_OP_3D   SAMPLER_CHANNEL  ExecSize    Var     RawOperand
1359    {
1360         ABORT_ON_FAIL(pBuilder->CISA_create_info_3d_instruction(
1361             VISA_3D_SAMPLEINFO, $3.emask, $3.exec_size,
1362             ChannelMask::createFromAPI($2), $4, NULL, $5, CISAlineno));
1363    }
1364 
1365 RTWriteOperandParse:
1366     %empty
1367     {
1368     }
1369     | RTWriteOperandParse VecSrcOperand_G_IMM
1370     {
1371         RTRWOperands.push_back($2.cisa_gen_opnd);
1372     }
1373     | RTWriteOperandParse RawOperand
1374     {
1375         RTRWOperands.push_back($2);
1376     }
1377             //      1            2                3                 4           5     6
1378 RTWriteInstruction: Predicate    RTWRITE_OP_3D    RTWriteModeOpt    ExecSize    Var   RTWriteOperandParse
1379    {
1380        bool result = pBuilder->CISA_create_rtwrite_3d_instruction(
1381            $1, $3, $4.emask, (unsigned int)$4.exec_size, $5,
1382            RTRWOperands, CISAlineno);
1383        RTRWOperands.clear();
1384        if (!result)
1385            YYABORT; // already reported
1386    }
1387 
1388 RTWriteModeOpt: %empty {$$ = 0;} | RTWRITE_OPTION
1389 
1390 
1391             //          1            2                3           4         5           6           7           8          9
1392 URBWriteInstruction: Predicate  URBWRITE_OP_3D    ExecSize    DEC_LIT    DEC_LIT    RawOperand  RawOperand  RawOperand  RawOperand
1393     {
1394         pBuilder->CISA_create_urb_write_3d_instruction(
1395             $1, $3.emask, (unsigned int)$3.exec_size, (unsigned int)$4, (unsigned int)$5,
1396             $6, $7, $8, $9, CISAlineno);
1397     }
1398 
1399             //      1         2         3   4          5                       6                   7                     8                     9                     10                    11              12        13                 14               15           16
1400 AVSInstruction: AVS_OP SAMPLER_CHANNEL Var Var VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM VecSrcOperand_G_I_IMM CNTRL VecSrcOperand_G_I_IMM EXECMODE VecSrcOperand_G_I_IMM RawOperand
1401     {
1402         pBuilder->CISA_create_avs_instruction(
1403             ChannelMask::createFromAPI($2), $3, $4,
1404             $5.cisa_gen_opnd, $6.cisa_gen_opnd, $7.cisa_gen_opnd, $8.cisa_gen_opnd,
1405             $9.cisa_gen_opnd, $10.cisa_gen_opnd, $11.cisa_gen_opnd, $12, $13.cisa_gen_opnd,
1406             $14, $15.cisa_gen_opnd, $16, CISAlineno);
1407     }
1408 
1409 
1410 VMEInstruction:
1411       //     1          2     3       4         5           6         7           8         9
1412        VME_IME_OP VMEOpndIME Var RawOperand RawOperand  RawOperand RawOperand RawOperand RawOperand
1413    {
1414        //     1 - OP
1415        //     2 - StreamMode, SearchCtrl
1416        //     3 - Surface
1417        //     4 - UNIInput
1418        //     5 - IMEInput
1419        //     6 - ref0
1420        //     7 - ref1
1421        //     8 - CostCenter
1422        //     9 - Output
1423         ABORT_ON_FAIL(pBuilder->CISA_create_vme_ime_instruction(
1424             $1, $2.streamMode, $2.searchCtrl, $4, $5, $3, $6, $7, $8, $9, CISAlineno));
1425    }
1426    |
1427     //    1    2      3           4          5
1428    VME_SIC_OP Var RawOperand RawOperand  RawOperand
1429    {
1430         ABORT_ON_FAIL(pBuilder->CISA_create_vme_sic_instruction($1, $3, $4, $2, $5, CISAlineno));
1431    }
1432    |
1433    //    1          2     3      4          5         6
1434    VME_FBR_OP VMEOpndFBR Var RawOperand RawOperand RawOperand
1435    {
1436         //    1 - OP
1437         //    2 - FBRMdMode, FBRSubMbShape, FBRSubPredMode
1438         //    3 - surface
1439         //    4 - UNIInput
1440         //    5 - FBRInput
1441         //    6 - output
1442         ABORT_ON_FAIL(pBuilder->CISA_create_vme_fbr_instruction($1, $4, $5, $3,
1443             $2.cisa_fbrMbMode_opnd, $2.cisa_fbrSubMbShape_opnd, $2.cisa_fbrSubPredMode_opnd, $6, CISAlineno));
1444     }
1445 
1446                  //    1         2          3       4            5               6
1447 OwordInstruction: OWORD_OP OwordModifier ExecSize Var VecSrcOperand_G_I_IMM RawOperand
1448     {
1449         ABORT_ON_FAIL(
1450             pBuilder->CISA_create_oword_instruction($1, $2, $3.exec_size, $4, $5.cisa_gen_opnd, $6, CISAlineno));
1451     }
1452 
1453 SvmInstruction:
1454     //     2        3                     4
1455     SVM_OP ExecSize VecSrcOperand_G_I_IMM RawOperand
1456     {
1457         bool aligned = false;
1458         pBuilder->CISA_create_svm_block_instruction((SVMSubOpcode)$1, $2.exec_size, aligned,
1459             $3.cisa_gen_opnd, $4, CISAlineno);
1460     }
1461     //     1          2         3     4     5     6        7          8        9
1462     | Predicate SVM_SCATTER_OP DOT DEC_LIT DOT DEC_LIT ExecSize RawOperand RawOperand
1463     {
1464         pBuilder->CISA_create_svm_scatter_instruction($1, (SVMSubOpcode)$2, $7.emask, $7.exec_size,
1465             (unsigned int)$4, (unsigned int)$6, $8, $9, CISAlineno);
1466     }
1467     // 1        2             3             4                 5        6          7          8          9
1468     | Predicate SVM_ATOMIC_OP ATOMIC_SUB_OP AtomicBitwidthOpt ExecSize RawOperand RawOperand RawOperand RawOperand
1469     {
1470         pBuilder->CISA_create_svm_atomic_instruction($1, $5.emask, $5.exec_size, $3, (unsigned short)$4,
1471             $6, $8, $9, $7, CISAlineno);
1472     }
1473     //   1                    2               3          4           5                 6          7
1474     | Predicate SVM_GATHER4SCALED_OP SAMPLER_CHANNEL ExecSize VecSrcOperand_G_I_IMM RawOperand RawOperand
1475     {
1476         pBuilder->CISA_create_svm_gather4_scaled($1, $4.emask, $4.exec_size, ChannelMask::createFromAPI($3),
1477             $5.cisa_gen_opnd, $6, $7, CISAlineno);
1478     }
1479     //   1                  2               3            4            5                  6          7
1480     | Predicate SVM_SCATTER4SCALED_OP SAMPLER_CHANNEL ExecSize VecSrcOperand_G_I_IMM RawOperand RawOperand
1481     {
1482         pBuilder->CISA_create_svm_scatter4_scaled($1, $4.emask, $4.exec_size, ChannelMask::createFromAPI($3),
1483             $5.cisa_gen_opnd, $6, $7, CISAlineno);
1484     }
1485 
1486 AtomicBitwidthOpt:
1487       %empty {$$ = 32;}
1488     | DOT DEC_LIT {
1489         MUST_HOLD($2 == 16 || $2 == 32 || $2 == 64, "only supports 16 or 64");
1490         $$ = $2;
1491     }
1492 
1493 ////////////////////////////////////////////////
1494 // LSC_LOAD - Load/Store Controller Instructions
1495 LscInstruction:
1496   // untyped loads
1497     LscUntypedLoad
1498   | LscUntypedStridedLoad
1499   | LscUntypedBlock2dLoad
1500   // untyped stores
1501   | LscUntypedStore
1502   | LscUntypedStridedStore
1503   | LscUntypedBlock2dStore
1504   // untyped atomics
1505   | LscUntypedAtomic
1506   //
1507   // typed*
1508   | LscTypedLoad
1509   | LscTypedStore
1510   | LscTypedAtomic
1511   | LscTypedReadStateInfo
1512   //
1513   | LscFence
1514 
1515 //
1516 // EXAMPLES:
1517 // FLAT (stateless):
1518 //     lsc_load.ugm   V53:u32  flat[V52]:a64
1519 //     lsc_load.slm   V53:u32  flat[V52]:a32
1520 //
1521 // FLAT with immediate offset  (32b with x2 elems per addr)
1522 //     lsc_load.ugm   V53:u32x2  flat[V52+0x100]:a64
1523 //
1524 // BTI:
1525 //     lsc_load.ugm   V53:u32  bti(0x10)[V52]:a32
1526 //     lsc_load.ugml  V53:u32  bti(V10.2)[V52]:a32
1527 //
1528 // SS:
1529 //     lsc_load.ugm   V53:u64   ss(0x200)[V52+0x100]:a16
1530 // BSS:
1531 //     lsc_load.ugm   V53:u8x8  bss(V10)[V52+0x100]:a16
1532 //
1533 LscUntypedLoad:
1534 //  1          2                  3                       4             5
1535     Predicate  LSC_LOAD_MNEMONIC  LSC_SFID_UNTYPED_TOKEN  LscCacheOpts  ExecSize
1536 //  6                  7
1537     LscDataOperand  LscUntypedAddrOperand
1538     {
1539         $5.exec_size =
1540             lscCheckExecSize($3, $2, $6.shape.order, $5.exec_size);
1541         pBuilder->CISA_create_lsc_untyped_inst(
1542             $1,  // predicate
1543             $2,  // subop
1544             $3,  // sfid
1545             $4,  // caching settings
1546             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1547             $5.emask,
1548             $7.addr,     // address
1549             $6.shape,    // data
1550             $7.surface,  // surface
1551             $6.reg,      // dst
1552             $7.regs[0],  // src0
1553             nullptr,     // src1
1554             nullptr,     // src2
1555             CISAlineno);
1556     }
1557 
1558 //
1559 // EXAMPLES:
1560 // FLAT (stateless):
1561 //     lsc_load_strided.ugm   V53:u32  flat[V52]:a64
1562 //     lsc_load_strided.ugm   V53:u32  flat[V52, 32]:a32
1563 //     lsc_load_strided.ugm   V53:u32  flat[4*V52+16, 32]:a32
1564 LscUntypedStridedLoad:
1565 //  1          2                          3                       4             5
1566     Predicate  LSC_LOAD_STRIDED_MNEMONIC  LSC_SFID_UNTYPED_TOKEN  LscCacheOpts  ExecSize
1567 //  6               7
1568     LscDataOperand  LscUntypedStridedAddrOperand
1569     {
1570         $5.exec_size =
1571             lscCheckExecSize($3, $2, $6.shape.order, $5.exec_size);
1572         pBuilder->CISA_create_lsc_untyped_strided_inst(
1573             $1,  // predicate
1574             $2,  // subop
1575             $3,  // sfid
1576             $4,  // caching settings
1577             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1578             $5.emask,
1579             $7.addr,     // address
1580             $6.shape,    // data
1581             $7.surface,  // surface
1582             $6.reg,      // dst
1583             $7.regs[0],  // src0 base
1584             $7.regs[1],  // src0 stride
1585             nullptr,     // src1
1586             CISAlineno);
1587     }
1588 
1589 //
1590 // EXAMPLES:
1591 // FLAT (stateless):
1592 // lsc_load_block2d.ugm   V53:u8.2x32x32  flat[V_BASE,V_SWIDTH,V_SHEIGHT,V_SPITCH,V_X,V_Y]
1593 LscUntypedBlock2dLoad:
1594 //  1          2                           3                       4             5
1595     Predicate  LSC_LOAD_BLOCK2D_MNEMONIC  LSC_SFID_UNTYPED_TOKEN  LscCacheOpts  ExecSize
1596 //  6                 7
1597     LscDataOperand2D  LscUntypedBlock2dAddrOperand
1598     {
1599         $5.exec_size =
1600             lscCheckExecSize($3, $2, $6.shape2D.order, $5.exec_size);
1601         pBuilder->CISA_create_lsc_untyped_block2d_inst(
1602             $1,  // predicate
1603             $2,  // subop
1604             $3,  // sfid
1605             $4,  // caching settings
1606             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1607             $5.emask,
1608             $6.shape2D,  // data shape
1609             $6.reg,      // dst
1610             $7.regs,     // src0 surface info / addrs
1611             nullptr,     // src1
1612             CISAlineno);
1613     }
1614 
1615 //
1616 // EXAMPLE:
1617 //     lsc_store.ugm    flat[V52]:a64      V53:u32
1618 LscUntypedStore:
1619 //  1          2                   3                       4             5
1620     Predicate  LSC_STORE_MNEMONIC  LSC_SFID_UNTYPED_TOKEN  LscCacheOpts  ExecSize
1621 //  6                      7
1622     LscUntypedAddrOperand  LscDataOperand
1623     {
1624         $5.exec_size =
1625             lscCheckExecSize($3, $2, $7.shape.order, $5.exec_size);
1626         pBuilder->CISA_create_lsc_untyped_inst(
1627             $1,  // predicate
1628             $2,  // subop
1629             $3,  // SFID
1630             $4,  // caching settings
1631             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1632             $5.emask,
1633             $6.addr,     // address
1634             $7.shape,    // data
1635             $6.surface,  // surface
1636             nullptr,     // dst
1637             $6.regs[0],  // src0
1638             $7.reg,      // src1
1639             nullptr,     // src2
1640             CISAlineno);
1641     }
1642 LscUntypedStridedStore:
1643 //  1          2                           3                       4             5
1644     Predicate  LSC_STORE_STRIDED_MNEMONIC  LSC_SFID_UNTYPED_TOKEN  LscCacheOpts  ExecSize
1645 //  6                             7
1646     LscUntypedStridedAddrOperand  LscDataOperand
1647     {
1648         $5.exec_size =
1649             lscCheckExecSize($3, $2, $7.shape.order, $5.exec_size);
1650         pBuilder->CISA_create_lsc_untyped_strided_inst(
1651             $1,  // predicate
1652             $2,  // subop
1653             $3,  // SFID
1654             $4,  // caching settings
1655             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1656             $5.emask,
1657             $6.addr,     // address
1658             $7.shape,    // data
1659             $6.surface,  // surface
1660             nullptr,     // dst
1661             $6.regs[0],  // src0 base
1662             $6.regs[1],  // src0 stride
1663             $7.reg,      // src1
1664             CISAlineno);
1665     }
1666 
1667 // EXAMPLES
1668 //     lsc_store_block2d.ugm   flat[V_BASE,V_X,V_Y,V_PITCH,V_HEIGHT,VBLOCK_X,VBLOCK_Y,32,4]   V53:u64
1669 LscUntypedBlock2dStore:
1670 //  1          2                           3                       4             5
1671     Predicate  LSC_STORE_BLOCK2D_MNEMONIC  LSC_SFID_UNTYPED_TOKEN  LscCacheOpts  ExecSize
1672 //  6                            7
1673     LscUntypedBlock2dAddrOperand LscDataOperand2D
1674     {
1675         $5.exec_size =
1676             lscCheckExecSize($3, $2, $7.shape2D.order, $5.exec_size);
1677         pBuilder->CISA_create_lsc_untyped_block2d_inst(
1678             $1,  // predicate
1679             $2,  // subop
1680             $3,  // sfid
1681             $4,  // caching settings
1682             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1683             $5.emask,
1684             $7.shape2D,  // data2d
1685             nullptr,     // dst
1686             $6.regs,     // src0 addrs
1687             $7.reg,      // src1
1688             CISAlineno);
1689     }
1690 
1691 // EXAMPLES:
1692 //     lsc_atomic_iinc.ugm   VRESULT:u32  flat[VADDR]:a64       V0     V0
1693 //     lsc_atomic_iinc.ugml  VRESULT:u32  flat[VADDR]:a64       V0     V0
1694 //     lsc_atomic_iadd.slm   VRESULT:u32  flat[VADDR+0x10]:a32  VSRC1  V0
1695 LscUntypedAtomic:
1696 //  1         2                    3                       4             5
1697     Predicate LSC_ATOMIC_MNEMONIC  LSC_SFID_UNTYPED_TOKEN  LscCacheOpts  ExecSize
1698 //  6               7                      8              9
1699     LscDataOperand  LscUntypedAddrOperand  LscPayloadReg  LscPayloadReg
1700     {
1701         $5.exec_size =
1702             lscCheckExecSize($3, $2, $6.shape.order, $5.exec_size);
1703         pBuilder->CISA_create_lsc_untyped_inst(
1704             $1,  // predicate
1705             $2,                // op
1706             $3,                // sfid
1707             $4,                // caching settings
1708             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1709             $5.emask,
1710             $7.addr,     // address info
1711             $6.shape,    // data type
1712             $7.surface,  // surface
1713             $6.reg,      // dst data
1714             $7.regs[0],  // src0 addr
1715             $8,          // src1 data
1716             $9,          // src2 data (for icas/fcas)
1717             CISAlineno);
1718     }
1719 
1720 //
1721 // EXAMPLES:
1722 // SS using only U:
1723 //     lsc_load_quad.tgm   V60:u32.x     ss(T6)[V52]:a32
1724 // BSS using U and V:
1725 //     lsc_load_quad.tgm   V60:u32.xyzw  bss(V10)[V52,V53]:a32
1726 // BSS using U, V, R, and LOD:
1727 //     lsc_load_quad.tgm   V60:u32.xz    bss(V10)[V52,V53,V54,V55]:a32
1728 //
1729 LscTypedLoad:
1730 //  1          2                  3                     4             5
1731     Predicate  LSC_LOAD_MNEMONIC  LSC_SFID_TYPED_TOKEN  LscCacheOpts  ExecSize
1732 //  6               7
1733     LscDataOperand  LscTypedAddrOperand
1734     {
1735         if ($2 != LSC_LOAD_QUAD) {
1736             PARSE_ERROR("unsupported load operation for .tgm");
1737         }
1738         $5.exec_size =
1739             lscCheckExecSize($3, $2, $6.shape.order, $5.exec_size);
1740         pBuilder->CISA_create_lsc_typed_inst(
1741             $1,  // predicate
1742             $2,  // subop
1743             $3,  // sfid
1744             $4,  // caching settings
1745             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1746             $5.emask,
1747             $7.addr.type,  // address model
1748             $7.addr.size,  // address size
1749             $6.shape,    // data type
1750             $7.surface,  // surface
1751             $6.reg,      // dst data
1752             $7.regs[0],  // src0_u
1753             $7.regs[1],  // src0_v
1754             $7.regs[2],  // src0_r
1755             $7.regs[3],  // src0_lod
1756             nullptr,     // src1 data
1757             nullptr,     // src2 data
1758             CISAlineno);
1759     }
1760 //
1761 // EXAMPLES:
1762 // SS using only U:
1763 //     lsc_store_quad.tgm   V60:u32.x     ss(T6)[V52]:a32
1764 // BSS using U and V:
1765 //     lsc_store_quad.tgm   V60:u32.xyzw  bss(V10)[V52,V53]:a32
1766 // BSS using U, V, R, and LOD:
1767 //     lsc_store_quad.tgm   V60:u32.xz    bss(V10)[V52,V53,V54,V55]:a32
1768 //
1769 LscTypedStore:
1770 //  1          2                   3                     4             5
1771     Predicate  LSC_STORE_MNEMONIC  LSC_SFID_TYPED_TOKEN  LscCacheOpts  ExecSize
1772 //  6                    7
1773     LscTypedAddrOperand  LscDataOperand
1774     {
1775         if ($2 != LSC_STORE_QUAD) {
1776             PARSE_ERROR("unsupported store operation for .tgm");
1777         }
1778         $5.exec_size =
1779             lscCheckExecSize($3, $2, $7.shape.order, $5.exec_size);
1780         pBuilder->CISA_create_lsc_typed_inst(
1781             $1,  // predicate
1782             $2,  // subop
1783             $3,  // sfid
1784             $4,  // caching settings
1785             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1786             $5.emask,
1787             $6.addr.type,  // address model
1788             $6.addr.size,  // address size
1789             $7.shape,    // data type
1790             $6.surface,  // surface
1791             nullptr,     // dst
1792             $6.regs[0],  // src0_u
1793             $6.regs[1],  // src0_v
1794             $6.regs[2],  // src0_r
1795             $6.regs[3],  // src0_lod
1796             $7.reg,      // src1 data
1797             nullptr,     // src2 data
1798             CISAlineno);
1799     }
1800 //
1801 // EXAMPLES:
1802 // SS using only U:
1803 //     lsc_atomic_iinc.tgm   ss(T6)[V52]:a32        V0:u32.x      V0  V0
1804 // BSS using U and V:
1805 //     lsc_atomic_iadd.tgm   bss(V10)[V52,V53]:a32  V60:u32.xyzw  V0  V70
1806 // BSS using U, V, R, and LOD:
1807 //     lsc_atomic_icas.tgm   bss(V10)[V52,V53,V54,V55]:a32  V60:u32.xz  V61 V70
1808 //
1809 LscTypedAtomic:
1810 //  1          2                    3                     4             5
1811     Predicate  LSC_ATOMIC_MNEMONIC  LSC_SFID_TYPED_TOKEN  LscCacheOpts  ExecSize
1812 //  6               7                    8              9
1813     LscDataOperand  LscTypedAddrOperand  LscPayloadReg  LscPayloadReg
1814     {
1815         $5.exec_size =
1816             lscCheckExecSize($3, $2, $6.shape.order, $5.exec_size);
1817         pBuilder->CISA_create_lsc_typed_inst(
1818             $1,  // predicate
1819             $2,  // subop
1820             $3,  // sfid
1821             $4,  // caching settings
1822             Get_VISA_Exec_Size_From_Raw_Size($5.exec_size),
1823             $5.emask,
1824             $7.addr.type, // address model
1825             $7.addr.size,  // address size
1826             $6.shape,    // data type
1827             $7.surface,  // surface
1828             $6.reg,      // dst data
1829             $7.regs[0],  // src0 addrs u
1830             $7.regs[1],  // src0 addrs v
1831             $7.regs[2],  // src0 addrs r
1832             $7.regs[3],  // src0 addrs lod
1833             $8,          // src1 data
1834             $9,          // src2 data
1835             CISAlineno);
1836     }
1837 
1838 // EXAMPLE:
1839 //   lsc_read_state_info.tgm  VDATA  bti(0x4)
1840 LscTypedReadStateInfo:
1841 // 1          2                             3
1842    Predicate  LSC_READ_STATE_INFO_MNEMONIC  LSC_SFID_TYPED_TOKEN
1843 // 4              5
1844    LscPayloadReg  LscRegAddrModel
1845    {
1846         LSC_CACHE_OPTS caching{LSC_CACHING_DEFAULT,LSC_CACHING_DEFAULT};
1847         LSC_DATA_SHAPE dataShape{LSC_DATA_SIZE_32b,LSC_DATA_ORDER_NONTRANSPOSE};
1848         dataShape.elems = LSC_DATA_ELEMS_1;
1849         pBuilder->CISA_create_lsc_typed_inst(
1850             $1,              // predicate
1851             $2,              // subop
1852             $3,              // sfid
1853             caching,         // caching settings
1854             EXEC_SIZE_1,
1855             vISA_EMASK_M1_NM,
1856             $5.type,           // address model
1857             LSC_ADDR_SIZE_32b, // address size
1858             dataShape,         // data type
1859             $5.surface,        // surface
1860             $4,                // dst data
1861             nullptr,           // src0 addrs u
1862             nullptr,           // src0 addrs v
1863             nullptr,           // src0 addrs r
1864             nullptr,           // src0 addrs lod
1865             nullptr,           // src1 data
1866             nullptr,           // src2 data
1867             CISAlineno);
1868    }
1869 
1870 // EXAMPLES:
1871 //    lsc_fence.ugm.evict.gpu   // evicts all caches up to the GPU level
1872 //    lsc_fence.slm.flush.group // flushes cache up to the thread-group level
1873 //    lsc_fence.tgm.flush.local // typed global memory flush to the local unit
1874 //
1875 LscFence:
1876 //  1                   2        3                  4
1877     LSC_FENCE_MNEMONIC  LscSfid  LSC_FENCE_OP_TYPE  LSC_FENCE_SCOPE
1878     {
1879         pBuilder->CISA_create_lsc_fence($2, $3, $4, CISAlineno);
1880     }
1881 
1882 LscSfid: LSC_SFID_UNTYPED_TOKEN | LSC_SFID_TYPED_TOKEN
1883 
1884 LscCacheOpts:
1885     %empty                          {$$ = {LSC_CACHING_DEFAULT,LSC_CACHING_DEFAULT};}
1886   | LSC_CACHING_OPT                 {$$ = {$1,LSC_CACHING_DEFAULT};}
1887   | LSC_CACHING_OPT LSC_CACHING_OPT {$$ = {$1,$2};}
1888 
1889 LscUntypedAddrOperand:
1890 //  1               2      3                  4
1891     LscAddrModelOpt LBRACK LscAddrImmScaleOpt LscPayloadNonNullReg
1892 //    5                    6             7
1893       LscAddrImmOffsetOpt  RBRACK LSC_ADDR_SIZE_TK
1894     {
1895         $$ = {$1.surface,{$4},{$1.type,(int)$3,(int)$5,$7}};
1896     }
1897 
1898 LscUntypedStridedAddrOperand:
1899 //  1               2      3                  4
1900     LscAddrModelOpt LBRACK LscAddrImmScaleOpt LscPayloadNonNullReg
1901 //    5                    6     7                   8      9
1902       LscAddrImmOffsetOpt  COMMA LscVectorOpRegOrImm RBRACK LSC_ADDR_SIZE_TK
1903     {
1904         $$ = {$1.surface,{$4,$7},{$1.type,(int)$3,(int)$5,$9}};
1905     }
1906     | LscUntypedAddrOperand {
1907         $$ = $1;
1908         $$.regs[1] = nullptr;
1909     }
1910 
1911 // e.g. flat[VBASE(0,0),VSWIDTH(1,0),VSHEIGHT(1,0),VPITCH(1,0),VX(0,4),VY(0,5)]
1912 LscUntypedBlock2dAddrOperand:
1913 //  1            2
1914     LSC_AM_FLAT  LBRACK
1915 //            3 (surfaceAddr)
1916               LscVectorOpReg
1917 //      4     5 (surfaceWidth)
1918         COMMA LscVectorOpRegOrImm
1919 //      6     7 (surfaceHeight)
1920         COMMA LscVectorOpRegOrImm
1921 //      8     9 (surfacePitch)
1922         COMMA LscVectorOpRegOrImm
1923 //      10    11 (baseX)
1924         COMMA LscVectorOpRegOrImm
1925 //      12    13 (baseY)
1926         COMMA LscVectorOpRegOrImm
1927 //      14
1928         RBRACK
1929     {
1930         $$ = {nullptr,{$3,$5,$7,$9,$11,$13},{LSC_ADDR_TYPE_FLAT,1,0,LSC_ADDR_SIZE_64b}};
1931     }
1932 
1933 LscTypedAddrOperand:
1934 //
1935 // just U
1936 //  1               2
1937     LscRegAddrModel LBRACK
1938 //    3
1939       LscPayloadNonNullReg
1940 //    4      5
1941       RBRACK LSC_ADDR_SIZE_TK
1942     {
1943         $$ = {$1.surface,{$3},{$1.type,1,0,$5}};
1944     }
1945 //
1946 // U, V
1947 //  1               2
1948   | LscRegAddrModel LBRACK
1949 //  3                    4     5
1950     LscPayloadNonNullReg COMMA LscPayloadNonNullReg
1951 //    6             7
1952       RBRACK LSC_ADDR_SIZE_TK
1953     {
1954         $$ = {$1.surface,{$3,$5},{$1.type,1,0,$7}};
1955     }
1956 //
1957 // U, V, R
1958 //  1               2
1959   | LscRegAddrModel LBRACK
1960 //  3                    4     5                    6     7
1961     LscPayloadNonNullReg COMMA LscPayloadNonNullReg COMMA LscPayloadNonNullReg
1962 //    8             9
1963       RBRACK LSC_ADDR_SIZE_TK
1964     {
1965         $$ = {$1.surface,{$3,$5,$7},{$1.type,1,0,$9}};
1966     }
1967 //
1968 // U, V, R, LOD
1969 //  1               2
1970   | LscRegAddrModel LBRACK
1971 //  3                    4     5                    6     7                    8     9
1972     LscPayloadNonNullReg COMMA LscPayloadNonNullReg COMMA LscPayloadNonNullReg COMMA LscPayloadNonNullReg
1973 //    10            11
1974       RBRACK LSC_ADDR_SIZE_TK
1975     {
1976         $$ = {$1.surface,{$3,$5,$7,$9},{$1.type,1,0,$11}};
1977     }
1978 
1979 // Enables stuff like
1980 // [VADDR + 4*0x100 - 32]
1981 // [VADDR - (32 + 4*0x100)]
1982 LscAddrImmOffsetOpt:
1983     %empty           {$$ =   0;}
1984   | PLUS  IntExpAdd  {$$ =  $2;}
1985   | MINUS IntExpPrim {$$ = -$2;}
1986   ;
1987 
1988 // e.g. [4*%sizeof(GRF)*VADDR + ...]
1989 //       ^
1990 // Note: we can't allow
1991 LscAddrImmScaleOpt:
1992     %empty            {$$ = 1;}
1993     | IntExpMul TIMES {$$ = $1;}
1994 
1995 LscAddrModelOpt:
1996     %empty       {$$ = {LSC_ADDR_TYPE_FLAT,nullptr};}
1997   | LSC_AM_FLAT  {$$ = {LSC_ADDR_TYPE_FLAT,nullptr};}
1998   | LscRegAddrModel
1999 
2000 LscRegAddrModel:
2001     // address models that take a reg parameter
2002     LscRegAddrModelKind  LPAREN  LscVectorOpRegOrImm  RPAREN {
2003         $$ = {$1,$3};
2004     }
2005 
2006 LscRegAddrModelKind:
2007     LSC_AM_BSS {$$ = LSC_ADDR_TYPE_BSS;}
2008   | LSC_AM_SS  {$$ = LSC_ADDR_TYPE_SS;}
2009   | LSC_AM_BTI {$$ = LSC_ADDR_TYPE_BTI;}
2010 
2011 LscVectorOpRegOrImm: LscVectorOpReg | LscVectorOpImm
2012 
2013 LscVectorOpImm:
2014     IntExp {
2015         $$ = pBuilder->CISA_create_immed($1,ISA_TYPE_UD, CISAlineno);
2016     }
2017 
2018 LscVectorOpReg:
2019     Var {
2020         ABORT_ON_FAIL($$ = pBuilder->CISA_create_gen_src_operand(
2021             $1,
2022             0, 1, 0, // region
2023             0, 0, // row and col offset
2024             MODIFIER_NONE, CISAlineno));
2025     }
2026     |
2027     Var DOT DEC_LIT {
2028         ABORT_ON_FAIL($$ = pBuilder->CISA_create_gen_src_operand(
2029             $1,
2030             0, 1, 0, // region
2031             0, (unsigned char)$3, // row and col offset
2032             MODIFIER_NONE, CISAlineno));
2033     }
2034     |
2035     Var LPAREN IntExp COMMA IntExp RPAREN {
2036         MUST_HOLD($3 <= 255 || $3 >= 0, "row is out of bounds");
2037         MUST_HOLD($5 <= 255 || $5 >= 0, "col is out of bounds");
2038         $$ = pBuilder->CISA_create_gen_src_operand(
2039             $1,
2040             0, 1, 0,
2041             (unsigned char)$3, (unsigned char)$5, // row and col offset
2042             MODIFIER_NONE, CISAlineno);
2043         if ($$ == nullptr) {
2044             PARSE_ERROR("cannot find surface variable");
2045         }
2046     }
2047 
2048 LscDataOperand:
2049     LscPayloadReg  LSC_DATA_SHAPE_TK {
2050         $$ = {$1,$2};
2051     }
2052     |
2053     LscPayloadReg  LSC_DATA_SHAPE_TK_CHMASK {
2054         $$ = {$1,$2};
2055     }
2056 
2057 LscDataOperand2D:
2058    // 1             2
2059     LscPayloadReg LSC_DATA_SHAPE_TK_BLOCK2D {
2060         $$ = {$1,$2};
2061     }
2062 
2063 LscPayloadReg:
2064     RawOperand
2065     |
2066     // TODO: remove this rule once RawOperand handles no-suffix case
2067     Var {
2068         ABORT_ON_FAIL($$ = pBuilder->CISA_create_RAW_operand($1, 0, CISAlineno));
2069     }
2070 LscPayloadNonNullReg:
2071     RawOperandNonNull
2072     |
2073     // TODO: remove this rule once RawOperand handles no-suffix case
2074     VarNonNull {
2075         ABORT_ON_FAIL($$ = pBuilder->CISA_create_RAW_operand($1, 0, CISAlineno));
2076     }
2077 
2078 SwitchLabels:
2079     %empty
2080     {
2081     }
2082     | COMMA SwitchLabels
2083     {
2084     }
2085     | IDENT SwitchLabels
2086     {
2087         // parse rule means we see last label first
2088         switchLabels.push_front($1);
2089     }
2090 
2091                    // 1        2         3          4
2092 BranchInstruction: Predicate BRANCH_OP ExecSize IdentOrStringLit
2093     {
2094         pBuilder->CISA_create_branch_instruction($1, $2, $3.emask, $3.exec_size, $4, false, CISAlineno);
2095     }
2096     | Predicate CALL_OP ExecSize IdentOrStringLit
2097     {
2098         pBuilder->CISA_create_branch_instruction($1, $2.opcode, $3.emask, $3.exec_size, $4, $2.is_fccall, CISAlineno);
2099     }
2100     | Predicate RET_OP ExecSize
2101     {
2102         pBuilder->CISA_Create_Ret($1, $2, $3.emask, $3.exec_size, CISAlineno);
2103     }
2104     | SWITCHJMP_OP ExecSize VecSrcOperand_G_I_IMM LPAREN SwitchLabels RPAREN
2105     {
2106         pBuilder->CISA_create_switch_instruction($1, $2.exec_size, $3.cisa_gen_opnd, switchLabels, CISAlineno);
2107         switchLabels.clear();
2108     }
2109     //  1          2         3     4       5       6
2110     | Predicate  FCALL   ExecSize IDENT  DEC_LIT DEC_LIT
2111     {
2112         pBuilder->CISA_create_fcall_instruction($1, $2, $3.emask, $3.exec_size, $4, (unsigned)$5, (unsigned)$6, CISAlineno);
2113     }
2114     // 1           2       3       4                    5       6
2115     | Predicate IFCALL ExecSize VecSrcOperand_G_I_IMM DEC_LIT DEC_LIT
2116     {
2117         pBuilder->CISA_create_ifcall_instruction(
2118         $1, $3.emask, $3.exec_size,
2119         $4.cisa_gen_opnd, (unsigned)$5, (unsigned)$6, CISAlineno);
2120     }
2121     // 1       2          3
2122     | FADDR  IDENT VecDstOperand_G_I
2123     {
2124         pBuilder->CISA_create_faddr_instruction($2, $3.cisa_gen_opnd, CISAlineno);
2125     }
2126 
2127 FILE: FILE_OP STRING_LIT
2128     {
2129         pBuilder->CISA_create_FILE_instruction($1, $2, CISAlineno);
2130     }
2131 
2132 LOC: LOC_OP DEC_LIT
2133     {
2134         pBuilder->CISA_create_LOC_instruction($1, (unsigned)$2, CISAlineno);
2135     }
2136 RawSendInstruction:
2137     //    1             2            3       4      5       6           7                8         9
2138     Predicate  RAW_SEND_STRING  ExecSize HEX_LIT DEC_LIT DEC_LIT VecSrcOperand_G_IMM RawOperand RawOperand
2139     {
2140         pBuilder->CISA_create_raw_send_instruction(ISA_RAW_SEND, false, $3.emask, $3.exec_size, $1,
2141             (unsigned)$4, (unsigned char)$5, (unsigned char)$6, $7.cisa_gen_opnd, $8, $9, CISAlineno);
2142     }
2143     |
2144     //    1             2           3       4        5       6          7               8           9
2145     Predicate  RAW_SENDC_STRING  ExecSize HEX_LIT DEC_LIT DEC_LIT VecSrcOperand_G_IMM RawOperand RawOperand
2146     {
2147         pBuilder->CISA_create_raw_send_instruction(ISA_RAW_SEND, true, $3.emask, $3.exec_size, $1,
2148             (unsigned)$4, (unsigned char)$5, (unsigned char)$6, $7.cisa_gen_opnd, $8, $9, CISAlineno);
2149     }
2150 
2151         //            1                      2
2152 LifetimeStartInst: LIFETIME_START_OP        IDENT
2153     {
2154         ABORT_ON_FAIL(pBuilder->CISA_create_lifetime_inst((unsigned char)0, $2, CISAlineno));
2155     }
2156 
2157         //            1                      2
2158 LifetimeEndInst:  LIFETIME_END_OP           IDENT
2159     {
2160         ABORT_ON_FAIL(pBuilder->CISA_create_lifetime_inst((unsigned char)1, $2, CISAlineno));
2161     }
2162 RawSendsInstruction:
2163     //    1             2         3        4       5      6          7              8                  9               10         11        12
2164     Predicate RAW_SENDS_STRING ElemNum ElemNum  ElemNum ElemNum ExecSize VecSrcOperand_G_IMM   VecSrcOperand_G_IMM RawOperand RawOperand RawOperand
2165     {
2166         pBuilder->CISA_create_raw_sends_instruction(
2167             ISA_RAW_SENDS, false, false, $7.emask, $7.exec_size, $1, $8.cisa_gen_opnd,
2168             (unsigned char)$3, (unsigned char)$4, (unsigned char)$5, (unsigned char)$6,
2169             $9.cisa_gen_opnd, $10, $11, $12, CISAlineno);
2170     }
2171     //    1             2               3        4       5      6          7              8                  9               10         11        12
2172     | Predicate RAW_SENDS_EOT_STRING ElemNum ElemNum  ElemNum ElemNum ExecSize VecSrcOperand_G_IMM   VecSrcOperand_G_IMM RawOperand RawOperand RawOperand
2173     {
2174         pBuilder->CISA_create_raw_sends_instruction(
2175             ISA_RAW_SENDS, false, true, $7.emask, $7.exec_size, $1, $8.cisa_gen_opnd,
2176             (unsigned char)$3, (unsigned char)$4, (unsigned char)$5, (unsigned char)$6,
2177             $9.cisa_gen_opnd, $10, $11, $12, CISAlineno);
2178     }
2179     //    1             2              3       4       5        6        7                         8             9          10        11
2180     | Predicate  RAW_SENDSC_STRING  ElemNum ElemNum ElemNum ExecSize VecSrcOperand_G_IMM VecSrcOperand_G_IMM RawOperand RawOperand RawOperand
2181     {
2182         pBuilder->CISA_create_raw_sends_instruction(
2183             ISA_RAW_SENDS, true, false, $6.emask, $6.exec_size, $1, $7.cisa_gen_opnd,
2184             0, (unsigned char)$3, (unsigned char)$4, (unsigned char)$5,
2185             $8.cisa_gen_opnd, $9, $10, $11, CISAlineno);
2186     }
2187     //    1             2                  3       4       5        6        7                         8             9          10        11
2188     | Predicate  RAW_SENDSC_EOT_STRING  ElemNum ElemNum ElemNum ExecSize VecSrcOperand_G_IMM VecSrcOperand_G_IMM RawOperand RawOperand RawOperand
2189     {
2190         pBuilder->CISA_create_raw_sends_instruction(
2191             ISA_RAW_SENDS, true, true, $6.emask, $6.exec_size, $1, $7.cisa_gen_opnd,
2192             0, (unsigned char)$3, (unsigned char)$4, (unsigned char)$5,
2193             $8.cisa_gen_opnd, $9, $10, $11, CISAlineno);
2194     }
2195 
2196 NullaryInstruction:
2197     CACHE_FLUSH_OP
2198     {
2199         pBuilder->CISA_create_NO_OPND_instruction($1, CISAlineno);
2200     }
2201     |
2202     WAIT_OP VecSrcOperand_G_IMM
2203     {
2204         pBuilder->CISA_create_wait_instruction($2.cisa_gen_opnd, CISAlineno);
2205     }
2206     |
2207     YIELD_OP
2208     {
2209         pBuilder->CISA_create_yield_instruction($1, CISAlineno);
2210     }
2211     |
2212     FENCE_GLOBAL_OP
2213     {
2214         pBuilder->CISA_create_fence_instruction($1, 0x0, CISAlineno);
2215     }
2216     |
2217     FENCE_GLOBAL_OP FENCE_OPTIONS
2218     {
2219         pBuilder->CISA_create_fence_instruction($1, $2, CISAlineno);
2220     }
2221     |
2222     FENCE_LOCAL_OP
2223     {
2224         pBuilder->CISA_create_fence_instruction($1, 0x20, CISAlineno);
2225     }
2226     |
2227     FENCE_LOCAL_OP FENCE_OPTIONS
2228     {
2229         pBuilder->CISA_create_fence_instruction($1, $2 | 0x20, CISAlineno);
2230     }
2231     |
2232     FENCE_SW_OP
2233     {
2234         pBuilder->CISA_create_fence_instruction($1, 0x80, CISAlineno);
2235     }
2236 
2237 OwordModifier: %empty {$$ = false;} | OWORD_MODIFIER;
2238 
2239 
2240 // ------ predicate and saturation and source modifiers ------
2241 
2242 Predicate:
2243     %empty
2244     {
2245         $$ = NULL;
2246     }
2247     |
2248     LPAREN PredSign PredVar PredCtrlOpt RPAREN
2249     {
2250         $$ = pBuilder->CISA_create_predicate_operand($3, $2, $4, CISAlineno);
2251     }
2252 
2253 PredSign: %empty {$$ = PredState_NO_INVERSE;} | BANG {$$ = PredState_INVERSE;}
2254 
2255 PredCtrlOpt: %empty {$$ = PRED_CTRL_NON;} | PRED_CNTL
2256 
2257 
2258 SatModOpt: %empty {$$ = false;} | SAT {$$ = true;}
2259 
2260 SrcModifier:
2261       SRCMOD_NEG    {$$.mod = MODIFIER_NEG;}
2262     | SRCMOD_ABS    {$$.mod = MODIFIER_ABS;}
2263     | SRCMOD_NEGABS {$$.mod = MODIFIER_NEG_ABS;}
2264     | SRCMOD_NOT    {$$.mod = MODIFIER_NOT;}
2265 
2266 ConditionalModifier: %empty {$$ = ISA_CMP_UNDEF;} | COND_MOD;
2267 
2268 // ------ operands groups ------
2269 
2270 // ------ DST -----------
2271 VecDstOperand_A: DstAddrOperand    {$$ = $1; $$.type = OPERAND_ADDRESS;}
2272 VecDstOperand_G: DstGeneralOperand {$$ = $1; $$.type = OPERAND_GENERAL;}
2273 VecDstOperand_G_I:
2274       DstGeneralOperand    {$$ = $1; $$.type = OPERAND_GENERAL;}
2275     | DstIndirectOperand   {$$ = $1; $$.type = OPERAND_INDIRECT;}
2276 
2277 // ------ SRC -----------
2278 VecSrcOperand_G_I_IMM_A_AO:
2279       VecSrcOperand_G_I_IMM_A
2280     | SrcAddrOfOperand     {$$ = $1; $$.type = OPERAND_ADDRESSOF;}
2281 
2282 VecSrcOperand_G_I_IMM_A:
2283       VecSrcOperand_G_I_IMM
2284     | SrcAddrOperand       {$$ = $1; $$.type = OPERAND_ADDRESS;}
2285 
2286 VecSrcOperand_G_I_IMM:
2287       VecSrcOperand_G
2288     | SrcIndirectOperand   {$$ = $1; $$.type = OPERAND_INDIRECT;}
2289     | SrcImmOperand        {$$ = $1; $$.type = OPERAND_IMMEDIATE;}
2290 
2291 VecSrcOperand_G_IMM:
2292       VecSrcOperand_G
2293     | SrcImmOperand       {$$ = $1; $$.type = OPERAND_IMMEDIATE;}
2294 
2295 VecSrcOperand_G_IMM_AO:
2296       VecSrcOperand_G
2297     | SrcImmOperand       {$$ = $1; $$.type = OPERAND_IMMEDIATE;}
2298     | SrcAddrOfOperand    {$$ = $1; $$.type = OPERAND_ADDRESSOF;}
2299 
2300 VecSrcOperand_G_A:
2301       VecSrcOperand_G
2302     | SrcAddrOperand      {$$ = $1; $$.type = OPERAND_ADDRESS;}
2303 
2304 VecSrcOperand_G_A_AO:
2305       VecSrcOperand_G_A
2306     | SrcAddrOfOperand    {$$ = $1; $$.type = OPERAND_ADDRESS;}
2307 
2308 VecSrcOperand_G: SrcGeneralOperand {$$ = $1; $$.type = OPERAND_GENERAL;}
2309 
2310 VecSrcOpndSimple: Var TwoDimOffset
2311     {
2312         // simple vector operand with no modifier that has an
2313         // implicit src region = <1,1,0>
2314         $$.type = OPERAND_GENERAL;
2315         ABORT_ON_FAIL($$.cisa_gen_opnd = pBuilder->CISA_create_gen_src_operand(
2316             $1, 1, 1, 0, $2.row, $2.elem, MODIFIER_NONE, CISAlineno));
2317     }
2318 
2319          //   1         2         3      4          5
2320 VMEOpndIME: LPAREN DEC_LIT COMMA DEC_LIT RPAREN
2321     {
2322         $$.streamMode = (unsigned char)$2;
2323         $$.searchCtrl = (unsigned char)$4;
2324     }
2325 
2326          //   1            2                3             4             5           6             7
2327 VMEOpndFBR: LPAREN VecSrcOperand_G_I_IMM COMMA VecSrcOperand_G_I_IMM COMMA VecSrcOperand_G_I_IMM RPAREN
2328     {
2329         $$.cisa_fbrMbMode_opnd = $2.cisa_gen_opnd;
2330         $$.cisa_fbrSubMbShape_opnd = $4.cisa_gen_opnd;
2331         $$.cisa_fbrSubPredMode_opnd = $6.cisa_gen_opnd;
2332     }
2333 
2334 SrcStateOperand:
2335   Var LPAREN IntExp RPAREN
2336     {
2337         MUST_HOLD($3 < 0x100, "offset out of bounds");
2338         $$.offset = (unsigned char)$3;
2339         ABORT_ON_FAIL($$.cisa_gen_opnd = pBuilder->CISA_create_state_operand($1, (unsigned char)$3, CISAlineno, false));
2340     }
2341 
2342 DstStateOperand:
2343   Var LPAREN IntExp RPAREN
2344     {
2345         MUST_HOLD($3 < 0x100, "offset out of bounds");
2346         $$.offset = (unsigned char)$3;
2347         ABORT_ON_FAIL($$.cisa_gen_opnd = pBuilder->CISA_create_state_operand($1, (unsigned char)$3, CISAlineno, true));
2348     }
2349 
2350 ///////////////////////////////////////////////////////////////////////////////
2351 // ------------ Operands ------------
2352 
2353 // ------  Raw Operands -----
2354 // EXAMPLES:
2355 //   VDATA.12   // raw operand with offset
2356 //   VDATA.(%sizeof X / 2)
2357 //   %null.0
2358 // TODO: these cases (see below for needed fixes)
2359 //   VDATA      // implicitly VDATA.0
2360 //   %null
2361 RawOperand:
2362     RawOperandNonNull
2363     |
2364 //
2365 // conflicts SampleInstruction: has a ... (Var Var | Var) ... part
2366 //  also RTWriteOperand, DSRTWriteInstruction
2367 // those instructions need to parse proper operands
2368 //
2369 //    BUILTIN_NULL
2370 //    {
2371 //        $$ = pBuilder->CISA_create_RAW_NULL_operand(CISAlineno); // can't fail
2372 //    }
2373 //    |
2374     BUILTIN_NULL DOT DEC_LIT
2375     {
2376         MUST_HOLD($3 == 0, "%null must have 0 as offset");
2377         $$ = pBuilder->CISA_create_RAW_NULL_operand(CISAlineno); // can't fail
2378     }
2379 
2380 RawOperandNonNull:
2381     VarNonNull RawOperandOffsetSuffix
2382     {
2383         ABORT_ON_FAIL($$ = pBuilder->CISA_create_RAW_operand($1, (unsigned short)$2, CISAlineno));
2384     }
2385 // TODO: see RawOperand: BUILTIN_NULL issues (same here)
2386 //    |
2387 //    VarNonNull
2388 //    {
2389 //        ABORT_ON_FAIL($$ = pBuilder->CISA_create_RAW_operand($1, 0, CISAlineno));
2390 //    }
2391 
2392 RawOperandOffsetSuffix:
2393     DOT DEC_LIT {
2394         MUST_HOLD($2 <= 0x10000, "offset out of bounds");
2395         $$ = $2;
2396     }
2397     |
2398     DOT LPAREN IntExp RPAREN {
2399         MUST_HOLD($3 <= 0x10000, "offset out of bounds");
2400         $$ = $3;
2401     }
2402 
2403 
2404 RawOperandArray:
2405     %empty
2406     {
2407         $$ = 0;
2408     }
2409     |
2410     RawOperandArray RawOperand
2411     {
2412         rawOperandArray[$1++] = (VISA_RawOpnd*)$2;
2413         $$ = $1;
2414     }
2415 
2416 
2417 // ------  Dst Operands -----
2418 DstAddrOperand: AddrVarAccessWithWidth
2419     {
2420         ABORT_ON_FAIL($$.cisa_gen_opnd =
2421           pBuilder->CISA_set_address_operand(
2422             $1.cisa_decl, $1.elem, $1.row, true, CISAlineno));
2423     }
2424 
2425 DstGeneralOperand:
2426     Var TwoDimOffset DstRegion
2427     {
2428         ABORT_ON_FAIL($$.cisa_gen_opnd = pBuilder->CISA_dst_general_operand(
2429             $1, $2.row, $2.elem, (unsigned short)$3, CISAlineno));
2430     }
2431     |
2432     Var DstRegion {
2433         ABORT_ON_FAIL($$.cisa_gen_opnd = pBuilder->CISA_dst_general_operand(
2434             $1, 0, 0, (unsigned short)$2, CISAlineno));
2435     }
2436 
2437 DstIndirectOperand: IndirectVarAccess DstRegion DataType
2438     {
2439         ABORT_ON_FAIL($$.cisa_gen_opnd = pBuilder->CISA_create_indirect_dst(
2440             $1.cisa_decl, MODIFIER_NONE, $1.row, $1.elem, $1.immOff, (unsigned short)$2, $3, CISAlineno));
2441     }
2442 
2443 
2444 //  ------  Src Operands --------------
2445 
2446 SrcAddrOfOperand:
2447     // This is a problem because any instruction that allows an operand that includes
2448     // an SrcAddrOf operand followed by a SrcImm operand will create a problem.
2449     //
2450     // For example, given the stream for a pair of sources where one is an
2451     // ADDR_OF and the other is an IMM:
2452     //     &V127 - 16 - 32:d
2453     // We don' tknow if that should be read as:
2454     //       SRC[i]     SRC[i+1]
2455     // 1.  &V127-16    -32:d
2456     //   OR
2457     // 2.  &V127       -16-32:d
2458     //
2459     AddrOfVar {
2460          $$.cisa_gen_opnd = pBuilder->CISA_set_address_expression($1.cisa_decl, 0, CISAlineno);
2461     }
2462     |
2463     AddrOfVar LBRACK IntExp RBRACK {
2464          MUST_HOLD((short)$3 == $3, "variable address offset is too large");
2465          $$.cisa_gen_opnd = pBuilder->CISA_set_address_expression($1.cisa_decl, (short)$3, CISAlineno);
2466     }
2467 
2468 AddrOfVar:
2469     AMP Var {
2470         // Both GENERAL_VAR and SURFACE_VAR are addressable
2471         $$.cisa_decl = pBuilder->CISA_find_decl($2);
2472         if ($$.cisa_decl == nullptr)
2473             PARSE_ERROR("unbound variable");
2474         $$.row = 0;
2475         $$.elem = 0;
2476     }
2477 
2478 
2479 SrcAddrOperand: AddrVarAccessWithWidth
2480     {
2481         ABORT_ON_FAIL($$.cisa_gen_opnd =
2482             pBuilder->CISA_set_address_operand(
2483                 $1.cisa_decl, $1.elem, $1.row, false, CISAlineno));
2484     }
2485 
2486 SrcGeneralOperand:
2487                 Var TwoDimOffset SrcRegionDirect
2488     {
2489         ABORT_ON_FAIL($$.cisa_gen_opnd =
2490             pBuilder->CISA_create_gen_src_operand(
2491                 $1, $3.v_stride, $3.width, $3.h_stride, $2.row, $2.elem, MODIFIER_NONE, CISAlineno));
2492     }
2493     |
2494     SrcModifier Var TwoDimOffset SrcRegionDirect
2495     {
2496         ABORT_ON_FAIL($$.cisa_gen_opnd =
2497             pBuilder->CISA_create_gen_src_operand(
2498                 $2, $4.v_stride, $4.width, $4.h_stride, $3.row, $3.elem, $1.mod, CISAlineno));
2499     }
2500 
2501 SrcImmOperand:
2502     ////////////////
2503     // Integral
2504     IntExpUnr DataTypeIntOrVector
2505     {
2506         $$.cisa_gen_opnd = pBuilder->CISA_create_immed($1, $2, CISAlineno);
2507     }
2508     ////////////////
2509     // FP16
2510     | HEX_LIT HFTYPE {
2511         MUST_HOLD($1 < 0x10000, "literal too large for half float");
2512         $$.cisa_gen_opnd = pBuilder->CISA_create_immed(
2513             (unsigned short)$1, ISA_TYPE_HF, CISAlineno);
2514     }
2515     ////////////////
2516     // FP32
2517     |       FloatLit
2518     {
2519         $$.cisa_gen_opnd = pBuilder->CISA_create_float_immed($1, ISA_TYPE_F, CISAlineno);
2520     }
2521     | MINUS FloatLit {
2522         $$.cisa_gen_opnd = pBuilder->CISA_create_float_immed(-$2, ISA_TYPE_F, CISAlineno);
2523     }
2524     ////////////////
2525     // FP64
2526     |       DoubleFloatLit
2527     {
2528         $$.cisa_gen_opnd = pBuilder->CISA_create_float_immed($1, ISA_TYPE_DF, CISAlineno);
2529     }
2530     | MINUS DoubleFloatLit
2531     {
2532         $$.cisa_gen_opnd = pBuilder->CISA_create_float_immed(-$2, ISA_TYPE_DF, CISAlineno);
2533     }
2534 
2535 FloatLit:
2536      F32_LIT
2537    | DEC_LIT FTYPE
2538    {
2539         // "1:f" means 1.4e-45
2540         int number = (int)$1;
2541         float *fp = (float *)&number;
2542         $$ = *fp;
2543    }
2544    | HEX_LIT FTYPE  // e.g. 0x3f800000:f
2545    {
2546         int number = (int)$1;
2547         float *fp = (float *)&number;
2548         $$ = *fp;
2549    }
2550 
2551 DoubleFloatLit:
2552      F64_LIT
2553    | DEC_LIT DFTYPE {
2554         // "1:df" means 5e-324
2555         int64_t number = $1;
2556         double *fp = (double *)&number;
2557         $$ = *fp;
2558    }
2559    | HEX_LIT DFTYPE {
2560         // to support 0x7ff0000000000000:df
2561         int64_t number = $1;
2562         double *fp = (double *)&number;
2563         $$ = *fp;
2564    }
2565 
2566 
2567 
2568 SrcIndirectOperand:
2569                 IndirectVarAccess SrcRegionIndirect DataType
2570     {
2571         ABORT_ON_FAIL($$.cisa_gen_opnd =
2572             pBuilder->CISA_create_indirect(
2573                 $1.cisa_decl, MODIFIER_NONE, $1.row, $1.elem, $1.immOff,
2574                 $2.v_stride, $2.width, $2.h_stride, $3, CISAlineno));
2575     }
2576     |
2577     SrcModifier IndirectVarAccess SrcRegionIndirect DataType
2578     {
2579         ABORT_ON_FAIL($$.cisa_gen_opnd =
2580             pBuilder->CISA_create_indirect(
2581                 $2.cisa_decl, $1.mod, $2.row, $2.elem, $2.immOff,
2582                 $3.v_stride, $3.width, $3.h_stride, $4, CISAlineno));
2583     }
2584 
2585 // -------- regions -----------
2586 DstRegion: LANGLE IntExpNRA RANGLE    // <HorzStride>
2587     {
2588         MUST_HOLD(($2 == 0 || $2 == 1 || $2 == 2 || $2 == 4),
2589              "Dst HorzStride must be 0, 1, 2, or 4");
2590         $$ = $2;
2591     }
2592 
2593 
2594 SrcRegionDirect:
2595     // <VertStride;Width,HorzStride>
2596     // FIXME: Using > as a closing delimiter is ambiguous with a > operator
2597     //  <1;2,4 > ...
2598     //         ^ ambiguity
2599     //  <1;2,4 > :ud
2600     //         ^ ambiguity
2601     //  <1;2,4 > x ? 1 : 0>:ud
2602     //         ^ ambiguity
2603     //   (see the note on AliasAttrOpt)
2604     LANGLE IntExp SEMI IntExp COMMA IntExpNRA RANGLE
2605     {
2606         MUST_HOLD(($2 == 0 || $2 == 1 || $2 == 2 || $2 == 4 || $2 == 8 || $2 == 16 || $2 == 32),
2607                  "Src Region VertStride must be 0, 1, 2, 4, 8, 16, or 32");
2608         MUST_HOLD(($4 == 0 || $4 == 1 || $4 == 2 || $4 == 4 || $4 == 8 || $4 == 16),
2609                  "Src Region Width must be 0, 1, 2, 4, 8 or 16");
2610         MUST_HOLD(($6 == 0 || $6 == 1 || $6 == 2 || $6 == 4),
2611                  "Src Region HorzStride must be 0, 1, 2, or 4");
2612         $$.v_stride = (unsigned)$2;
2613         $$.width = (unsigned)$4;
2614         $$.h_stride = (unsigned)$6;
2615     }
2616 
2617 SrcRegionIndirect:
2618     SrcRegionDirect
2619     |
2620 //    LANGLE IntExp COMMA IntExpNRA RANGLE   // <Width,HorzStride>
2621     LANGLE IntExp COMMA DEC_LIT RANGLE   // <Width,HorzStride>
2622     {
2623         MUST_HOLD(($2 == 0 || $2 == 1 || $2 == 2 || $2 == 4 || $2 == 8 || $2 == 16),
2624                  "Width must be 0, 1, 2, 4, 8 or 16");
2625         MUST_HOLD(($4 == 0 || $4 == 1 || $4 == 2 || $4 == 4),
2626                  "HorzStride must be 0, 1, 2, or 4");
2627         $$.v_stride = -1;
2628         $$.width = (unsigned)$2;
2629         $$.h_stride = (unsigned)$4;
2630     }
2631     |
2632     LANGLE IntExpNRA RANGLE   // <HorzStride>
2633     {
2634         MUST_HOLD(($2 == 0 || $2 == 1 || $2 == 2 || $2 == 4),
2635              "HorzStride must be 0, 1, 2, or 4");
2636         $$.v_stride = -1;
2637         $$.width = -1;
2638         $$.h_stride = (unsigned)$2;
2639     }
2640 
2641 
2642 IndirectVarAccess:
2643     IND_LBRACK AddrVarAccess COMMA IntExp RBRACK {
2644         $$ = $2;
2645         $$.immOff = (int)$4;
2646     }
2647     |
2648     IND_LBRACK AddrVarAccess              RBRACK {
2649           $$ = $2;
2650           $$.immOff = 0;
2651     }
2652 
2653 TwoDimOffset: LPAREN IntExp COMMA IntExp RPAREN {
2654         MUST_HOLD($2 >= 0, "row (register) offset must be positive");
2655         $$.row = (int)$2;
2656         MUST_HOLD($4 >= 0 && $4 <= 0xFFFF, "sub-register offset out of bounds");
2657         $$.elem = (int)$4;
2658     }
2659 
2660 PredVar:
2661     Var {
2662         $$ = pBuilder->CISA_find_decl($1);
2663         if ($$ == nullptr)
2664             PARSE_ERROR($1, ": undefined predicate variable");
2665         if ($$->type != PREDICATE_VAR)
2666             PARSE_ERROR($1, ": not a predicate variable");
2667     }
2668 
2669 AddrVarAccess:
2670     Var LPAREN IntExp RPAREN {
2671         $$.cisa_decl = pBuilder->CISA_find_decl($1);
2672         if ($$.cisa_decl == nullptr) {
2673             PARSE_ERROR($1, ": unbound variable");
2674         } else if ($$.cisa_decl->type != ADDRESS_VAR) {
2675             PARSE_ERROR($1, ": not an address variable");
2676         }
2677         $$.row = 1;
2678         $$.elem = (int)$3;
2679     }
2680 
2681 AddrVarAccessWithWidth:
2682     Var LPAREN IntExp RPAREN LANGLE IntExpNRA RANGLE {
2683         $$.cisa_decl = pBuilder->CISA_find_decl($1);
2684         if ($$.cisa_decl == nullptr) {
2685             PARSE_ERROR($1, ": unbound variable");
2686         } else if ($$.cisa_decl->type != ADDRESS_VAR) {
2687             PARSE_ERROR($1, ": not an address variable");
2688         }
2689         $$.row = (int)$6;
2690         $$.elem = (int)$3;
2691     }
2692 
2693 
2694 // -----------register size ------------------------------
2695 SIMDMode:
2696     %empty {$$ = 0;}
2697     |
2698     LPAREN DEC_LIT RPAREN
2699     {
2700        MUST_HOLD(($2 == 8 || $2 == 16 || $2 == 32),
2701                  "SIMD mode can only be 8, 16, or 32");
2702        $$ = $2;
2703     }
2704 
2705 
2706 
2707 // ----------- Execution size --------------
2708 
2709 ElemNum: DOT DEC_LIT
2710     {
2711         $$ = $2;
2712     }
2713 
2714 ExecSize:
2715 //    %empty
2716 //    {
2717 //        $$.exec_size = UNDEFINED_EXEC_SIZE;
2718 //        $$.emask = vISA_EMASK_M1;
2719 //    }
2720 //    |
2721     LPAREN ExecSizeInt RPAREN
2722     {
2723         $$.emask = vISA_EMASK_M1;
2724         $$.exec_size = (int)$2;
2725     }
2726     |
2727     LPAREN Var COMMA ExecSizeInt RPAREN
2728     {
2729         if (!ParseEMask(pBuilder, $2, $$.emask)) {
2730             PARSE_ERROR("invalid execution offset info");
2731         }
2732         $$.exec_size = (int)$4;
2733     }
2734 
2735 ExecSizeInt: DEC_LIT
2736     {
2737         if ($1 != 1 && $1 != 2 && $1 != 4 && $1 != 8 && $1 != 16 && $1 != 32) {
2738             PARSE_ERROR("invalid execution size");
2739         }
2740         $$ = (unsigned short)$1;
2741     }
2742 
2743 // ------ imm values -----------------------------------
2744 Var: VarNonNull | BUILTIN_NULL
2745 VarNonNull: IDENT | BUILTIN
2746 
2747 
2748 IntExp: IntExpCond
2749 IntExpCond:
2750       IntExpAND QUESTION IntExpAND COLON IntExpCond {$$ = $1 ? $3 : $5;}
2751     | IntExpAND
2752 IntExpAND:
2753       IntExpAND AMP  IntExpXOR {$$ = $1 & $3;}
2754     | IntExpXOR
2755 IntExpXOR:
2756       IntExpXOR CIRC  IntExpOR {$$ = $1 ^ $3;}
2757     | IntExpOR
2758 IntExpOR:
2759       IntExpOR  PIPE  IntExpCmp {$$ = $1 | $3;}
2760     | IntExpCmp
2761 IntExpCmp:
2762       IntExpRel EQ   IntExpRel {$$ = $1 == $3;}
2763     | IntExpRel NEQ  IntExpRel {$$ = $1 != $3;}
2764     | IntExpRel
2765 IntExpRel:
2766       IntExpNRA LANGLE IntExpNRA {$$ = $1 < $3;}
2767     | IntExpNRA RANGLE IntExpNRA {$$ = $1 > $3;}
2768     | IntExpNRA LEQ    IntExpNRA {$$ = $1 <= $3;}
2769     | IntExpNRA GEQ    IntExpNRA {$$ = $1 >= $3;}
2770     | IntExpNRA
2771 
2772 // In all cases where RANGLE follows an int expression we must start
2773 // expression parsing at a higher precedence than relational operators
2774 //
2775 // e.g. .decl ... alias=<%r0,IntExp>
2776 //                           ^^^^^^
2777 //  ...  DST<4;1,IntExp>   SRC<4;1,IntExp>
2778 //               ^^^^^^            ^^^^^^
2779 // e.g given ... alias=<%r0, 3 > ...
2780 //                             ^ we don't know if we are looking at
2781 //               alias=<%r0, 3 > x ? 0x10 : 20> // end
2782 //  or
2783 //               alias=<%r0, 3 > // end
2784 //
2785 // In practice, the user can use parentheses to force precedence
2786 // when needed.  99.9999% of the users will never need this.
2787 IntExpNRA: IntExpShift
2788 
2789 IntExpShift:
2790       IntExpAdd SHL  IntExpAdd {$$ = $1 << $3;}
2791     | IntExpAdd SHRS IntExpAdd {$$ = (int64_t)$1 >> (int)$3;}
2792     | IntExpAdd SHRZ IntExpAdd {$$ = (int64_t)((uint64_t)$1 >> (uint64_t)$3);}
2793     | IntExpAdd
2794 IntExpAdd:
2795       IntExpAdd PLUS  IntExpMul {$$ = $1 + $3;}
2796     | IntExpAdd MINUS IntExpMul {$$ = $1 - $3;}
2797     | IntExpMul
2798 IntExpMul:
2799       IntExpMul TIMES IntExpUnr {$$ = $1 * $3;}
2800     | IntExpMul SLASH IntExpUnr {
2801             if ($3 == 0)
2802                 PARSE_ERROR("division by 0");
2803             $$ = $1 / $3;
2804         }
2805     | IntExpMul PERCENT IntExpUnr {
2806             if ($3 == 0)
2807                 PARSE_ERROR("division by 0");
2808             $$ = $1 % $3;
2809         }
2810     | IntExpUnr
2811 IntExpUnr:
2812       MINUS IntExpUnr {$$ = -$2;}
2813     | TILDE IntExpUnr {$$ = ~$2;}
2814     | BANG  IntExpUnr {$$ = !($2);}
2815     | IntExpPrim
2816 
2817 IntExpPrim:
2818       // A literal
2819       DEC_LIT
2820     | HEX_LIT
2821       // a grouping (1 + 2)
2822     | LPAREN IntExp RPAREN {$$ = $2;}
2823     //
2824     //  %sizeof V0034
2825     //  %sizeof GRF  << matches GRF size (unless someone declares a GRF variable)
2826     | BUILTIN_SIZEOF IDENT {
2827         $$ = 0;
2828         ABORT_ON_FAIL(pBuilder->CISA_eval_sizeof_decl(CISAlineno, $2, $$));
2829     }
2830     | BUILTIN_SIZEOF LPAREN IDENT RPAREN {
2831         // TODO: %AlignOf(...), %Max(..)
2832         $$ = 0;
2833         ABORT_ON_FAIL(pBuilder->CISA_eval_sizeof_decl(CISAlineno, $3, $$));
2834     }
2835     // a built-in constant
2836     | BUILTIN_DISPATCH_SIMD_SIZE {
2837         // e.g. %DispatchSimdSize
2838         // N.B. %sizeof happens above
2839         $$ = 0;
2840         ABORT_ON_FAIL(pBuilder->CISA_lookup_builtin_constant(CISAlineno, "%DispatchSimd", $$));
2841     }
2842 
2843 
2844 // ------ data types ------------------------------------
2845 DataType: DataTypeIntOrVector
2846         | DFTYPE
2847         | FTYPE
2848         | HFTYPE
2849 DataTypeIntOrVector:
2850           ITYPE
2851         | VTYPE
2852 
2853 
2854 %%
2855 ///////////////////////////////////////////////////////////////////////////////
2856 //                                                                           //
2857 //                        Utility Functions                                  //
2858 //                                                                           //
2859 ///////////////////////////////////////////////////////////////////////////////
2860 
2861 void CISAerror(CISA_IR_Builder* pBuilder, char const *s)
2862 {
2863     pBuilder->RecordParseError(CISAlineno, s);
2864 }
2865 
ParseAlign(CISA_IR_Builder * pBuilder,const char * sym,VISA_Align & value)2866 static bool ParseAlign(CISA_IR_Builder* pBuilder, const char *sym, VISA_Align &value)
2867 {
2868     if (strcmp(sym, "byte") == 0) {
2869         value = ALIGN_BYTE;
2870     } else if (strcmp(sym, "word") == 0) {
2871         value = ALIGN_WORD;
2872     } else if (strcmp(sym, "dword") == 0) {
2873         value = ALIGN_DWORD;
2874     } else if (strcmp(sym, "qword") == 0) {
2875         value = ALIGN_QWORD;
2876     } else if (strcmp(sym, "oword") == 0) {
2877         value = ALIGN_OWORD;
2878     } else if (strcmp(sym, "GRF") == 0) {
2879         value = ALIGN_GRF;
2880     } else if (strcmp(sym, "GRFx2") == 0 || strcmp(sym, "2GRF") == 0) {
2881         value = ALIGN_2_GRF;
2882     } else if (strcmp(sym, "hword") == 0) {
2883         value = ALIGN_HWORD;
2884     } else if (strcmp(sym, "wordx32") == 0) {
2885         value = ALIGN_32WORD;
2886     } else if (strcmp(sym, "wordx64") == 0) {
2887         value = ALIGN_64WORD;
2888     } else {
2889         value = ALIGN_UNDEF;
2890         return false;
2891     }
2892     return true;
2893 }
2894 
2895 
AlignBytesToVisaAlignment(int bytes)2896 static VISA_Align AlignBytesToVisaAlignment(int bytes)
2897 {
2898     VISA_Align val = ALIGN_UNDEF;
2899     switch (bytes) {
2900     case 1:   val = ALIGN_BYTE; break;
2901     case 2:   val = ALIGN_WORD; break;
2902     case 4:   val = ALIGN_DWORD; break;
2903     case 8:   val = ALIGN_QWORD; break;
2904     case 16:  val = ALIGN_OWORD; break;
2905     case 32:  val = ALIGN_HWORD; break;
2906     case 64:  val = ALIGN_32WORD; break;
2907     case 128: val = ALIGN_64WORD; break;
2908     default:  val = ALIGN_UNDEF; break;
2909     }
2910     return val;
2911 }
2912 
2913 
2914 
ParseEMask(CISA_IR_Builder * pBuilder,const char * sym,VISA_EMask_Ctrl & emask)2915 static bool ParseEMask(
2916     CISA_IR_Builder* pBuilder,
2917     const char* sym,
2918     VISA_EMask_Ctrl &emask)
2919 {
2920     if (strcmp(sym, "NoMask") == 0) {
2921         emask = vISA_EMASK_M1_NM;
2922         return true;
2923     }
2924     for (int i = 0; i < vISA_NUM_EMASK +1; i++)
2925     {
2926         if (!strcmp(emask_str[i], sym))
2927         {
2928             emask = (VISA_EMask_Ctrl)i;
2929             return true;
2930         }
2931     }
2932 
2933     emask = vISA_NUM_EMASK;
2934     return false;
2935 }
2936 
lscCheckExecSize(LSC_SFID sfid,LSC_OP op,LSC_DATA_ORDER data_order,int exec_size)2937 static int lscCheckExecSize(
2938     LSC_SFID sfid,
2939     LSC_OP op,
2940     LSC_DATA_ORDER data_order,
2941     int exec_size)
2942 {
2943     int is_vector_op =
2944         op != LSC_LOAD_BLOCK2D &&
2945         op != LSC_STORE_BLOCK2D;
2946         // other ops like LSC_LOAD_SURFACE_INFO may be SIMD1
2947     if (op == LSC_READ_STATE_INFO) {
2948         exec_size = 1;
2949     } else if (data_order == LSC_DATA_ORDER_NONTRANSPOSE && is_vector_op) {
2950         if (exec_size == UNDEFINED_EXEC_SIZE) {
2951             if (getGenxPlatform() == GENX_DG2) // for DG2 typed is 8, untyped is 16
2952                 exec_size = sfid == LSC_TGM ? 8 : 16;
2953             else if (getGenxPlatform() >= GENX_PVC) // on PVC typed is 16, untyped is 32
2954                 exec_size = sfid == LSC_TGM ? 16 : 32;
2955             else
2956                 exec_size = 32; // the world is finally sane
2957         }
2958     } else {
2959         // block and transpose get SIMD by default
2960         if (exec_size == UNDEFINED_EXEC_SIZE) {
2961            exec_size = 1; // transpose is implicitly 1 if needed
2962         }
2963     }
2964     return exec_size;
2965 }
2966