summaryrefslogtreecommitdiff
path: root/assembler/lex.l
blob: 1e58b6acdf9390e49102809651d9fec0bc8cf81a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
%option yylineno
%{
#include "gen4asm.h"
#include "y.tab.h"

int saved_state = INITIAL;

%}
%s IN_REG
%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" { return MOV; }

"mul" { return MUL; }
"mac" { return MAC; }
"mach" { return MACH; }
"line" { return LINE; }
"sad2" { return SAD2; }
"sada2" { return SADA2; }
"dp4" { return DP4; }
"dph" { return DPH; }
"dp3" { return DP3; }
"dp2" { return DP2; }

"add" { return ADD; }

"nop" { return NOP; }

"send" { return SEND; }
"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; }

";" { return SEMICOLON; }
"(" { return LPAREN; }
")" { return RPAREN; }
"<" { return LANGLE; }
">" { return RANGLE; }
"{" { return LCURLY; }
"}" { return RCURLY; }
"," { return COMMA; }
"." { return DOT; }
"-" { return MINUS; }
"(abs)" { return ABS; }

 /* XXX: this lexing of register files is shady */
"acc" {
	BEGIN(IN_REG);
	return ACCREG;
}
"a" {
	BEGIN(IN_REG);
	return ADDRESSREG;
}
"m" {
	BEGIN(IN_REG);
	return MSGREG;
}
"f" {
	BEGIN(IN_REG);
	return FLAGREG;
}
[gr] {
	BEGIN(IN_REG);
	return GENREG;
}
"cr" {
	BEGIN(IN_REG);
	return CONTROLREG;
}
"ip" {
	BEGIN(IN_REG);
	return IPREG;
}

 /*
  * 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" { BEGIN(INITIAL); return TYPE_UD; }
"D" { BEGIN(INITIAL); return TYPE_D; }
"UW" { BEGIN(INITIAL); return TYPE_UW; }
"W" { BEGIN(INITIAL); return TYPE_W; }
"UB" { BEGIN(INITIAL); return TYPE_UB; }
"B" { BEGIN(INITIAL); return TYPE_B; }
"F" { BEGIN(INITIAL); return TYPE_F; }

"sat" { return SATURATE; }
"align1" { return ALIGN1; }
"align16" { return ALIGN16; }
"mask_disable" { return MASK_DISABLE; }
"EOT" { return EOT; }

[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