diff options
Diffstat (limited to 'assembler/src/lex.l')
-rw-r--r-- | assembler/src/lex.l | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/assembler/src/lex.l b/assembler/src/lex.l new file mode 100644 index 000000000..97b9c3d26 --- /dev/null +++ b/assembler/src/lex.l @@ -0,0 +1,324 @@ +%option yylineno +%{ +#include "gen4asm.h" +#include "gram.h" +#include "brw_defines.h" + +int saved_state = INITIAL; + +%} +%x BLOCK_COMMENT + +%% +\/\/.*[\r\n] { } /* eat up single-line comments */ + + /* eat up multi-line comments, non-nesting. */ +\/\* { + saved_state = YYSTATE; + BEGIN(BLOCK_COMMENT); +} +<BLOCK_COMMENT>\*\/ { + BEGIN(saved_state); +} +<BLOCK_COMMENT>. { } +<BLOCK_COMMENT>[\r\n] { } + + /* used for both null send and null register. */ +"null" { return NULL_TOKEN; } + + /* opcodes */ +"mov" { yylval.integer = BRW_OPCODE_MOV; return MOV; } +"frc" { yylval.integer = BRW_OPCODE_FRC; return FRC; } +"rndu" { yylval.integer = BRW_OPCODE_RNDU; return RNDU; } +"rndd" { yylval.integer = BRW_OPCODE_RNDD; return RNDD; } +"rnde" { yylval.integer = BRW_OPCODE_RNDE; return RNDE; } +"rndz" { yylval.integer = BRW_OPCODE_RNDZ; return RNDZ; } +"not" { yylval.integer = BRW_OPCODE_NOT; return NOT; } +"lzd" { yylval.integer = BRW_OPCODE_LZD; return LZD; } + +"mul" { yylval.integer = BRW_OPCODE_MUL; return MUL; } +"mac" { yylval.integer = BRW_OPCODE_MAC; return MAC; } +"mach" { yylval.integer = BRW_OPCODE_MACH; return MACH; } +"line" { yylval.integer = BRW_OPCODE_LINE; return LINE; } +"sad2" { yylval.integer = BRW_OPCODE_SAD2; return SAD2; } +"sada2" { yylval.integer = BRW_OPCODE_SADA2; return SADA2; } +"dp4" { yylval.integer = BRW_OPCODE_DP4; return DP4; } +"dph" { yylval.integer = BRW_OPCODE_DPH; return DPH; } +"dp3" { yylval.integer = BRW_OPCODE_DP3; return DP3; } +"dp2" { yylval.integer = BRW_OPCODE_DP2; return DP2; } + +"avg" { yylval.integer = BRW_OPCODE_AVG; return AVG; } +"add" { yylval.integer = BRW_OPCODE_ADD; return ADD; } +"sel" { yylval.integer = BRW_OPCODE_SEL; return SEL; } +"and" { yylval.integer = BRW_OPCODE_AND; return AND; } +"or" { yylval.integer = BRW_OPCODE_OR; return OR; } +"xor" { yylval.integer = BRW_OPCODE_XOR; return XOR; } +"shr" { yylval.integer = BRW_OPCODE_SHR; return SHR; } +"shl" { yylval.integer = BRW_OPCODE_SHL; return SHL; } +"asr" { yylval.integer = BRW_OPCODE_ASR; return ASR; } +"cmp" { yylval.integer = BRW_OPCODE_CMP; return CMP; } +"cmpn" { yylval.integer = BRW_OPCODE_CMPN; return CMPN; } + +"send" { yylval.integer = BRW_OPCODE_SEND; return SEND; } +"nop" { yylval.integer = BRW_OPCODE_NOP; return NOP; } +"jmpi" { yylval.integer = BRW_OPCODE_JMPI; return JMPI; } +"if" { yylval.integer = BRW_OPCODE_IF; return IF; } +"iff" { yylval.integer = BRW_OPCODE_IFF; return IFF; } +"while" { yylval.integer = BRW_OPCODE_NOP; return NOP; } +"send" { yylval.integer = BRW_OPCODE_SEND; return SEND; } +"else" { yylval.integer = BRW_OPCODE_ELSE; return ELSE; } +"break" { yylval.integer = BRW_OPCODE_BREAK; return BREAK; } +"cont" { yylval.integer = BRW_OPCODE_CONTINUE; return CONT; } +"halt" { yylval.integer = BRW_OPCODE_HALT; return HALT; } +"msave" { yylval.integer = BRW_OPCODE_MSAVE; return MSAVE; } +"push" { yylval.integer = BRW_OPCODE_PUSH; return PUSH; } +"mrest" { yylval.integer = BRW_OPCODE_MRESTORE; return MREST; } +"pop" { yylval.integer = BRW_OPCODE_POP; return POP; } +"wait" { yylval.integer = BRW_OPCODE_WAIT; return WAIT; } +"do" { yylval.integer = BRW_OPCODE_DO; return DO; } +"endif" { yylval.integer = BRW_OPCODE_ENDIF; return ENDIF; } + + /* send argument tokens */ +"mlen" { return MSGLEN; } +"rlen" { return RETURNLEN; } +"math" { return MATH; } +"sampler" { return SAMPLER; } +"gateway" { return GATEWAY; } +"read" { return READ; } +"write" { return WRITE; } +"urb" { return URB; } +"thread_spawner" { return THREAD_SPAWNER; } + +"allocate" { return ALLOCATE; } +"used" { return USED; } +"complete" { return COMPLETE; } +"transpose" { return TRANSPOSE; } +"interleave" { return INTERLEAVE; } + +";" { return SEMICOLON; } +"(" { return LPAREN; } +")" { return RPAREN; } +"<" { return LANGLE; } +">" { return RANGLE; } +"{" { return LCURLY; } +"}" { return RCURLY; } +"[" { return LSQUARE; } +"]" { return RSQUARE; } +"," { return COMMA; } +"." { return DOT; } +"+" { return PLUS; } +"-" { return MINUS; } +"(abs)" { return ABS; } + + /* Most register accesses are lexed as REGFILE[0-9]+, to prevent the register + * with subreg from being lexed as REGFILE NUMBER instead of + * REGISTER INTEGER DOT INTEGER like we want. The alternative was to use a + * start condition, which wasn't very clean-looking. + * + * However, this means we need to lex the general and message register file + * characters as well, for register-indirect access which is formatted + * like g[a#.#] or m[a#.#]. + */ +"acc"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return ACCREG; +} +"a"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return ADDRESSREG; +} +"m"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return MSGREG; +} +"m" { + return MSGREGFILE; +} +"mask"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return MASKREG; +} +"ms"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return MASKSTACKREG; +} +"msd"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return MASKSTACKDEPTHREG; +} +"n"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return NOTIFYREG; +} + /* Unlike other registers, flagreg returns the subreg number in the lvalue + * rather than the reg number, to avoid a shift/reduce conflict in the + * predicate control. + */ +"f0.[0-9]+" { + yylval.integer = atoi(yytext + 3); + return FLAGREG; +} +"f0" { + yylval.integer = 0; + return FLAGREG; +} +[gr][0-9]+ { + yylval.integer = atoi(yytext + 1); + return GENREG; +} +[gr] { + return GENREGFILE; +} +"cr"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return CONTROLREG; +} +"sr"[0-9]+ { + yylval.integer = atoi(yytext + 1); + return STATEREG; +} +"ip" { + return IPREG; +} +"amask" { + yylval.integer = BRW_AMASK; + return AMASK; +} +"imask" { + yylval.integer = BRW_IMASK; + return IMASK; +} +"lmask" { + yylval.integer = BRW_LMASK; + return LMASK; +} +"cmask" { + yylval.integer = BRW_CMASK; + return CMASK; +} +"imsd" { + yylval.integer = 0; + return IMSD; +} +"lmsd" { + yylval.integer = 1; + return LMSD; +} +"ims" { + yylval.integer = 0; + return IMS; +} +"lms" { + yylval.integer = 16; + return LMS; +} + + /* + * Lexing of register types should probably require the ":" symbol specified + * in the BNF of the assembly, but our existing source didn't use that syntax. + */ +"UD" { return TYPE_UD; } +"D" { return TYPE_D; } +"UW" { return TYPE_UW; } +"W" { return TYPE_W; } +"UB" { return TYPE_UB; } +"B" { return TYPE_B; } +"F" { return TYPE_F; } + +"sat" { return SATURATE; } +"align1" { return ALIGN1; } +"align16" { return ALIGN16; } +"sechalf" { return SECHALF; } +"compr" { return COMPR; } +"switch" { return SWITCH; } +"atomic" { return ATOMIC; } +"noddchk" { return NODDCHK; } +"noddclr" { return NODDCLR; } +"mask_disable" { return MASK_DISABLE; } +"nomask" { return MASK_DISABLE; } +"breakpoint" { return BREAKPOINT; } +"EOT" { return EOT; } + + /* extended math functions */ +"inv" { yylval.integer = BRW_MATH_FUNCTION_INV; return SIN; } +"log" { yylval.integer = BRW_MATH_FUNCTION_LOG; return LOG; } +"exp" { yylval.integer = BRW_MATH_FUNCTION_EXP; return EXP; } +"sqrt" { yylval.integer = BRW_MATH_FUNCTION_SQRT; return SQRT; } +"rsq" { yylval.integer = BRW_MATH_FUNCTION_RSQ; return RSQ; } +"pow" { yylval.integer = BRW_MATH_FUNCTION_POW; return POW; } +"sin" { yylval.integer = BRW_MATH_FUNCTION_SIN; return SIN; } +"cos" { yylval.integer = BRW_MATH_FUNCTION_COS; return COS; } +"sincos" { yylval.integer = BRW_MATH_FUNCTION_SINCOS; return SINCOS; } +"intdiv" { + yylval.integer = BRW_MATH_FUNCTION_INT_DIV_QUOTIENT; + return INTDIV; +} +"intmod" { + yylval.integer = BRW_MATH_FUNCTION_INT_DIV_REMAINDER; + return INTMOD; +} +"intdivmod" { + yylval.integer = BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER; + return INTDIVMOD; +} + +"signed" { return SIGNED; } +"scalar" { return SCALAR; } + + /* predicate control */ +"any2h" { return ANY2H; } +"all2h" { return ALL2H; } +"any4h" { return ANY4H; } +"all4h" { return ALL4H; } +"any8h" { return ANY8H; } +"all8h" { return ALL8H; } +"any16h" { return ANY16H; } +"all16h" { return ALL16H; } + + /* channel selectors */ +"x" { + yylval.integer = BRW_CHANNEL_X; + return X; +} +"y" { + yylval.integer = BRW_CHANNEL_Y; + return Y; +} +"z" { + yylval.integer = BRW_CHANNEL_Z; + return Z; +} +"w" { + yylval.integer = BRW_CHANNEL_W; + return W; +} + +[0-9]* { + yylval.integer = atoi(yytext); + return INTEGER; +} + +<INITIAL>[-]?[0-9]+"."[0-9]+ { + yylval.number = strtod(yytext, NULL); + return NUMBER; +} + +[ \t\n]+ { } /* eat up whitespace */ + +. { + printf("parse error at line %d: unexpected \"%s\"\n", + yylineno, yytext); + exit(1); +} +%% + +char * +lex_text(void) +{ + return yytext; +} + +#ifndef yywrap +int yywrap() { return 1; } +#endif + |