123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- #define RCSID4 "$Id$"
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- *
- */
- /*
- * Zilog Z80 parsing rules
- */
- operation
- : NOOPOP
- { emit1($1);}
- | LDOP ldargs
- | PSHPOP R16
- { switch ($2) {
- case BC: emit1($1); break;
- case DE: emit1($1 | 020); break;
- case AF: emit1($1 | 060); break;
- case HL:
- case IX:
- case IY: xyreg($2,$1 | 040); break;
- default: serror("register error");
- }
- }
- | EXOP R16 ',' R16
- { if ($2==DE && $4==HL)
- emit1(0353);
- else if ($2==AF && $4==AF2)
- emit1(010);
- else serror("register error");
- }
- | EXOP '(' R16 ')' ',' R16
- { if ($3!=SP) serror("register error");
- xyreg($6,$1);
- }
- | E_ED
- { emit1(0355); emit1($1);}
- | ADDOP R16 ',' R16
- { if ($4 == $2)
- xyreg($2,051);
- else {
- if ($4==HL || $4>SP)
- serror("register error");
- xyreg($2,011 | $4<<4);
- }
- }
- | ADCSBC R16 ',' R16
- { if ($2!=HL || $4>SP) serror("register error");
- emit1(0355);
- emit1(($1==0210 ? 0112 : 0102) | ($4<<4));
- }
- | INCDEC R16
- { switch ($2) {
- case BC: case DE: case SP:
- emit1(($1==04 ? 03 : 013) | $2<<4);
- break;
- case HL: case IX: case IY:
- xyreg($2,$1==04 ? 043 : 053);
- break;
- default: serror("register error");
- }
- }
- | INCDEC r8
- { emit1($1 | $2<<3);}
- | INCDEC ind
- { xymem($2,$1 | 060);}
- | ari8 r8
- { emit1($1 | $2);}
- | ari8 expr
- { emit1($1 | 0106); emit1($2.val);}
- | ari8 ind
- { xymem($2,$1 | 06);}
- | IMOP absexp
- { emit1(0355);
- switch ($2) {
- case 0: emit1(0106); break;
- case 1: emit1(0126); break;
- case 2: emit1(0136); break;
- default: serror("range 0..2");
- }
- }
- | ROTATE r8
- { emit1(0313); emit1($1 | $2);}
- | ROTATE ind
- { xymem($2,0313); emit1($1 | 06);}
- | BITS absexp ',' r8
- { fit(fit3($2));
- emit1(0313); emit1($1 | low3($2)<<3 | $4);
- }
- | BITS absexp ',' ind
- { fit(fit3($2));
- xymem($4,0313);
- emit1($1 | low3($2)<<3 | 06);
- }
- | JP expr
- { emit1($1);
- #ifdef RELOCATION
- newrelo($2.typ, RELO2);
- #endif
- emit2($2.val);
- }
- | JP coco ',' expr
- { emit1(0302 | $2<<3);
- #ifdef RELOCATION
- newrelo($4.typ, RELO2);
- #endif
- emit2($4.val);
- }
- | JP indir
- { xyreg($2,0351);}
- | JR expr
- { branch($1,$2);}
- | JR coco ',' expr
- { if ($2 > 3) serror("bad condition code");
- branch(040 | ($2<<3), $4);
- }
- | DJNZ expr
- { branch($1,$2);}
- | CALL expr
- { emit1($1);
- #ifdef RELOCATION
- newrelo($2.typ, RELO2);
- #endif
- emit2($2.val);
- }
- | CALL coco ',' expr
- { emit1(0304 | $2<<3);
- #ifdef RELOCATION
- newrelo($4.typ, RELO2);
- #endif
- emit2($4.val);
- }
- | RET
- { emit1($1);}
- | RET coco
- { emit1(0300 | $2<<3);}
- | RST absexp
- { if (($2&070)!=$2)
- serror("rst expression out of range");
- emit1($1 | $2);
- }
- | IN R8 ',' expr
- { if ($2 != A) serror("register error");
- emit1($1);
- #ifdef RELOCATION
- newrelo($4.typ, RELO1);
- #endif
- emit1($4.val);
- }
- | IN R8 ',' R8
- { if ($4 != C) serror("register error");
- emit1(0355); emit1(0100 | $2<<3);
- }
- | OUT expr ',' R8
- { if ($4 != A) serror("register error");
- emit1($1);
- #ifdef RELOCATION
- newrelo($2.typ, RELO1);
- #endif
- emit1($2.val);
- }
- | OUT R8 ',' R8
- { if ($2 != C) serror("register error");
- emit1(0355); emit1(0101 | $4<<3);
- }
- ;
- ari8 : ARI8
- | ADDOP R8 ','
- { if ($2 != A) serror("register error");}
- | ADCSBC R8 ','
- { if ($2 != A) serror("register error");}
- ;
- ldargs : R8 ',' R8
- { if ($1==F || $3==F) serror("register error");
- if ($1<=A && $3<=A)
- emit1(0100 | $1<<3 | $3);
- else {
- emit1(0355);
- if ((($1==A) ^ ($3==A)) == 0)
- serror("register error");
- emit1( 0107 |
- ($1==R||$3==R)<<3 |
- ($1==A)<<4
- );
- }
- }
- | R8 ',' expr
- { if ($1==F || $1==I || $1==R)
- serror("register error");
- emit1(06 | $1<<3);
- #ifdef RELOCATION
- newrelo($3.typ, RELO1);
- #endif
- emit1($3.val);
- }
- | R8 ',' indir
- { if ($1==F || $1==I || $1==R)
- serror("register error");
- if ($1==A && ($3==BC || $3==DE))
- emit1($3==BC ? 012 : 032);
- else
- xymem($3,0106 | $1<<3);
- }
- | R8 ',' index
- { if ($1==F || $1==I || $1==R)
- serror("register error");
- xymem($3,0106 | $1<<3);
- }
- | R8 ',' '(' expr ')'
- { if ($1!=A) serror("register error");
- emit1(072);
- #ifdef RELOCATION
- newrelo($4.typ, RELO2);
- #endif
- emit2($4.val);
- }
- | indir ',' r8
- { if ($3==A && ($1==BC || $1==DE))
- emit1($1==BC ? 02 : 022);
- else
- xymem($1,0160 | $3);
- }
- | index ',' r8
- { xymem($1,0160 | $3);}
- | indir ',' expr
- { xymem($1,066);
- #ifdef RELOCATION
- newrelo($3.typ, RELO1);
- #endif
- emit1($3.val);
- }
- | index ',' expr
- { xymem($1,066);
- #ifdef RELOCATION
- newrelo($3.typ, RELO1);
- #endif
- emit1($3.val);
- }
- | R16 ',' expr
- { switch ($1) {
- case BC: case DE: case HL: case SP:
- emit1(01 | $1<<4); break;
- case IX: case IY:
- xyreg($1,041); break;
- default: serror("register error");
- }
- #ifdef RELOCATION
- newrelo($3.typ, RELO2);
- #endif
- emit2($3.val);
- }
- | R16 ',' R16
- { if ($1!=SP) serror("register error");
- xyreg($3,0371);
- }
- | R16 ',' '(' expr ')'
- { switch ($1) {
- case BC: case DE: case SP:
- emit1(0355); emit1(0113 | $1<<4); break;
- case HL: case IX: case IY:
- xyreg($1,052); break;
- default: serror("register error");
- }
- #ifdef RELOCATION
- newrelo($4.typ, RELO2);
- #endif
- emit2($4.val);
- }
- | '(' expr ')' ',' R8
- { if ($5!=A) serror("register error");
- emit1(062);
- #ifdef RELOCATION
- newrelo($2.typ, RELO2);
- #endif
- emit2($2.val);
- }
- | '(' expr ')' ',' R16
- { switch ($5) {
- case BC: case DE: case SP:
- emit1(0355); emit1(0103 | $5<<4); break;
- case HL: case IX: case IY:
- xyreg($5,042); break;
- default: serror("register error");
- }
- #ifdef RELOCATION
- newrelo($2.typ, RELO2);
- #endif
- emit2($2.val);
- }
- ;
- r8 : R8
- { if ($1==F || $1==I || $1==R)
- serror("register error");
- }
- ;
- indir : '(' R16 ')'
- { if ($2>=SP && $2!=IX && $2!=IY)
- serror("register error");
- exp_ind.typ = S_ABS; exp_ind.val = 0;
- $$ = $2;
- }
- ;
- index : '(' R16 '+' expr ')'
- { if ($2!=IX && $2!=IY) serror("register error");
- exp_ind = $4;
- RELOMOVE(rel_ind, relonami);
- $$ = $2;
- }
- | '(' R16 '-' expr ')'
- {
- if ($2!=IX && $2!=IY) serror("register error");
- fit(fitb($4.val));
- exp_ind = $4;
- RELOMOVE(rel_ind, relonami);
- $$ = $2;
- }
- ;
- ind : indir
- | index
- ;
- coco : CC
- | R8
- { if ($1 != C) serror("bad condition code");
- $$ = 3;
- }
- ;
|