%{
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"
#define YYSTYPE Yystype
static Sib
mkSib(u32int index, u32int scale)
{
Sib s;
s.index = index;
s.scale = scale;
return s;
}
int
yyerror(char *s)
{
fprint(2, "oops: %s\n", s);
return -1;
}
%}
%start start
%token <i> CONST
%token <s> ERROR
%token <prefix> PREFIX
%token <s> OP
%token <r8> REG8
%token <r32> REG32
%type <inst> basic_inst
%type <i> disp
%type <expr> expr
%type <inst> inst
%type <mem> mem
%type <i> scale
%type <sib> sib
%%
start
: inst '\n' { return 1; }
| error '\n' { return 0; }
;
inst
: basic_inst { $$ = $1; }
| PREFIX inst { $$ = $2; $$.prefix |= $1; }
;
basic_inst
: OP { $$ = mkInst($1, 0); }
| OP expr { $$ = mkInst($1, 1, $2); }
| OP expr ',' expr { $$ = mkInst($1, 2, $2, $4); }
| OP expr ',' expr ',' expr { $$ = mkInst($1, 3, $2, $4, $6); }
;
expr
: REG8 { $$ = mkExprReg8($1); }
| REG32 { $$ = mkExprReg32($1); }
| CONST { $$ = mkExprConst($1); }
| mem { $$ = mkExprMem($1); }
;
mem
: disp '[' REG32 ']' sib { $$ = mkMem($1, $3, $5.index, $5.scale); }
;
disp
: /* nothing */ { $$ = 0; }
| CONST { $$ = $1; }
;
sib
: /* nothing */ { $$ = mkSib(-1, -1); }
| '[' REG32 scale ']' { $$ = mkSib($2, $3); }
;
scale
: /* nothing */ { $$ = 1; }
| '*' CONST { $$ = $2; }
;
|