Mercurial > hg > CbC > old > device
changeset 462:f7c87020e6fe
inline
author | kono |
---|---|
date | Fri, 03 Dec 2004 01:05:17 +0900 |
parents | 2a49dfe59540 |
children | 50a59dfb4606 |
files | Changes mc-inline.c mc-inline.h |
diffstat | 3 files changed, 892 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Thu Dec 02 19:38:00 2004 +0900 +++ b/Changes Fri Dec 03 01:05:17 2004 +0900 @@ -6991,3 +6991,11 @@ attribute ねぇ。見たくないねぇ。 inline は、あとは partial evaluator だけだね。 + +gexpr とおんなじ感じで、すべてをcopyする必要がある。lvar は、 +表引で入れ換え。disp は、その分、増加させる。register 宣言は、 +その時で探すことになる。pfdecl でもレジスタは再配分しないと +いけないんだけどね。 + +partial evaluator って思ったより量が多いなぁ。 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc-inline.c Fri Dec 03 01:05:17 2004 +0900 @@ -0,0 +1,860 @@ +/* Micro-C Partial Evaluator Part */ +/* $Id$ */ + +#include <stdio.h> +#include "mc.h" +#include "mc-parse.h" +#include "mc-codegen.h" +#include "mc-switch.h" + + +/* + Basic code generator from parse tree + */ + +extern void +st_decl(int e1){ + // NMTBL *n = (NMTBL *)caddr(e1); + // int stmode = cadddr(e1); +} + +extern void +st_if(int e1){ + int l1,l2,slfree; + int e2=caddr(e1),e3; + // conv->if_(); + slfree=lfree; + checkret(); + l1 = bexpr(car(e2),0,fwdlabel()); + // conv->if_then_(); + g_expr_u(cadr(e2)); + checkret(); + if ((e3=caddr(e2))) { // else + // conv->if_else_(); + if ((l2 = control)) + gen_jmp(l2=fwdlabel()); + fwddef(l1); + g_expr_u(e3); + checkret(); + if (l2) fwddef(l2); + } else { + fwddef(l1); + } + // conv->if_endif_(); +} + + +extern void +st_do(int e1){ + int sbreak,scontinue,l; + + sbreak=blabel; + scontinue=clabel; + blabel=fwdlabel(); + clabel=fwdlabel(); + control=1; + checkret(); + l=backdef(); + // conv->dowhile_(); + g_expr_u(cadddr(e1)); + checkret(); + // conv->dowhile_cond_(); + bexpr(caddr(e1),1,l); + // conv->dowhile_end_(); + fwddef(blabel); + clabel=scontinue; + blabel=sbreak; +} + + +extern void +st_while(int e1){ + int sbreak,scontinue,e; + + sbreak=blabel; + scontinue=clabel; + blabel=fwdlabel(); + control=1; + checkret(); + clabel=backdef(); + // conv->while_(); + // conv->while_body_(); + if(!(e=cadddr(e1))) { + bexpr(caddr(e1),1,clabel); + // conv->sm_(); + } else { + bexpr(caddr(e1),0,blabel); + g_expr_u(e); + checkret(); + if(control) + gen_jmp(clabel); + } + // conv->while_end_(); + fwddef(blabel); + clabel=scontinue; + blabel=sbreak; +} + + +extern void +st_for(int e1){ + int p0,p1,p2,body; + int l,e; + int sbreak=blabel; + int scontinue=clabel; + + e = caddr(e1); + p0 = car(e); p1 = cadr(e); p2 = caddr(e); body = cadddr(e); + + blabel=fwdlabel(); + // conv->for_(); + if (p0) { + checkret(); + g_expr_u(p0); + } + // conv->for1_(); + control=1; + checkret(); + l=backdef(); + if (p1) { + bexpr(p1,0,blabel); + } + // conv->for2_(); + // conv->for_body_(); + if (!p2) { + clabel=l; + g_expr_u(body); + checkret(); + } else { + clabel=fwdlabel(); + g_expr_u(body); + checkret(); + fwddef(clabel); + g_expr_u(p2); + } + // conv->for_end_(); + gen_jmp(l); + fwddef(blabel); + clabel=scontinue; + blabel=sbreak; +} + + +extern void +st_switch(int e1){ + int sbreak,scase,sdefault,slfree,svalue,slist; + + checkret(); + slist = cslist; + cslist = 0; + sbreak=blabel; /* save parents break label */ + blabel=fwdlabel(); + sdefault=dlabel; /* save parents default label */ + dlabel=0; + scase=cslabel; /* save parents next case label */ + // conv->switch_(); + slfree=lfree; + svalue=csvalue1; /* save parents switch value */ + gexpr(caddr(e1),1); + csvalue1=csvalue() ; + // conv->switch_body_(); + cslabel = control = 0; + g_expr_u(cadddr(e1)); + // conv->switch_end_(); + checkret(); +#if CASE_CODE + if (control) gen_jmp(blabel); + genswitch(cslist,cslabel); +#else + if(dlabel) def_label(cslabel,dlabel); + else fwddef(cslabel); +#endif + csvalue1=svalue; + cslabel=scase; + dlabel=sdefault; + fwddef(blabel); + blabel=sbreak; + cslist = slist; +} + + +extern void +st_comp(int e1){ + g_expr_u(caddr(e1)); +} + + +extern void +st_break(int e1){ + checkret(); + // conv->break_(); + if (control) + gen_jmp(blabel); +} + + +extern void +st_continue(int e1){ + checkret(); + // conv->continue_(); + if (control) gen_jmp(clabel); +} + + +extern void +st_case(int e1){ +#if CASE_CODE + int l,clist=caddr(e1),c; + l = fwdlabel(); + // conv->case_begin_(0,0); + // conv->case_(0,0); + if (retpending) { + ret(); retpending=0; + } + if (!cslabel) { + if (!control) { + cmpdimm(car(clist),csvalue1,cslabel=fwdlabel(),1); + caddr(clist)=0; + } else { + error(-1); + } + } + while(clist) { + caddr(clist) = l; + clist = cadr(c=clist); cadr(c) = 0; // insert destroy cadr of clist + cslist=insert_ascend(cslist,c,docase_eq); + } + fwddef(l); + control=1; +#else + /* casading branch implementation */ + int c,l; + c = caddr(e1); + if (retpending) { + ret(); retpending=0; + } + // conv->case_begin_(0,0); + // conv->case_(0,0); + l=fwdlabel(); + if (control) { + control=0; + gen_jmp(l); + } + if (cslabel) fwddef(cslabel); + while(cadr(c)) { + cmpdimm(car(c),csvalue1,l,0); + c=cadr(c); + } + cmpdimm(car(c),csvalue1,cslabel=fwdlabel(),1); + if (l) fwddef(l); +#endif +} + + +extern void +st_default(int e1){ + control=1; + checkret(); + if (dlabel) error(STERR); // double default: + dlabel = backdef(); + // conv->case_(0,1); +} + + +extern void +st_return(int e1){ + int e; + + if (!cslabel) gen_jmp(cslabel = fwdlabel()); + if(!(e=caddr(e1))) { + // conv->return_(); + // conv->return_end_(); + retpending = 1; + return; + } + // conv->return_(); + if (struct_return) { + if ((car(type)==STRUCT || car(type)==UNION)&& + size(type)==cadr(struct_return)) { + if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) { + /* pass the return pointer to the called function */ + replace_return_struct(cadr(e), + rvalue_t(car(struct_return),caddr(struct_return))); + replace_return_struct(cadr(e), + rvalue_t(car(struct_return),caddr(struct_return))); + gexpr(cadr(e),0); + } else { + type = caddr(struct_return); + // e1 = rvalue_t(cadr(struct_return),INT); /* size */ + e1 = cadr(struct_return); /* size */ + gexpr(list4(STASS,rvalue(car(struct_return)),e,e1),0); + } + } else { + error(TYERR); /* should check compatible */ + } + } else { + gexpr(correct_type(e,cadr(fnptr->ty)),1); + } + // conv->return_end_(); + retpending = 1; +} + + +extern void +st_goto(int e){ + NMTBL *nlist,*nptr0; + int t,e1,e2,env; + + checkret(); + // conv->goto_(); + e1 = caddr(e); + if (car(e1)==RINDIRECT) { + gen_indirect_goto(cadr(e1)); + return; + } else if (car(e1)==FLABEL) { + nlist = (NMTBL *)cadr(e1); + nptr0 = name_space_search(nlist,0); + t = nptr0->sc; + if (t==EMPTY||t==EXTRN1||t==EXTRN) { + nptr0 = make_local_scope(nlist,nptr0,0); + nptr0->sc = FLABEL; + nptr0->dsp = fwdlabel(); + } else if (!(t==FLABEL||t==BLABEL)) { + error(STERR); + } + gen_jmp(nptr0->dsp); + control=0; + // conv->sm_(); + // conv->goto_label_(nptr0); + return; + } else { + /* CbC continuation */ + // conv->jump_(env); + e2 = cadr(e1); + env = caddr(e1); + if (car(e2) == FNAME) { + nptr0=(NMTBL *)cadr(e2); + if (nptr0->sc==EMPTY) + nptr0->sc = EXTRN1; + else if(nptr0->sc==FUNCTION) + nptr0->sc = CODE; + if (nptr0->ty>0&&car(nptr0->ty)==FUNCTION) + car(nptr0->ty)=CODE; + } + gexpr(list3(CODE,e1,env),0); + control=0; + // conv->sm_(); + return; + } +} + + +#if ASM_CODE +extern void +st_asm(int e1){ + checkret(); + g_expr_u(list3(ASM,caddr(e1),cadddr(e1))); +} +#endif + + +extern void +st_label(int e1){ + NMTBL *nptr,*nlist; + nlist = (NMTBL *)caddr(e1); + nptr = name_space_search(nlist,0); + control=1; + checkret(); + if(nptr->sc == FLABEL) { + fwddef(nptr->dsp); + } else if(nptr->sc != EMPTY && nptr->sc != EXTRN1 && nptr->sc !=BLABEL) { + error(TYERR); + } else { + nptr->sc=EMPTY; + nptr = make_local_scope(nlist,nptr,0); + nptr->sc = BLABEL; + nptr->dsp = backdef(); + } + // conv->label_(); +} + +extern void +st_comment(int e1){ + gen_comment((char *)caddr(e1)); +} + +/* + partial evaluator + */ + +static int convlvar; + +static int +pconv_var(int e) +{ + return 0; +} + +static int +p_lvar(int e1) +{ + return e1; +} + +static int +pfunction(int e) +{ + +} + +static int +prindirect(int e) +{ + +} + +static int +paddress(int e) +{ + +} + +static int +p_conv(int e) +{ + +} + +code_lpreinc(int e) +{ + +} + +static int +pbinop(int e) +{ + +} + +static int +pdbinop(int e) +{ + +} + +static int +plbinop(int e) +{ + +} + +static int +psassign(int e) +{ + +} + +static int +passign(int e) +{ + +} + +static int +passop(int e) +{ + +} + +static int +pdassign(int e) +{ + +} + +static int +pdassop(int e) +{ + +} + +static int +plassign(int e) +{ + +} + +static int +plassop(int e) +{ + +} + +static int +palloc(int e) +{ + +} + +static int +pcomma(int e) +{ + +} + +static int +prbit_field(int e) +{ + +} + +static int +pbassign(int e) +{ + +} + +static int +pbassop(int e) +{ + +} + +static int +p_decl(int e) +{ + +} + +static int +p_if(int e) +{ + +} + +static int +p_do(int e) +{ + +} + +static int +p_while(int e) +{ + +} + +static int +p_for(int e) +{ + +} + +static int +p_switch(int e) +{ + +} + +static int +p_comp(int e) +{ + +} + +static int +p_break(int e) +{ + +} + +static int +p_continue(int e) +{ + +} + +static int +p_case(int e) +{ + +} + +static int +p_default(int e) +{ + +} + +static int +p_return(int e) +{ + +} + +static int +p_goto(int e) +{ + +} + +static int +p_asm(int e) +{ + +} + +static int +p_label(int e) +{ + +} + +static int +p_bool(int e) +{ + +} + +static int +pexpr0(int e1) +{ + int e2,e3; + NMTBL *n; + + if (inmode) error(-1); + e2 = cadr(e1); + switch (car(e1)){ + case GVAR: case RGVAR: case CRGVAR: case CURGVAR: case SRGVAR: + case SURGVAR: case REGISTER: +#if FLOAT_CODE + case DREGISTER: case FREGISTER: +#endif +#if LONGLONG_CODE + case LREGISTER: +#endif + case LABEL: case CONST: +#if FLOAT_CODE + case DCONST: case FCONST: +#endif +#if LONGLONG_CODE + case LCONST: +#endif + case STRING: + case FNAME: + case RSTRUCT: + return e1; + case LVAR: + case RLVAR: case CRLVAR: case CURLVAR: case SRLVAR: case SURLVAR: +#if FLOAT_CODE + case FRLVAR: case FRGVAR: case DRLVAR: case DRGVAR: +#endif +#if LONGLONG_CODE + case LRLVAR: case LRGVAR: case LURLVAR: case LURGVAR: + return p_lvar(e1); +#endif + case FUNCTION: + return pfunction(e1); + case CODE: + return list2(car(e1),pexpr0(e2)); + case INLINE: + return pexpr(e1); + case INDIRECT: + return prindirect(e1); + case RINDIRECT: case URINDIRECT: + case CRINDIRECT: case CURINDIRECT: + case SRINDIRECT: case SURINDIRECT: +#if FLOAT_CODE + case FRINDIRECT: case DRINDIRECT: +#endif +#if LONGLONG_CODE + case LRINDIRECT: case LURINDIRECT: +#endif + return prindirect(e1); + case ADDRESS: + return paddress(pexpr0(e2)); + case MINUS: + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==CONST) return list2(CONST,-cadr(e3)); + return list2(car(e1),e3); +#if LONGLONG_CODE + case LMINUS: + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==LCONST) return llist2(LCONST,-lcadr(e3)); + return list2(car(e1),e3); +#endif +#if FLOAT_CODE + case DMINUS: + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==DCONST) return dlist2(DCONST,-dcadr(e3)); + if (car(e3)==FCONST) return dlist2(FCONST,-dcadr(e3)); + return list2(car(e1),e3); + case FMINUS: + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==DCONST) return dlist2(DCONST,-dcadr(e3)); + if (car(e3)==FCONST) return dlist2(FCONST,-dcadr(e3)); + return list2(car(e1),e3); +#endif + case CONV: + return p_conv(caddr(e1),pexpr0(e2)); + case BNOT: /* ~ */ + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==CONST) return list2(CONST,~cadr(e3)); + return list2(BNOT,e3); + case LNOT: /* ! */ + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==CONST) return list2(CONST,!cadr(e3)); + return list2(LNOT,e3); + case PREINC: + case UPREINC: + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==CONST) return list2(CONST,cadr(e3)+1); + return list2(car(e1),e3); + case POSTINC: + case UPOSTINC: + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==CONST) return e3; + return list2(car(e1),e3); +#if FLOAT_CODE + case DPREINC: /* ++d */ + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+1.0); + if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+1.0); + return list2(car(e1),e3); + case DPOSTINC: /* d++ */ + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==FCONST||car(e3)==DCONST) return e3; + return list2(car(e1),e3); + case FPREINC: /* ++f */ + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+1.0); + if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+1.0); + return list2(car(e1),e3); + case FPOSTINC: /* f++ */ + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==FCONST||car(e3)==DCONST) return e3; + return list2(car(e1),e3); +#endif +#if LONGLONG_CODE + case LPREINC: /* ++d */ + case LUPREINC: /* ++d */ + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==LCONST) return llist2(LCONST,lcadr(e3)+1); + return list2(car(e1),e3); + case LPOSTINC: /* d++ */ + case LUPOSTINC: /* d++ */ + if ((e3 = pexpr0(e2))==e2) return e1; + if (car(e3)==LCONST) return e3; + return list2(car(e1),e3); + code_lpreinc(e1,e2,USE_CREG); + return ULONGLONG; +#endif + case MUL: case UMUL: + case DIV: case UDIV: + case MOD: case UMOD: + case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: + case ADD: case SUB: case BAND: case EOR: case BOR: case CMP: case CMPGE: + case UCMP: case CMPEQ: case CMPNEQ: case UCMPGE: + pbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1))); + return INT; +#if FLOAT_CODE + case DMUL: case DDIV: + case DADD: case DSUB: + case DCMP: case DCMPGE: case DCMPEQ: case DCMPNEQ: + return pdbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)),1); + case FMUL: case FDIV: + case FADD: case FSUB: + case FCMP: case FCMPGE: case FCMPEQ: case FCMPNEQ: + return pdbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)),0); +#endif +#if LONGLONG_CODE + case LMUL: case LUMUL: + case LDIV: case LUDIV: + case LMOD: case LUMOD: + case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: + case LADD: case LSUB: case LBAND: case LEOR: case LBOR: case LCMP: + return plbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1))); +#endif + case LCOND: case DCOND: case FCOND: case COND: + e3 = pexpr0(e2); + if (car(e3)==CONST) return pexpr0(cadr(e3)?caddr(e1):cadddr(e1)); + return list4(car(e1),e3,pexpr0(cadr(e1)),pexpr0(cadr(e2))); + case STASS: + return psassign(e1); + case ASS: case CASS: case SASS: + return passign(e1); + case SASSOP: case SUASSOP: + case ASSOP: case CASSOP: case CUASSOP: + return passop(e1); +#if FLOAT_CODE + case FASS: case DASS: + return pdassign(e1); + case DASSOP: case FASSOP: + return pdassop(e1); +#endif +#if LONGLONG_CODE + case LASS: + return plassign(e1); + case LASSOP: case LUASSOP: + return plassop(e1); +#endif + case ALLOCA: + return palloc(pexpr0(e2)); + case BUILTINP: + return list2(CONST,is_const(pexpr0(e2))); + case COMMA: + return pcomma(pexpr0(e2),pexpr0(caddr(e1))); + case RETURN: + case ENVIRONMENT: + case LCALL: + return e1; +#if BIT_FIELD_CODE + case RBIT_FIELD: + return prbit_field(e1); + case BASS: + return pbassign(e1); + case BPREINC: + case BPOSTINC: + case BASSOP: + return pbassop(e1); +#endif +#if ASM_CODE + case ASM: + return list3(ASM,list4( + pexpr0(car(e2)),pexpr0(cadr(e2)),pexpr0(caddr(e2)),pexpr0(cadddr(e2))), + pexpr0(caddr(e1))); +#endif + case ST_DECL: return p_decl(e1); + case ST_IF: return p_if(e1); + case ST_DO: return p_do(e1); + case ST_WHILE: return p_while(e1); + case ST_FOR: return p_for(e1); + case ST_SWITCH: return p_switch(e1); + case ST_COMP: return p_comp(e1); + case ST_BREAK: return p_break(e1); + case ST_CONTINUE: return p_continue(e1); + case ST_CASE: return p_case(e1); + case ST_DEFAULT: return p_default(e1); + case ST_RETURN: return p_return(e1); + case ST_GOTO: return p_goto(e1); + case ST_ASM: return p_asm(e1); + case ST_LABEL: return p_label(e1); + case ST_COMMENT: return p_comment(e1); + default: + return p_bool(e1); + } + return VOID; +} + +int +pexpr(int e) +{ + int sconvlvar = convlvar; + // compute new disp, and local variable table + convlvar = pconv_var(e); + e = pexpr0(e1); + convlvar = sconvlvar; + return e; +} + +/* end */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc-inline.h Fri Dec 03 01:05:17 2004 +0900 @@ -0,0 +1,24 @@ +/* Micro-C Partial Evaluator Part */ +/* $Id$ */ + +extern int pexpr(int e); + +extern void st_decl(int e1); +extern void st_if(int e1); +extern void st_do(int e1); +extern void st_while(int e1); +extern void st_for(int e1); +extern void st_switch(int e1); +extern void st_comp(int e1); +extern void st_break(int e1); +extern void st_continue(int e1); +extern void st_case(int e1); +extern void st_default(int e1); +extern void st_return(int e1); +extern void st_goto(int e1); +extern void st_asm(int e1); +extern void st_label(int e1); +extern void st_comment(int e1); + + +/* end */