Mercurial > hg > CbC > old > device
view mc-inline.c @ 510:2bd6ff6ee9a8
inline continue...
author | kono |
---|---|
date | Sun, 25 Dec 2005 16:29:40 +0900 |
parents | e58848f6ebc1 |
children | 14c7faf78910 |
line wrap: on
line source
/* Micro-C Partial Evaluator Part */ /* $Id$ */ #include <stdio.h> #include "mc.h" #include "mc-parse.h" #include "mc-codegen.h" #include "mc-switch.h" #include "mc-code.h" #include "mc-inline.h" static int pvartable; static int pdisp; /* 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); /* switch value */ 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; g_expr_u(cadr(e1)); 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))); g_expr_u(cadr(e)); } else { type = caddr(struct_return); // e1 = rvalue_t(cadr(struct_return),INT); /* size */ e1 = cadr(struct_return); /* size */ g_expr_u(list4(STASS,rvalue(car(struct_return)),e,e1)); } } else { error(TYERR); /* should check compatible */ } } else { g_expr(correct_type(e,cadr(fnptr->ty))); } // 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 p_vartable(int e,int adisp,int ldisp) { int i; int pvartable = getfree(adisp-ldisp); // have to be local heap pdisp = pvartable-ldisp; for(i=ldisp;i<0;i++) { heap[pdisp+i] = 0; } return pvartable; } static int p_lvar(int e1) { int sz = is_memory(e1); int d = cadr(e1); int d1; if ((d1=(heap[pdisp+d]))) return d1; return (heap[pdisp+d]=list3(LVAR,new_lvar(sz),0)); } static int pfunction(int e) { // list4(INLINE,e1,arglist,ftype); // include code segement case int e1 = pexpr(cadr(e)); int arglist = caddr(e); int newargs = 0; int ftype = cadddr(e); int e3; for (e3 = arglist; e3; e3 = cadr(e3)) { newargs = list3( pexpr(car(e3)), cadr(e3), caddr(e3)); } newargs = reverse0(newargs); return list4(INLINE,e1,newargs,ftype); } static int prindirect(int e) { return list3(car(e),pexpr(cadr(e)),caddr(e)); } static int paddress(int e) { return list2(car(e),pexpr(cadr(e))); } static int p_conv(int e1,int e2) { return list3(CONV,pexpr(e1),e2); } static int pbinop(int op,int e1,int e2) { return list3(op,pexpr(e1),pexpr(e2)); } static int prexpr(int op,int e1,int e2) { return list3(op,pexpr(e1),pexpr(e2)); } static int psassign(int e) { return list4(car(e),pexpr(cadr(e)),pexpr(caddr(e)),cadddr(e)); } static int passign(int e) { return list3(car(e),pexpr(cadr(e)),pexpr(caddr(e))); } static int passop(int e) { return list4(car(e),pexpr(cadr(e)),pexpr(caddr(e)),cadddr(e)); } static int pdassign(int e) { return list3(car(e),pexpr(cadr(e)),pexpr(caddr(e))); } static int pdassop(int e) { return list4(car(e),pexpr(cadr(e)),pexpr(caddr(e)),cadddr(e)); } static int plassign(int e) { return list3(car(e),pexpr(cadr(e)),pexpr(caddr(e))); } static int plassop(int e) { return list4(car(e),pexpr(cadr(e)),pexpr(caddr(e)),cadddr(e)); } static int palloc(int e) { return list2(car(e),pexpr(cadr(e))); } static int pcomma(int e1,int e2) { return list3(COMMA,pexpr(e1),pexpr(e2)); } static int prbit_field(int e) { return list3(car(e),pexpr(cadr(e)),caddr(e)); } static int pbassign(int e) { return list4(car(e),pexpr(cadr(e)),pexpr(caddr(e)),cadddr(e)); } static int pbassop(int e) { return list4(car(e),pexpr(cadr(e)),pexpr(caddr(e)),cadddr(e)); } static int p_decl(int e) { // list4(ST_DECL,parse,(int)n,stmode); int stmode=cadddr(e); NMTBL *n=(NMTBL*)caddr(e); int dsp = n->dsp; int v; // in real partial evaluation, we have to check whether this variable // is used or not. switch(stmode) { case REGISTER: switch(n->ty) { case ULONGLONG: case LONGLONG: v = get_lregister_var(n); break; case FLOAT: v = get_dregister_var(n,0); break; case DOUBLE: v = get_dregister_var(n,1); break; default: if (scalar(n->ty)) v = get_dregister_var(n,1); else error(TYERR); } case EXTRN: case EXTRN1: case STATIC: return pexpr(cadr(e)); default: v = list3(LVAR,new_lvar(size(n->dsp)),(int)n); } if (heap[pdisp+dsp]) error(-1); heap[pdisp+dsp]=v; return pexpr(cadr(e)); } static int p_if(int e1) { int cond,l1,l2; int e2=caddr(e1),e3; cond = pexpr(car(e2)); // conv->if_then_(); l1 = pexpr(cadr(e2)); if ((e3=caddr(e2))) { // else l2 = pexpr(e3); } else { l2 = 0; } return list3(ST_IF,pexpr(cadr(e1)),list3(cond,l1,l2)); } static int p_do(int e) { return list4(ST_DO,pexpr(cadr(e)),pexpr(caddr(e)),pexpr(cadddr(e))); } static int p_while(int e) { return list4(ST_WHILE,pexpr(cadr(e)),pexpr(caddr(e)),pexpr(cadddr(e))); } static int p_for(int e) { int e1=caddr(e); int p0=car(e1); int p1=cadr(e1); int p2=caddr(e1); int p3=cadddr(e1); return list3(ST_FOR,pexpr(cadr(e)), list4(pexpr(p0),pexpr(p1),pexpr(p2),pexpr(p3))); } static int p_switch(int e) { return list4(ST_SWITCH,pexpr(cadr(e)),pexpr(caddr(e)),pexpr(cadddr(e))); } static int p_comp(int e) { return list3(ST_COMP,pexpr(cadr(e)),pexpr(caddr(e))); } static int p_break(int e) { return list2(ST_BREAK,pexpr(cadr(e))); } static int p_continue(int e) { return list2(ST_CONTINUE,pexpr(cadr(e))); } static int p_case(int e) { int new=0,clist = caddr(e); // insert destory clist, we have to copy it now for(;clist;clist=cadr(clist)) new=glist3(car(clist),new,0); return list3(ST_CASE,pexpr(cadr(e)),reverse0(new)); } static int p_default(int e) { return list2(ST_DEFAULT,pexpr(cadr(e))); } static int p_return(int e) { return list3(ST_RETURN,pexpr(cadr(e)),pexpr(caddr(e))); } static int p_goto(int e) { int e1; if ((e1=caddr(e))) { switch(car(e1)) { case RINDIRECT: e1=pexpr(e1); break; case CODE: e1=list3(CODE,pexpr(cadr(e1)),pexpr(caddr(e1))); break; case FLABEL: break; } } return list3(ST_GOTO,pexpr(cadr(e)),e1); } static int p_list_expr(int e) { int e3,new = 0; for (e3 = e; e3; e3 = cadr(e3)) { new= list2( pexpr(car(e3)), new); } return reverse0(new); } static int p_asm(int e) { int param=caddr(e); int e1 = p_list_expr(cadddr(e)); return list4(ST_ASM,pexpr(cadr(e)),param,e1); } static int p_label(int e) { return list3(ST_LABEL,pexpr(cadr(e)),caddr(e)); } static int p_bool(int e) { error(-1); return e; } static int p_comment(int e) { return list3(ST_COMMENT,pexpr(cadr(e)),caddr(e)); } static int pgen_inline(int e) { int e3; int narg; /* inline function arguments */ narg = 0; for (e3 = caddr(e); e3; e3 = cadr(e3)) { narg=list3(pexpr(car(e3)),narg,caddr(e3)); } return list4(INLINE,cadr(e),reverse0(narg),cadddr(e)); } extern int pexpr(int e1) { int e2,e3; // if (inmode) error(-1); if (e1==0) return 0; 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: case FRGVAR: case DRGVAR: #endif #if LONGLONG_CODE case LREGISTER: case LRGVAR: case LURGVAR: #endif case LABEL: case CONST: #if FLOAT_CODE case DCONST: case FCONST: #endif #if LONGLONG_CODE case LCONST: #endif case STRING: case FNAME: case FLABEL: case RSTRUCT: return e1; case LVAR: case RLVAR: case CRLVAR: case CURLVAR: case SRLVAR: case SURLVAR: #if FLOAT_CODE case FRLVAR: case DRLVAR: #endif #if LONGLONG_CODE case LRLVAR: case LURLVAR: #endif return e1; case IVAR: return p_lvar(e1); case FUNCTION: return pfunction(e1); case CODE: return list2(car(e1),pexpr(e2)); case INLINE: return pgen_inline(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(e1); case MINUS: if ((e3 = pexpr(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 = pexpr(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 = pexpr(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 = pexpr(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),e2); case BNOT: /* ~ */ if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==CONST) return list2(CONST,~cadr(e3)); return list2(BNOT,e3); case LNOT: /* ! */ if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==CONST) return list2(CONST,!cadr(e3)); return list2(LNOT,e3); case PREINC: case UPREINC: if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==CONST) return list2(CONST,cadr(e3)+1); return list4(car(e1),e3,caddr(e1),cadddr(e1)); case POSTINC: case UPOSTINC: if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==CONST) return e3; return list4(car(e1),e3,caddr(e1),cadddr(e1)); #if FLOAT_CODE case DPREINC: /* ++d */ if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+cadr(e2)); if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+cadr(e2)); return list4(car(e1),e3,caddr(e1),cadddr(e1)); case DPOSTINC: /* d++ */ if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==FCONST||car(e3)==DCONST) return e3; return list4(car(e1),e3,caddr(e1),cadddr(e1)); case FPREINC: /* ++f */ if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+cadr(e2)); if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+cadr(e2)); return list4(car(e1),e3,caddr(e1),cadddr(e1)); case FPOSTINC: /* f++ */ if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==FCONST||car(e3)==DCONST) return e3; return list4(car(e1),e3,caddr(e1),cadddr(e1)); #endif #if LONGLONG_CODE case LPREINC: /* ++d */ case LUPREINC: /* ++d */ if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==LCONST) return llist2(LCONST,lcadr(e3)+cadr(e2)); return list4(car(e1),e3,caddr(e1),cadddr(e1)); case LPOSTINC: /* d++ */ case LUPOSTINC: /* d++ */ if ((e3 = pexpr(e2))==e2) return e1; if (car(e3)==LCONST) return e3; return list4(car(e1),e3,caddr(e1),cadddr(e1)); #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: #if FLOAT_CODE case DMUL: case DDIV: case DADD: case DSUB: case DCMP: case DCMPGE: case DCMPEQ: case DCMPNEQ: case FMUL: case FDIV: case FADD: case FSUB: case FCMP: case FCMPGE: case FCMPEQ: case FCMPNEQ: #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: #endif return pbinop(car(e1),e2,caddr(e1)); case LCOND: case DCOND: case FCOND: case COND: e3 = pexpr(e2); if (car(e3)==CONST) return pexpr(cadr(e3)?caddr(e1):cadddr(e1)); return list4(car(e1),e3,pexpr(cadr(e1)),pexpr(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(e2); case BUILTINP: return list2(CONST,is_const(pexpr(e2))); case COMMA: return pcomma(pexpr(e2),pexpr(caddr(e1))); case RETURN: case ENVIRONMENT: case LCALL: return e1; // relational operator case GT: case UGT: case GE: case UGE: case LT: case ULT: case LE: case ULE: case DOP+GT: case DOP+GE: case DOP+LT: case DOP+LE: case FOP+GT: case FOP+GE: case FOP+LT: case FOP+LE: case FOP+EQ: case FOP+NEQ: case EQ: case NEQ: case DOP+EQ: case DOP+NEQ: return prexpr(car(e1),cadr(e1),caddr(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( car(e2),cadr(e2),caddr(e2),cadddr(e2)), 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; } #define round4(i) ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1)) extern int gen_inline(int e) { int svartable = pvartable; NMTBL *sfnptr = fnptr; int sdisp = pdisp; int narg,arg; NMTBL *n = (NMTBL*)cadr(cadr(e)); int e1 = attr_value(n,INLINE); int parse = car(e1); // inline parse tree int arg_disp = cadr(e1); // size of local variable int e3,t,e4,dots; int ret_type = function_type(cadddr(e),&dots); fnptr = n; // st_return see this pvartable = p_vartable(e,arg_disp,caddr(e1)); /* inline function arguments */ narg = 0; for (e3 = e1 = reverse0(caddr(e)); e3; e3 = cadr(e3)) { t=caddr(e3); // type e4 = car(e3); if (is_const(e4) /* ||(is_memory(e3)&&is_readonly(e3)) */ ) { heap[pdisp+narg]=e4; } else { arg = heap[pdisp+narg]=list3(LVAR,new_lvar(size(t)),0); // should contain correct argument variable name g_expr_u(assign_expr0(arg,e4,t,t)); } narg ++; } caddr(e) = reverse0(e1); // make it normal e = pexpr(parse); pdisp = sdisp; pvartable = svartable; // how to handle return value? g_expr_u(e); fnptr = sfnptr; return ret_type; } /* end */