%{#include "a.h"%}%union{ Sym *sym; long lval; double dval; char sval[8]; Gen gen;}%left '|'%left '^'%left '&'%left '<' '>'%left '+' '-'%left '*' '/' '%'%token <lval> LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5%token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA%token <lval> LTYPEB LTYPEC LTYPED LTYPEE LTYPEF%token <lval> LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK%token <lval> LCONST LSP LSB LFP LPC LHI LLO LMREG %token <lval> LTYPEX LREG LFREG LFCREG LR LM LF%token <lval> LFCR LSCHED%token <dval> LFCONST%token <sval> LSCONST%token <sym> LNAME LLAB LVAR%type <lval> con expr pointer offset sreg%type <gen> gen vgen lgen vlgen rel reg freg mreg fcreg%type <gen> imm ximm ireg name oreg imr nireg fgen%%prog:| prog line line: LLAB ':' { if($1->value != pc) yyerror("redeclaration of %s", $1->name); $1->value = pc; } line| LNAME ':' { $1->type = LLAB; $1->value = pc; } line| LNAME '=' expr ';' { $1->type = LVAR; $1->value = $3; }| LVAR '=' expr ';' { if($1->value != $3) yyerror("redeclaration of %s", $1->name); $1->value = $3; }| LSCHED ';' { nosched = $1; }| ';'| inst ';'| error ';' inst:/* * Immed-type */ LTYPE1 imr ',' sreg ',' reg { outcode($1, &$2, $4, &$6); }| LTYPE1 imr ',' reg { outcode($1, &$2, NREG, &$4); }/* * NOR */| LTYPE2 imr ',' sreg ',' imr { outcode($1, &$2, $4, &$6); }| LTYPE2 imr ',' imr { outcode($1, &$2, NREG, &$4); }/* * LOAD/STORE, but not MOVW */| LTYPE3 lgen ',' gen { if(!isreg(&$2) && !isreg(&$4)) print("one side must be register\n"); outcode($1, &$2, NREG, &$4); }/* * SPECIAL */| LTYPE4 comma { outcode($1, &nullgen, NREG, &nullgen); }/* * MOVW */| LTYPE5 vlgen ',' vgen { if(!isreg(&$2) && !isreg(&$4)) print("one side must be register\n"); outcode($1, &$2, NREG, &$4); }/* * MUL/DIV */| LTYPE6 reg ',' sreg comma { outcode($1, &$2, $4, &nullgen); }| LTYPE6 reg ',' sreg ',' reg { outcode($1, &$2, $4, &$6); }/* * JMP/JAL */| LTYPE7 comma rel { outcode($1, &nullgen, NREG, &$3); }| LTYPE7 comma nireg { outcode($1, &nullgen, NREG, &$3); }| LTYPE8 comma rel { outcode($1, &nullgen, NREG, &$3); }| LTYPE8 comma nireg { outcode($1, &nullgen, NREG, &$3); }| LTYPE8 sreg ',' nireg { outcode($1, &nullgen, $2, &$4); }/* * BEQ/BNE */| LTYPE9 gen ',' rel { if(!isreg(&$2)) print("left side must be register\n"); outcode($1, &$2, NREG, &$4); }| LTYPE9 gen ',' sreg ',' rel { if(!isreg(&$2)) print("left side must be register\n"); outcode($1, &$2, $4, &$6); }/* * B-other */| LTYPEA gen ',' rel { if(!isreg(&$2)) print("left side must be register\n"); outcode($1, &$2, NREG, &$4); }/* * TEXT/GLOBL */| LTYPEB name ',' imm { outcode($1, &$2, NREG, &$4); }| LTYPEB name ',' con ',' imm { outcode($1, &$2, $4, &$6); }/* * DATA */| LTYPEC name '/' con ',' ximm { outcode($1, &$2, $4, &$6); }/* * floating-type */| LTYPED freg ',' freg { outcode($1, &$2, NREG, &$4); }| LTYPEE freg ',' freg { outcode($1, &$2, NREG, &$4); }| LTYPEE freg ',' LFREG ',' freg { outcode($1, &$2, $4, &$6); }| LTYPEF freg ',' LFREG comma { outcode($1, &$2, $4, &nullgen); }/* * coprocessor branch */| LTYPEG comma rel { outcode($1, &nullgen, NREG, &$3); }/* * word */| LTYPEH comma ximm { outcode($1, &nullgen, NREG, &$3); }/* * NOP */| LTYPEI comma { outcode($1, &nullgen, NREG, &nullgen); }| LTYPEI ',' vgen { outcode($1, &nullgen, NREG, &$3); }| LTYPEI vgen comma { outcode($1, &$2, NREG, &nullgen); }/* * BREAK -- overloaded with CACHE opcode */| LTYPEJ comma { outcode($1, &nullgen, NREG, &nullgen); }| LTYPEJ vgen ',' vgen { outcode($1, &$2, NREG, &$4); } comma:| ',' rel: con '(' LPC ')' { $$ = nullgen; $$.type = D_BRANCH; $$.offset = $1 + pc; }| LNAME offset { $$ = nullgen; if(pass == 2) yyerror("undefined label: %s", $1->name); $$.type = D_BRANCH; $$.sym = $1; $$.offset = $2; }| LLAB offset { $$ = nullgen; $$.type = D_BRANCH; $$.sym = $1; $$.offset = $1->value + $2; } vlgen: lgen| fgen| mreg| fcreg| LHI { $$ = nullgen; $$.type = D_HI; }| LLO { $$ = nullgen; $$.type = D_LO; } vgen: gen| fgen| mreg| fcreg| LHI { $$ = nullgen; $$.type = D_HI; }| LLO { $$ = nullgen; $$.type = D_LO; } lgen: gen| ximm fgen: freg mreg: LMREG { $$ = nullgen; $$.type = D_MREG; $$.reg = $1; }| LM '(' con ')' { $$ = nullgen; $$.type = D_MREG; $$.reg = $3; } fcreg: LFCREG { $$ = nullgen; $$.type = D_FCREG; $$.reg = $1; }| LFCR '(' con ')' { $$ = nullgen; $$.type = D_FCREG; $$.reg = $3; } freg: LFREG { $$ = nullgen; $$.type = D_FREG; $$.reg = $1; }| LF '(' con ')' { $$ = nullgen; $$.type = D_FREG; $$.reg = $3; } ximm: '$' con { $$ = nullgen; $$.type = D_CONST; $$.offset = $2; }| '$' oreg { $$ = $2; $$.type = D_CONST; }| '$' '*' '$' oreg { $$ = $4; $$.type = D_OCONST; }| '$' LSCONST { $$ = nullgen; $$.type = D_SCONST; memcpy($$.sval, $2, sizeof($$.sval)); }| '$' LFCONST { $$ = nullgen; $$.type = D_FCONST; $$.dval = $2; }| '$' '-' LFCONST { $$ = nullgen; $$.type = D_FCONST; $$.dval = -$3; } nireg: ireg| con ireg { if($1 != 0) yyerror("offset must be zero"); $$ = $2; }| name { $$ = $1; if($1.name != D_EXTERN && $1.name != D_STATIC) { } } ireg: '(' sreg ')' { $$ = nullgen; $$.type = D_OREG; $$.reg = $2; $$.offset = 0; } gen: reg| con { $$ = nullgen; $$.type = D_OREG; $$.offset = $1; }| oreg oreg: name| name '(' sreg ')' { $$ = $1; $$.type = D_OREG; $$.reg = $3; }| '(' sreg ')' { $$ = nullgen; $$.type = D_OREG; $$.reg = $2; $$.offset = 0; }| con '(' sreg ')' { $$ = nullgen; $$.type = D_OREG; $$.reg = $3; $$.offset = $1; } imr: reg| imm imm: '$' con { $$ = nullgen; $$.type = D_CONST; $$.offset = $2; } reg: sreg { $$ = nullgen; $$.type = D_REG; $$.reg = $1; } sreg: LREG| LR '(' con ')' { if($$ < 0 || $$ >= NREG) print("register value out of range\n"); $$ = $3; } name: con '(' pointer ')' { $$ = nullgen; $$.type = D_OREG; $$.name = $3; $$.sym = S; $$.offset = $1; }| LNAME offset '(' pointer ')' { $$ = nullgen; $$.type = D_OREG; $$.name = $4; $$.sym = $1; $$.offset = $2; }| LNAME '<' '>' offset '(' LSB ')' { $$ = nullgen; $$.type = D_OREG;Lines 1–500 of 588. Load more
%{ #include "a.h" %} %union { Sym *sym; long lval; double dval; char sval[8]; Gen gen; } %left '|' %left '^' %left '&' %left '<' '>' %left '+' '-' %left '*' '/' '%' %token <lval> LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5 %token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA %token <lval> LTYPEB LTYPEC LTYPED LTYPEE LTYPEF %token <lval> LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK %token <lval> LCONST LSP LSB LFP LPC LHI LLO LMREG %token <lval> LTYPEX LREG LFREG LFCREG LR LM LF %token <lval> LFCR LSCHED %token <dval> LFCONST %token <sval> LSCONST %token <sym> LNAME LLAB LVAR %type <lval> con expr pointer offset sreg %type <gen> gen vgen lgen vlgen rel reg freg mreg fcreg %type <gen> imm ximm ireg name oreg imr nireg fgen %% prog: | prog line line: LLAB ':' { if($1->value != pc) yyerror("redeclaration of %s", $1->name); $1->value = pc; } line | LNAME ':' { $1->type = LLAB; $1->value = pc; } line | LNAME '=' expr ';' { $1->type = LVAR; $1->value = $3; } | LVAR '=' expr ';' { if($1->value != $3) yyerror("redeclaration of %s", $1->name); $1->value = $3; } | LSCHED ';' { nosched = $1; } | ';' | inst ';' | error ';' inst: /* * Immed-type */ LTYPE1 imr ',' sreg ',' reg { outcode($1, &$2, $4, &$6); } | LTYPE1 imr ',' reg { outcode($1, &$2, NREG, &$4); } /* * NOR */ | LTYPE2 imr ',' sreg ',' imr { outcode($1, &$2, $4, &$6); } | LTYPE2 imr ',' imr { outcode($1, &$2, NREG, &$4); } /* * LOAD/STORE, but not MOVW */ | LTYPE3 lgen ',' gen { if(!isreg(&$2) && !isreg(&$4)) print("one side must be register\n"); outcode($1, &$2, NREG, &$4); } /* * SPECIAL */ | LTYPE4 comma { outcode($1, &nullgen, NREG, &nullgen); } /* * MOVW */ | LTYPE5 vlgen ',' vgen { if(!isreg(&$2) && !isreg(&$4)) print("one side must be register\n"); outcode($1, &$2, NREG, &$4); } /* * MUL/DIV */ | LTYPE6 reg ',' sreg comma { outcode($1, &$2, $4, &nullgen); } | LTYPE6 reg ',' sreg ',' reg { outcode($1, &$2, $4, &$6); } /* * JMP/JAL */ | LTYPE7 comma rel { outcode($1, &nullgen, NREG, &$3); } | LTYPE7 comma nireg { outcode($1, &nullgen, NREG, &$3); } | LTYPE8 comma rel { outcode($1, &nullgen, NREG, &$3); } | LTYPE8 comma nireg { outcode($1, &nullgen, NREG, &$3); } | LTYPE8 sreg ',' nireg { outcode($1, &nullgen, $2, &$4); } /* * BEQ/BNE */ | LTYPE9 gen ',' rel { if(!isreg(&$2)) print("left side must be register\n"); outcode($1, &$2, NREG, &$4); } | LTYPE9 gen ',' sreg ',' rel { if(!isreg(&$2)) print("left side must be register\n"); outcode($1, &$2, $4, &$6); } /* * B-other */ | LTYPEA gen ',' rel { if(!isreg(&$2)) print("left side must be register\n"); outcode($1, &$2, NREG, &$4); } /* * TEXT/GLOBL */ | LTYPEB name ',' imm { outcode($1, &$2, NREG, &$4); } | LTYPEB name ',' con ',' imm { outcode($1, &$2, $4, &$6); } /* * DATA */ | LTYPEC name '/' con ',' ximm { outcode($1, &$2, $4, &$6); } /* * floating-type */ | LTYPED freg ',' freg { outcode($1, &$2, NREG, &$4); } | LTYPEE freg ',' freg { outcode($1, &$2, NREG, &$4); } | LTYPEE freg ',' LFREG ',' freg { outcode($1, &$2, $4, &$6); } | LTYPEF freg ',' LFREG comma { outcode($1, &$2, $4, &nullgen); } /* * coprocessor branch */ | LTYPEG comma rel { outcode($1, &nullgen, NREG, &$3); } /* * word */ | LTYPEH comma ximm { outcode($1, &nullgen, NREG, &$3); } /* * NOP */ | LTYPEI comma { outcode($1, &nullgen, NREG, &nullgen); } | LTYPEI ',' vgen { outcode($1, &nullgen, NREG, &$3); } | LTYPEI vgen comma { outcode($1, &$2, NREG, &nullgen); } /* * BREAK -- overloaded with CACHE opcode */ | LTYPEJ comma { outcode($1, &nullgen, NREG, &nullgen); } | LTYPEJ vgen ',' vgen { outcode($1, &$2, NREG, &$4); } comma: | ',' rel: con '(' LPC ')' { $$ = nullgen; $$.type = D_BRANCH; $$.offset = $1 + pc; } | LNAME offset { $$ = nullgen; if(pass == 2) yyerror("undefined label: %s", $1->name); $$.type = D_BRANCH; $$.sym = $1; $$.offset = $2; } | LLAB offset { $$ = nullgen; $$.type = D_BRANCH; $$.sym = $1; $$.offset = $1->value + $2; } vlgen: lgen | fgen | mreg | fcreg | LHI { $$ = nullgen; $$.type = D_HI; } | LLO { $$ = nullgen; $$.type = D_LO; } vgen: gen | fgen | mreg | fcreg | LHI { $$ = nullgen; $$.type = D_HI; } | LLO { $$ = nullgen; $$.type = D_LO; } lgen: gen | ximm fgen: freg mreg: LMREG { $$ = nullgen; $$.type = D_MREG; $$.reg = $1; } | LM '(' con ')' { $$ = nullgen; $$.type = D_MREG; $$.reg = $3; } fcreg: LFCREG { $$ = nullgen; $$.type = D_FCREG; $$.reg = $1; } | LFCR '(' con ')' { $$ = nullgen; $$.type = D_FCREG; $$.reg = $3; } freg: LFREG { $$ = nullgen; $$.type = D_FREG; $$.reg = $1; } | LF '(' con ')' { $$ = nullgen; $$.type = D_FREG; $$.reg = $3; } ximm: '$' con { $$ = nullgen; $$.type = D_CONST; $$.offset = $2; } | '$' oreg { $$ = $2; $$.type = D_CONST; } | '$' '*' '$' oreg { $$ = $4; $$.type = D_OCONST; } | '$' LSCONST { $$ = nullgen; $$.type = D_SCONST; memcpy($$.sval, $2, sizeof($$.sval)); } | '$' LFCONST { $$ = nullgen; $$.type = D_FCONST; $$.dval = $2; } | '$' '-' LFCONST { $$ = nullgen; $$.type = D_FCONST; $$.dval = -$3; } nireg: ireg | con ireg { if($1 != 0) yyerror("offset must be zero"); $$ = $2; } | name { $$ = $1; if($1.name != D_EXTERN && $1.name != D_STATIC) { } } ireg: '(' sreg ')' { $$ = nullgen; $$.type = D_OREG; $$.reg = $2; $$.offset = 0; } gen: reg | con { $$ = nullgen; $$.type = D_OREG; $$.offset = $1; } | oreg oreg: name | name '(' sreg ')' { $$ = $1; $$.type = D_OREG; $$.reg = $3; } | '(' sreg ')' { $$ = nullgen; $$.type = D_OREG; $$.reg = $2; $$.offset = 0; } | con '(' sreg ')' { $$ = nullgen; $$.type = D_OREG; $$.reg = $3; $$.offset = $1; } imr: reg | imm imm: '$' con { $$ = nullgen; $$.type = D_CONST; $$.offset = $2; } reg: sreg { $$ = nullgen; $$.type = D_REG; $$.reg = $1; } sreg: LREG | LR '(' con ')' { if($$ < 0 || $$ >= NREG) print("register value out of range\n"); $$ = $3; } name: con '(' pointer ')' { $$ = nullgen; $$.type = D_OREG; $$.name = $3; $$.sym = S; $$.offset = $1; } | LNAME offset '(' pointer ')' { $$ = nullgen; $$.type = D_OREG; $$.name = $4; $$.sym = $1; $$.offset = $2; } | LNAME '<' '>' offset '(' LSB ')' { $$ = nullgen; $$.type = D_OREG;