📄 aicasm_gram.y
字号:
snprintf(errbuf, sizeof(errbuf), "Undefined symbol %s referenced", symbol->name); stop(errbuf, 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; }| 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++; };macrodefn_prologue: T_DEFINE T_SYMBOL { if ($2->type != UNINITIALIZED) { stop("Re-definition of symbol as a macro", EX_DATAERR); /* NOTREACHED */ } cur_symbol = $2; cur_symbol->type = MACRO; initialize_symbol(cur_symbol); };macrodefn: macrodefn_prologue T_MACROBODY { add_macro_body($2); }| macrodefn_prologue '(' macro_arglist ')' T_MACROBODY { add_macro_body($5); cur_symbol->info.macroinfo->narg = $3; };macro_arglist: { /* Macros can take no arguments */ $$ = 0; }| T_ARG { $$ = 1; add_macro_arg($1, 0); }| macro_arglist ',' T_ARG { if ($1 == 0) { stop("Comma without preceeding argument in arg list", EX_DATAERR); /* NOTREACHED */ } $$ = $1 + 1; add_macro_arg($3, $1); };numerical_value: T_NUMBER { $$ = $1; }| '-' T_NUMBER { $$ = -$2; };scratch_ram: T_SRAM '{' { snprintf(errbuf, sizeof(errbuf), "%s%d", SRAM_SYMNAME, num_srams); cur_symbol = symtable_get(SRAM_SYMNAME); cur_symtype = SRAMLOC; cur_symbol->type = SRAMLOC; initialize_symbol(cur_symbol); } reg_address { sram_or_scb_offset = cur_symbol->info.rinfo->address; } size { scb_or_sram_symbol = cur_symbol; } scb_or_sram_attributes '}' { cur_symbol = NULL; scb_or_sram_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); /* 64 bytes of SCB space */ cur_symbol->info.rinfo->size = 64; } reg_address { sram_or_scb_offset = cur_symbol->info.rinfo->address; } size { scb_or_sram_symbol = cur_symbol; } scb_or_sram_attributes '}' { cur_symbol = NULL; scb_or_sram_symbol = NULL; };scb_or_sram_attributes: /* NULL definition is okay */| modes| scb_or_sram_reg_list| modes scb_or_sram_reg_list;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_SYMBOL ']' { process_register(&$1); if ($3->type != CONST) { stop("register offset must be a constant", EX_DATAERR); /* NOTREACHED */ } if (($3->info.cinfo->value + 1) > $1->info.rinfo->size) { stop("Accessing offset beyond range of register", EX_DATAERR); /* NOTREACHED */ } $$.symbol = $1; $$.offset = $3->info.cinfo->value; }| 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.symbol == NULL) { stop("No accumulator has been defined", EX_DATAERR); /* NOTREACHED */ } $$.symbol = accumulator.symbol; $$.offset = 0; };destination: reg_symbol { test_writable_symbol($1.symbol); $$ = $1; };immediate: expression { $$ = $1; };immediate_or_a: expression { if ($1.value == 0 && is_download_const(&$1) == 0) { snprintf(errbuf, sizeof(errbuf), "\nExpression evaluates to 0 and thus " "references the accumulator.\n " "If this is the desired effect, use 'A' " "instead.\n"); stop(errbuf, EX_DATAERR); } $$ = $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; };set_src_mode: T_SET_SRC_MODE T_NUMBER ';' { src_mode = $2; };set_dst_mode: T_SET_DST_MODE T_NUMBER ';' { dst_mode = $2; };critical_section_start: T_BEGIN_CS ';' { critical_section_t *cs; if (in_critical_section != FALSE) { stop("Critical Section within Critical Section", EX_DATAERR); /* NOTREACHED */ } cs = cs_alloc(); cs->begin_addr = instruction_ptr; in_critical_section = TRUE; }critical_section_end: T_END_CS ';' { critical_section_t *cs; if (in_critical_section == FALSE) { stop("Unballanced 'end_cs'", EX_DATAERR); /* NOTREACHED */ } cs = TAILQ_LAST(&cs_tailq, cs_tailq); cs->end_addr = instruction_ptr; in_critical_section = FALSE; }export: { $$ = 0; }| T_EXPORT { $$ = 1; };label: export T_SYMBOL ':' { if ($2->type != UNINITIALIZED) { stop("Program label multiply defined", EX_DATAERR); /* NOTREACHED */ } $2->type = LABEL; initialize_symbol($2); $2->info.linfo->address = instruction_ptr; $2->info.linfo->exported = $1; };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 '{' { 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 == SCOPE_ELSE) { stop("'else' without leading 'if'", EX_DATAERR); /* NOTREACHED */ } new_scope = scope_alloc(); new_scope->type = SCOPE_ELSE; new_scope->begin_addr = instruction_ptr; };conditional: '}' { scope_t *scope_context; scope_context = SLIST_FIRST(&scope_stack); if (scope_context->type == SCOPE_ROOT) { stop("Unexpected '}' encountered", EX_DATAERR); /* NOTREACHED */ } scope_context->end_addr = instruction_ptr; /* Pop the scope */ SLIST_REMOVE_HEAD(&scope_stack, scope_stack_links); process_scope(scope_context); if (SLIST_FIRST(&scope_stack) == NULL) { stop("Unexpected '}' encountered", EX_DATAERR); /* NOTREACHED */ } };f1_opcode: T_AND { $$ = AIC_OP_AND; }| T_XOR { $$ = AIC_OP_XOR; }| T_ADD { $$ = AIC_OP_ADD; }| T_ADC { $$ = AIC_OP_ADC; };code: f1_opcode destination ',' immediate_or_a opt_source ret ';' { format_1_instr($1, &$2, &$4, &$5, $6); };code: T_OR reg_symbol ',' immediate_or_a opt_source ret ';' { format_1_instr(AIC_OP_OR, &$2, &$4, &$5, $6); };code: T_INC destination opt_source ret ';' { expression_t immed; make_expression(&immed, 1); format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4); };code: T_DEC destination opt_source ret ';' { expression_t immed; make_expression(&immed, -1); format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4); };code: T_CLC ret ';' { expression_t immed; make_expression(&immed, -1); format_1_instr(AIC_OP_ADD, &none, &immed, &allzeros, $2); }| T_CLC T_MVI destination ',' immediate_or_a ret ';' { format_1_instr(AIC_OP_ADD, &$3, &$5, &allzeros, $6); };code: T_STC ret ';' { expression_t immed; make_expression(&immed, 1); format_1_instr(AIC_OP_ADD, &none, &immed, &allones, $2); }| T_STC destination ret ';' { expression_t immed; make_expression(&immed, 1); format_1_instr(AIC_OP_ADD, &$2, &immed, &allones, $3); };code: T_BMOV destination ',' source ',' immediate ret ';' { format_1_instr(AIC_OP_BMOV, &$2, &$6, &$4, $7); };code: T_MOV destination ',' source ret ';' { expression_t immed; make_expression(&immed, 1); format_1_instr(AIC_OP_BMOV, &$2, &immed, &$4, $5); };code: T_MVI destination ',' immediate_or_a ret ';' { format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5); };code: T_NOT destination opt_source ret ';' { expression_t immed; make_expression(&immed, 0xff); format_1_instr(AIC_OP_XOR, &$2, &immed, &$3, $4); };code: T_CLR destination ret ';' { expression_t immed; make_expression(&immed, 0xff); format_1_instr(AIC_OP_AND, &$2, &immed, &allzeros, $3); };code: T_NOP ret ';' { expression_t immed; make_expression(&immed, 0xff); format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, $2); };code: T_RET ';' { expression_t immed; make_expression(&immed, 0xff); format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, TRUE); }; /* * This grammer differs from the one in the aic7xxx * reference manual since the grammer listed there is * ambiguous and causes a shift/reduce conflict. * It also seems more logical as the "immediate" * argument is listed as the second arg like the * other formats. */f2_opcode: T_SHL { $$ = AIC_OP_SHL; }| T_SHR { $$ = AIC_OP_SHR; }| T_ROL { $$ = AIC_OP_ROL; }| T_ROR { $$ = AIC_OP_ROR; };code: f2_opcode destination ',' expression opt_source ret ';' { format_2_instr($1, &$2, &$4, &$5, $6); };jmp_jc_jnc_call: T_JMP { $$ = AIC_OP_JMP; }| T_JC { $$ = AIC_OP_JC; }| T_JNC { $$ = AIC_OP_JNC; }| T_CALL { $$ = AIC_OP_CALL; };jz_jnz:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -