📄 aicasm_gram.y
字号:
}| 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); /* 64 bytes of SCB space */ cur_symbol->info.rinfo->size = 64; } 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_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 == 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; };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; }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 '{' { 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -