202 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#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 int 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");
 | 
						|
				}
 | 
						|
			}
 | 
						|
	;
 |