⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aicasm_gram.y

📁 基于组件方式开发操作系统的OSKIT源代码
💻 Y
📖 第 1 页 / 共 2 页
字号:
%{/* * Parser for the Aic7xxx SCSI Host adapter sequencer assembler. * * Copyright (c) 1997-1998 Justin T. Gibbs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions, and the following disclaimer, *    without modification, immediately at the beginning of the file. * 2. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *      $Id: aicasm_gram.y,v 1.6 1998/12/10 04:14:50 gibbs Exp $ */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sysexits.h>#include <sys/types.h>#include <sys/queue.h>#include "aicasm.h"#include "aicasm_symbol.h"#include "sequencer.h"int yylineno;char *yyfilename;static symbol_t *cur_symbol;static symtype cur_symtype;static symbol_t *accumulator;static symbol_ref_t allones;static symbol_ref_t allzeros;static symbol_ref_t none;static symbol_ref_t sindex;static int instruction_ptr;static int sram_or_scb_offset;static int download_constant_count;static void process_bitmask __P((int mask_type, symbol_t *sym, int mask));static void initialize_symbol __P((symbol_t *symbol));static void process_register __P((symbol_t **p_symbol));static void format_1_instr __P((int opcode, symbol_ref_t *dest,				expression_t *immed, symbol_ref_t *src,				int ret));static void format_2_instr __P((int opcode, symbol_ref_t *dest,				expression_t *places, symbol_ref_t *src,				int ret));static void format_3_instr __P((int opcode, symbol_ref_t *src,				expression_t *immed, symbol_ref_t *address));static void test_readable_symbol __P((symbol_t *symbol));static void test_writable_symbol __P((symbol_t *symbol));static void type_check __P((symbol_t *symbol, expression_t *expression,			    int and_op));static void make_expression __P((expression_t *immed, int value));static void add_conditional __P((symbol_t *symbol));static int  is_download_const __P((expression_t *immed));#define YYDEBUG 1#define SRAM_SYMNAME "SRAM_BASE"#define SCB_SYMNAME "SCB_BASE"%}%union {	int		value;	char		*str;	symbol_t	*sym;	symbol_ref_t	sym_ref;	expression_t	expression;}%token T_REGISTER%token <value> T_CONST%token T_DOWNLOAD%token T_SCB%token T_SRAM%token T_ALIAS%token T_SIZE%token <value> T_ADDRESS%token T_ACCESS_MODE%token <value> T_MODE%token T_BIT%token T_MASK%token <value> T_NUMBER%token <str> T_PATH%token <sym> T_CEXPR%token T_EOF T_INCLUDE %token <value> T_SHR T_SHL T_ROR T_ROL%token <value> T_MVI T_MOV T_CLR T_BMOV%token <value> T_JMP T_JC T_JNC T_JE T_JNE T_JNZ T_JZ T_CALL%token <value> T_ADD T_ADC%token <value> T_INC T_DEC%token <value> T_STC T_CLC%token <value> T_CMP T_XOR%token <value> T_TEST T_AND%token <value> T_OR%token T_RET%token T_NOP%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX%token T_A%token <sym> T_SYMBOL%token T_NL%token T_IF T_ELSE T_ELSE_IF T_ENDIF%type <sym_ref> reg_symbol address destination source opt_source%type <expression> expression immediate immediate_or_a%type <value> ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne%type <value> numerical_value%left '|'%left '&'%left '+' '-'%right '~'%nonassoc UMINUS%%program:	include|	program include|	register|	program register|	constant|	program constant|	scratch_ram|	program scratch_ram|	scb|	program scb|	label|	program label|	conditional|	program conditional|	code|	program code;include:	T_INCLUDE '<' T_PATH '>'	{ include_file($3, BRACKETED_INCLUDE); }|	T_INCLUDE '"' T_PATH '"'	{ include_file($3, QUOTED_INCLUDE); };register:	T_REGISTER { cur_symtype = REGISTER; } reg_definition;reg_definition:	T_SYMBOL '{'		{			if ($1->type != UNINITIALIZED) {				stop("Register multiply defined", EX_DATAERR);				/* NOTREACHED */			}			cur_symbol = $1; 			cur_symbol->type = cur_symtype;			initialize_symbol(cur_symbol);		}		reg_attribute_list	'}'		{                    			/*			 * Default to allowing everything in for registers			 * with no bit or mask definitions.			 */			if (cur_symbol->info.rinfo->valid_bitmask == 0)				cur_symbol->info.rinfo->valid_bitmask = 0xFF;			if (cur_symbol->info.rinfo->size == 0)				cur_symbol->info.rinfo->size = 1;			/*			 * This might be useful for registers too.			 */			if (cur_symbol->type != REGISTER) {				if (cur_symbol->info.rinfo->address == 0)					cur_symbol->info.rinfo->address =					    sram_or_scb_offset;				sram_or_scb_offset +=				    cur_symbol->info.rinfo->size;			}			cur_symbol = NULL;		};reg_attribute_list:	reg_attribute|	reg_attribute_list reg_attribute;reg_attribute:			reg_address|	size|	access_mode|	bit_defn|	mask_defn|	alias|	accumulator|	allones|	allzeros|	none|	sindex;reg_address:	T_ADDRESS T_NUMBER	{		cur_symbol->info.rinfo->address = $2;	};size:	T_SIZE T_NUMBER	{		cur_symbol->info.rinfo->size = $2;	};access_mode:	T_ACCESS_MODE T_MODE	{		cur_symbol->info.rinfo->mode = $2;	};bit_defn:	T_BIT T_SYMBOL T_NUMBER	{		process_bitmask(BIT, $2, $3);	};mask_defn:	T_MASK T_SYMBOL expression	{		process_bitmask(MASK, $2, $3.value);	};alias:	T_ALIAS	T_SYMBOL	{		if ($2->type != UNINITIALIZED) {			stop("Re-definition of register alias",			     EX_DATAERR);			/* NOTREACHED */		}		$2->type = ALIAS;		initialize_symbol($2);		$2->info.ainfo->parent = cur_symbol;	};accumulator:	T_ACCUM	{		if (accumulator != NULL) {			stop("Only one accumulator definition allowed",			     EX_DATAERR);			/* NOTREACHED */		}		accumulator = cur_symbol;	};allones:	T_ALLONES	{		if (allones.symbol != NULL) {			stop("Only one definition of allones allowed",			     EX_DATAERR);			/* NOTREACHED */		}		allones.symbol = cur_symbol;	};allzeros:	T_ALLZEROS	{		if (allzeros.symbol != NULL) {			stop("Only one definition of allzeros allowed",			     EX_DATAERR);			/* NOTREACHED */		}		allzeros.symbol = cur_symbol;	};none:	T_NONE	{		if (none.symbol != NULL) {			stop("Only one definition of none allowed",			     EX_DATAERR);			/* NOTREACHED */		}		none.symbol = cur_symbol;	};sindex:	T_SINDEX	{		if (sindex.symbol != NULL) {			stop("Only one definition of sindex allowed",			     EX_DATAERR);			/* NOTREACHED */		}		sindex.symbol = cur_symbol;	};expression:	expression '|' expression	{		 $$.value = $1.value | $3.value;		 symlist_merge(&$$.referenced_syms,			       &$1.referenced_syms,			       &$3.referenced_syms);	}|	expression '&' expression	{		$$.value = $1.value & $3.value;		symlist_merge(&$$.referenced_syms,			       &$1.referenced_syms,			       &$3.referenced_syms);	}|	expression '+' expression	{		$$.value = $1.value + $3.value;		symlist_merge(&$$.referenced_syms,			       &$1.referenced_syms,			       &$3.referenced_syms);	}|	expression '-' expression	{		$$.value = $1.value - $3.value;		symlist_merge(&($$.referenced_syms),			       &($1.referenced_syms),			       &($3.referenced_syms));	}|	'(' expression ')'	{		$$ = $2;	}|	'~' expression	{		$$ = $2;		$$.value = (~$$.value) & 0xFF;	}|	'-' expression %prec UMINUS	{		$$ = $2;		$$.value = -$$.value;	}|	T_NUMBER	{		$$.value = $1;		SLIST_INIT(&$$.referenced_syms);	}|	T_SYMBOL	{		symbol_t *symbol;		symbol = $1;		switch (symbol->type) {		case ALIAS:			symbol = $1->info.ainfo->parent;		case REGISTER:		case SCBLOC:		case SRAMLOC:			$$.value = symbol->info.rinfo->address;			break;		case MASK:		case BIT:			$$.value = symbol->info.minfo->mask;			break;		case DOWNLOAD_CONST:		case CONST:			$$.value = symbol->info.cinfo->value;			break;		case UNINITIALIZED:		default:		{			char buf[255];			snprintf(buf, sizeof(buf),				 "Undefined symbol %s referenced",				 symbol->name);			stop(buf, EX_DATAERR);			/* NOTREACHED */			break;		}		}		SLIST_INIT(&$$.referenced_syms);		symlist_add(&$$.referenced_syms, symbol, SYMLIST_INSERT_HEAD);	};constant:	T_CONST T_SYMBOL numerical_value	{		if ($2->type != UNINITIALIZED) {			stop("Re-definition of symbol as a constant",			     EX_DATAERR);			/* NOTREACHED */		}		$2->type = CONST;		initialize_symbol($2);		$2->info.cinfo->value = $3;		$2->info.cinfo->define = $1;	}|	T_CONST T_SYMBOL T_DOWNLOAD	{		if ($1) {			stop("Invalid downloaded constant declaration",			     EX_DATAERR);			/* NOTREACHED */		}		if ($2->type != UNINITIALIZED) {			stop("Re-definition of symbol as a downloaded constant",			     EX_DATAERR);			/* NOTREACHED */		}		$2->type = DOWNLOAD_CONST;		initialize_symbol($2);		$2->info.cinfo->value = download_constant_count++;		$2->info.cinfo->define = FALSE;	};numerical_value:	T_NUMBER	{		$$ = $1;	}|	'-' T_NUMBER	{		$$ = -$2;	};scratch_ram:	T_SRAM '{'		{			cur_symbol = symtable_get(SRAM_SYMNAME);			cur_symtype = SRAMLOC;			if (cur_symbol->type != UNINITIALIZED) {				stop("Only one SRAM definition allowed",				     EX_DATAERR);				/* NOTREACHED */			}			cur_symbol->type = SRAMLOC;			initialize_symbol(cur_symbol);		}		reg_address		{			sram_or_scb_offset = cur_symbol->info.rinfo->address;		}		scb_or_sram_reg_list	'}'		{			cur_symbol = NULL;		};scb:	T_SCB '{'		{			cur_symbol = symtable_get(SCB_SYMNAME);			cur_symtype = SCBLOC;			if (cur_symbol->type != UNINITIALIZED) {				stop("Only one SRAM definition allowed",				     EX_SOFTWARE);				/* NOTREACHED */			}			cur_symbol->type = SCBLOC;			initialize_symbol(cur_symbol);		}		reg_address		{			sram_or_scb_offset = cur_symbol->info.rinfo->address;		}		scb_or_sram_reg_list	'}'		{			cur_symbol = NULL;		};scb_or_sram_reg_list:	reg_definition|	scb_or_sram_reg_list reg_definition;reg_symbol:	T_SYMBOL	{		process_register(&$1);		$$.symbol = $1;		$$.offset = 0;	}|	T_SYMBOL '[' T_NUMBER ']'	{		process_register(&$1);		if (($3 + 1) > $1->info.rinfo->size) {			stop("Accessing offset beyond range of register",			     EX_DATAERR);			/* NOTREACHED */		}		$$.symbol = $1;		$$.offset = $3;	}|	T_A	{		if (accumulator == NULL) {			stop("No accumulator has been defined", EX_DATAERR);			/* NOTREACHED */		}		$$.symbol = accumulator;		$$.offset = 0;	};destination:	reg_symbol	{		test_writable_symbol($1.symbol);		$$ = $1;	};immediate:	expression	{ $$ = $1; };immediate_or_a:	expression	{		$$ = $1;	}|	T_A	{		SLIST_INIT(&$$.referenced_syms);		$$.value = 0;	};source:	reg_symbol	{		test_readable_symbol($1.symbol);		$$ = $1;	};opt_source:	{		$$.symbol = NULL;		$$.offset = 0;	}|	',' source	{ $$ = $2; };ret:	{ $$ = 0; }|	T_RET	{ $$ = 1; };label:	T_SYMBOL ':'	{		if ($1->type != UNINITIALIZED) {			stop("Program label multiply defined", EX_DATAERR);			/* NOTREACHED */		}		$1->type = LABEL;		initialize_symbol($1);		$1->info.linfo->address = instruction_ptr;	};address:	T_SYMBOL	{		$$.symbol = $1;		$$.offset = 0;	}|	T_SYMBOL '+' T_NUMBER	{		$$.symbol = $1;		$$.offset = $3;	}|	T_SYMBOL '-' T_NUMBER	{		$$.symbol = $1;		$$.offset = -$3;	}|	'.'	{		$$.symbol = NULL;		$$.offset = 0;	}|	'.' '+' T_NUMBER	{		$$.symbol = NULL;		$$.offset = $3;	}|	'.' '-' T_NUMBER	{		$$.symbol = NULL;		$$.offset = -$3;	};conditional:	T_IF T_CEXPR '{'	{		scope_t *new_scope;		add_conditional($2);		new_scope = scope_alloc();		new_scope->type = SCOPE_IF;		new_scope->begin_addr = instruction_ptr;		new_scope->func_num = $2->info.condinfo->func_num;	}|	T_ELSE T_IF T_CEXPR '{'	{		scope_t *new_scope;		scope_t *scope_context;		scope_t *last_scope;		/*		 * Ensure that the previous scope is either an		 * if or and else if.		 */		scope_context = SLIST_FIRST(&scope_stack);		last_scope = TAILQ_LAST(&scope_context->inner_scope,					scope_tailq);		if (last_scope == NULL		 || last_scope->type == T_ELSE) {			stop("'else if' without leading 'if'", EX_DATAERR);			/* NOTREACHED */		}		add_conditional($3);		new_scope = scope_alloc();		new_scope->type = SCOPE_ELSE_IF;		new_scope->begin_addr = instruction_ptr;		new_scope->func_num = $3->info.condinfo->func_num;	}|	T_ELSE '{'

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -