changeset 426:fb136af3bf09

Bitfield reorganization.
author kono
date Sat, 30 Oct 2004 14:04:45 +0900
parents 7851023f5af1
children 0c256ea2a97e
files Changes mc-code-powerpc.c mc-code.h mc-codegen.c mc-parse.c mc-parse.h
diffstat 6 files changed, 354 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Fri Oct 29 21:21:28 2004 +0900
+++ b/Changes	Sat Oct 30 14:04:45 2004 +0900
@@ -6379,3 +6379,5 @@
 いいのかな?
 
 あっと、goto の浮動小数点レジスタ渡しをあまりテストしてないね。
+
+bitfield は、アドレス渡しで、代入しない方が良いね。
--- a/mc-code-powerpc.c	Fri Oct 29 21:21:28 2004 +0900
+++ b/mc-code-powerpc.c	Sat Oct 30 14:04:45 2004 +0900
@@ -1058,16 +1058,16 @@
     return list2(LVAR,new_lvar(SIZE_OF_DOUBLE));
 }
 
-void
-
+int
 emit_push()
 {
-    int new_reg;
+    int new_reg,old=creg;
     if (!is_int_reg(creg)) error(-1);
     if (reg_sp>MAX_MAX) error(-1);
     new_reg = get_register();       /* 絶対に取れる */
     reg_stack[reg_sp++] = creg;     /* push するかわりにレジスタを使う */
     ireg = creg = new_reg;
+    return old;
 }
 
 int
@@ -5214,10 +5214,13 @@
 /* bit field alignment calcuration */
 
 static void
-set_bitsz(int type,int *psign,int *pbitsz,int *palign,int *pl)
+set_bitsz(int type,int *pbitpos,int *pbitsize,
+	int *psign,int *pbitsz,int *palign,int *pl)
 { 
     int sign=0,bitsz; 
     int align,l=0;
+    *pbitpos = cadr(caddr(type));
+    *pbitsize = caddr(caddr(type));
     switch(cadr(type)) {   /* value type */
     case INT:		sign=1; bitsz=32; align=4;break; 
     case UNSIGNED:		bitsz=32; align=4;break; 
@@ -5246,10 +5249,11 @@
     int sign,bitsz,align;
     int i;
     int bitpos = *bfd;
+    int bitpos0;
+    int bitsize;
     int offset = *poffset;
     int l;
-    int bitsize = caddr(caddr(type));
-    set_bitsz(type,&sign,&bitsz,&align,&l);
+    set_bitsz(type,&bitpos0,&bitsize,&sign,&bitsz,&align,&l);
 
     if (bitsize>bitsz) { error(BTERR); bitsize = i; }
 
@@ -5279,7 +5283,7 @@
 	*poffset = (offset += (align-i));
     }
     bitpos = 0;
-    *bfd = bitsize;
+    *bfd = (bitsize==bitsz)?0:bitsize;
     *sz = (bitsize+7)/8;
 
 // printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",bitpos,bitsize,bitsz,*poffset);
@@ -5288,18 +5292,20 @@
 
 /* bit field value */
 
-/* reg contains container value, result should be in reg */
 extern void
-code_bit_field(int type,int bitpos,int reg)
+code_bit_field(int type,int adr, int reg)
 {
     int sign,bitsz,l,align;
-    int bitsize = caddr(caddr(type));
-    int i;
-    set_bitsz(type,&sign,&bitsz,&align,&l);
+    int bitsize,bitpos;
+    int i,size;
+    set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
+    size = bitsz/8;
 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     /* this implementation returns -1 for int i:1; */
     if (l==1) {
+	use_int(adr);
 	use_longlong(reg);
+	lload(adr,reg,0);
 	/* shift left */
 	if (bitpos) 
 	    loprtc(LLSHIFT,reg,list2(CONST,bitpos));
@@ -5307,7 +5313,11 @@
 	if ((i=bitsz-bitsize)) 
 	    loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i));
     } else {
+	use_int(adr);
 	use_int(reg);
+	printf("\t%s %s,lo16(%d)(%s)\n",cload(size),
+		register_name(reg),0,register_name(adr));
+	cext(sign,size,reg);
 	/* shift left */
 	if ((i=bitpos+(32-bitsz))) 
 	    oprtc(LSHIFT,reg,list2(CONST,i));
@@ -5335,17 +5345,23 @@
 }
 
 extern void
-code_bit_replace(int value,int lvalue,int type,int bitpos)
+code_bit_replace(int reg,int value,int type)
 {
     int sign,bitsz,l,align;
-    int bitsize = caddr(caddr(type));
+    int bitsize,bitpos;
     int mask = 0;
     int tmp = -1;
     int i;
+    int lvalue;
     char *crn,*lrn,*trn;
-    set_bitsz(type,&sign,&bitsz,&align,&l);
+    int size;
+    set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
+    size = bitsz/8;
 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     if (l) {
+	use_int(reg);
+	lvalue = get_lregister();
+	lload(reg,lvalue,0);
 	use_longlong(value);
 	crn = lregister_name_low(value);
 	lrn = lregister_name_low(lvalue);
@@ -5365,8 +5381,16 @@
 	    mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1);
 	    make_mask_and_or(mask,tmp,trn,crn,lrn);
 	}
+	code_lassign(reg,value);
+	free_register(lvalue);
+	// free_register(reg);
     } else {
+	use_int(reg);
 	use_int(value);
+	lvalue = get_register();
+	printf("\t%s %s,lo16(%d)(%s)\n",cload(size),
+		register_name(lvalue),0,register_name(reg));
+	cext(sign,size,lvalue);
 	crn = register_name(value);
 	lrn = register_name(lvalue);
 	/* shift left */
@@ -5376,8 +5400,13 @@
 	/* make and-mask */
 	mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz));
 	make_mask_and_or(mask,tmp,trn,crn,lrn);
+	free_register(lvalue);
+	code_assign(reg,size,value);
     }
     if (tmp!=-1) free_register(tmp);
+    if (use) {
+	code_bit_field(type,reg,USE_CREG);
+    }
 }
 
 static void
@@ -5408,22 +5437,26 @@
 }
 
 extern void
-code_bit_replace_const(int value,int lvalue,int type,int bitpos)
+code_bit_replace_const(int value,int reg,int type)
 {
     int sign,bitsz,l,align;
-    int bitsize = caddr(caddr(type));
+    int bitsize,bitpos,size;
     int mask = 0;
     int i;
     int c;
+    int lvalue;
 #if LONGLONG_CODE
     long long lc;
 #endif
     char *crn;
-    set_bitsz(type,&sign,&bitsz,&align,&l);
+    set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
+    size = bitsz/8;
 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     if (l) {
 #if LONGLONG_CODE
-	use_longlong(lvalue);
+	use_int(reg);
+	lvalue = get_lregister();
+	lload(reg,lvalue,0);
 	crn = lregister_name_low(lvalue);
 	/* shift left */
 	lc = lcadr(value);
@@ -5440,9 +5473,15 @@
 	    mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1);
 	    make_mask_and_or_const(mask,crn,(int)(lc>>32));
 	}
+	code_lassign(reg,lvalue);
+	free_register(lvalue);
 #endif
     } else {
-	use_int(lvalue);
+	use_int(reg);
+	lvalue = get_register();
+	printf("\t%s %s,lo16(%d)(%s)\n",cload(size),
+		register_name(lvalue),0,register_name(reg));
+	cext(sign,size,lvalue);
 	crn = register_name(lvalue);
 	/* shift left */
 	c = cadr(value);
@@ -5451,6 +5490,11 @@
 	/* make and-mask */
 	mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz));
 	make_mask_and_or_const(mask,crn,c);
+	code_assign(reg,size,lvalue);
+	free_register(lvalue);
+    }
+    if (use) {
+	code_bit_field(type,reg,USE_CREG);
     }
 }
 
--- a/mc-code.h	Fri Oct 29 21:21:28 2004 +0900
+++ b/mc-code.h	Sat Oct 30 14:04:45 2004 +0900
@@ -56,7 +56,7 @@
 extern void use_ptr_cache(int r);
 extern int code_register_overlap(int s,int t);
 
-extern void emit_push();
+extern int emit_push();
 extern int emit_pop(int type);
 extern void gexpr_code_init();
 extern int  code_csvalue();
@@ -276,13 +276,13 @@
 /* bit field value */
 
 /* reg contains address of bit_field, result should goto reg */
-extern void code_bit_field(int type,int bit_offset,int reg);
+extern void code_bit_field(int type,int adr,int reg);
 
 /* bit field replacement */
 
-extern void code_bit_replace(int value,int lvalue,int type,int bit_offset);
+extern void code_bit_replace(int value,int lvalue,int type);
                           /*  register,   register */
-extern void code_bit_replace_const(int value,int lvalue,int type,int bit_offset);
+extern void code_bit_replace_const(int value,int lvalue,int type);
                           /*  exp,   register */
 
 #endif
--- a/mc-codegen.c	Fri Oct 29 21:21:28 2004 +0900
+++ b/mc-codegen.c	Sat Oct 30 14:04:45 2004 +0900
@@ -491,8 +491,6 @@
     case BASSOP:
 	return bassop(e2,caddr(e1),car(cadddr(e1)),/* op */
 				    cadr(cadddr(e1))/* type */,0);
-    case BFD_REPL:
-	return bit_field_repl(e2,caddr(e1),cadddr(e1) /* type */);
 #endif
 #if ASM_CODE
     case ASM:
@@ -1876,7 +1874,7 @@
 	switch(car(t)) {
 	case BIT_FIELD:
             //        type = list4(BIT_FIELD,type,
-            //            list3(type /*store type*/,0 /*bit offset*/,symval));
+            //            list3(type /*store type*/,0 /*bit offset*/,bitsize));
 	    e2 = correct_type(e2,cadr(t)); /* value type */
 	    return(list4(BASS,e1,e2,list2(BASS,t)));
 	case STRUCT:case UNION:
@@ -2391,6 +2389,11 @@
 
 #endif
 
+/*
+    define symbol name contents 
+      depending on stmode, mode
+      define displacement
+ */
 
 extern NMTBL *
 def(NMTBL *n)
@@ -2700,6 +2703,11 @@
 
 #define ARG_REORDER_DEBUG 0
 
+/*
+     In K&R style, order of argment list and order of argment
+     type decl are differnt. Fix them.
+ */
+
 extern int
 arg_reorder(int arg,int new_arg)
 {
@@ -2926,7 +2934,7 @@
 	case POINTER:
 	    break;
 	case BIT_FIELD:
-	    e =  list3(RBIT_FIELD,rvalue_t(cadr(e),car(caddr(type))),type);
+	    e =  list3(RBIT_FIELD,cadr(e),type);
             /*                         byte rvalue,   store type */
 	    type = cadr(type); /* value type */
 	    return e;
@@ -3479,76 +3487,56 @@
 #define is_long_type(type)  (type==LONGLONG||type==ULONGLONG)
 
 #if BIT_FIELD_CODE
+
+/* 
+    bitfield   struct { char a:1; unsigned int b:10; }
+    System dependent bit alignment is defined by code_bit_field_disp.
+       type of bitfield represents type of the value
+       these values are stored in a stored type which can be different from
+       value type.
+ */
+
 static int
 bit_field(int e1,int t)
 {
+    int reg;
 if (car(e1)==BIT_FIELD) {
     printf("# bit_field_bug\n");
     e1 = cadr(e1);
 }
     g_expr(e1);
-    code_bit_field(t, cadr(caddr(t))  /* bit offset */, USE_CREG);
-    return cadr(t);
+    emit_push();
+    code_bit_field(t, reg = emit_pop(0), USE_CREG);
+    emit_pop_free(reg);
+    return cadr(t); /* value type */
 }
 
 static int
 bit_field_repl(int e1,int e2,int t)
 {
     /* e1 = e2 */
-    int stype = car(caddr(t));   /* store type */
-    int lo = is_long_type(stype);
     if ((car(e2)==CONST||car(e2)==LCONST)) {
 	g_expr(e1);
-	code_bit_replace_const(e2,USE_CREG,
-	    t /* type */,cadr(caddr(t)) /* bit offset */);
-	return stype;
+	code_bit_replace_const(e2,USE_CREG,t);
+	return t;
     }
     g_expr(e1);
-    if (lo) emit_lpush(); else emit_push();
+    emit_push();
     g_expr(e2);
-    code_bit_replace(USE_CREG,(e2=lo?emit_lpop():emit_pop(0)),
-	t /* type */,cadr(caddr(t)) /* bit offset */);
-    if (lo) emit_lpop_free(e2); else emit_pop_free(e2);
-    return stype;
+    code_bit_replace(e2=emit_pop(0),USE_CREG,t);
+    emit_pop_free(e2);
+    return t;
 }
 
 static int
 bassign(int e2,int e3,int t)
 {
-    int n,e4;
     int type  = cadr(t);
-    int stype  = car(caddr(t));
     /*  e2 = e3 */
     if (car(e2)==BIT_FIELD) {
 	e2 = cadr(e2);
     }
-    if (car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR) {
-	e4 = rvalue_t(e2,stype);
-	if (stype>0 && car(stype)==STRUCT)
-	    g_expr(list4(BFD_REPL,e4,e3,t));
-	else
-	    g_expr(assign_expr0(e2, list4(BFD_REPL,e4,e3,t), stype,stype));
-	if (use)
-	    code_bit_field(t, cadr(caddr(t))  /* bit offset */, USE_CREG);
-	return type;
-    }
-    /*  new = &e2 */
-    /*  *new = *new bit_repl e3 */
-    //  n = get_register_var(0);
-    if (stype>0 && car(stype)==STRUCT) {
-	e4 = rvalue_t(list2(INDIRECT,rvalue_t(n,INT)),stype);
-	g_expr(list4(BFD_REPL,list2(ADDRESS,cadr(e2)),e3,t));
-    } else {
-	n = list2(LVAR,new_lvar(size_of_int));
-	g_expr_u(assign_expr0(n,list2(ADDRESS,cadr(e2)),INT,INT));
-	e4 = rvalue_t(list2(INDIRECT,rvalue_t(n,INT)),stype);
-	g_expr(assign_expr0(list2(INDIRECT,rvalue_t(n,INT)),
-	    list4(BFD_REPL,e4,e3,t),
-	    stype,stype));
-	free_lvar(cadr(n));
-    }
-    if (use)
-	code_bit_field(t, cadr(caddr(t))  /* bit offset */, USE_CREG);
+    bit_field_repl(e2,e3,t);
     return type;
 }
 
@@ -3556,86 +3544,53 @@
 bassop(int e2,int e3,int op,int t,int post)
 {
   /*
-    if (simple) {
-	tmp_var1 = bit_field byte
-	tmp_var2 = tmp_var  = code_bit_field
-        tmp_var op= operand
-        bit_field = tmp_var1 bit-repl tmp_var
-    } else {
-        address = lvalue;
-
-	tmp_var1 = bit_field byte (*address)
-	tmp_var2 = tmp_var  = code_bit_field
-        tmp_var op= operand
-        bit_field (*address) = tmp_var1 bit-repl tmp_var
-
-    }
-    if (post) tmp_var2;
+	n = bit_field address
+	code_bit_field
+	if (post) n1 = value
+        value op= operand
+	n bit-repl value
+	if (post) n1;
    */
+    /*  e2 = e2 op e3; */
+    /*  new = &e2 */
+    /*  *new = *new op e3 */
+    int suse = use;
+    int lo = (type==LONGLONG||type==ULONGLONG);
+    int n,n1;
+    int reg;
 
-    int n=-1,n1=-1,n2=-1,adr=-1,e4;
-    int type  = cadr(t);
-    int stype  = car(caddr(t));
-    int byte;
-    int bit_offset = cadr(caddr(t));
-    byte = size(type); if (byte==4) byte = 0;
-
-    n = list2(LVAR,new_lvar(size(type)));
-    n1 = list2(LVAR,new_lvar(size(type)));
-    if (post) n2 = list2(LVAR,new_lvar(size(type)));
-    /*  e2 = e3 */
-    if (car(e2)==BIT_FIELD) {
-	e2 = cadr(e2);
-    }
-    if (!(car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR)) {
-	adr = list2(LVAR,new_lvar(size(stype)));
-	g_expr_u(assign_expr0(adr,list2(ADDRESS,cadr(e2)),INT,INT));
-	e4 = rvalue_t(list2(INDIRECT,rvalue_t(adr,INT)),stype);
-	e2 = list2(INDIRECT,rvalue_t(adr,INT));
+    n = list2(LVAR,new_lvar(size_of_int));
+    g_expr(assign_expr0(n,list2(ADDRESS,cadr(e2)),INT,INT));
+    reg = emit_push();
+    code_bit_field(t, reg, USE_CREG);
+    use=1;
+    if (lo) {
+	if (post) {
+	    n1 = list2(LVAR,new_lvar(size_of_longlong));
+	    code_lassign_lvar(cadr(n1),USE_CREG);
+	}
+	emit_lpush();
+	g_expr(e3);
+	code_register_lassop(USE_CREG,op+LOP);
     } else {
-	e4 = rvalue_t(e2,stype);
+	if (post) {
+	    n1 = list2(LVAR,new_lvar(size_of_int));
+	    code_assign_lvar(cadr(n1),USE_CREG,0);
+	}
+	emit_push();
+	g_expr(e3);
+	code_register_assop((e2=emit_pop(0)),USE_CREG,op,size(type));
+	if (use) {
+	    code_register(e2,USE_CREG);
+	}
+	emit_pop_free(e2);
     }
-    if (stype==ULONGLONG||stype==LONGLONG) {
-	g_expr(e4);
-	code_lassign_lvar(cadr(n1),USE_CREG);
-	code_bit_field(t, bit_offset, USE_CREG);
-	code_lassign_lvar(cadr(n),USE_CREG);
-	if (post) code_lassign_lvar(cadr(n2),USE_CREG);
-    } else if (stype==STRUCT) {
-	g_expr0(assign_expr0(n1,e4,stype,stype));
-	code_bit_field(t, bit_offset, USE_CREG);
-	code_lassign_lvar(cadr(n),USE_CREG);
-	if (post) code_lassign_lvar(cadr(n2),USE_CREG);
-    } else {
-	g_expr(e4);
-	code_assign_lvar(cadr(n1),USE_CREG,byte);
-	code_bit_field(t, bit_offset, USE_CREG);
-	code_assign_lvar(cadr(n),USE_CREG,byte);
-	if (post) code_assign_lvar(cadr(n2),USE_CREG,byte);
-    }
-
-    switch(type) {
-    case LONGLONG:	lassop(list4(LASSOP,n,longlong_value(e3),op+LOP)); break;
-    case ULONGLONG:	lassop(list4(LUASSOP,n,longlong_value(e3),op+LOP)); break;
-    case CHAR: 		iassop(list4(CASSOP,n,int_value(e3),op)); break;
-    case UCHAR: 	iassop(list4(CUASSOP,n,unsigned_value(e3),op)); break;
-    case SHORT: 	iassop(list4(SASSOP,n,int_value(e3),op)); break;
-    case USHORT: 	iassop(list4(SUASSOP,n,unsigned_value(e3),op)); break;
-    case UNSIGNED: 	iassop(list4(ASSOP,n,unsigned_value(e3),op)); break;
-    case INT: 		iassop(list4(ASSOP,n,int_value(e3),op)); break;
-    default: error(-1);
-    }
-
-    g_expr(assign_expr0(e2,
-	    list4(BFD_REPL,rvalue_t(n1,type),rvalue_t(n,type),t),stype,stype));
-
-    if (post) { g_expr(rvalue_t(n2,type)); free_lvar(cadr(n2)); }
-    else if (use)  { 
-	code_bit_field(t, bit_offset, USE_CREG);
-    }
-    if (adr!=-1) free_lvar(cadr(adr));
+    use=post?0:suse;
+    code_bit_replace(e2=emit_pop(0),USE_CREG,t);
+    emit_pop_free(e2);
+    use = suse;
+    if (post&&use) { g_expr(rvalue_t(n1,type)); free_lvar(cadr(n1)); }
     free_lvar(cadr(n));
-    free_lvar(cadr(n1));
     return type;
 }
 
@@ -3760,6 +3715,10 @@
     code_indirect_jmp(USE_CREG);
 }
 
+/*
+    make bit mask
+      MSB 1 2 3 4 .... 29 30 31 LSB
+ */
 extern int
 make_mask(int from,int to)
 {
@@ -3780,6 +3739,10 @@
 static int ptr_cache=0;
 static int ptr_cache_last=0;
 
+/* 
+    global name pointer cache
+ */
+
 extern void
 init_ptr_cache()
 {
@@ -3880,6 +3843,7 @@
 extern int
 ilog(int i)
 {
+    /* number of bit (i-1) is better? */
     switch(i) {
     case 2: return 1;
     case 4: return 2;
--- a/mc-parse.c	Fri Oct 29 21:21:28 2004 +0900
+++ b/mc-parse.c	Sat Oct 30 14:04:45 2004 +0900
@@ -100,6 +100,7 @@
 static int adecl(NMTBL *n);
 static void code_decl(NMTBL *n);
 static void decl(void);
+static int typespec(void);
 static void docase(void);
 static void docomp(int);
 static void dodefault(void);
@@ -174,6 +175,9 @@
 {
     int i;
 
+/*
+     option handling
+ */
     if(argc==1) exit(1);
     lsrc = chk = asmf = 0;
     ac=argc;
@@ -213,6 +217,7 @@
     if (!chk && ccout)
 	if ( (freopen(ccout,"w",stdout)) == NULL ) error(FILERR);
     init();
+    /* top level */
     while(1) {
 	mode=TOP;
 	if (gfree > heapsize-30000) {
@@ -241,6 +246,10 @@
     /*NOTREACHED*/
 }
 
+/*
+    error handler
+    when EOF, process next file
+ */
 extern void
 error(int n)
 {
@@ -315,6 +324,9 @@
     fprintf (stderr,"^\n");
 }
 
+/*
+     required symbol check
+ */
 static void
 checksym(int s)
 {
@@ -331,6 +343,12 @@
 	getsym(0);
 }
 
+/*
+    heap array memory pool initialize
+    init before reserve()
+    this can be called twice or more.
+ */
+
 static void
 heap_init()
 {
@@ -342,6 +360,10 @@
     lfree=heapsize;
 }
 
+/*
+   Par file initialization.
+ */
+
 static void
 reinit(void)
 {
@@ -421,6 +443,10 @@
     enter_scope();
 }
 
+/*
+    one time initialization
+ */
+
 static void
 init(void)
 {
@@ -433,6 +459,10 @@
     getch();
 }
 
+/*
+    keep track current directory
+ */
+
 extern void
 copy_current_file_dir(char *name)
 {
@@ -446,6 +476,11 @@
     *p = 0;
 }
 
+/*
+    search possible exisiting file name
+      with new extension hoge.c -> hoge.s     
+ */
+
 static int first_newfile = 1;
 
 extern char *
@@ -479,6 +514,10 @@
     return p;
 }
 
+/*
+    start new file in argument list
+    create filep 
+ */
 
 static void
 newfile(void)
@@ -529,6 +568,10 @@
 #endif
 }
 
+/*
+    regist reserved word
+ */
+
 static void
 reserve(char *s, int d)
 {
@@ -544,13 +587,23 @@
     }
 }
 
+/*
+     Parse part
+ */
+
+/*
+    storage class 
+        volatile, static, extern..
+ */
+
 static void
 storage_class()
 {
-   if(sym==VOLATILE) {
+    if(sym==VOLATILE) {
 	getsym(0);
-   }
-   if(sym==STATIC) {
+    }
+    switch(sym) {
+    case STATIC:
 	if(mode==LDECL) {
 		getsym(0);
 		conv->static_();
@@ -562,13 +615,15 @@
 		stmode=STATIC;
 	} else
 	    error(DCERR);
-    } else if(sym==REGISTER) {
+	break;
+    case REGISTER:
 	if(mode!=LDECL)
 	    error(DCERR);
 	stmode=REGISTER;
 	getsym(0);
 	conv->register_();
-    } else if(sym==EXTRN) {
+	break;
+    case EXTRN:
 	if(mode==LDECL) {
 		getsym(0);
 		conv->static_();
@@ -580,12 +635,14 @@
 	    stmode=EXTRN;
 	} else
 	    error(DCERR);
-    } else if(sym==LABEL) {
+	break;
+    case LABEL:  /* GNU extension */
 	if(mode==LDECL) {
 	    getsym(0);
 	    mode = LLDECL;
 	} else error(DCERR);
-    } else if(sym==TYPEDEF) {
+	break;
+    case TYPEDEF:
 	if(mode==GDECL) {
 		getsym(0);
 		conv->typedef_();
@@ -596,9 +653,19 @@
 		mode=LTDECL;
 	} else
 		error(DCERR);
+	break;
     }
 }
 
+/*
+       declaration
+         int i;
+         int f(arg) {...}
+         STORAGE_CLASS TYPESPEC name () { }
+         STORAGE_CLASS TYPESPEC name ,
+         STORAGE_CLASS TYPESPEC name = value,
+ */
+
 static void
 decl(void)
 {
@@ -621,6 +688,7 @@
 	}
     }
     if(sym==LC || ( sym!=SM && sym!=COMMA && sym!=ASS)) {
+	/* function body */
 	if (mode!=GDECL) error(DCERR);
         stypedecl=sd;
 	if (car(type)==CODE) {
@@ -628,35 +696,42 @@
 	} else if (car(type)==FUNCTION) {
 	    fdecl(n); return;
 	} else error(DCERR);
+    } else {
+	conv->return_type_(type,n,sd);
+	n = def(n);
+	if (sym==ASS && n!=&null_nptr) { 
+	    decl_data(type,n,0,0); data_closing(n); 
+	}
+	while(sym==COMMA) {
+	    conv->comma_();
+	    getsym(0);
+	    type=t;
+	    n=decl0();
+	    reverse(t);
+	    if(n == &null_nptr) {
+		/* only bitfield allow null field name */
+		if (!(type>0&&car(type)==BIT_FIELD))
+		    error(DCERR);
+	    }
+	    conv->return_type_(type,n,1);
+	    def(n);
+	    if (sym==ASS && n!=&null_nptr) {
+		decl_data(type,n,0,0);data_closing(n);
+	    }
+	}
+	if(sym!=SM) error(DCERR);
+	conv->sm_();
+	if(mode==GTDECL)
+	    mode=GDECL;
+	if(mode==STADECL||mode==LTDECL)
+	    mode=LDECL;
     }
-    conv->return_type_(type,n,sd);
-    n = def(n);
-    if (sym==ASS && n!=&null_nptr) { decl_data(type,n,0,0); data_closing(n); }
-
-    while(sym==COMMA) {
-	conv->comma_();
-	getsym(0);
-	type=t;
-	n=decl0();
-	reverse(t);
-	if(n == &null_nptr) {
-	    /* only bitfield allow null field name */
-	    if (!(type>0&&car(type)==BIT_FIELD))
-		error(DCERR);
-	}
-	conv->return_type_(type,n,1);
-	def(n);
-	if (sym==ASS && n!=&null_nptr) {decl_data(type,n,0,0);data_closing(n);}
-    }
-    if(sym!=SM) error(DCERR);
-    conv->sm_();
-    if(mode==GTDECL)
-	mode=GDECL;
-    if(mode==STADECL||mode==LTDECL)
-	mode=LDECL;
 }
 
-extern int
+/*
+      type specification
+ */
+static int
 typespec(void)
 {
     int t = INT;
@@ -760,7 +835,7 @@
 	break;
     default:
 	if(sym==IDENT) {
-	    if(nptr->sc==TYPE) {
+	    if (nptr->sc==TYPE) {
 		t=nptr->ty;
 		typedefed=glist2((int)nptr,typedefed);
 		getsym(0);
@@ -782,6 +857,10 @@
     return t;
 }
 
+/*
+      indirect *
+      type prefix
+ */
 static struct nametable *
 decl0(void)
 {
@@ -798,6 +877,10 @@
     return decl1();
 }
 
+/*
+      type postfix
+      a() a[] (type)
+ */
 
 static NMTBL *
 decl1(void)
@@ -891,6 +974,10 @@
     /* NOT REACHED */
 }
 
+/*
+     argument declaration (ANSI)
+	    argtypes=list2(type,argtypes);
+ */
 
 static int
 adecl(NMTBL *n)
@@ -972,6 +1059,9 @@
     type = t2;
 }
 
+/*
+    destructive reverse
+ */
 int
 reverse0(int t1)
 {
@@ -987,6 +1077,10 @@
     return t2;
 }
 
+/*
+     calcurate size of type
+ */
+
 extern int
 size(int t)
 {
@@ -1033,6 +1127,11 @@
 
 #define hash_value(hash,ch) (hash = (39*hash)^((unsigned char)(ch)))
 
+/*
+    new name for static global variable
+         delimitor _
+ */
+
 extern NMTBL *
 new_static_name(char *name,int delimit)
 {
@@ -1071,10 +1170,13 @@
     return n;
 }
 
+/*
+    data declaration
+    a[] = {,,,,};
+ */
 
 #define LOCAL_STRUCT_INIT_STATIC 1
 
-
 static void
 decl_data_field(int type,NMTBL *n,int offset)
 {
@@ -1154,7 +1256,9 @@
     decl_str_init = decl_str_init_save;
 }
 
-// data structure initialization
+/*
+    data structure initialization
+ */
 
 static int
 decl_data(int t, NMTBL *n,int offset,int skip)
@@ -1247,6 +1351,9 @@
     return offset; /* not reached */
 }
 
+/*
+    declaration in struct/union
+ */
 static void
 sdecl_field()
 {
@@ -1439,7 +1546,7 @@
 
 /* local decl can be used, after {}         */
 /*  but it's lexical scope remains after {} */
-/*  my be in for(int i=....) not yet        */
+/*  my be in for(int i=....) not yet  (fixed already?)      */
 
 static void
 local_decl()
@@ -1516,6 +1623,9 @@
     arglist=0;
 }
 
+/*
+    basic C statement
+ */
 
 static void
 statement(int use)
@@ -1761,6 +1871,9 @@
     blabel=sbreak;
 }
 
+/*
+    compound statement {}
+ */
 static void
 docomp(int use)
 {
@@ -1773,6 +1886,10 @@
     getsym(0);
 }
 
+/*
+     CASE_CODE generates table jump
+ */
+
 static void
 doswitch(void)
 {
@@ -1798,7 +1915,7 @@
     checksym(RPAR);
     conv->switch_body_();
     cslabel = control = 0;
-    /* should be case statement but...  for example,
+    /* next syntax should be a case statement but...  
 	main() {
 	    int i=3,j=1,k=0;
 	    switch(i)  {
@@ -1829,6 +1946,7 @@
     cslist = slist;
 }
 
+/* used in insert ascend */
 static int
 docase_eq()
 {
@@ -1877,6 +1995,7 @@
     fwddef(l);
     control=1;
 #else
+    /* casading branch implementation */
     int c,l,slfree;
     l = 0;
     if (retpending) ret();
@@ -2003,6 +2122,7 @@
 	env = 0;
     }
     if (t==FUNCTION) {
+        /*   CbC continuation */
 	conv->jump_(env);
 	e2 = cadr(e1);
 	if (car(e2) == FNAME) {
@@ -2044,6 +2164,10 @@
 }
 
 #if ASM_CODE
+
+/*
+     asm( asm_string : output expr : input expr : option_string )
+ */
 static void
 doasm()
 {
@@ -2574,6 +2698,8 @@
     return e;
 }
 
+/* mark extern symbol is used */
+
 static void
 extrn_use(NMTBL *nptr)
 {
@@ -2586,6 +2712,8 @@
     }
 }
 
+/*  define function name as extern */
+
 static int
 fname(NMTBL *nptr)
 {
@@ -2730,7 +2858,10 @@
 	conv->lpar_();
 	getsym(0);
 	if(sym==VOLATILE) getsym(0);
-	if(typeid(sym)) { /* cast */
+
+	/* type cast */
+
+	if(typeid(sym)) {
 	    t=typename();
 	    conv->return_type_(t,0,0);
 	    conv->rpar_();
@@ -2754,7 +2885,7 @@
 	    e1=expr13();
 	    return correct_type(e1,t);
 	} else if (sym==LC) {
-	    // statement in expression
+	    // statement in expression  (GNU extension)
 	    docomp(1);
 	    e1 = lastexp; lastexp = 0;
 	} else {
@@ -2802,6 +2933,7 @@
     return e1;
 }
 
+/* function call */
 
 static int
 expr15(int e1)
@@ -2905,6 +3037,10 @@
     return type;
 }
 
+/*
+    type prefix in cast
+ */
+
 static int
 ndecl0(void)
 {
@@ -2915,6 +3051,10 @@
     return ndecl1();
 }
 
+/*
+    type postfix in cast
+ */
+
 static int
 ndecl1(void)
 {
@@ -2952,6 +3092,10 @@
     }
 }
 
+/*
+     string heap management
+ */
+
 static struct cheap *
 new_cheap()
 {
@@ -2999,6 +3143,7 @@
     return cheap;
 }
 
+/* mark string cheap */
 extern void
 save_cheap(struct cheap *scheap,struct cheap *cheap)
 {
@@ -3007,6 +3152,7 @@
     scheap->next = cheap;
 }
 
+/* discard string heap until marked string */
 extern struct cheap *
 reset_cheap(struct cheap *scheap)
 {
@@ -3021,6 +3167,9 @@
     return cheap;
 }
 
+/*
+     Symbol table handling
+ */
 
 static int
 neqnamel(char *p,char *q,int len)
@@ -3122,6 +3271,9 @@
     symval = i;
 }
 
+/*
+   long long posfix (0ULL etc.)
+ */
 static int
 is_ll()
 {
@@ -3273,6 +3425,10 @@
     return sym;
 }
 
+/*
+    Tokenizer
+ */
+
 extern int
 getsym(int sc)
 {
@@ -3470,6 +3626,10 @@
     return ret;
 }
 
+/*
+    dummy name table element
+ */
+
 int dummy_count = 0;
 
 extern NMTBL *
--- a/mc-parse.h	Fri Oct 29 21:21:28 2004 +0900
+++ b/mc-parse.h	Sat Oct 30 14:04:45 2004 +0900
@@ -101,7 +101,6 @@
 extern NMTBL *new_static_name(char *name,int delimit);
 extern int reverse0(int t1);
 extern int size(int t);
-extern int typespec(void);
 
 /* used in mc-macro.c */