1 %option yylineno 2 %{ 3 #include <string.h> 4 #include "gen4asm.h" 5 #include "gram.h" 6 #include "brw_defines.h" 7 8 #include "string.h" 9 int saved_state = 0; 10 extern char *input_filename; 11 12 /* Locations */ 13 int yycolumn = 1; 14 15 #define YY_NO_INPUT 16 #define YY_USER_ACTION \ 17 yylloc.first_line = yylloc.last_line = yylineno; \ 18 yylloc.first_column = yycolumn; \ 19 yylloc.last_column = yycolumn+yyleng-1; \ 20 yycolumn += yyleng; 21 22 %} 23 %x BLOCK_COMMENT 24 %x CHANNEL 25 %x LINENUMBER 26 %x FILENAME 27 %x REG 28 %x DOTSEL 29 30 %% 31 \/\/.*[\r\n] { yycolumn = 1; } /* eat up single-line comments */ 32 "\.kernel".*[\r\n] { yycolumn = 1; } 33 "\.end_kernel".*[\r\n] { yycolumn = 1; } 34 "\.code".*[\r\n] { yycolumn = 1; } 35 "\.end_code".*[\r\n] { yycolumn = 1; } 36 37 /* eat up multi-line comments, non-nesting. */ 38 \/\* { 39 saved_state = YYSTATE; 40 BEGIN(BLOCK_COMMENT); 41 } 42 <BLOCK_COMMENT>\*\/ { 43 BEGIN(saved_state); 44 } 45 <BLOCK_COMMENT>. { } 46 <BLOCK_COMMENT>[\r\n] { } 47 "#line"" "* { 48 yycolumn = 1; 49 saved_state = YYSTATE; 50 BEGIN(LINENUMBER); 51 } 52 <LINENUMBER>[0-9]+" "* { 53 yylineno = atoi (yytext) - 1; 54 BEGIN(FILENAME); 55 } 56 <FILENAME>\"[^\"]+\" { 57 char *name = malloc (yyleng - 1); 58 memmove (name, yytext + 1, yyleng - 2); 59 name[yyleng-1] = '\0'; 60 input_filename = name; 61 BEGIN(saved_state); 62 } 63 64 <CHANNEL>"x" { 65 yylval.integer = BRW_CHANNEL_X; 66 return X; 67 } 68 <CHANNEL>"y" { 69 yylval.integer = BRW_CHANNEL_Y; 70 return Y; 71 } 72 <CHANNEL>"z" { 73 yylval.integer = BRW_CHANNEL_Z; 74 return Z; 75 } 76 <CHANNEL>"w" { 77 yylval.integer = BRW_CHANNEL_W; 78 return W; 79 } 80 <CHANNEL>. { 81 yyless(0); 82 BEGIN(INITIAL); 83 } 84 85 /* used for both null send and null register. */ 86 "null" { return NULL_TOKEN; } 87 88 /* opcodes */ 89 "mov" { yylval.integer = BRW_OPCODE_MOV; return MOV; } 90 "frc" { yylval.integer = BRW_OPCODE_FRC; return FRC; } 91 "rndu" { yylval.integer = BRW_OPCODE_RNDU; return RNDU; } 92 "rndd" { yylval.integer = BRW_OPCODE_RNDD; return RNDD; } 93 "rnde" { yylval.integer = BRW_OPCODE_RNDE; return RNDE; } 94 "rndz" { yylval.integer = BRW_OPCODE_RNDZ; return RNDZ; } 95 "not" { yylval.integer = BRW_OPCODE_NOT; return NOT; } 96 "lzd" { yylval.integer = BRW_OPCODE_LZD; return LZD; } 97 "f16to32" { yylval.integer = BRW_OPCODE_F16TO32; return F16TO32; } 98 "f32to16" { yylval.integer = BRW_OPCODE_F32TO16; return F32TO16; } 99 "fbh" { yylval.integer = BRW_OPCODE_FBH; return FBH; } 100 "fbl" { yylval.integer = BRW_OPCODE_FBL; return FBL; } 101 102 "mad" { yylval.integer = BRW_OPCODE_MAD; return MAD; } 103 "lrp" { yylval.integer = BRW_OPCODE_LRP; return LRP; } 104 "bfe" { yylval.integer = BRW_OPCODE_BFE; return BFE; } 105 "bfi1" { yylval.integer = BRW_OPCODE_BFI1; return BFI1; } 106 "bfi2" { yylval.integer = BRW_OPCODE_BFI2; return BFI2; } 107 "bfrev" { yylval.integer = BRW_OPCODE_BFREV; return BFREV; } 108 "mul" { yylval.integer = BRW_OPCODE_MUL; return MUL; } 109 "mac" { yylval.integer = BRW_OPCODE_MAC; return MAC; } 110 "mach" { yylval.integer = BRW_OPCODE_MACH; return MACH; } 111 "line" { yylval.integer = BRW_OPCODE_LINE; return LINE; } 112 "sad2" { yylval.integer = BRW_OPCODE_SAD2; return SAD2; } 113 "sada2" { yylval.integer = BRW_OPCODE_SADA2; return SADA2; } 114 "dp4" { yylval.integer = BRW_OPCODE_DP4; return DP4; } 115 "dph" { yylval.integer = BRW_OPCODE_DPH; return DPH; } 116 "dp3" { yylval.integer = BRW_OPCODE_DP3; return DP3; } 117 "dp2" { yylval.integer = BRW_OPCODE_DP2; return DP2; } 118 119 "cbit" { yylval.integer = BRW_OPCODE_CBIT; return CBIT; } 120 "avg" { yylval.integer = BRW_OPCODE_AVG; return AVG; } 121 "add" { yylval.integer = BRW_OPCODE_ADD; return ADD; } 122 "addc" { yylval.integer = BRW_OPCODE_ADDC; return ADDC; } 123 "sel" { yylval.integer = BRW_OPCODE_SEL; return SEL; } 124 "and" { yylval.integer = BRW_OPCODE_AND; return AND; } 125 "or" { yylval.integer = BRW_OPCODE_OR; return OR; } 126 "xor" { yylval.integer = BRW_OPCODE_XOR; return XOR; } 127 "shr" { yylval.integer = BRW_OPCODE_SHR; return SHR; } 128 "shl" { yylval.integer = BRW_OPCODE_SHL; return SHL; } 129 "asr" { yylval.integer = BRW_OPCODE_ASR; return ASR; } 130 "cmp" { yylval.integer = BRW_OPCODE_CMP; return CMP; } 131 "cmpn" { yylval.integer = BRW_OPCODE_CMPN; return CMPN; } 132 "subb" { yylval.integer = BRW_OPCODE_SUBB; return SUBB; } 133 134 "send" { yylval.integer = BRW_OPCODE_SEND; return SEND; } 135 "sendc" { yylval.integer = BRW_OPCODE_SENDC; return SENDC; } 136 "nop" { yylval.integer = BRW_OPCODE_NOP; return NOP; } 137 "jmpi" { yylval.integer = BRW_OPCODE_JMPI; return JMPI; } 138 "if" { yylval.integer = BRW_OPCODE_IF; return IF; } 139 "iff" { yylval.integer = BRW_OPCODE_IFF; return IFF; } 140 "while" { yylval.integer = BRW_OPCODE_WHILE; return WHILE; } 141 "else" { yylval.integer = BRW_OPCODE_ELSE; return ELSE; } 142 "break" { yylval.integer = BRW_OPCODE_BREAK; return BREAK; } 143 "cont" { yylval.integer = BRW_OPCODE_CONTINUE; return CONT; } 144 "halt" { yylval.integer = BRW_OPCODE_HALT; return HALT; } 145 "msave" { yylval.integer = BRW_OPCODE_MSAVE; return MSAVE; } 146 "push" { yylval.integer = BRW_OPCODE_PUSH; return PUSH; } 147 "mrest" { yylval.integer = BRW_OPCODE_MRESTORE; return MREST; } 148 "pop" { yylval.integer = BRW_OPCODE_POP; return POP; } 149 "wait" { yylval.integer = BRW_OPCODE_WAIT; return WAIT; } 150 "do" { yylval.integer = BRW_OPCODE_DO; return DO; } 151 "endif" { yylval.integer = BRW_OPCODE_ENDIF; return ENDIF; } 152 "call" { yylval.integer = BRW_OPCODE_CALL; return CALL; } 153 "ret" { yylval.integer = BRW_OPCODE_RET; return RET; } 154 "brd" { yylval.integer = BRW_OPCODE_BRD; return BRD; } 155 "brc" { yylval.integer = BRW_OPCODE_BRC; return BRC; } 156 157 "pln" { yylval.integer = BRW_OPCODE_PLN; return PLN; } 158 159 /* send argument tokens */ 160 "mlen" { return MSGLEN; } 161 "rlen" { return RETURNLEN; } 162 "math" { if (IS_GENp(6)) { yylval.integer = BRW_OPCODE_MATH; return MATH_INST; } else return MATH; } 163 "sampler" { return SAMPLER; } 164 "gateway" { return GATEWAY; } 165 "read" { return READ; } 166 "write" { return WRITE; } 167 "urb" { return URB; } 168 "thread_spawner" { return THREAD_SPAWNER; } 169 "vme" { return VME; } 170 "cre" { return CRE; } 171 "data_port" { return DATA_PORT; } 172 173 "allocate" { return ALLOCATE; } 174 "used" { return USED; } 175 "complete" { return COMPLETE; } 176 "transpose" { return TRANSPOSE; } 177 "interleave" { return INTERLEAVE; } 178 179 ";" { return SEMICOLON; } 180 "(" { return LPAREN; } 181 ")" { return RPAREN; } 182 "<" { return LANGLE; } 183 ">" { return RANGLE; } 184 "{" { return LCURLY; } 185 "}" { return RCURLY; } 186 "[" { return LSQUARE; } 187 "]" { return RSQUARE; } 188 "," { return COMMA; } 189 "." { BEGIN(CHANNEL); return DOT; } 190 "+" { return PLUS; } 191 "-" { return MINUS; } 192 "*" { return MULTIPLY;} 193 "/" { return DIVIDE; } 194 ":" { return COLON; } 195 "=" { return EQ; } 196 "(abs)" { return ABS; } 197 198 /* Most register accesses are lexed as REGFILE[0-9]+, to prevent the register 199 * with subreg from being lexed as REGFILE NUMBER instead of 200 * REGISTER INTEGER DOT INTEGER like we want. The alternative was to use a 201 * start condition, which wasn't very clean-looking. 202 * 203 * However, this means we need to lex the general and message register file 204 * characters as well, for register-indirect access which is formatted 205 * like g[a#.#] or m[a#.#]. 206 */ 207 "acc"[0-9]+ { 208 yylval.integer = atoi(yytext + 3); 209 return ACCREG; 210 } 211 "a"[0-9]+ { 212 yylval.integer = atoi(yytext + 1); 213 return ADDRESSREG; 214 } 215 "m"[0-9]+ { 216 yylval.integer = atoi(yytext + 1); 217 return MSGREG; 218 } 219 "m" { 220 return MSGREGFILE; 221 } 222 "mask"[0-9]+ { 223 yylval.integer = atoi(yytext + 4); 224 return MASKREG; 225 } 226 "ms"[0-9]+ { 227 yylval.integer = atoi(yytext + 2); 228 return MASKSTACKREG; 229 } 230 "msd"[0-9]+ { 231 yylval.integer = atoi(yytext + 3); 232 return MASKSTACKDEPTHREG; 233 } 234 235 "n0."[0-9]+ { 236 yylval.integer = atoi(yytext + 3); 237 return NOTIFYREG; 238 } 239 240 "n"[0-9]+ { 241 yylval.integer = atoi(yytext + 1); 242 return NOTIFYREG; 243 } 244 245 "f"[0-9] { 246 yylval.integer = atoi(yytext + 1); 247 return FLAGREG; 248 } 249 250 [gr][0-9]+ { 251 yylval.integer = atoi(yytext + 1); 252 BEGIN(REG); 253 return GENREG; 254 } 255 <REG>"<" { return LANGLE; } 256 <REG>[0-9][0-9]* { 257 yylval.integer = strtoul(yytext, NULL, 10); 258 return INTEGER; 259 } 260 <REG>">" { return RANGLE; } 261 262 <REG>"," { return COMMA; } 263 <REG>"." { BEGIN(DOTSEL); return DOT; } 264 <REG>";" { return SEMICOLON; } 265 266 <DOTSEL>"x" { 267 yylval.integer = BRW_CHANNEL_X; 268 return X; 269 } 270 <DOTSEL>"y" { 271 yylval.integer = BRW_CHANNEL_Y; 272 return Y; 273 } 274 <DOTSEL>"z" { 275 yylval.integer = BRW_CHANNEL_Z; 276 return Z; 277 } 278 <DOTSEL>"w" { 279 yylval.integer = BRW_CHANNEL_W; 280 return W; 281 } 282 <DOTSEL>[0-9][0-9]* { 283 yylval.integer = strtoul(yytext, NULL, 10); 284 BEGIN(REG); 285 return INTEGER; 286 } 287 <DOTSEL>. { 288 yyless(0); 289 BEGIN(INITIAL); 290 } 291 292 [gr] { 293 return GENREGFILE; 294 } 295 "cr"[0-9]+ { 296 yylval.integer = atoi(yytext + 2); 297 return CONTROLREG; 298 } 299 "sr"[0-9]+ { 300 yylval.integer = atoi(yytext + 2); 301 return STATEREG; 302 } 303 "ip" { 304 return IPREG; 305 } 306 "amask" { 307 yylval.integer = BRW_AMASK; 308 return AMASK; 309 } 310 "imask" { 311 yylval.integer = BRW_IMASK; 312 return IMASK; 313 } 314 "lmask" { 315 yylval.integer = BRW_LMASK; 316 return LMASK; 317 } 318 "cmask" { 319 yylval.integer = BRW_CMASK; 320 return CMASK; 321 } 322 "imsd" { 323 yylval.integer = 0; 324 return IMSD; 325 } 326 "lmsd" { 327 yylval.integer = 1; 328 return LMSD; 329 } 330 "ims" { 331 yylval.integer = 0; 332 return IMS; 333 } 334 "lms" { 335 yylval.integer = 16; 336 return LMS; 337 } 338 339 <REG>. { 340 yyless(0); 341 BEGIN(INITIAL); 342 } 343 344 /* 345 * Lexing of register types should probably require the ":" symbol specified 346 * in the BNF of the assembly, but our existing source didn't use that syntax. 347 */ 348 "UD" { return TYPE_UD; } 349 ":UD" { return TYPE_UD; } 350 "D" { return TYPE_D; } 351 ":D" { return TYPE_D; } 352 "UW" { return TYPE_UW; } 353 ":UW" { return TYPE_UW; } 354 "W" { return TYPE_W; } 355 ":W" { return TYPE_W; } 356 "UB" { return TYPE_UB; } 357 ":UB" { return TYPE_UB; } 358 "B" { return TYPE_B; } 359 ":B" { return TYPE_B; } 360 "F" { return TYPE_F; } 361 ":F" { return TYPE_F; } 362 "VF" {return TYPE_VF; } 363 ":VF" {return TYPE_VF; } 364 "V" { return TYPE_V; } 365 ":V" { return TYPE_V; } 366 367 #".kernel" { return KERNEL_PRAGMA;} 368 #".end_kernel" { return END_KERNEL_PRAGMA;} 369 #".code" { return CODE_PRAGMA;} 370 #".end_code" { return END_CODE_PRAGMA;} 371 ".reg_count_payload" { return REG_COUNT_PAYLOAD_PRAGMA; } 372 ".reg_count_total" { return REG_COUNT_TOTAL_PRAGMA; } 373 ".default_execution_size" { return DEFAULT_EXEC_SIZE_PRAGMA; } 374 ".default_register_type" { return DEFAULT_REG_TYPE_PRAGMA; } 375 ".declare" { return DECLARE_PRAGMA; } 376 "Base" { return BASE; } 377 "ElementSize" { return ELEMENTSIZE; } 378 "SrcRegion" { return SRCREGION; } 379 "DstRegion" { return DSTREGION; } 380 "Type" { return TYPE; } 381 382 383 ".sat" { return SATURATE; } 384 "align1" { return ALIGN1; } 385 "align16" { return ALIGN16; } 386 "sechalf" { return SECHALF; } 387 "compr" { return COMPR; } 388 "switch" { return SWITCH; } 389 "atomic" { return ATOMIC; } 390 "noddchk" { return NODDCHK; } 391 "noddclr" { return NODDCLR; } 392 "mask_disable" { return MASK_DISABLE; } 393 "nomask" { return MASK_DISABLE; } 394 "breakpoint" { return BREAKPOINT; } 395 "accwrctrl" { return ACCWRCTRL; } 396 "EOT" { return EOT; } 397 398 /* extended math functions */ 399 "inv" { yylval.integer = BRW_MATH_FUNCTION_INV; return SIN; } 400 "log" { yylval.integer = BRW_MATH_FUNCTION_LOG; return LOG; } 401 "exp" { yylval.integer = BRW_MATH_FUNCTION_EXP; return EXP; } 402 "sqrt" { yylval.integer = BRW_MATH_FUNCTION_SQRT; return SQRT; } 403 "rsq" { yylval.integer = BRW_MATH_FUNCTION_RSQ; return RSQ; } 404 "pow" { yylval.integer = BRW_MATH_FUNCTION_POW; return POW; } 405 "sin" { yylval.integer = BRW_MATH_FUNCTION_SIN; return SIN; } 406 "cos" { yylval.integer = BRW_MATH_FUNCTION_COS; return COS; } 407 "sincos" { yylval.integer = BRW_MATH_FUNCTION_SINCOS; return SINCOS; } 408 "intdiv" { 409 yylval.integer = BRW_MATH_FUNCTION_INT_DIV_QUOTIENT; 410 return INTDIV; 411 } 412 "intmod" { 413 yylval.integer = BRW_MATH_FUNCTION_INT_DIV_REMAINDER; 414 return INTMOD; 415 } 416 "intdivmod" { 417 yylval.integer = BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER; 418 return INTDIVMOD; 419 } 420 421 "signed" { return SIGNED; } 422 "scalar" { return SCALAR; } 423 424 /* predicate control */ 425 ".anyv" { return ANYV; } 426 ".allv" { return ALLV; } 427 ".any2h" { return ANY2H; } 428 ".all2h" { return ALL2H; } 429 ".any4h" { return ANY4H; } 430 ".all4h" { return ALL4H; } 431 ".any8h" { return ANY8H; } 432 ".all8h" { return ALL8H; } 433 ".any16h" { return ANY16H; } 434 ".all16h" { return ALL16H; } 435 436 ".z" { yylval.integer = BRW_CONDITIONAL_Z; return ZERO; } 437 ".e" { yylval.integer = BRW_CONDITIONAL_Z; return EQUAL; } 438 ".nz" { yylval.integer = BRW_CONDITIONAL_NZ; return NOT_ZERO; } 439 ".ne" { yylval.integer = BRW_CONDITIONAL_NZ; return NOT_EQUAL; } 440 ".g" { yylval.integer = BRW_CONDITIONAL_G; return GREATER; } 441 ".ge" { yylval.integer = BRW_CONDITIONAL_GE; return GREATER_EQUAL; } 442 ".l" { yylval.integer = BRW_CONDITIONAL_L; return LESS; } 443 ".le" { yylval.integer = BRW_CONDITIONAL_LE; return LESS_EQUAL; } 444 ".r" { yylval.integer = BRW_CONDITIONAL_R; return ROUND_INCREMENT; } 445 ".o" { yylval.integer = BRW_CONDITIONAL_O; return OVERFLOW; } 446 ".u" { yylval.integer = BRW_CONDITIONAL_U; return UNORDERED; } 447 448 [a-zA-Z_][0-9a-zA-Z_]* { 449 yylval.string = strdup(yytext); 450 return STRING; 451 } 452 453 0x[0-9a-fA-F][0-9a-fA-F]* { 454 yylval.integer = strtoul(yytext + 2, NULL, 16); 455 return INTEGER; 456 } 457 [0-9][0-9]* { 458 yylval.integer = strtoul(yytext, NULL, 10); 459 return INTEGER; 460 } 461 462 <INITIAL>[-]?[0-9]+"."[0-9]+ { 463 yylval.number = strtod(yytext, NULL); 464 return NUMBER; 465 } 466 467 [ \t]+ { } /* eat up whitespace */ 468 469 \n { yycolumn = 1; } 470 471 . { 472 fprintf(stderr, "%s: %d: %s at \"%s\"\n", 473 input_filename, yylineno, "unexpected token", lex_text()); 474 } 475 %% 476 477 char * 478 lex_text(void) 479 { 480 return yytext; 481 (void) yyunput; 482 } 483 484 #ifndef yywrap 485 int yywrap() { return 1; } 486 #endif 487 488