changeset 456:b8f95294eb77

inline continue... if test passed.
author kono
date Wed, 01 Dec 2004 19:32:34 +0900
parents 563a5d29ec5e
children a7d76928e3c1
files Changes mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc-macro.c mc-parse.c mc-switch.c mc.h
diffstat 12 files changed, 203 insertions(+), 545 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Tue Nov 30 16:46:55 2004 +0900
+++ b/Changes	Wed Dec 01 19:32:34 2004 +0900
@@ -6963,3 +6963,10 @@
 static でもポインタを取られたりすると関数を生成する必要がある。
 extern なら、なおさら。それは、自分でやらないとダメ。まぁ、
 inline の関数リストを作るのが良いんだろうけど。
+
+Wed Dec  1 18:40:37 JST 2004
+
+chk は、mc-code-*.c に現れるべきではない。
+
+static  で used っていう属性がないとちょっとまずい。compiler warning
+だすべきだし。
--- a/mc-code-arm.c	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-code-arm.c	Wed Dec 01 19:32:34 2004 +0900
@@ -1051,7 +1051,6 @@
     int i,j;
 #endif
 #define USAGE_MAX 4
-    if (chk) return;
     if (!lsrc) return;
     printf("# %d: %s:",lineno,s);
     if (ireg) printf(" creg=%s",register_name(ireg));
@@ -2244,6 +2243,7 @@
 	case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE :
 	case DOP+EQ : case DOP+NEQ:
 	case RBIT_FIELD: case BASS: case BASSOP: case LCALL:
+	case INLINE:
 	return 1;
     }
     return 0;
@@ -3133,7 +3133,6 @@
     int sign,reg=-1;
     int regsv;
     char *rn,*crn;
-    if(chk) return;
     crn = register_name(csreg);
 
     inc_inst(2);
@@ -3282,7 +3281,6 @@
 static void
 jcond(int l, int cond)
 {       
-    if (chk) return;
     inc_inst(1);
     printf("\tb%s\t.L%d\n",cond?"ne":"eq",l);
 }
@@ -3290,7 +3288,6 @@
 void
 jmp(int l)
 {       
-    if (chk) return;
     printf("\tb\t.L%d\n",l);
     if (inst_count>CONST_TBL_COUNT/2) {
 	const_list_table();
@@ -3299,9 +3296,8 @@
 }
 
 void
-gen_comment(char *s)
-{
-    if (chk) return;
+code_comment(char *s)
+{
     printf("## %s",s);
 }
 
@@ -3704,7 +3700,6 @@
 #ifdef DOT_SIZE
     int lb;
 #endif
-    if (chk) return;
     if (mode==GDECL) {
 	data_mode(0);
 #ifdef DOT_SIZE
--- a/mc-code-ia32.c	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-code-ia32.c	Wed Dec 01 19:32:34 2004 +0900
@@ -477,7 +477,6 @@
 register_usage(char *s)
 {
     int i;
-    if (chk) return;
     printf("# %d: %s:",lineno,s);
     printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0));
     for(i=0;i<MAX_REGISTER;i++) {
@@ -1741,7 +1740,6 @@
 code_cmpdimm(int e, int csreg,int label,int cond)
 {
     /* used in dosiwtch() */
-    if(chk) return;
     use_register(creg,csreg,0);
     printf("\tcmpl $%d,%s\n",e,register_name(creg,0));
     jcond(label,cond);
@@ -1806,14 +1804,12 @@
 static void
 jcond(int l, char cond)
 {       
-    if (chk) return;
     printf("\tj%s\t_%d\n",cond==LT?code_ge(0):cond?"ne":"e",l);
 }
 
 void
 jmp(int l)
 {       
-    if (chk) return;
     printf("\tjmp\t_%d\n",l);
     /* align? */
     /*
@@ -1825,9 +1821,8 @@
 }
 
 void
-gen_comment(char *s)
+code_comment(char *s)
 {
-    if (chk) return;
     printf("## %s",s);
 }
 
@@ -2130,7 +2125,6 @@
 #ifdef DOT_SIZE
     int lb;
 #endif
-    if (chk) return;
     if (mode==GDECL) {
 	data_mode(0);
 #ifdef DOT_SIZE
@@ -3769,6 +3763,7 @@
         case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE :
         case DOP+EQ : case DOP+NEQ:
         case RBIT_FIELD: case BASS: case BASSOP: case LCALL:
+	case INLINE:
         return 1;
     }
     return 0;
--- a/mc-code-mips.c	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-code-mips.c	Wed Dec 01 19:32:34 2004 +0900
@@ -986,7 +986,6 @@
     int i,j;
 #endif
 #define USAGE_MAX 4
-    if (chk) return;
     if (!lsrc) return;
     printf("# %d: %s:",lineno,s);
     if (ireg) printf(" creg=%s",register_name(ireg));
@@ -1835,13 +1834,14 @@
 not_simple_p(int e3)
 {
     switch(e3) {
-    case FUNCTION: case CONV: case RSTRUCT: case STASS: case ALLOCA: 
+	case FUNCTION: case CONV: case RSTRUCT: case STASS: case ALLOCA: 
 	case LDIV: case LUDIV: case LMOD: case LUMOD: 
-		case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: 
+	case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: 
 	case DDIV: case DADD: case DSUB: case DMUL: case DMINUS: 
-            case  DPOSTINC :  case DPREINC :  case DASSOP : 
-            case  DOP+LT :  case  DOP+LE :  case  DOP+GT : 
-            case  DOP+GE :  case  DOP+EQ :  case  DOP+NEQ:
+	case  DPOSTINC :  case DPREINC :  case DASSOP : 
+	case  DOP+LT :  case  DOP+LE :  case  DOP+GT : 
+	case  DOP+GE :  case  DOP+EQ :  case  DOP+NEQ:
+	case INLINE:
     return 1;
     }
     return 0;
@@ -2680,7 +2680,6 @@
     /* used in dosiwtch() */
     int reg=-1,regsv;
     char *rn,*crn;
-    if(chk) return;
     crn = register_name(csreg);
 
     if (e<-32767||32766<e) {
@@ -2849,7 +2848,6 @@
 static void
 jcond(int l, char cond)
 {       
-    if (chk) return;
     if (cmpreg==CMP_C1T)  {
       printf("\tbc1%s $L_%d\n",cond?"f":"t",l);
     } else
@@ -2859,14 +2857,12 @@
 void
 jmp(int l)
 {       
-    if (chk) return;
     printf("\tj\t$L_%d\n",l);
 }
 
 void
-gen_comment(char *s)
-{
-    if (chk) return;
+code_comment(char *s)
+{
     printf("## %s",s);
 }
 
@@ -3355,7 +3351,6 @@
 #ifdef DOT_SIZE
     int lb;
 #endif
-    if (chk) return;
     if (mode==GDECL) {
 	data_mode(0);
 #ifdef DOT_SIZE
--- a/mc-code-powerpc.c	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-code-powerpc.c	Wed Dec 01 19:32:34 2004 +0900
@@ -903,7 +903,6 @@
     int i,j;
 #endif
 #define USAGE_MAX 4
-    if (chk) return;
     if (!lsrc) return;
     printf("# %d: %s:",lineno,s);
     if (ireg) printf(" creg=%s",register_name(ireg));
@@ -1777,9 +1776,10 @@
 not_simple_p(int e3)
 {
     switch (e3) {
-    case FUNCTION: case CONV: case LCALL: case STASS:  
+	case FUNCTION: case CONV: case LCALL: case STASS:  
 	case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: 
 	case LDIV: case LUDIV: case LMOD: case LUMOD: case LASSOP: case ALLOCA:
+	case INLINE:
     return 1;
     }
     return 0;
@@ -2599,7 +2599,6 @@
 {
     int reg,regsv;
     /* used in dosiwtch() */
-    if(chk) return;
     inc_cmpflag();
     if (-32767<e&&e<32767) {
 	printf("\tcmpwi cr%d,%s,%d\n",cmpflag,register_name(csreg),e);
@@ -2695,7 +2694,6 @@
 static void
 jcond(int l, char cond)
 {       
-    if (chk) return;
     if (cond==LT) {
 	printf("\tb%s cr%d,L_%d\n",code_ge(0),cmpflag,l);
     } else if (cond==1||cond==0) {
@@ -2706,14 +2704,12 @@
 void
 jmp(int l)
 {       
-    if (chk) return;
     printf("\tb\tL_%d\n",l);
 }
 
 extern void
-gen_comment(char *s)
+code_comment(char *s)
 {
-    if (chk) return;
     printf("## %s",s);
 }
 
@@ -3088,7 +3084,6 @@
 #ifdef DOT_SIZE
     int lb;
 #endif
-    if (chk) return;
     if (mode==GDECL) {
 	data_mode(0);
 #ifdef DOT_SIZE
--- a/mc-code.h	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-code.h	Wed Dec 01 19:32:34 2004 +0900
@@ -269,7 +269,7 @@
 
 #endif
 
-extern void gen_comment(char *s);
+extern void code_comment(char *s);
 
 #if BIT_FIELD_CODE
 
--- a/mc-codegen.c	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-codegen.c	Wed Dec 01 19:32:34 2004 +0900
@@ -58,23 +58,6 @@
 static int bassop(int e1,int e2,int op,int t,int post);
 #endif
 
-static void st_decl(int e1);
-static void st_if(int e1);
-static void st_do(int e1);
-static void st_while(int e1);
-static void st_for(int e1);
-static void st_switch(int e1);
-static void st_comp(int e1);
-static void st_break(int e1);
-static void st_continue(int e1);
-static void st_case(int e1);
-static void st_default(int e1);
-static void st_return(int e1);
-static void st_goto(int e1);
-static void st_asm(int e1);
-static void st_label(int e1);
-static void st_comment(int e1);
-
 extern void
 codegen_init()
 {
@@ -151,7 +134,7 @@
   if (inmode) {
 	return (parse = list3(ST_COMP,parse,e1));
   }
-  if (!control) return VOID;
+  if (!control && !IS_STATEMENT(car(e1))) return VOID;
 
   for(;e1;e1=e2) {
     code_gexpr(e1);
@@ -488,6 +471,10 @@
     case ALLOCA:
 	code_alloca(e2,USE_CREG);
 	return list2(POINTER,CHAR);
+    case BUILTINP:
+	/* Too late. Should be evaluated in pexpr. */
+	code_const(is_const(e2),USE_CREG);
+	return INT;
     case COMMA:
 	g_expr_u(e2);
 	return g_expr0(caddr(e1));
@@ -769,6 +756,19 @@
 }
 
 extern int 
+is_const(int e)
+{
+    switch(car(e)) {
+	case CONST: case LCONST: case FCONST: case DCONST:
+	// case ADDRESS:   what happen?
+	// case POINTER:
+	return 1;
+    default:
+	return 0;
+    }
+}
+
+extern int 
 is_code(NMTBL *fnptr)
 {
     int type = fnptr->ty;
@@ -2317,7 +2317,8 @@
 extern void 
 cmpdimm(int e, int csreg,int label,int cond)
 {
-    code_cmpdimm(e, csreg,label,cond);
+    if (!chk)
+	code_cmpdimm(e, csreg,label,cond);
 }
 
 extern int 
@@ -2354,7 +2355,8 @@
     if (p) {
 	if (p!=l) {
 	    control=0;
-	    jmp(p);
+	    if (!chk)
+		jmp(p);
 	}
     }
 }
@@ -2400,7 +2402,8 @@
 extern void
 ret(void)
 {       
-    code_set_return_register(1);
+    if (!chk)
+	code_set_return_register(1);
     gen_jmp(retlabel); 
 }
 
@@ -2419,8 +2422,10 @@
     NMTBL *n;
     for(e=inline_funcs;e;e=cadr(e)) {
 	n = (NMTBL*)car(e);
-	if (1 || n->sc==EXTRN || has_attr(n,FNAME))  // global or used as pointer
+	if (1 || n->sc==EXTRN || n->sc==EXTRN1 || has_attr(n,FNAME)) {  
+            // global or used as pointer
 	    pfdecl(n);
+	}
     }
     if (!chk)
 	code_closing();
@@ -2910,7 +2915,6 @@
     error(INERR);
 }
 
-
 extern int
 assign_data(int e, int t, NMTBL *n,int offset)
 {
@@ -2966,7 +2970,8 @@
 extern void
 data_closing(NMTBL *n)
 {
-    emit_data_closing(n);
+    if (!chk)
+	emit_data_closing(n);
 }
 
 #define ARG_REORDER_DEBUG 0
@@ -3997,6 +4002,13 @@
 }
 
 extern void
+gen_comment(char *s)
+{
+    if (!chk)
+	code_comment(s);
+}
+
+extern void
 gen_code_enter(char *name)
 {
     code_enter(name);
@@ -4201,368 +4213,4 @@
     return 0;
 }
 
-static void
-st_decl(int e1){
-    // NMTBL *n = (NMTBL *)caddr(e1);
-    // int stmode = cadddr(e1);
-}
- 
-static 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_();
-    checkret();
-    g_expr_u(cadr(e2));
-    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_();
-}
-
- 
-static 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;
-}
-
- 
-static 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;
-}
-
- 
-static 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;
-}
-
- 
-static 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;
-}
-
- 
-static void
-st_comp(int e1){
-    g_expr_u(caddr(e1));
-}
-
- 
-static void
-st_break(int e1){
-    checkret();
-    // conv->break_();
-    if (control)
-	gen_jmp(blabel);
-}
-
- 
-static void
-st_continue(int e1){
-    checkret();
-    // conv->continue_();
-    if (control) gen_jmp(clabel);
-}
-
- 
-static 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) {
-        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
-}
-
- 
-static void
-st_default(int e1){
-    control=1;
-    checkret();
-    if (dlabel) error(STERR);  // double default:
-    dlabel = backdef();
-    // conv->case_(0,1);
-}
-
- 
-static 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;
-}
-
- 
-static void
-st_goto(int e){
-    NMTBL *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)!=CODE) {
-        nptr0 = (NMTBL *)cadr(e1);
-        t = nptr0->sc;
-        if (t==EMPTY||t==EXTRN1||t==EXTRN) {
-            // error check?
-            nptr0->sc=EMPTY;
-            nptr0=l_top_search(nptr0->nm,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
-static void
-st_asm(int e1){
-    checkret();
-    gexpr(list3(ASM,caddr(e1),cadddr(e1)),0);
-}
-#endif
-
- 
-static void
-st_label(int e1){
-    NMTBL *nptr = (NMTBL*)caddr(e1);
-    control=1;
-    checkret();
-    if(nptr->sc == FLABEL) {
-	fwddef(nptr->dsp);
-    } else if(nptr->sc == BLABEL) {
-	nptr->dsp = backdef();
-    } else error(TYERR);
-    // conv->label_();
-}
-
-static void
-st_comment(int e1){
-    gen_comment((char *)caddr(e1));
-}
-
 /* end */
--- a/mc-codegen.h	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-codegen.h	Wed Dec 01 19:32:34 2004 +0900
@@ -59,6 +59,7 @@
 extern void fcheck(NMTBL *n);
 extern void fdecl_struct(int fntype);
 extern void free_lvar(int disp);
+extern void gen_comment(char *s);
 extern void gen_code_enter(char *name);
 extern void gen_code_enter1(int args);
 extern void gen_code_leave(char *name);
@@ -87,6 +88,7 @@
 extern int g_expr(int e1);
 extern int g_expr0(int e1);
 extern int g_expr_u(int e1);
+extern int is_const(int e);
 extern int is_code(NMTBL *fnptr);
 extern int is_function(NMTBL *fnptr);
 extern int is_inline(NMTBL *fnptr);
--- a/mc-macro.c	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-macro.c	Wed Dec 01 19:32:34 2004 +0900
@@ -4,6 +4,7 @@
 #include "mc.h"
 #include "mc-parse.h"
 #include "mc-macro.h"
+#include "mc-codegen.h"
 #include "mc-code.h"
 
 extern struct {int fd,ln;char *name0;int inc;FILE *fcb;} *filep,filestack[FILES];
--- a/mc-parse.c	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-parse.c	Wed Dec 01 19:32:34 2004 +0900
@@ -279,11 +279,11 @@
 	    newfile();
 	    return;
 	} else if(mode == TOP) {
+	    closing();
 	    if (chk) {
 		fprintf(stderr, "Total internal labels : %u.\n",labelno-1);
 		fprintf(stderr, "Total global variables: %u bytes.\n",gpc);
 	    }
-	    closing();
 	    exit(0);
 	}
     }
@@ -407,6 +407,9 @@
     for(i=0;i<GSYMS;i++) htable[i] = 0;
     free_glist2_list = 0;
     free_glist3_list = 0;
+    parse = 0;
+    inline_funcs = 0;
+    inmode = 0;
 
     heap_init();
 
@@ -449,6 +452,7 @@
     reserve("typeof",TYPEOF);
     reserve("__typeof__",TYPEOF);
     reserve("__builtin_alloca",ALLOCA);
+    reserve("__builtin_constant_p",BUILTINP);
     reserve("__label__",LABEL);
 #if ASM_CODE
     reserve("asm",ASM);
@@ -1639,7 +1643,10 @@
 	retlabel=fwdlabel();
     } else {
 	if (parse && (car(parse)!=ST_DECL&&car(parse)!=ST_COMMENT)) error(-1);
-	parse = 0;
+	if (car(parse)==ST_COMMENT)
+	    cadr(parse)=0;
+	else
+	    parse = 0;
     }
     local_static_list = &null_nptr;
     fnptr=n;
@@ -2369,19 +2376,19 @@
     }
     if (t==FNAME) {
 	nptr0 = (NMTBL *)cadr(e1);
-	t = nptr0->sc;
-	if (t==EMPTY||t==EXTRN1||t==EXTRN) {
-	    // error check?
-	    nptr0->sc=EMPTY;
-	    nptr0=l_top_search(nptr0->nm,0);
-	    nptr0->sc = FLABEL;
-	    nptr0->dsp = fwdlabel();
-	} else if (!(t==FLABEL||t==BLABEL)) {
-	    error(STERR);
-	}
 	if (inmode) {
-	    parse = list3(ST_GOTO,parse,e1);
+	    parse = list3(ST_GOTO,parse,list2(FLABEL,(int)nptr0->nm));
 	} else {
+	    t = nptr0->sc;
+	    if (t==EMPTY||t==EXTRN1||t==EXTRN) {
+		// error check?
+		nptr0->sc=EMPTY;
+		nptr0=l_top_search(nptr0->nm,0);
+		nptr0->sc = FLABEL;
+		nptr0->dsp = fwdlabel();
+	    } else if (!(t==FLABEL||t==BLABEL)) {
+		error(STERR);
+	    }
 	    gen_jmp(nptr0->dsp);
 	}
 	control=0;
@@ -2431,20 +2438,17 @@
     control=1;
     if (!inmode)
 	checkret();
-    if(nptr->sc == FLABEL) {
-	if (inmode)
-	    parse = list3(ST_LABEL,parse,(int)nptr);
-	else
+    if (inmode)
+	parse = list3(ST_LABEL,parse,(int)nptr->nm);
+    else {
+	if(nptr->sc == FLABEL) {
 	    fwddef(nptr->dsp);
-    } else if(nptr->sc != EMPTY && nptr->sc != EXTRN1) {
-	error(TYERR);
-    } else {
-	nptr->sc=EMPTY;
-	nptr1=l_top_search(nptr->nm,0);
-	nptr1->sc = BLABEL;
-	if (inmode) {
-	    parse = list3(ST_LABEL,parse,(int)nptr1);
+	} else if(nptr->sc != EMPTY && nptr->sc != EXTRN1) {
+	    error(TYERR);
 	} else {
+	    nptr->sc=EMPTY;
+	    nptr1=l_top_search(nptr->nm,0);
+	    nptr1->sc = BLABEL;
 	    nptr1->dsp = backdef();
 	}
     }
@@ -2907,12 +2911,24 @@
 	return list2(LNOT,e);
     case ALLOCA:
 	conv->prefix_(sym);
-	type=POINTER;
+	getsym(0);
+	checksym(LPAR);
+	e=rvalue(expr0());
+	checksym(RPAR);
+	type=list2(POINTER,VOID);
+	return list2(ALLOCA,e);
+    case BUILTINP:
+	/* builtin___builtin_constant_p GNU extenstion */
+	conv->prefix_(sym);
 	getsym(0);
 	checksym(LPAR);
 	e=expr0();
 	checksym(RPAR);
-	return list2(ALLOCA,rvalue(e));
+	type=INT;
+	if (inmode)
+	    return list2(BUILTINP,rvalue(e));  /* evalue it later */
+	else 
+	    return list2(CONST,is_const(e));
     case SIZEOF:
 	conv->prefix_(sym);
 	if(getsym(0)==LPAR) {
@@ -3955,6 +3971,7 @@
 	ret = free_nptr_list;
 	free_nptr_list = (NMTBL *)free_nptr_list->dsp;
 	ret->sc = 0;
+	ret->ty = 0;
 	ret->dsp = 0;
 	ret->attr = 0;
 	return ret;
@@ -3971,6 +3988,7 @@
     }
     ret = ((NMTBL *)nptr_pool->ptr)++;
     ret->sc = 0;
+    ret->ty = 0;
     ret->dsp = 0;
     ret->attr = 0;
     return ret;
@@ -4094,7 +4112,7 @@
     scope = car(current_scope);
     while(scope) {
 	ns = (NMTBL *)caddr(car(scope));
-	if (ns->sc != GVAR) free_nptr(ns);
+	if (ns->sc != GVAR && !inmode) free_nptr(ns);
 	caddr(car(scope)) = caddr(scope);
 	next = cadr(scope);
 	free_glist2(scope); // will destroy cadr
--- a/mc-switch.c	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc-switch.c	Wed Dec 01 19:32:34 2004 +0900
@@ -368,6 +368,7 @@
     }
 #endif
     control=1;
+    if (chk) return;
     /* find stepwise chunks */
     chunks=make_chunk(cslist);
 #if 0
--- a/mc.h	Tue Nov 30 16:46:55 2004 +0900
+++ b/mc.h	Wed Dec 01 19:32:34 2004 +0900
@@ -199,56 +199,57 @@
 #define LURINDIRECT     (LOP+URINDIRECT)
 #define RSTRUCT	32
 #define ALLOCA 	33
-#define BIT_FIELD 	34
-#define RBIT_FIELD 	35
-#define BPREINC 	36
-#define BPOSTINC 	37
-#define CONV   	38
+#define BUILTINP 	34
+#define BIT_FIELD 	35
+#define RBIT_FIELD 	36
+#define BPREINC 	37
+#define BPOSTINC 	38
+#define CONV   	39
 
 #define UNARY_ARGS(i) (ADDRESS<=(i%SOP)&&(i%SOP)<=CONV)
 
 /* binary  argments */
 
-#define MUL    	39
-#define UMUL   	40
-#define DIV    	41
-#define UDIV   	42
-#define MOD    	43
-#define UMOD   	44
-#define ADD    	45
-#define SUB    	46
-#define CMP    	47      
-#define RSHIFT 	48
-#define URSHIFT	49
-#define LSHIFT 	50
-#define ULSHIFT	51
-#define GT     	52
-#define UGT    	53
-#define GE     	54
-#define UGE    	55
-#define LT     	56
-#define ULT    	57
-#define LE     	58
-#define ULE    	59
-#define EQ     	60
-#define NEQ    	61
-#define BAND   	62
-#define EOR    	63
-#define BOR    	64
-#define LAND   	65
-#define LOR    	66
-#define ASS    	67
-#define UCMP   	68
-#define UCMPGE 	69
-#define CMPGE  	70
-#define CMPEQ  	71
-#define CMPNEQ 	72
-#define ASSOP  	73
-#define COMMA  	74
+#define MUL    	40
+#define UMUL   	41
+#define DIV    	42
+#define UDIV   	43
+#define MOD    	44
+#define UMOD   	45
+#define ADD    	46
+#define SUB    	47
+#define CMP    	48      
+#define RSHIFT 	49
+#define URSHIFT	50
+#define LSHIFT 	51
+#define ULSHIFT	52
+#define GT     	53
+#define UGT    	54
+#define GE     	55
+#define UGE    	56
+#define LT     	57
+#define ULT    	58
+#define LE     	59
+#define ULE    	60
+#define EQ     	61
+#define NEQ    	62
+#define BAND   	63
+#define EOR    	64
+#define BOR    	65
+#define LAND   	66
+#define LOR    	67
+#define ASS    	68
+#define UCMP   	69
+#define UCMPGE 	70
+#define CMPGE  	71
+#define CMPEQ  	72
+#define CMPNEQ 	73
+#define ASSOP  	74
+#define COMMA  	75
 
-#define CASS   	75
-#define CASSOP 	76
-#define CUASSOP	77
+#define CASS   	76
+#define CASSOP 	77
+#define CUASSOP	78
 
 #define SASS    (SOP+CASS)
 #define SASSOP (SOP+CASSOP)
@@ -304,18 +305,18 @@
 #define LEOR    (LOP+EOR)
 #define LBOR    (LOP+BOR)
 
-#define BASS   	78
-#define BASSOP 	79
-#define BFD_REPL 	80
+#define BASS   	79
+#define BASSOP 	80
+#define BFD_REPL 	81
 
-#define STASS  	81
+#define STASS  	82
 
 
 #define BINARY_ARGS(i) (MUL<=(i%SOP)&&(i%SOP)<=STASS)
 
 /* tarnary  argments */
 
-#define COND   	82
+#define COND   	83
 #define SCOND   (SOP+COND)
 #define DCOND   (DOP+COND)
 #define FCOND   (FOP+COND)
@@ -325,35 +326,35 @@
 
 /* not appeared as tags */
 
-#define LPAR   	83
-#define RPAR   	84
-#define LBRA   	85
-#define RBRA   	86
-#define LC     	87
-#define RC     	88
-#define COLON  	89
-#define SM     	90
-#define PERIOD 	91
-#define ARROW  	92
-#define CNAME  	93
+#define LPAR   	84
+#define RPAR   	85
+#define LBRA   	86
+#define RBRA   	87
+#define LC     	88
+#define RC     	89
+#define COLON  	90
+#define SM     	91
+#define PERIOD 	92
+#define ARROW  	93
+#define CNAME  	94
 
-#define I2C  	94
-#define I2S  	95
-#define I2I    	96
-#define I2U    	97
-#define I2D    	98
-#define I2F    	99
-#define I2LL   	100
-#define I2ULL  	101
+#define I2C  	95
+#define I2S  	96
+#define I2I    	97
+#define I2U    	98
+#define I2D    	99
+#define I2F    	100
+#define I2LL   	101
+#define I2ULL  	102
 
-#define U2UC  	102
-#define U2US  	103
-#define U2I    	104
-#define U2U    	105
-#define U2D    	106
-#define U2F    	107
-#define U2LL   	108
-#define U2ULL  	109
+#define U2UC  	103
+#define U2US  	104
+#define U2I    	105
+#define U2U    	106
+#define U2D    	107
+#define U2F    	108
+#define U2LL   	109
+#define U2ULL  	110
 
 
 #define D2I     (DOP+I2I)
@@ -388,22 +389,22 @@
 
 /* statement start */
 
-#define ST_DECL		110
-#define ST_IF		111
-#define ST_DO		112
-#define ST_WHILE	113
-#define ST_FOR		114
-#define ST_SWITCH	115
-#define ST_COMP		116
-#define ST_BREAK	117
-#define ST_CONTINUE	118
-#define ST_CASE		119
-#define ST_DEFAULT	120
-#define ST_RETURN	121
-#define ST_GOTO		122
-#define ST_ASM		123
-#define ST_LABEL	124
-#define ST_COMMENT	125
+#define ST_DECL		111
+#define ST_IF		112
+#define ST_DO		113
+#define ST_WHILE	114
+#define ST_FOR		115
+#define ST_SWITCH	116
+#define ST_COMP		117
+#define ST_BREAK	118
+#define ST_CONTINUE	119
+#define ST_CASE		120
+#define ST_DEFAULT	121
+#define ST_RETURN	122
+#define ST_GOTO		123
+#define ST_ASM		124
+#define ST_LABEL	125
+#define ST_COMMENT	126
 
 #define IS_STATEMENT(i) (ST_DECL<=i&&i<=ST_COMMENT)