diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 486a6ed..43c5a7b 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -136,6 +136,56 @@ static int doswitch(void); static void docase(int isdefault); static int dogoto(void); static void dolabel(void); +static void emit_invalid_token(int expected_token,int found_token); +static regid emit_findreg(char *opname); +static int emit_getlval(int *identptr,emit_outval *p,int *islocal, + regid reg,int allow_char,int allow_const, + int store_pri,int store_alt,int *ispushed); +static int emit_getrval(int *identptr,cell *val); +static int emit_param_any_internal(emit_outval *p,int expected_tok, + int allow_nonint,int allow_expr); +static void emit_param_any(emit_outval *p); +static void emit_param_integer(emit_outval *p); +static void emit_param_index(emit_outval *p,int isrange, + const cell *valid_values,int numvalues); +static void emit_param_nonneg(emit_outval *p); +static void emit_param_shift(emit_outval *p); +static void emit_param_data(emit_outval *p); +static void emit_param_local(emit_outval *p,int allow_ref); +static void emit_param_label(emit_outval *p); +static void emit_param_function(emit_outval *p,int isnative); +static void emit_noop(char *name); +static void emit_parm0(char *name); +static void emit_parm1_any(char *name); +static void emit_parm1_integer(char *name); +static void emit_parm1_nonneg(char *name); +static void emit_parm1_shift(char *name); +static void emit_parm1_data(char *name); +static void emit_parm1_local(char *name); +static void emit_parm1_local_noref(char *name); +static void emit_parm1_label(char *name); +static void emit_do_casetbl(char *name); +static void emit_do_case(char *name); +static void emit_do_lodb_strb(char *name); +static void emit_do_align(char *name); +static void emit_do_call(char *name); +static void emit_do_sysreq_c(char *name); +static void emit_do_sysreq_n(char *name); +static void emit_do_const(char *name); +static void emit_do_const_s(char *name); +static void emit_do_load_both(char *name); +static void emit_do_load_s_both(char *name); +static void emit_do_pushn_c(char *name); +static void emit_do_pushn(char *name); +static void emit_do_pushn_s_adr(char *name); +static void emit_do_load_u_pri_alt(char *name); +static void emit_do_stor_u_pri_alt(char *name); +static void emit_do_addr_u_pri_alt(char *name); +static void emit_do_push_u(char *name); +static void emit_do_push_u_adr(char *name); +static void emit_do_zero_u(char *name); +static void emit_do_inc_dec_u(char *name); +static int emit_findopcode(const char *instr); static int isterminal(int tok); static void doreturn(void); static void dobreak(void); @@ -148,7 +198,7 @@ static int *readwhile(void); static void dopragma(void); static void pragma_apply(symbol *sym); -typedef void (SC_FASTCALL *OPCODE_PROC)(char *name); +typedef void (*OPCODE_PROC)(char *name); typedef struct { char *name; OPCODE_PROC func; @@ -1737,6 +1787,7 @@ static void parse(void) /* ignore zero's */ break; case t__EMIT: + begcseg(); emit_flags |= efGLOBAL; lex(&val,&str); emit_parse_line(); @@ -6561,7 +6612,7 @@ static symbol *fetchlab(char *name) return sym; } -static void SC_FASTCALL emit_invalid_token(int expected_token,int found_token) +static void emit_invalid_token(int expected_token,int found_token) { char s[2]; @@ -6574,7 +6625,7 @@ static void SC_FASTCALL emit_invalid_token(int expected_token,int found_token) } /* if */ } -static regid SC_FASTCALL emit_findreg(char *opname) +static regid emit_findreg(char *opname) { const char *regname=strrchr(opname,'.'); assert(regname!=NULL); @@ -6588,9 +6639,9 @@ static regid SC_FASTCALL emit_findreg(char *opname) * Looks for an lvalue and generates code to get cell address in PRI * if the lvalue is an array element (iARRAYCELL or iARRAYCHAR). */ -static int SC_FASTCALL emit_getlval(int *identptr,emit_outval *p,int *islocal, - regid reg,int allow_char,int allow_const, - int store_pri,int store_alt,int *ispushed) +static int emit_getlval(int *identptr,emit_outval *p,int *islocal, + regid reg,int allow_char,int allow_const, + int store_pri,int store_alt,int *ispushed) { int tok,index,ident,close; cell cidx,val,length; @@ -6650,9 +6701,7 @@ invalid_lvalue: pushreg(store_pri ? sPRI : sALT); *ispushed=TRUE; } /* if */ - errorset(sEXPRMARK,0); ident=expression(&val,NULL,NULL,TRUE); - errorset(sEXPRRELEASE,0); needtoken(close); /* check if the index isn't out of bounds */ @@ -6778,16 +6827,14 @@ invalid_lvalue: * * Looks for an rvalue and generates code to handle expressions. */ -static int SC_FASTCALL emit_getrval(int *identptr,emit_outval *p,int *islocal) +static int emit_getrval(int *identptr,cell *val) { int index,result=TRUE; cell cidx; - cell val; symbol *sym; assert(identptr!=NULL); - assert(p!=NULL); - assert(islocal!=NULL); + assert(val!=NULL); if (staging) { assert((emit_flags & efEXPR)!=0); @@ -6797,14 +6844,12 @@ static int SC_FASTCALL emit_getrval(int *identptr,emit_outval *p,int *islocal) result=FALSE; } /* if */ - errorset(sEXPRMARK,0); - *identptr=expression(&val,NULL,&sym,TRUE); - p->type=eotNUMBER; + *identptr=expression(val,NULL,&sym,TRUE); switch (*identptr) { case iVARIABLE: case iREFERENCE: - *islocal=((sym->vclass & sLOCAL)!=0); - /* fallthrough */ + *val=sym->addr; + break; case iCONSTEXPR: /* If the expression result is a constant value or a variable - erase the code * for this expression so the caller would be able to generate more optimal @@ -6812,7 +6857,6 @@ static int SC_FASTCALL emit_getrval(int *identptr,emit_outval *p,int *islocal) */ if (staging) stgdel(index,cidx); - p->value.ucell=*(ucell *)((*identptr==iCONSTEXPR) ? &val : &sym->addr); break; case iARRAY: case iREFARRAY: @@ -6820,13 +6864,12 @@ static int SC_FASTCALL emit_getrval(int *identptr,emit_outval *p,int *islocal) result=FALSE; break; } /* switch */ - errorset(sEXPRRELEASE,0); return result; } -static int SC_FASTCALL emit_param_any_internal(emit_outval *p,int expected_tok, - int allow_nonint,int allow_expr) +static int emit_param_any_internal(emit_outval *p,int expected_tok, + int allow_nonint,int allow_expr) { char *str; cell val,cidx; @@ -6899,9 +6942,7 @@ fetchtok: if ((emit_flags & efEXPR)==0) stgset(TRUE); stgget(&index,&cidx); - errorset(sEXPRMARK,0); ident=expression(&val,NULL,NULL,FALSE); - errorset(sEXPRRELEASE,0); stgdel(index,cidx); if ((emit_flags & efEXPR)==0) stgset(FALSE); @@ -6947,18 +6988,18 @@ fetchtok: return TRUE; } -static void SC_FASTCALL emit_param_any(emit_outval *p) +static void emit_param_any(emit_outval *p) { emit_param_any_internal(p,teANY,TRUE,TRUE); } -static void SC_FASTCALL emit_param_integer(emit_outval *p) +static void emit_param_integer(emit_outval *p) { emit_param_any_internal(p,tNUMBER,FALSE,TRUE); } -static void SC_FASTCALL emit_param_index(emit_outval *p,int isrange, - const cell *valid_values,int numvalues) +static void emit_param_index(emit_outval *p,int isrange, + const cell *valid_values,int numvalues) { int i; cell val; @@ -6978,7 +7019,7 @@ static void SC_FASTCALL emit_param_index(emit_outval *p,int isrange, error(241); /* negative or too big shift count */ } -static void SC_FASTCALL emit_param_nonneg(emit_outval *p) +static void emit_param_nonneg(emit_outval *p) { if (!emit_param_any_internal(p,teNONNEG,FALSE,TRUE)) return; @@ -6997,14 +7038,14 @@ static void SC_FASTCALL emit_param_nonneg(emit_outval *p) } /* if */ } -static void SC_FASTCALL emit_param_shift(emit_outval *p) +static void emit_param_shift(emit_outval *p) { if (emit_param_any_internal(p,tNUMBER,FALSE,TRUE)) if (p->value.ucell>=(sizeof(cell)*8)) error(50); /* invalid range */ } -static void SC_FASTCALL emit_param_data(emit_outval *p) +static void emit_param_data(emit_outval *p) { cell val; char *str; @@ -7030,7 +7071,7 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) goto invalid_token; } /* if */ } else { - sym=findglb(str,sSTATIC); + sym=findglb(str,sSTATEVAR); if (sym==NULL) { error(17,str); /* undefined symbol */ return; @@ -7058,7 +7099,7 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) error(11); /* must be a multiple of cell size */ } -static void SC_FASTCALL emit_param_local(emit_outval *p,int allow_ref) +static void emit_param_local(emit_outval *p,int allow_ref) { cell val; char *str; @@ -7137,7 +7178,7 @@ fetchtok: p->value.ucell=(ucell)(negate ? -val : val); } -static void SC_FASTCALL emit_param_label(emit_outval *p) +static void emit_param_label(emit_outval *p) { cell val; char *str; @@ -7184,7 +7225,7 @@ static void SC_FASTCALL emit_param_label(emit_outval *p) } } -static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative) +static void emit_param_function(emit_outval *p,int isnative) { cell val; char *str; @@ -7238,17 +7279,17 @@ static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative) } /* if */ } -static void SC_FASTCALL emit_noop(char *name) +static void emit_noop(char *name) { (void)name; } -static void SC_FASTCALL emit_parm0(char *name) +static void emit_parm0(char *name) { outinstr(name,NULL,0); } -static void SC_FASTCALL emit_parm1_any(char *name) +static void emit_parm1_any(char *name) { emit_outval p[1]; @@ -7256,7 +7297,7 @@ static void SC_FASTCALL emit_parm1_any(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_parm1_integer(char *name) +static void emit_parm1_integer(char *name) { emit_outval p[1]; @@ -7264,7 +7305,7 @@ static void SC_FASTCALL emit_parm1_integer(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_parm1_nonneg(char *name) +static void emit_parm1_nonneg(char *name) { emit_outval p[1]; @@ -7272,7 +7313,7 @@ static void SC_FASTCALL emit_parm1_nonneg(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_parm1_shift(char *name) +static void emit_parm1_shift(char *name) { emit_outval p[1]; @@ -7280,7 +7321,7 @@ static void SC_FASTCALL emit_parm1_shift(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_parm1_data(char *name) +static void emit_parm1_data(char *name) { emit_outval p[1]; @@ -7288,7 +7329,7 @@ static void SC_FASTCALL emit_parm1_data(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_parm1_local(char *name) +static void emit_parm1_local(char *name) { emit_outval p[1]; @@ -7296,7 +7337,7 @@ static void SC_FASTCALL emit_parm1_local(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_parm1_local_noref(char *name) +static void emit_parm1_local_noref(char *name) { emit_outval p[1]; @@ -7304,7 +7345,7 @@ static void SC_FASTCALL emit_parm1_local_noref(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_parm1_label(char *name) +static void emit_parm1_label(char *name) { emit_outval p[1]; @@ -7312,7 +7353,7 @@ static void SC_FASTCALL emit_parm1_label(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_do_casetbl(char *name) +static void emit_do_casetbl(char *name) { emit_outval p[2]; @@ -7323,7 +7364,7 @@ static void SC_FASTCALL emit_do_casetbl(char *name) outinstr("case",p,arraysize(p)); } -static void SC_FASTCALL emit_do_case(char *name) +static void emit_do_case(char *name) { emit_outval p[2]; @@ -7333,7 +7374,7 @@ static void SC_FASTCALL emit_do_case(char *name) code_idx-=opcodes(1); } -static void SC_FASTCALL emit_do_lodb_strb(char *name) +static void emit_do_lodb_strb(char *name) { static const cell valid_values[] = { 1,2,4 }; emit_outval p[1]; @@ -7342,7 +7383,7 @@ static void SC_FASTCALL emit_do_lodb_strb(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_do_align(char *name) +static void emit_do_align(char *name) { static const cell valid_values[] = { 0,sizeof(cell)-1 }; emit_outval p[1]; @@ -7351,7 +7392,7 @@ static void SC_FASTCALL emit_do_align(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_do_call(char *name) +static void emit_do_call(char *name) { emit_outval p[1]; @@ -7359,7 +7400,7 @@ static void SC_FASTCALL emit_do_call(char *name) outinstr(name,p,arraysize(p)); } -static void SC_FASTCALL emit_do_sysreq_c(char *name) +static void emit_do_sysreq_c(char *name) { emit_outval p[1]; @@ -7378,7 +7419,7 @@ static void SC_FASTCALL emit_do_sysreq_c(char *name) } /* if */ } -static void SC_FASTCALL emit_do_sysreq_n(char *name) +static void emit_do_sysreq_n(char *name) { emit_outval p[2]; @@ -7401,7 +7442,7 @@ static void SC_FASTCALL emit_do_sysreq_n(char *name) } /* if */ } -static void SC_FASTCALL emit_do_const(char *name) +static void emit_do_const(char *name) { emit_outval p[2]; @@ -7425,7 +7466,7 @@ static void SC_FASTCALL emit_do_const(char *name) } /* if */ } -static void SC_FASTCALL emit_do_const_s(char *name) +static void emit_do_const_s(char *name) { emit_outval p[2]; @@ -7449,7 +7490,7 @@ static void SC_FASTCALL emit_do_const_s(char *name) } /* if */ } -static void SC_FASTCALL emit_do_load_both(char *name) +static void emit_do_load_both(char *name) { emit_outval p[2]; @@ -7469,7 +7510,7 @@ static void SC_FASTCALL emit_do_load_both(char *name) } /* if */ } -static void SC_FASTCALL emit_do_load_s_both(char *name) +static void emit_do_load_s_both(char *name) { emit_outval p[2]; @@ -7489,7 +7530,7 @@ static void SC_FASTCALL emit_do_load_s_both(char *name) } /* if */ } -static void SC_FASTCALL emit_do_pushn_c(char *name) +static void emit_do_pushn_c(char *name) { emit_outval p[5]; int i,numargs; @@ -7511,7 +7552,7 @@ static void SC_FASTCALL emit_do_pushn_c(char *name) } /* if */ } -static void SC_FASTCALL emit_do_pushn(char *name) +static void emit_do_pushn(char *name) { emit_outval p[5]; int i,numargs; @@ -7533,7 +7574,7 @@ static void SC_FASTCALL emit_do_pushn(char *name) } /* if */ } -static void SC_FASTCALL emit_do_pushn_s_adr(char *name) +static void emit_do_pushn_s_adr(char *name) { emit_outval p[5]; int i,numargs; @@ -7556,39 +7597,22 @@ static void SC_FASTCALL emit_do_pushn_s_adr(char *name) } /* if */ } -static void SC_FASTCALL emit_do_load_u_pri_alt(char *name) +static void emit_do_load_u_pri_alt(char *name) { - emit_outval p[1]; + cell val; regid reg; - int ident,islocal; + int ident; - if (!emit_getrval(&ident,&p[0],&islocal)) + if (!emit_getrval(&ident,&val)) return; reg=emit_findreg(name); - switch (ident) { - case iCONSTEXPR: - if (p[0].value.ucell==(ucell)0) - outinstr((reg==sPRI) ? "zero.pri" : "zero.alt",NULL,0); - else - outinstr((reg==sPRI) ? "const.pri" : "const.alt",p,1); - break; - case iVARIABLE: - if (islocal) - outinstr((reg==sPRI) ? "load.s.pri" : "load.s.alt",p,1); - else - outinstr((reg==sPRI) ? "load.pri" : "load.alt",p,1); - break; - case iREFERENCE: - outinstr((reg==sPRI) ? "lref.s.pri" : "lref.s.alt",p,1); - break; - default: - if (reg==sALT) - outinstr("move.alt",NULL,0); - break; - } /* switch */ + if (ident==iCONSTEXPR) + ldconst(val,reg); + else if (reg==sALT) + outinstr("move.alt",NULL,0); } -static void SC_FASTCALL emit_do_stor_u_pri_alt(char *name) +static void emit_do_stor_u_pri_alt(char *name) { emit_outval p[1]; regid reg; @@ -7624,7 +7648,7 @@ static void SC_FASTCALL emit_do_stor_u_pri_alt(char *name) } /* switch */ } -static void SC_FASTCALL emit_do_addr_u_pri_alt(char *name) +static void emit_do_addr_u_pri_alt(char *name) { emit_outval p[1]; regid reg; @@ -7654,30 +7678,20 @@ static void SC_FASTCALL emit_do_addr_u_pri_alt(char *name) } /* switch */ } -static void SC_FASTCALL emit_do_push_u(char *name) +static void emit_do_push_u(char *name) { - emit_outval p[1]; - int ident,islocal; + cell val; + int ident; - if (!emit_getrval(&ident,&p[0],&islocal)) + if (!emit_getrval(&ident,&val)) return; - switch (ident) { - case iCONSTEXPR: - outinstr("push.c",&p[0],1); - break; - case iVARIABLE: - outinstr(islocal ? "push.s" : "push",p,1); - break; - case iREFERENCE: - outinstr("lref.s.pri",&p[0],1); - /* fallthrough */ - default: + if (ident==iCONSTEXPR) + pushval(val); + else outinstr("push.pri",NULL,0); - break; - } /* switch */ } -static void SC_FASTCALL emit_do_push_u_adr(char *name) +static void emit_do_push_u_adr(char *name) { emit_outval p[1]; int ident,islocal; @@ -7701,7 +7715,7 @@ static void SC_FASTCALL emit_do_push_u_adr(char *name) } /* switch */ } -static void SC_FASTCALL emit_do_zero_u(char *name) +static void emit_do_zero_u(char *name) { emit_outval p[1]; int ident,islocal; @@ -7731,7 +7745,7 @@ static void SC_FASTCALL emit_do_zero_u(char *name) } /* switch */ } -static void SC_FASTCALL emit_do_inc_dec_u(char *name) +static void emit_do_inc_dec_u(char *name) { emit_outval p[1]; int ident,islocal; diff --git a/source/compiler/tests/__emit_pcode_check.meta b/source/compiler/tests/__emit_pcode_check.meta index 3c1fd70..268a73e 100644 --- a/source/compiler/tests/__emit_pcode_check.meta +++ b/source/compiler/tests/__emit_pcode_check.meta @@ -409,12 +409,15 @@ [0-9a-f]+ strb.i 00000001 [0-9a-f]+ push.r 00000028 [0-9a-f]+ push.c 00001234 -[0-9a-f]+ push 00000000 +[0-9a-f]+ load.pri 00000000 +[0-9a-f]+ push.pri [0-9a-f]+ lref.s.pri 0000000c [0-9a-f]+ push.pri [0-9a-f]+ push.c 00005678 -[0-9a-f]+ push.s fffffffc -[0-9a-f]+ push 0000000c +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ push.pri +[0-9a-f]+ load.pri 0000000c +[0-9a-f]+ push.pri [0-9a-f]+ push.c 00009abc [0-9a-f]+ push.r 00000029 [0-9a-f]+ push.c 000068ac