123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #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".
- *
- */
- /*
- * Motorola 6809 parsing rules
- */
- operation
- : SETDP expr
- { dpvalue = $2.val;}
- |
- NOARG
- { emit1or2($1);}
- |
- BRANCH expr
- { branch($1,$2);}
- |
- LBRNCH expr
- { emit1(0x10); emit1($1);
- $2.val -= (DOTVAL+2);
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($2.typ, RELPC|RELO2|RELBR);
- #endif
- emit2($2.val);
- }
- |
- SBRNCH expr
- { emit1($1);
- $2.val -= (DOTVAL+2);
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($2.typ, RELPC|RELO2|RELBR);
- #endif
- emit2($2.val);
- }
- |
- IMMED '#' expr
- { emit1($1);
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($3.typ, RELO1);
- #endif
- emit1($3.val);
- }
- |
- XOP '#' expr
- { emit1or2($1 - 0x20);
- switch ($1 & 0x0F) {
- case 0x03:
- case 0x0C:
- case 0x0E:
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($3.typ, RELO2|RELBR);
- #endif
- emit2($3.val);
- break;
- default:
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($3.typ, RELO1);
- #endif
- emit1($3.val);
- break;
- }
- }
- |
- XOP '<' expr
- { if (0 <= $1 && $1 < 0x80)
- emit1(($1-0x10) & 0x3F);
- else
- emit1or2($1 - 0x10);
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($3.typ, RELO1);
- #endif
- emit1($3.val);
- }
- |
- XOP '>' expr
- { emit1or2($1 + 0x10);
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($3.typ, RELO2|RELBR);
- #endif
- emit2($3.val);
- }
- |
- STACK reglist
- { emit1($1); emit1($2);}
- |
- TWOREG REG ',' REG
- {
- emit1($1);
- emit1($2 << 4 | $4);
- }
- |
- XOP REG
- { switch ($2) {
- case A: emit1($1 - 0x20);
- break;
- case B: emit1($1 - 0x10);
- break;
- default:serror("register error");
- }
- }
- |
- XOP expr ',' REG
- { emit1or2($1);
- offset($4,$2,0);
- }
- |
- XOP '(' expr ',' REG ')'
- { emit1or2($1);
- offset($5,$3,0x10);
- }
- |
- XOP '(' expr ')'
- { emit1or2($1);
- emit1(0x9F);
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($3.typ, RELO2|RELBR);
- #endif
- emit2($3.val);
- }
- |
- XOP xmode
- { emit1or2($1);
- emit1($2);
- }
- |
- XOP '(' xmode ')'
- { if (($3 & 0x8D) == 0x80)
- serror("invalid index mode");
- emit1or2($1);
- emit1($3 + 0x10);
- }
- |
- XOP expr
- { if (($2.typ & S_TYP) == S_ABS &&
- ((unsigned)$2.val >> 8) == dpvalue
- ) {
- if (0 <= $1 && $1 < 0x80)
- emit1(($1-0x20) & 0x3F);
- else
- emit1or2($1 - 0x10);
- emit1($2.val);
- } else {
- emit1or2($1 + 0x10);
- #ifdef RELOCATION
- if (rflag != 0 && PASS_RELO)
- newrelo($2.typ, RELO2|RELBR);
- #endif
- emit2($2.val);
- }
- }
- ;
- reglist : ALL
- | REG
- { if (($$ = regbit[$1]) < 0) serror("register error");}
- |
- reglist ',' REG
- { register i;
- if ((i = regbit[$3]) < 0 || ($1 & i) != 0)
- serror("register error");
- $$ = $1 | i;
- }
- ;
- xyus : REG
- { if (($$ = regno($1)) < 0) serror("register error");}
- ;
- xmode : ',' xyus '+' '+'
- { $$ = 0x81 + $2;}
- |
- ',' xyus '+'
- { $$ = 0x80 + $2;}
- |
- ',' xyus
- { $$ = 0x84 + $2;}
- |
- ',' '-' '-' xyus
- { $$ = 0x83 + $4;}
- |
- ',' '-' xyus
- { $$ = 0x82 + $3;}
- |
- REG ',' xyus
- { switch($1) {
- case A: $$ = 0x86 + $3; break;
- case B: $$ = 0x85 + $3; break;
- case D: $$ = 0x8B + $3; break;
- default: serror("register error");
- }
- }
- ;
|