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 <string.h>
11 #include <stdio.h>
12 #include <ctype.h>
13 
14 #ifdef _MSC_VER
15 // To disable warning for duplicate macros definitions
16 // such as INT8_MAX in lex.CISA.c with one from stdint.h
17 #pragma warning(disable: 4005)
18 #endif
19 
20 #include "visa_igc_common_header.h"
21 #include "Common_ISA_framework.h"
22 #include "VISAKernel.h"
23 #include "BuildCISAIR.h"
24 
25 #ifdef _MSC_VER
26 #pragma warning(default: 4005)
27 #endif
28 
29 #include "CISA.tab.hpp"
30 
31 #define TRACE(S) \
32     do { \
33       if (CISAout && pBuilder->debugParse()) \
34           fprintf(CISAout, "line %d: %-32s \"%s\"\n", CISAlineno, S, yytext); \
35     } while (0)
36 
37 static VISA_Type               str2type(const char *str, int str_len);
38 static VISA_Cond_Mod           str2cond(const char *str);
39 static VISAAtomicOps           str2atomic_opcode(const char *op_str);
40 static ISA_Opcode              str2opcode(const char* op_str);
41 static GenPrecision            str2Precision(const char *str, int str_len);
42 static LSC_OP                  str2lscop(const char *str);
43 static LSC_DATA_SIZE           decodeDataSizePrefix(const char *str,int *off);
44 static LSC_DATA_ELEMS          decodeDataElems(const char *str,int *off);
45 static VISASampler3DSubOpCode  str2SampleOpcode(const char* str);
46 static int64_t                 hexToInt(const char *hex_str, int str_len);
47 static MEDIA_LD_mod            mediaMode(const char* str);
48 static OutputFormatControl     avs_control(const char* str);
49 static AVSExecMode             avsExecMode(const char* str);
50 static unsigned char           FENCEOptions(const char *str);
51 static COMMON_ISA_VME_OP_MODE  VMEType(const char *str);
52 static CHANNEL_OUTPUT_FORMAT   Get_Channel_Output(const char* str);
53 static void                    appendStringLiteralChar(char c, char *buf, size_t *len);
54 
55 #ifdef _MSC_VER
56 #include <io.h>
57 #pragma warning(disable:4102; disable:4244; disable:4267)
58 #endif
59 %}
60 
61 %option yylineno
62 
63 %x   eat_comment
64 %x   string_literal
65 
66 %%
67 
68 \n {
69       return NEWLINE;
70    }
71 
72 [ \t] { /*drop non-newline spaces*/}
73 "//"[^\n]* {
74         // drop comments
75         // TRACE("** COMMENT\n");
76         // CISAlval.string = strdup(yytext);
77         // return COMMENT_LINE;
78     }
79 
80 "/*"  BEGIN(eat_comment);
81 <eat_comment>[^*]* /* eat anything that is not a * */
82 <eat_comment>"*"+[^*/]*  /* eat up '*'s not followed by '/'s */
83 <eat_comment>"*"+"/"  BEGIN(INITIAL);
84 
85 
86 \" {CISAlval.strlit.len = 0; CISAlval.strlit.decoded[0] = 0; BEGIN(string_literal);}
87 <string_literal>{
88     \n                        YY_FATAL_ERROR("lexical error: newline in string literal");
89     <<EOF>>                   YY_FATAL_ERROR("lexical error: unterminated string (reached EOF)");
90     \\a                       {appendStringLiteralChar('\a',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
91     \\b                       {appendStringLiteralChar('\b',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
92     \\e                       {appendStringLiteralChar(0x1B,CISAlval.strlit.decoded,&CISAlval.strlit.len);}
93     \\f                       {appendStringLiteralChar('\f',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
94     \\n                       {appendStringLiteralChar('\n',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
95     \\r                       {appendStringLiteralChar('\r',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
96     \\t                       {appendStringLiteralChar('\t',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
97     \\v                       {appendStringLiteralChar('\v',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
98     \\"'"                     {appendStringLiteralChar('\'',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
99     \\"\""                    {appendStringLiteralChar('\"',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
100     \\"?"                     {appendStringLiteralChar('?',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
101     \\\\                      {appendStringLiteralChar('\\',CISAlval.strlit.decoded,&CISAlval.strlit.len);}
102     \\[0-9]{1,3} {
103         int val = 0;
104         for (int i = 1; i < yyleng; i++)
105             val = 8*val + yytext[i] - '0';
106         appendStringLiteralChar(val,CISAlval.strlit.decoded,&CISAlval.strlit.len);
107     }
108     \\x[0-9A-Fa-f]{1,2} {
109         int val = 0;
110         for (int i = 2; i < yyleng; i++) {
111             int dig =
112                 yytext[i] >= '0' && yytext[i] <= '9' ? yytext[i] - '0' :
113                 yytext[i] >= 'a' && yytext[i] <= 'f' ? yytext[i] - 'a' + 10 :
114                                                        yytext[i] - 'A' + 10;
115             val = 16*val + dig;
116         }
117         appendStringLiteralChar(val,CISAlval.strlit.decoded,&CISAlval.strlit.len);
118     }
119     \\.                       YY_FATAL_ERROR("lexical error: illegal escape sequence");
120     \"                        {CISAlval.string = strdup(CISAlval.strlit.decoded); BEGIN(INITIAL); return STRING_LIT;}
121     .                         {
122     /* important: this must succeed the exit rule above (\"); lex prefers the first match */
123         appendStringLiteralChar(yytext[0],CISAlval.strlit.decoded,&CISAlval.strlit.len);
124     }
125 }
126 
127 
128 "*" {TRACE("** TIMES");  return TIMES;}
129 "+" {TRACE("** PLUS");   return PLUS;}
130 "-" {TRACE("** MINUS");  return MINUS;}
131 "=" {TRACE("** EQUALS"); return EQUALS;}
132 "&" {TRACE("** AMP");    return AMP;}
133 "^" {TRACE("** CIRC");   return CIRC;}
134 "|" {TRACE("** PIPE");   return PIPE;}
135 "~" {TRACE("** TILDE");  return TILDE;}
136 "!" {TRACE("** BANG");   return BANG;}
137 
138 "<=" {TRACE("** LEQ"); return LEQ;}
139 ">=" {TRACE("** GEQ"); return GEQ;}
140 "==" {TRACE("** EQ");  return  EQ;}
141 "!=" {TRACE("** NEQ"); return NEQ;}
142 
143 
144 "." {TRACE("** DOT");     return DOT;}
145 "," {TRACE("** COMMA");   return COMMA;}
146 ";" {TRACE("** SEMI");    return SEMI;}
147 ":" {TRACE("** COLON");   return COLON;}
148 "/" {TRACE("** SLASH");    return SLASH;}
149 "%" {TRACE("** PERCENT");  return PERCENT;}
150 "?" {TRACE("** QUESTION"); return QUESTION;}
151 
152 "(" {TRACE("** LPAREN"); return LPAREN;}
153 ")" {TRACE("** RPAREN"); return RPAREN;}
154 "{" {TRACE("** LBRACE"); return LBRACE;}
155 "}" {TRACE("** RBRACE"); return RBRACE;}
156 "<" {TRACE("** LANGLE"); return LANGLE;}
157 ">" {TRACE("** RANGLE"); return RANGLE;}
158 "<<"  {TRACE("** SHL");  return SHL;}
159 ">>"  {TRACE("** SHRS"); return SHRS;}
160 ">>>" {TRACE("** SHRZ"); return SHRZ;}
161 
162 "r[" {TRACE("** IND_LBRACK"); return IND_LBRACK;}
163 "["  {TRACE("** LBRACK"); return LBRACK;}
164 "]"  {TRACE("** RBRACK"); return RBRACK;}
165 
166 
167 ".version"          {TRACE("** VERSION"); return DIRECTIVE_VERSION;}
168 ".decl"             {TRACE("** DECLARE"); return DIRECTIVE_DECL;}
169 ".funcdecl"         {TRACE("** FUNCTION DECLARE"); return DIRECTIVE_FUNCDECL;}
170 ".kernel_attr"      {TRACE("** KERNEL ATTR"); return DIRECTIVE_KERNEL_ATTR;}
171 ".input"            {TRACE("** INPUT"); return DIRECTIVE_INPUT;}
172 "."implicit[a-zA-Z0-9_\-$@?]* {
173         TRACE("**  DIRECTIVE_IMPLICIT");
174         CISAlval.string = strdup(yytext);
175         CISAlval.string[yyleng] = '\0';
176         return DIRECTIVE_IMPLICIT;
177     }
178 ".parameter"        {TRACE("** PARAMETER"); return DIRECTIVE_PARAMETER;}
179 ".function"         {TRACE("** FUNCTION"); return DIRECTIVE_FUNC;}
180 ".global_function"  {TRACE("** GLOBAL FUNCTION"); return DIRECTIVE_GLOBAL_FUNC;}
181 ".kernel"           {TRACE("** KERNEL NAME DIRECTIVE"); return DIRECTIVE_KERNEL;}
182 
183 num_elts[ ]*= {TRACE("** NUM_ELTS_EQ"); return NUM_ELTS_EQ;}
184 align[ ]*=    {TRACE("** ALIGN_EQ");    return ALIGN_EQ;}
185 offset[ ]*=   {TRACE("** OFFSET_EQ");   return OFFSET_EQ;}
186 size[ ]*=     {TRACE("** SIZE_EQ");     return SIZE_EQ;}
187 alias[ ]*=    {TRACE("** ALIAS_EQ");    return ALIAS_EQ;}
188 attrs[ ]*=     {TRACE("** ATTR_EQ");     return ATTR_EQ;}
189 v_name[ ]*=   {TRACE("** V_NAME_EQ");   return V_NAME_EQ;}
190 
191 v_type[ ]*=[ ]*G {TRACE("** V_TYPE_EQ_G"); return V_TYPE_EQ_G;}
192 v_type[ ]*=[ ]*A {TRACE("** V_TYPE_EQ_A"); return V_TYPE_EQ_A;}
193 v_type[ ]*=[ ]*P {TRACE("** V_TYPE_EQ_P"); return V_TYPE_EQ_P;}
194 v_type[ ]*=[ ]*S {TRACE("** V_TYPE_EQ_S"); return V_TYPE_EQ_S;}
195 v_type[ ]*=[ ]*T {TRACE("** V_TYPE_EQ_T"); return V_TYPE_EQ_T;}
196 
197 
198 "."(add|sub|inc|dec|min|max|xchg|cmpxchg|and|or|xor|minsint|maxsint|fmax|fmin|fcmpwr)   {
199         TRACE("** Atomic Operations");
200         CISAlval.atomic_op = str2atomic_opcode(yytext + 1);
201         return ATOMIC_SUB_OP;
202     }
203 
204 not|cbit|fbh|fbl|bfrev {
205         TRACE("** Unary Logic INST");
206         CISAlval.opcode = str2opcode(yytext);
207         return UNARY_LOGIC_OP;
208     }
209 
210 bfe {
211       TRACE("** Ternary Logic INST");
212       CISAlval.opcode = str2opcode(yytext);
213       return TERNARY_LOGIC_OP;
214   }
215 
216 bfi {
217       TRACE("** Quaternary Logic INST");
218       CISAlval.opcode = str2opcode(yytext);
219       return QUATERNARY_LOGIC_OP;
220 }
221 
222 
223 inv|log|exp|sqrt|rsqrt|sin|cos|sqrtm {
224          TRACE("** 2 operand math INST");
225          CISAlval.opcode = str2opcode(yytext);
226          return MATH2_OP;
227     }
228 
229 div|mod|pow|divm {
230         TRACE("** 3 operand math INST");
231         CISAlval.opcode = str2opcode(yytext);
232         return MATH3_OP;
233     }
234 
235 frc|lzd|rndd|rndu|rnde|rndz {
236         TRACE("** ARITH2_OP");
237         CISAlval.opcode = str2opcode(yytext);
238         return ARITH2_OP;
239     }
240 
241 add|avg|dp2|dp3|dp4|dph|line|mul|pow|mulh|sad2|plane {
242         TRACE("** ARITH3_OP");
243         CISAlval.opcode = str2opcode(yytext);
244         return ARITH3_OP;
245     }
246 
247 mad|lrp|sad2add|madw {
248         TRACE("** ARITH4_OP");
249         CISAlval.opcode = str2opcode(yytext);
250         return ARITH4_OP;
251     }
252 
253 and|or|xor|shl|shr|asr {
254         TRACE("** BINARY_LOGIC_OP");
255         CISAlval.opcode = str2opcode(yytext);
256         return BINARY_LOGIC_OP;
257     }
258 
259 rol|ror {
260         TRACE("** BINARY_LOGIC_OP");
261         CISAlval.opcode = str2opcode(yytext);
262         return BINARY_LOGIC_OP;
263     }
264 
265 dpas"."tf32"."tf32"."(1|2|4|8)"."[12345678] {
266         TRACE("** DPAS");
267         CISAlval.opcode = ISA_DPAS;
268         CISAlval.dpas_info.src1Precision = GenPrecision::TF32;
269         CISAlval.dpas_info.src2Precision = GenPrecision::TF32;
270         CISAlval.dpas_info.depth = (yytext[15] - '0');
271         CISAlval.dpas_info.count = (yytext[17] - '0');
272         return DPAS_OP;
273     }
274 dpas"."bf8"."bf8"."(1|2|4|8)"."[12345678] {
275         TRACE("** DPAS");
276         CISAlval.opcode = ISA_DPAS;
277         CISAlval.dpas_info.src1Precision = GenPrecision::BF8;
278         CISAlval.dpas_info.src2Precision = GenPrecision::BF8;
279         CISAlval.dpas_info.depth = (yytext[13] - '0');
280         CISAlval.dpas_info.count = (yytext[15] - '0');
281         return DPAS_OP;
282     }
283 
284 dp4a {
285         TRACE("** ARITH4_OP");
286         CISAlval.opcode = str2opcode(yytext);
287         return ARITH4_OP;
288     }
289 
290 dpas"."[sSuUbBHh][1248fF]"."[sSuUbBHh][1248fF]"."[1248]"."[12345678] {
291         TRACE("** DPAS");
292         CISAlval.opcode = ISA_DPAS;
293         CISAlval.dpas_info.src1Precision = str2Precision(yytext + 5, 2);
294         CISAlval.dpas_info.src2Precision = str2Precision(yytext + 8, 2);
295         CISAlval.dpas_info.depth = (yytext[11] - '0');
296         CISAlval.dpas_info.count = (yytext[13] - '0');
297         return DPAS_OP;
298     }
299 
300 dpasw"."[sSuUbBhH][1248fF]"."[sSuUbBhH][1248fF]"."[1248]"."[12345678] {
301         TRACE("** DPASW");
302         CISAlval.opcode = ISA_DPASW;
303         CISAlval.dpas_info.src1Precision = str2Precision(yytext + 6, 2);
304         CISAlval.dpas_info.src2Precision = str2Precision(yytext + 9, 2);
305         CISAlval.dpas_info.depth = (yytext[12] - '0');
306         CISAlval.dpas_info.count = (yytext[14] - '0');
307         return DPAS_OP;
308     }
309 
310 add3 {
311         TRACE("** ADD3 INST");
312         CISAlval.opcode = str2opcode(yytext);
313         return ARITH4_OP;
314     }
315 
316 add3\.o {
317         TRACE("** ADD3O INST");
318         CISAlval.opcode = str2opcode(yytext);
319         return ARITH4_OP;
320     }
321 
322 bfn"."x[[:xdigit:]]+ {
323         TRACE("** BFN INST");
324         CISAlval.bfn_info.func_ctrl = (uint8_t)hexToInt(yytext+5, yyleng-5);
325         return BFN_OP;
326     }
327 
328 qw_gather|qw_scatter {
329         TRACE("** qword gather/scatter INST");
330         CISAlval.opcode = str2opcode(yytext);
331         return QW_SCATTER_OP;
332     }
333 
334 bf_cvt {
335         TRACE("** bfloat16 conversion INST");
336         CISAlval.opcode = str2opcode(yytext);
337         return BF_CVT_OP;
338     }
339 
340 "."(fadd|fsub) {
341         TRACE("** Float Atomic add/sub");
342         CISAlval.atomic_op = str2atomic_opcode(yytext + 1);
343         return ATOMIC_SUB_OP;
344 }
345 
346 fcvt {
347     TRACE("** special float (bf8, etc) conversion INST");
348     CISAlval.opcode = str2opcode(yytext);
349     return FCVT_OP;
350 }
351 
352 srnd {
353     TRACE("** srnd INST");
354     CISAlval.opcode = str2opcode(yytext);
355     return ARITH3_OP;
356 }
357 
358 addc|subb {
359         TRACE("** MATH INST");
360         CISAlval.opcode = str2opcode(yytext);
361         return ARITH4_OP2;
362     }
363 
364 asin|acos|atan {
365         TRACE("** ANTI TRIGONOMETRIC INST");
366         CISAlval.opcode = str2opcode(yytext);
367         return ANTI_TRIG_OP;
368     }
369 
370 addr_add   {
371         TRACE("** Addr add INST");
372         CISAlval.opcode = str2opcode(yytext);
373         return ADDR_ADD_OP;
374     }
375 
376 sel {
377         TRACE("** Mod INST");
378         CISAlval.opcode = str2opcode(yytext);
379         return SEL_OP;
380     }
381 
382 min {
383         TRACE("** MIN INST");
384         CISAlval.opcode = ISA_FMINMAX;
385         return MIN_OP;
386     }
387 
388 max {
389         TRACE("** MAX INST");
390         CISAlval.opcode = ISA_FMINMAX;
391         return MAX_OP;
392     }
393 
394 mov {
395         TRACE("** MOV INST");
396         CISAlval.opcode = str2opcode(yytext);
397         return MOV_OP;
398     }
399 
400 movs {
401         TRACE("** MOVS INST");
402         CISAlval.opcode = str2opcode(yytext);
403         return MOVS_OP;
404     }
405 
406 setp {
407         TRACE("** SETP INST");
408         CISAlval.opcode = str2opcode(yytext);
409         return SETP_OP;
410     }
411 
412 cmp {
413         TRACE("** compare INST");
414         CISAlval.opcode = str2opcode(yytext);
415         return CMP_OP;
416     }
417 
418 svm_block_ld|svm_block_st|svm_scatter|svm_gather|svm_gather4scaled|svm_scatter4scaled|svm_atomic {
419         TRACE("** svm INST");
420         /// XXX: Piggyback svm sub-opcode as an opcode.
421         if (!strcmp(yytext, "svm_gather4scaled")) {CISAlval.opcode = (ISA_Opcode)SVM_GATHER4SCALED; return SVM_GATHER4SCALED_OP;}
422         if (!strcmp(yytext, "svm_scatter4scaled")) {CISAlval.opcode = (ISA_Opcode)SVM_SCATTER4SCALED; return SVM_SCATTER4SCALED_OP;}
423         if (!strcmp(yytext, "svm_block_ld")) CISAlval.opcode = (ISA_Opcode)SVM_BLOCK_LD;
424         if (!strcmp(yytext, "svm_block_st")) CISAlval.opcode = (ISA_Opcode)SVM_BLOCK_ST;
425         if (!strcmp(yytext, "svm_scatter" )) {CISAlval.opcode = (ISA_Opcode)SVM_SCATTER; return SVM_SCATTER_OP;}
426         if (!strcmp(yytext, "svm_gather"  )) {CISAlval.opcode = (ISA_Opcode)SVM_GATHER; return SVM_SCATTER_OP;}
427         if (!strcmp(yytext, "svm_atomic"  )) {CISAlval.opcode = (ISA_Opcode)SVM_ATOMIC; return SVM_ATOMIC_OP;}
428         return SVM_OP;
429     }
430 
431 lsc_load|lsc_load_quad|lsc_load_status {
432         TRACE("** lsc_load* INST");
433         CISAlval.lsc_subOpcode = str2lscop(yytext);
434         // this is set in the parser based on the SFID
435         // CISAlval.lsc_opcode = ISA_LSC_UNTYPED OR ISA_LSC_TYPED;
436         return LSC_LOAD_MNEMONIC;
437     }
438 lsc_load_strided {
439         TRACE("** lsc_load_strided INST");
440         CISAlval.lsc_subOpcode = str2lscop(yytext);
441         // this is set in the parser based on the SFID
442         // CISAlval.lsc_opcode = ISA_LSC_UNTYPED OR ISA_LSC_TYPED;
443         return LSC_LOAD_STRIDED_MNEMONIC;
444     }
445 lsc_load_block2d {
446         TRACE("** lsc_load_block2d INST");
447         CISAlval.lsc_subOpcode = str2lscop(yytext);
448         // this is set in the parser based on the SFID
449         // CISAlval.lsc_opcode = ISA_LSC_UNTYPED OR ISA_LSC_TYPED;
450         return LSC_LOAD_BLOCK2D_MNEMONIC;
451     }
452 
453 lsc_store|lsc_store_quad|lsc_store_uncompressed|lsc_ccs_update {
454         TRACE("** lsc_store* INST");
455         CISAlval.lsc_subOpcode = str2lscop(yytext);
456         // this is set in the parser based on the SFID
457         // CISAlval.lsc_opcode = ISA_LSC_UNTYPED OR ISA_LSC_TYPED;
458         return LSC_STORE_MNEMONIC;
459     }
460 lsc_store_strided {
461         TRACE("** lsc_store_strided INST");
462         CISAlval.lsc_subOpcode = str2lscop(yytext);
463         // this is set in the parser based on the SFID
464         // CISAlval.lsc_opcode = ISA_LSC_UNTYPED;
465         return LSC_STORE_STRIDED_MNEMONIC;
466     }
467 lsc_store_block2d {
468         TRACE("** lsc_store_block2d INST");
469         CISAlval.lsc_subOpcode = str2lscop(yytext);
470         // this is set in the parser based on the SFID
471         // CISAlval.lsc_opcode = ISA_LSC_UNTYPED OR ISA_LSC_TYPED;
472         return LSC_STORE_BLOCK2D_MNEMONIC;
473     }
474 
475 lsc_atomic_iinc|lsc_atomic_idec|lsc_atomic_iadd|lsc_atomic_load|lsc_atomic_store|lsc_atomic_iadd|lsc_atomic_isub|lsc_atomic_smin|lsc_atomic_smax|lsc_atomic_umin|lsc_atomic_umax|lsc_atomic_icas|lsc_atomic_fadd|lsc_atomic_fsub|lsc_atomic_fmin|lsc_atomic_fmax|lsc_atomic_fcas|lsc_atomic_and|lsc_atomic_xor|lsc_atomic_or|lsc_apndctr_atomic_add|lsc_apndctr_atomic_sub {
476         TRACE("** lsc_atomic INST");
477         CISAlval.lsc_subOpcode = str2lscop(yytext);
478         // this is set in the parser based on the SFID
479         // CISAlval.lsc_opcode = ISA_LSC_UNTYPED;
480         return LSC_ATOMIC_MNEMONIC;
481     }
482 lsc_read_state_info {
483         TRACE("** lsc_read_state_info INST");
484         CISAlval.lsc_subOpcode = LSC_READ_STATE_INFO;
485         return LSC_READ_STATE_INFO_MNEMONIC;
486     }
487 lsc_fence {
488         TRACE("** lsc_fence INST");
489         CISAlval.lsc_opcode = ISA_LSC_FENCE;
490         return LSC_FENCE_MNEMONIC;
491     }
492 
493 nbarrier\.signal {
494         TRACE("** nbarrier.signal INST");
495         CISAlval.opcode = ISA_NBARRIER;
496         return NBARRIER_SIGNAL;
497     }
498 
499 nbarrier\.wait {
500         TRACE("** nbarrier.wait INST");
501         CISAlval.opcode = ISA_NBARRIER;
502         return NBARRIER_WAIT;
503     }
504 
505 oword_ld|oword_st|oword_ld_unaligned {
506         TRACE("** oword_load INST");
507         CISAlval.opcode = str2opcode(yytext);
508         return OWORD_OP;
509     }
510 
511 media_ld|media_st {
512         TRACE("** media INST");
513         CISAlval.opcode = str2opcode(yytext);
514         return MEDIA_OP;
515     }
516 
517 gather|scatter {
518         TRACE("** gather/scatter INST");
519         CISAlval.opcode = str2opcode(yytext);
520         return SCATTER_OP;
521     }
522 
523 gather4_typed|scatter4_typed {
524         TRACE("** gather/scatter typed INST");
525         CISAlval.opcode = str2opcode(yytext);
526         return SCATTER_TYPED_OP;
527     }
528 
529 gather_scaled|scatter_scaled {
530         TRACE("** scaled gather/scatter INST");
531         CISAlval.opcode = str2opcode(yytext);
532         return SCATTER_SCALED_OP;
533     }
534 
535 gather4_scaled|scatter4_scaled {
536         TRACE("** scaled gather/scatter INST");
537         CISAlval.opcode = str2opcode(yytext);
538         return SCATTER4_SCALED_OP;
539     }
540 
541 barrier {
542         TRACE("** barrier INST");
543         CISAlval.opcode = str2opcode(yytext);
544         return BARRIER_OP;
545     }
546 
547 sbarrier\.signal {
548         TRACE("** sbarrier.signal INST");
549         CISAlval.opcode = ISA_SBARRIER;
550         return SBARRIER_SIGNAL;
551     }
552 
553 sbarrier\.wait {
554         TRACE("** sbarrier.wait INST");
555         CISAlval.opcode = ISA_SBARRIER;
556         return SBARRIER_WAIT;
557     }
558 
559 sampler_cache_flush {
560         TRACE("** sampler_cache_flush INST");
561         CISAlval.opcode = str2opcode(yytext);
562         return CACHE_FLUSH_OP;
563     }
564 
565 wait {
566         TRACE("** wait INST");
567         CISAlval.opcode = str2opcode(yytext);
568         return WAIT_OP;
569     }
570 
571 fence_global {
572         TRACE("** fence global INST");
573         CISAlval.opcode = str2opcode("fence");
574         return FENCE_GLOBAL_OP;
575     }
576 fence_local {
577         TRACE("** fence local INST");
578         CISAlval.opcode = str2opcode("fence");
579         return FENCE_LOCAL_OP;
580     }
581 
582 fence_sw {
583         TRACE("** fence SW INST");
584         CISAlval.opcode = str2opcode("fence");
585         return FENCE_SW_OP;
586     }
587 
588 yield {
589         TRACE("** yield INST");
590         CISAlval.opcode = str2opcode(yytext);
591         return YIELD_OP;
592     }
593 
594 dword_atomic {
595         TRACE("** atomic INST");
596         CISAlval.opcode = str2opcode(yytext);
597         return DWORD_ATOMIC_OP;
598     }
599 
600 typed_atomic {
601         TRACE("** typed atomic INST");
602         CISAlval.opcode = str2opcode(yytext);
603         return TYPED_ATOMIC_OP;
604     }
605 
606 sample|load {
607         TRACE("** sample INST");
608         CISAlval.opcode = str2opcode(yytext);
609         return SAMPLE_OP;
610     }
611 sample_unorm {
612         TRACE("** sample INST");
613         CISAlval.opcode = str2opcode(yytext);
614         return SAMPLE_UNORM_OP;
615     }
616 
617 vme_ime {
618         TRACE("** VME_IME INST");
619         CISAlval.opcode = str2opcode(yytext);
620         return VME_IME_OP;
621     }
622 vme_sic {
623         TRACE("** VME_SIC INST");
624         CISAlval.opcode = str2opcode(yytext);
625         return VME_SIC_OP;
626     }
627 vme_fbr {
628         TRACE("** VME_FBR INST");
629         CISAlval.opcode = str2opcode(yytext);
630         return VME_FBR_OP;
631     }
632 
633 jmp|goto {
634         TRACE("** branch INST");
635         CISAlval.opcode = str2opcode(yytext);
636         return BRANCH_OP;
637     }
638 
639 ret|fret {
640         TRACE("** return INST");
641         CISAlval.opcode = str2opcode(yytext);
642         return RET_OP;
643 }
644 
645 call {
646         TRACE("** call INST");
647         CISAlval.cisa_call.opcode = ISA_CALL;
648         CISAlval.cisa_call.is_fccall = false;
649         return CALL_OP;
650 }
651 
652 fccall {
653         TRACE("** fccall INST");
654         CISAlval.cisa_call.opcode = ISA_CALL;
655         CISAlval.cisa_call.is_fccall = true;
656         return CALL_OP;
657 }
658 
659 fcall {
660    TRACE("** function call INST");
661         CISAlval.opcode = ISA_FCALL;
662         return FCALL;
663 }
664 
665 ifcall {
666         TRACE("** indirect call INST");
667         CISAlval.opcode = ISA_IFCALL;
668         return IFCALL;
669     }
670 
671 faddr {
672         TRACE("** function address INST");
673         CISAlval.opcode = ISA_FADDR;
674         return FADDR;
675     }
676 
677 switchjmp {
678         TRACE("** branch INST");
679         CISAlval.opcode = str2opcode(yytext);
680         return SWITCHJMP_OP;
681     }
682 
683 raw_send {
684        TRACE("** RAW_SEND");
685        CISAlval.opcode = ISA_RAW_SEND;
686        return RAW_SEND_STRING;
687     }
688 
689 raw_sendc {
690         TRACE("** RAW_SENDC");
691         CISAlval.opcode = ISA_RAW_SEND;
692         return RAW_SENDC_STRING;
693     }
694 
695 raw_sends {
696         TRACE("** RAW_SENDS");
697         CISAlval.opcode = ISA_RAW_SENDS;
698         return RAW_SENDS_STRING;
699     }
700 
701 raw_sends_eot {
702         TRACE("** RAW_SENDS_EOT");
703         CISAlval.opcode = ISA_RAW_SENDS;
704         return RAW_SENDS_EOT_STRING;
705     }
706 
707 raw_sendsc {
708         TRACE("** RAW_SENDSC");
709         CISAlval.opcode = ISA_RAW_SENDS;
710         return RAW_SENDSC_STRING;
711     }
712 
713 raw_sendsc_eot {
714         TRACE("** RAW_SENDSC_EOT");
715         CISAlval.opcode = ISA_RAW_SENDS;
716         return RAW_SENDSC_EOT_STRING;
717     }
718 
719 
720 avs {
721         TRACE("** AVS INST");
722         CISAlval.opcode = str2opcode(yytext);
723         return AVS_OP;
724     }
725 
726 (FILE|\.file) {
727         // FIXME: need to retire FILE and LOC because
728         // they will confict with identifiers
729         // retain .file and migrate to that
730         TRACE("** FILE");
731         CISAlval.opcode = str2opcode("file");
732         return FILE_OP;
733     }
734 
735 (LOC|\.loc) {
736         // FIXME: same as FILE above...
737         TRACE("** LOC");
738         CISAlval.opcode = str2opcode("loc");
739         return LOC_OP;
740     }
741 
742 sample_3d|sample_b|sample_l|sample_c|sample_d|sample_b_c|sample_l_c|sample_d_c|sample_lz|sample_c_lz {
743         TRACE("** SAMPLE_3D");
744         CISAlval.sample3DOp = str2SampleOpcode(yytext);
745         return SAMPLE_3D_OP;
746     }
747 
748 
749 load_3d|load_mcs|load_2dms_w|load_lz {
750         TRACE("** LOAD_3D");
751         CISAlval.sample3DOp = str2SampleOpcode(yytext);
752         return LOAD_3D_OP;
753     }
754 
755 sample4|sample4_c|sample4_po|sample4_po_c {
756         TRACE("** SAMPLE4_3D");
757         CISAlval.sample3DOp = str2SampleOpcode(yytext);
758         return SAMPLE4_3D_OP;
759     }
760 
761 resinfo {
762         TRACE("** RESINFO_3D");
763         CISAlval.opcode = str2opcode("info_3d");
764         return RESINFO_OP_3D;
765     }
766 
767 sampleinfo {
768         TRACE("** SAMPLEINFO_3D");
769         CISAlval.opcode = str2opcode("info_3d");
770         return SAMPLEINFO_OP_3D;
771     }
772 
773 rt_write_3d {
774         TRACE("** RTWRITE_3D");
775         CISAlval.opcode = str2opcode("rt_write_3d");
776         return RTWRITE_OP_3D;
777     }
778 
779 urb_write_3d {
780         TRACE("** URBWRITE_3D");
781         CISAlval.opcode = str2opcode("urb_write_3d");
782         return URBWRITE_OP_3D;
783     }
784 
785 lifetime"."start {
786         TRACE("** Lifetime.start");
787         CISAlval.opcode = str2opcode("lifetime");
788         return LIFETIME_START_OP;
789     }
790 
791 lifetime"."end {
792         TRACE("** Lifetime.end");
793         CISAlval.opcode = str2opcode("lifetime");
794         return LIFETIME_END_OP;
795     }
796 
797 ^[a-zA-Z_$@?][a-zA-Z0-9_\-$@?]*: {
798         TRACE("**  LABEL");
799         CISAlval.string = strdup(yytext);
800         CISAlval.string[yyleng - 1] = '\0';
801         return LABEL;
802     }
803 
804 
805 
806 "."(nomod|modified|top|bottom|top_mod|bottom_mod) {
807         TRACE("** MEDIA MODE :");
808         CISAlval.media_mode = mediaMode(yytext+1);
809         return MEDIA_MODE;
810     }
811 
812 AVS_(16|8)_(FULL|DOWN_SAMPLE) {
813       TRACE("** Output Format Control");
814       CISAlval.cntrl = avs_control(yytext);
815       return CNTRL;
816     }
817 
818 AVS_(4|8|16)x(4|8) {
819       TRACE("** AVS Exec Mode");
820       CISAlval.execMode = avsExecMode(yytext);
821       return EXECMODE;
822     }
823 
824 "."mod {
825         TRACE("** O MODE :");
826         CISAlval.oword_mod = true;
827         return OWORD_MODIFIER;
828     }
829 
830 [0-9]+         {
831         TRACE("** DEC_LIT");
832         CISAlval.intval = atoi(yytext);
833         return DEC_LIT;
834     }
835 
836 0[xX][[:xdigit:]]+ {
837         TRACE("** HEX_LIT");
838         CISAlval.intval = hexToInt(yytext+2, yyleng-2);
839         return HEX_LIT;
840     }
841 
842 [0-9]+"."[0-9]+":f" {
843         TRACE("** F32_LIT");
844         CISAlval.fltval = (float)atof(yytext);
845         return F32_LIT;
846     }
847 
848 ([0-9]+|[0-9]+"."[0-9]+)[eE]("+"|"-")[0-9]+":f" {
849         TRACE("** F32_LIT");
850         CISAlval.fltval = (float)atof(yytext);
851         return F32_LIT;
852     }
853 
854 [0-9]+"."[0-9]+":df" {
855         TRACE("** F64_LIT");
856         CISAlval.fltval = atof(yytext);
857         return F64_LIT;
858     }
859 
860 ([0-9]+|[0-9]+"."[0-9]+)[eE]("+"|"-")[0-9]+":df" {
861         TRACE("** F64_LIT");
862         CISAlval.fltval = atof(yytext);
863         return F64_LIT;
864     }
865 
866 
867 
868 type[ ]*=[ ]*(ud|d|uw|w|ub|b|df|f|bool|uq|q|UD|D|UW|W|UB|B|DF|F|Bool|BOOL|UQ|Q|hf|HF|bf|BF) {
869         TRACE("** TYPE");
870         CISAlval.type = str2type(yytext, yyleng);
871         return DECL_DATA_TYPE;
872     }
873 
874 2GRF {
875         /* other cases are handled as VAR */
876         TRACE("** AlignType - 2GRF");
877         CISAlval.align = ALIGN_2_GRF;
878         // fprintf(stderr, "%s", "2GRF symbol is deprecated; please use GRFx2");
879         return ALIGN_KEYWORD;
880 }
881 
882 32word {
883         /* other cases are handled as VAR */
884         TRACE("** AlignType - 32word");
885         CISAlval.align = ALIGN_32WORD;
886         return ALIGN_KEYWORD;
887 }
888 64word {
889         /* other cases are handled as VAR */
890         TRACE("** AlignType - 64word");
891         CISAlval.align = ALIGN_64WORD;
892         return ALIGN_KEYWORD;
893 }
894 
895 "(-)"    {TRACE("** SRCMOD_NEG"); return SRCMOD_NEG;}
896 "(abs)"  {TRACE("** SRCMOD_ABS"); return SRCMOD_ABS;}
897 "(-abs)" {TRACE("** SRCMOD_NEGABS"); return SRCMOD_NEGABS;}
898 "(~)"    {TRACE("** SRCMOD_NOT"); return SRCMOD_NOT;}
899 
900 ".sat"   {TRACE("** SAT");  return SAT;}
901 
902 ".pixel_null_mask" {
903         TRACE("** PIXEL_NULL_MASK");
904         return PIXEL_NULL_MASK;
905     }
906 
907 ".cps" {
908         TRACE("** CPS LOD Compensation enable");
909         return CPS;
910     }
911 
912 ".divS" {
913         TRACE("** non-uniform Sampler State");
914         return NON_UNIFORM_SAMPLER;
915     }
916 
917 
918 "."(eq|ne|gt|ge|lt|le|EQ|NE|GT|GE|LT|LE) {
919         TRACE("** COND_MOD");
920         CISAlval.cond_mod = str2cond(yytext+1);
921         return COND_MOD;
922     }
923 
924 :(df|DF)  {
925         TRACE("** DFTYPE");
926         CISAlval.type = str2type(yytext, yyleng);
927         return DFTYPE;
928     }
929 
930 :(f|F)      {
931         TRACE("** FTYPE");
932         CISAlval.type = str2type(yytext, yyleng);
933         return FTYPE;
934     }
935 
936 :(hf|HF)  {
937         TRACE("** HFTYPE");
938         CISAlval.type = str2type(yytext, yyleng);
939         return HFTYPE;
940     }
941 
942 :(ud|d|uw|w|ub|b|bool|UD|D|UW|W|UB|B|BOOL|Bool|q|uq|Q|UQ|hf|HF)  {
943         TRACE("** DATA TYPE");
944         CISAlval.type = str2type(yytext, yyleng);
945         return ITYPE;
946     }
947 
948 :(v|vf|V|VF|uv)  {
949         TRACE("** VTYPE");
950         CISAlval.type = str2type(yytext, yyleng);
951         return VTYPE;
952     }
953 
954 :a(64|32|16) {
955         TRACE("** LSC_ADDR_SIZE_TK");
956         if (yytext[2]  == '6')
957             CISAlval.lsc_addr_size = LSC_ADDR_SIZE_64b;
958         else if (yytext[2]  == '3')
959             CISAlval.lsc_addr_size = LSC_ADDR_SIZE_32b;
960         else
961             CISAlval.lsc_addr_size = LSC_ADDR_SIZE_16b;
962         return LSC_ADDR_SIZE_TK;
963     }
964 
965 
966 :((d64|d32|d16|d8|d8c32|d16c32|d16c32h)|(u64|u32|u16|u8|u8c32|u16c32|u16c32h))(x(64|32|16|8|4|3|2|1))?t? {
967         TRACE("** LSC_DATA_SHAPE_TK");
968 
969         int off = 1;
970         LSC_DATA_SIZE dsz = decodeDataSizePrefix(yytext,&off);
971         LSC_DATA_ELEMS vsz = decodeDataElems(yytext,&off);
972         LSC_DATA_ORDER trans = LSC_DATA_ORDER_NONTRANSPOSE;
973         if (yytext[off] == 't') {
974             trans = LSC_DATA_ORDER_TRANSPOSE;
975         }
976 
977         CISAlval.lsc_data_shape.size = dsz;
978         CISAlval.lsc_data_shape.elems = vsz;
979         CISAlval.lsc_data_shape.order = trans;
980 
981         return LSC_DATA_SHAPE_TK;
982     }
983 
984 :((d64|d32|d16|d8|d8c32|d16c32|d16c32h)|(u64|u32|u16|u8|u8c32|u16c32|u16c32h))\.((xy?z?w?)|(yz?w?)|(zw?)|(w)) {
985         TRACE("** LSC_DATA_SHAPE_TK_CHMASK");
986         int off = 1; // if there's an x (vector suffix), it starts here
987         LSC_DATA_SIZE dsz = decodeDataSizePrefix(yytext, &off);
988         off++; // skip the .
989         int chmask = 0;
990         while (off < yyleng) {
991             switch (yytext[off++]) {
992             case 'x': chmask |= LSC_DATA_CHMASK_X; break;
993             case 'y': chmask |= LSC_DATA_CHMASK_Y; break;
994             case 'z': chmask |= LSC_DATA_CHMASK_Z; break;
995             case 'w': chmask |= LSC_DATA_CHMASK_W; break;
996             default: break; // unreachable
997             }
998         }
999         CISAlval.lsc_data_shape.size = dsz;
1000         CISAlval.lsc_data_shape.order = LSC_DATA_ORDER_NONTRANSPOSE;
1001         CISAlval.lsc_data_shape.chmask = chmask;
1002         return LSC_DATA_SHAPE_TK_CHMASK;
1003     }
1004 
1005 :((d64|d32|d16|d8|d8c32|d16c32|d16c32h)|(u64|u32|u16|u8|u8c32|u16c32|u16c32h))"."([1-9][0-9]*x)?([1-9][0-9]*x)([1-9][0-9]*)(n|t)?(n|t)? {
1006         TRACE("** LSC_DATA_SHAPE_TK_BLOCK2D");
1007 
1008         int off = 0;
1009         off++; // skip 'd' prefix
1010 
1011         LSC_DATA_SIZE dsz = decodeDataSizePrefix(yytext, &off);
1012 
1013         auto parseNextInt =
1014             [&]() {
1015                 if (!isdigit(yytext[off]))
1016                     YY_FATAL_ERROR("LEXICAL SPEC ERROR (should be digit)");
1017                 int val = 0;
1018                 while (isdigit(yytext[off]))
1019                     val = 10*val + yytext[off++] - '0';
1020                 return val;
1021             };
1022 
1023         off++; // skip '.'
1024         // e.g.  d8.2x32x32nn or d8.32x64 (implicitly .1x32x64)
1025 
1026         int numBlocks = 1;
1027         int width = parseNextInt(); // width
1028         off++; // 'x'
1029         int height = parseNextInt(); // num blocks or height
1030         if (yytext[off] == 'x') {
1031             // e.g. 2x32x32...: arrlen x width x height
1032             off++;
1033             numBlocks = width;
1034             width = height;
1035             height = parseNextInt();
1036         } // else: short form: e.g. 32x32 (width x height)
1037         LSC_DATA_ORDER dord = LSC_DATA_ORDER_NONTRANSPOSE;
1038         bool vnni = false;
1039         if (yytext[off] == 'n' || yytext[off] == 't') {
1040             dord = yytext[off] == 't' ?
1041                 LSC_DATA_ORDER_TRANSPOSE : LSC_DATA_ORDER_NONTRANSPOSE;
1042             off++;
1043             if (yytext[off] == 'n' || yytext[off] == 't') {
1044                 vnni = yytext[off] == 't';
1045                 off++;
1046             }
1047         }
1048         if (yytext[off] != 0)
1049             YY_FATAL_ERROR("LEXICAL SPEC ERROR (should NUL)");
1050 
1051         CISAlval.lsc_data_shape2d.size = dsz;
1052         CISAlval.lsc_data_shape2d.order = dord;
1053         CISAlval.lsc_data_shape2d.blocks = numBlocks;
1054         CISAlval.lsc_data_shape2d.width = width;
1055         CISAlval.lsc_data_shape2d.height = height;
1056         CISAlval.lsc_data_shape2d.vnni = vnni;
1057 
1058         return LSC_DATA_SHAPE_TK_BLOCK2D;
1059     }
1060 
1061 "."(df|uc|ca|wb|wt|st|cc|ri) {
1062         if (strcmp(yytext+1,"df") == 0) {
1063             CISAlval.lsc_caching_opt = LSC_CACHING_DEFAULT;
1064         } else if (strcmp(yytext+1,"uc") == 0) {
1065             CISAlval.lsc_caching_opt = LSC_CACHING_UNCACHED;
1066         } else if (strcmp(yytext+1,"ca") == 0) {
1067             CISAlval.lsc_caching_opt = LSC_CACHING_CACHED;
1068         } else if (strcmp(yytext+1,"wb") == 0) {
1069             CISAlval.lsc_caching_opt = LSC_CACHING_WRITEBACK;
1070         } else if (strcmp(yytext+1,"wt") == 0) {
1071             CISAlval.lsc_caching_opt = LSC_CACHING_WRITETHROUGH;
1072         } else if (strcmp(yytext+1,"st") == 0) {
1073             CISAlval.lsc_caching_opt = LSC_CACHING_STREAMING;
1074         } else { /* ri */
1075             CISAlval.lsc_caching_opt = LSC_CACHING_READINVALIDATE;
1076         }
1077         return LSC_CACHING_OPT;
1078     }
1079 
1080 flat   {return LSC_AM_FLAT;}
1081 bti    {return LSC_AM_BTI;}
1082 ss     {return LSC_AM_SS;}
1083 bss    {return LSC_AM_BSS;}
1084 
1085 ".none" {
1086         CISAlval.lsc_fence_op = LSC_FENCE_OP_NONE;
1087         return LSC_FENCE_OP_TYPE;
1088     }
1089 ".evict" {
1090         CISAlval.lsc_fence_op = LSC_FENCE_OP_EVICT;
1091         return LSC_FENCE_OP_TYPE;
1092     }
1093 ".invalidate" {
1094         CISAlval.lsc_fence_op = LSC_FENCE_OP_INVALIDATE;
1095         return LSC_FENCE_OP_TYPE;
1096     }
1097 ".discard" {
1098         CISAlval.lsc_fence_op = LSC_FENCE_OP_DISCARD;
1099         return LSC_FENCE_OP_TYPE;
1100     }
1101 ".clean" {
1102         CISAlval.lsc_fence_op = LSC_FENCE_OP_CLEAN;
1103         return LSC_FENCE_OP_TYPE;
1104     }
1105 ".flushl3" {
1106         CISAlval.lsc_fence_op = LSC_FENCE_OP_FLUSHL3;
1107         return LSC_FENCE_OP_TYPE;
1108     }
1109 ".type6" {
1110         CISAlval.lsc_fence_op = LSC_FENCE_OP_TYPE6;
1111         return LSC_FENCE_OP_TYPE;
1112     }
1113 
1114 ".group" {
1115         CISAlval.lsc_scope = LSC_SCOPE_GROUP;
1116         return LSC_FENCE_SCOPE;
1117     }
1118 ".local" {
1119         CISAlval.lsc_scope = LSC_SCOPE_LOCAL;
1120         return LSC_FENCE_SCOPE;
1121     }
1122 ".tile" {
1123         CISAlval.lsc_scope = LSC_SCOPE_TILE;
1124         return LSC_FENCE_SCOPE;
1125     }
1126 ".gpu" {
1127         CISAlval.lsc_scope = LSC_SCOPE_GPU;
1128         return LSC_FENCE_SCOPE;
1129     }
1130 ".gpus" {
1131         CISAlval.lsc_scope = LSC_SCOPE_GPUS;
1132         return LSC_FENCE_SCOPE;
1133     }
1134 ".sysrel" {
1135         CISAlval.lsc_scope = LSC_SCOPE_SYSREL;
1136         return LSC_FENCE_SCOPE;
1137     }
1138 ".sysacq" {
1139         CISAlval.lsc_scope = LSC_SCOPE_SYSACQ;
1140         return LSC_FENCE_SCOPE;
1141     }
1142 
1143 ".ugml" {
1144         CISAlval.lsc_sfid = LSC_UGML;
1145         return LSC_SFID_UNTYPED_TOKEN;
1146     }
1147 ".ugm" {
1148         CISAlval.lsc_sfid = LSC_UGM;
1149         return LSC_SFID_UNTYPED_TOKEN;
1150     }
1151 ".slm" {
1152         CISAlval.lsc_sfid = LSC_SLM;
1153         return LSC_SFID_UNTYPED_TOKEN;
1154     }
1155 ".tgm" {
1156         CISAlval.lsc_sfid = LSC_TGM;
1157         return LSC_SFID_TYPED_TOKEN;
1158     }
1159 
1160 
1161 
1162 
1163 "."((R|r)((G|g)?(B|b)?(A|a)?)|(G|g)((B|b)?(A|a)?)|(B|b)((A|a)?)|(A|a))  {
1164         TRACE("** CHANNEL MASK");
1165         CISAlval.s_channel = ChannelMask::createFromString(yytext+1).getAPI();
1166         return SAMPLER_CHANNEL;
1167     }
1168 
1169 "."(16-full|16-downsampled|8-full|8-downsampled) {
1170         TRACE("** OUTPUT_FORMAT");
1171         CISAlval.s_channel_output = Get_Channel_Output(yytext+1);
1172         return CHANNEL_OUTPUT;
1173     }
1174 
1175 "."("<"[a-zA-Z]+">")+ {
1176         TRACE("** RTWRITE OPTION");
1177         CISAlval.string = strdup(yytext+1);
1178         return RTWRITE_OPTION;
1179     }
1180 
1181 ".any" {
1182         TRACE("** PRED_CNTL (.any)");
1183         CISAlval.pred_ctrl = PRED_CTRL_ANY;
1184         return PRED_CNTL;
1185     }
1186 ".all" {
1187         TRACE("** PRED_CNTL (.all)");
1188         CISAlval.pred_ctrl = PRED_CTRL_ALL;
1189         return PRED_CNTL;
1190     }
1191 
1192 
1193 %null {
1194         TRACE("** Built-in %%null");
1195         CISAlval.string = strdup(yytext);
1196         return BUILTIN_NULL;
1197     }
1198 
1199 %sizeof {
1200         TRACE("** Built-in %%sizeof");
1201         return BUILTIN_SIZEOF;
1202     }
1203 
1204 %DispatchSimd {
1205         TRACE("** Built-in %%DispatchSimd");
1206         return BUILTIN_DISPATCH_SIMD_SIZE;
1207     }
1208 
1209 
1210 %[[:alpha:]_][[:alnum:]_]* {
1211         // this matches %null, but lex prefers the first pattern
1212         TRACE("** Builtin-in variable");
1213         CISAlval.string = strdup(yytext);
1214         return BUILTIN;
1215     }
1216 
1217 [[:alpha:]_][[:alnum:]_]* {
1218         TRACE("** IDENTIFIER");
1219         CISAlval.string = strdup(yytext);
1220         return IDENT;
1221     }
1222 
1223 
1224 
1225 
1226 
1227 [^ \t\n]       {TRACE("** SPACE END"); return *yytext;}
1228 
1229 "."(E?I?S?C?R?(L1)?)     {
1230         TRACE("** FENCE Options");
1231 
1232         CISAlval.fence_options = FENCEOptions(yytext+1);
1233         return FENCE_OPTIONS;
1234     }
1235 
1236 [ \n\t]+"\\"\n {TRACE("** Multiple instructions in a line");}
1237 
1238 
1239 %%
1240 
1241 int yywrap() { return 1;}
1242 
1243 // convert "ud", "w" to Type_UD Type_W
1244 static VISA_Type str2type(const char *str, int str_len)
1245 {
1246     // find the starting of the type string
1247     int i;
1248     char *ty_str;
1249     char lowered[20];
1250 
1251     //lower the chars
1252     for (i = 0; i < str_len; i++) {
1253         lowered[i] = tolower(str[i]);
1254     }
1255     lowered[i] = '\0';
1256     ty_str = lowered + str_len;
1257 
1258     while (*ty_str != ' ' &&
1259            *ty_str != '=' &&
1260            *ty_str != ':' &&
1261            ty_str != lowered )
1262        ty_str--;
1263 
1264     ty_str++;
1265 
1266     // match string
1267     for (int i = 0; i < ISA_TYPE_NUM; i++) {
1268         if (strcmp(CISATypeTable[i].typeName, ty_str) == 0)
1269             return (VISA_Type)i;
1270     }
1271 
1272     return ISA_TYPE_NUM;
1273 }
1274 
1275 
1276 static GenPrecision str2Precision(const char *str, int str_len)
1277 {
1278     if (str_len == 2)
1279     {
1280         char c0 = tolower(str[0]);
1281         char c1 = str[1];
1282         if (c0 == 's')
1283         {
1284             switch (c1) {
1285             default: break; // fall-thru
1286             case '1' : return GenPrecision::S1;
1287             case '2' : return GenPrecision::S2;
1288             case '4' : return GenPrecision::S4;
1289             case '8' : return GenPrecision::S8;
1290             }
1291         } else if (c0 == 'u') {
1292             switch (c1) {
1293             default: break; // fall-thru
1294             case '1' : return GenPrecision::U1;
1295             case '2' : return GenPrecision::U2;
1296             case '4' : return GenPrecision::U4;
1297             case '8' : return GenPrecision::U8;
1298             }
1299         } else if (c0 == 'b') {
1300             c1 = tolower(c1);
1301             if (c1 == 'f') {
1302                return GenPrecision::BF16;
1303             }
1304         } else if (c0 == 'h') {
1305             c1 = tolower(c1);
1306             if (c1 == 'f') {
1307                 return GenPrecision::FP16;
1308             }
1309         }
1310     }
1311 
1312     YY_FATAL_ERROR("Invalid Gen Precision");
1313 
1314     return GenPrecision::INVALID;
1315 }
1316 
1317 static LSC_OP str2lscop(const char *str)
1318 {
1319     // could get called for typed, but untyped has all subops and
1320     // will return the correct subopcode.
1321     const auto &lsc_op = CISA_INST_table[ISA_LSC_UNTYPED];
1322     return (LSC_OP)lsc_op.getSubInstDescByName(str).subOpcode;
1323 }
1324 
1325 static LSC_DATA_SIZE decodeDataSizePrefix(const char *yytext, int *off) {
1326     LSC_DATA_SIZE dsz = LSC_DATA_SIZE_INVALID;
1327     *off += 1; // 'd' or 'u'
1328     if (strncmp(yytext + *off,"8c32", 4) == 0) {
1329         dsz = LSC_DATA_SIZE_8c32b;
1330         *off += 4;
1331     } else if (strncmp(yytext + *off, "16c32h", 6) == 0) {
1332         // must be above "u16c32" case (longest match first)
1333         dsz = LSC_DATA_SIZE_16c32bH;
1334         *off += 6;
1335     } else if (strncmp(yytext + *off, "16c32", 5) == 0) {
1336         dsz = LSC_DATA_SIZE_16c32b;
1337         *off += 5;
1338     } else if (strncmp(yytext + *off, "64", 2) == 0) {
1339         dsz = LSC_DATA_SIZE_64b;
1340         *off += 2;
1341     } else if (strncmp(yytext + *off, "32", 2) == 0) {
1342         dsz = LSC_DATA_SIZE_32b;
1343         *off += 2;
1344     } else if (strncmp(yytext + *off, "16", 2) == 0) {
1345         dsz = LSC_DATA_SIZE_16b;
1346         *off += 2;
1347     } else if (strncmp(yytext + *off, "8", 1) == 0) {
1348         dsz = LSC_DATA_SIZE_8b;
1349         *off += 1;
1350     } else {
1351         YY_FATAL_ERROR("decodeDataSizePrefix: lexical spec error (the pattern is busted)");
1352     }
1353     return dsz;
1354 }
1355 
1356 static LSC_DATA_ELEMS decodeDataElems(const char *str, int *off)
1357 {
1358     LSC_DATA_ELEMS vsz = LSC_DATA_ELEMS_1;
1359     if (yytext[*off] == 'x') {
1360         *off += 1;
1361         if (strncmp(yytext + *off,"64", 2) == 0) {
1362             vsz = LSC_DATA_ELEMS_64;
1363             *off += 2;
1364         } else if (strncmp(yytext + *off,"32", 2) == 0) {
1365             vsz = LSC_DATA_ELEMS_32;
1366             *off += 2;
1367         } else if (strncmp(yytext + *off,"16", 2) == 0) {
1368             vsz = LSC_DATA_ELEMS_16;
1369             *off += 2;
1370         } else if (yytext[*off] == '8') {
1371             vsz = LSC_DATA_ELEMS_8;
1372             *off += 1;
1373         } else if (yytext[*off] == '4') {
1374             vsz = LSC_DATA_ELEMS_4;
1375             *off += 1;
1376         } else if (yytext[*off] == '3') {
1377             vsz = LSC_DATA_ELEMS_3;
1378             *off += 1;
1379         } else if (yytext[*off] == '2') {
1380             vsz = LSC_DATA_ELEMS_2;
1381             *off += 1;
1382         } else if (yytext[*off] == '1') {
1383             vsz = LSC_DATA_ELEMS_1;
1384             *off += 1;
1385         } else {
1386             YY_FATAL_ERROR("decodeDataElems: lexical spec error (the pattern is busted)");
1387         }
1388     }
1389     return vsz;
1390 }
1391 
1392 // convert "z" to Mod_z
1393 static VISA_Cond_Mod str2cond(const char *str)
1394 {
1395     for (int i = 0; i < ISA_CMP_UNDEF; i++)
1396         if (strcmp(Rel_op_str[i], str) == 0)
1397             return (VISA_Cond_Mod)i;
1398 
1399     YY_FATAL_ERROR("Invalid Data Type");
1400 
1401     return ISA_CMP_UNDEF;
1402 }
1403 
1404 static unsigned hexCharToDigit(char d)
1405 {
1406     if (d >= '0' && d <= '9')
1407         return d - '0';
1408     else if (d >= 'a' && d <= 'f')
1409         return d - 'a' + 10;
1410     else if (d >= 'A' && d <= 'F')
1411         return d - 'A' + 10;
1412 
1413     YY_FATAL_ERROR("lexical error: invalid hex digit");
1414 
1415     return 0;
1416 }
1417 
1418 // convert hex string to int
1419 static int64_t hexToInt(const char *hex_str, int str_len)
1420 {
1421     if (str_len > 16) { // make sure is within 32 bits
1422         YY_FATAL_ERROR("lexical error: hex literal too long");
1423     }
1424 
1425     uint64_t result = 0;
1426 
1427     // starting from the last digit
1428     for (int i = 0; i < str_len; i++)
1429         result += (uint64_t)hexCharToDigit(*(hex_str+str_len-1-i)) << (i*4);
1430 
1431     return (int64_t)result;
1432 }
1433 
1434 // convert str to its corresponding opcode
1435 static ISA_Opcode str2opcode(const char *op_str)
1436 {
1437     for (int i = 0; i < ISA_NUM_OPCODE; i++)
1438         if (strcmp(ISA_Inst_Table[i].str, op_str) == 0)
1439             return ISA_Inst_Table[i].op;
1440 
1441     YY_FATAL_ERROR("Invalid OpCode");
1442 
1443     return ISA_RESERVED_0;
1444 }
1445 
1446 static VISASampler3DSubOpCode str2SampleOpcode(const char *str)
1447 {
1448     VISASampler3DSubOpCode op = getSampleOpFromName(str);
1449     if (op >= 0)
1450         return op;
1451 
1452     YY_FATAL_ERROR("Invalid 3D Sample OpCode");
1453 
1454     return VISA_3D_TOTAL_NUM_OPS;
1455 }
1456 
1457 static VISAAtomicOps str2atomic_opcode(const char *op_str)
1458 {
1459     for (unsigned i = 0; i < ATOMIC_UNDEF; ++i)
1460         if (strcmp(CISAAtomicOpNames[i], op_str) == 0)
1461             return static_cast<VISAAtomicOps>(i);
1462 
1463     YY_FATAL_ERROR("Invalid Atomic OpCode");
1464 
1465     return ATOMIC_UNDEF;
1466 }
1467 
1468 // convert str to its corresponding media load mode
1469 static MEDIA_LD_mod mediaMode(const char *str)
1470 {
1471     for (int i = 0; i < MEDIA_LD_Mod_NUM; i++)
1472         if (!strcmp(media_ld_mod_str[i], str))
1473             return (MEDIA_LD_mod)i;
1474 
1475     YY_FATAL_ERROR("Invalid Medial Mode");
1476 
1477     return MEDIA_LD_nomod;
1478 }
1479 
1480 // convert str to its corresponding avs output format control
1481 static OutputFormatControl avs_control(const char* str)
1482 {
1483     for (int i = 0; i < 4; i++)
1484         if (!strcmp(avs_control_str[i], str))
1485             return (OutputFormatControl)i;
1486 
1487     YY_FATAL_ERROR("Invalid AVS Control");
1488 
1489     return AVS_16_FULL;
1490 }
1491 
1492 static AVSExecMode avsExecMode(const char* str)
1493 {
1494     for (int i = 0; i < 3; i++)
1495         if (!strcmp(avs_exec_mode[i], str))
1496             return (AVSExecMode)i;
1497 
1498     YY_FATAL_ERROR("Invalid AVS Exec Mode");
1499 
1500     return AVS_16x4;
1501 }
1502 
1503 static unsigned char FENCEOptions(const char *str)
1504 {
1505     int count = strlen(str);
1506     unsigned char result=0;
1507     /*
1508         Bit 0: commit enable
1509         Bit 1: flush instruction cache if set.
1510         Bit 2: flush sampler cache if set.
1511         Bit 3: flush constant cache if set.
1512         Bit 4: flush read-write cache if set.
1513         Bit 5: reserved (global/SLM is determined by opcode)
1514         Bit 6: flush L1
1515     */
1516     for(int i = 0; i < count; i++)
1517     {
1518         if (str[i] == 'E')
1519         {
1520             result |= 1;
1521         }
1522         else if(str[i] == 'I')
1523         {
1524             result |= (1<<1);
1525         }
1526         else if(str[i] == 'S')
1527         {
1528             result |= (1<<2);
1529         }
1530         else if(str[i] == 'C')
1531         {
1532             result |= (1<<3);
1533         }
1534         else if(str[i] == 'R')
1535         {
1536             result |= (1<<4);
1537         }
1538         else if (str[i] == 'L' && i + 1 < count && str[i+1] == '1')
1539         {
1540             result |= (1<<6);
1541         }
1542     }
1543 
1544     return result;
1545 }
1546 
1547 static COMMON_ISA_VME_OP_MODE VMEType(const char* str)
1548 {
1549     for (int i = 0; i < VME_OP_MODE_NUM; i++)
1550         if (!strcmp(vme_op_mode_str[i], str))
1551             return (COMMON_ISA_VME_OP_MODE)i;
1552 
1553     YY_FATAL_ERROR("Invalid Media Mode");
1554 
1555     return VME_OP_MODE_NUM;
1556 }
1557 
1558 static CHANNEL_OUTPUT_FORMAT Get_Channel_Output(const char* str)
1559 {
1560     for (int i = 0; i < CHANNEL_OUTPUT_NUM; i++)
1561     {
1562         if (!strcmp(sampler_channel_output_str[i], str))
1563         {
1564             return (CHANNEL_OUTPUT_FORMAT)i;
1565         }
1566     }
1567 
1568     YY_FATAL_ERROR("Invalid channel output format\n");
1569     YY_FATAL_ERROR(str);
1570     return CHANNEL_16_BIT_FULL;
1571 }
1572 
1573 static void appendStringLiteralChar(char c, char *buf, size_t *len)
1574 {
1575     if (*len == sizeof(CISAlval.strlit)) {
1576         YY_FATAL_ERROR("string literal too long");
1577     }
1578     buf[(*len)++] = c;
1579     buf[*len] = 0;
1580 }
1581