changeset 61:8ffb8ca3fe34

separation of architecture dependent part.
author kono
date Thu, 20 Feb 2003 03:29:15 +0900
parents aa779bcffef7
children 129f4802b027
files Makefile mc-code-ia32.c mc-code.h mc-codegen.c mc-codegen.h mc-nop-386.c mc-parse.c mc.h stdio.h
diffstat 9 files changed, 2531 insertions(+), 222 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Feb 19 21:22:49 2003 +0900
+++ b/Makefile	Thu Feb 20 03:29:15 2003 +0900
@@ -9,8 +9,10 @@
 
 all: mc 
 
-mc : mc-parse.o mc-nop-386.o mc-tree.o $(CONVERTER)
-	$(CC) -g mc-parse.o mc-nop-386.o mc-tree.o $(CONVERTER) -o $@
+mc : mc-parse.o mc-codegen.o mc-code-ia32.o mc-tree.o $(CONVERTER)
+	$(CC) -g mc-parse.o mc-codegen.o mc-code-ia32.o \
+		mc-tree.o $(CONVERTER) -o $@
+
 tar :
 	make clean
 	tar cBf - . | gzip > ../comp.tgz 
@@ -19,7 +21,7 @@
 	makedepend mc-parse.c mc-nop-386.c mc-tree.c
 
 clean :
-	-rm -f *.s *.o mc mc1 a.out *~ core*
+	-rm -f *.s *.o mc mc1 a.out *~ core* */*.o
 
 mc1 : b00.s b01.s mc-tree.o
 	$(CC) -g -o $@ $(PRINTF) mc-tree.o b00.s b01.s 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mc-code-ia32.c	Thu Feb 20 03:29:15 2003 +0900
@@ -0,0 +1,1304 @@
+/* Micro-C Code Generatation Part for intel386 */
+/* $Id$ */
+
+#define EXTERN extern
+#include "mc.h"
+#include "mc-codegen.h"
+
+#define TEXT_EMIT_MODE 0
+#define DATA_EMIT_MODE 1
+#define RODATA_EMIT_MODE 2
+
+static int output_mode = TEXT_EMIT_MODE;
+static int data_alignment = 0;
+
+static int code_disp_label;
+static int func_disp_label;
+
+/*
+                                           -16  -8 local2
+                                           -12  -4 local1
+                                            -8  8  arg3
+                                            -4  4  arg2
+                                             0  0  arg1
+         local2     -20 4                    0    (%edi)
+         local1 <-- -16 0 local variable     0    (%esi)
+        %edi        -12  <- disp_offset          %ebp
+        %esi         -8
+        %ebx         -4
+        %ebp = %esp   0
+        %eip          4   <- arg_offset
+          arg1        8 0
+          arg2       12 4
+            see enter/enter1/leave           see code_enter
+ */
+int arg_offset = 8;
+int disp_offset = -12;
+int func_disp_offset = -12;
+int code_disp_offset = 0;
+int jump_offset = 0;
+
+int size_of_int = 4;
+int endian = 0;
+int MAX_REGISTER=6;         /* intel386のレジスタを4つまで使う*/
+int REAL_MAX_REGISTER=8;    /* intel386のレジスタが8つということ*/
+int MAX_DATA_REG=4;    
+int MAX_POINTER=3;    
+int MAX_REGISTGER_VAR=2;    
+
+EXTERN int  creg;     /* current register */
+EXTERN int  dreg;     /* temporary register */
+EXTERN int  reg_sp;   /* REGister Stack-Pointer */
+
+
+#define REG_EAX   0
+#define REG_EBX   1
+#define REG_ECX   2
+#define REG_EDX   3
+#define REG_ESI   4
+#define REG_EDI   5
+#define REG_EBP   6
+#define REG_ESP   7
+
+
+#define DATA_REG 0    
+#define POINTER_REG 3    
+static char *reg_name[8]; 
+static char *reg_name_l[4];
+static char *reg_name_w[4];
+
+extern int  creg;     /* current register */
+extern int  dreg;     /* temporary register */
+extern int  reg_sp;   /* REGister Stack-Pointer */
+
+#define MAX_MAX 10
+int rname[MAX_MAX];
+int regs[MAX_MAX];       /* 使われているレジスタを示すフラグ */
+int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
+int regv[MAX_MAX];       /* 値が入っているかどうか */
+
+
+void use_register(int virt, int real, int move);
+void code_preinc(int e1,int e2) ;
+void code_cmp_register(int e2) ;
+void code_assign_gvar(int e2,int byte) ;
+void tosop(int op,int oreg);
+void edx_cleanup();
+void shift(char *op, int reg);
+void ld_indexx(int byte, int n, int xreg);
+void jmp(int l);
+void global_table(void);
+void local_table(void);
+void text_mode(void);
+void data_mode(char *name);
+
+char *register_name(int i,int byte);
+int register_var(int r);
+int get_register_var(void);
+void emit_push(void);
+void emit_push_x(int xreg);
+int emit_pop(int type);
+void code_crlvar(int e2);
+void code_preinc(int e1,int e2);
+void code_postinc(int e1,int e2);
+void code_bool(int e1);
+void string(int e1);
+void emit_copy(int from,int  to,int length,int offset,int value,int det);
+int struct_push(int e4,int t);
+void function(int e1);
+void code_assop(int op,int byte);
+int edx_setup();
+void opening(char *filename);
+void code_leave(char *name);
+int lvar(int l);
+
+void
+code_init(void)
+{
+    arg_offset = 8;
+    func_disp_offset = -12;
+    disp_offset = -12;
+    size_of_int = 4;
+    endian = 0;
+    MAX_REGISTER=6;
+    MAX_DATA_REG=4;    
+    MAX_POINTER=3;    
+    MAX_REGISTER_VAR=2;    
+
+    reg_name[REG_EAX] = "%eax";
+    reg_name[REG_EBX] = "%ebx";
+    reg_name[REG_ECX] = "%ecx";
+    reg_name[REG_EDX] = "%edx";
+    reg_name[REG_ESI] = "%esi";
+    reg_name[REG_EDI] = "%edi";
+    reg_name[REG_EBP] = "%ebp";
+    reg_name[REG_ESP] = "%esp";
+    reg_name_l[REG_EAX] = "%al";
+    reg_name_l[REG_EBX] = "%bl";
+    reg_name_l[REG_ECX] = "%cl";
+    reg_name_l[REG_EDX] = "%dl";
+    reg_name_w[REG_EAX] = "%ax";
+    reg_name_w[REG_EBX] = "%bx";
+    reg_name_w[REG_ECX] = "%cx";
+    reg_name_w[REG_EDX] = "%dx";
+
+}
+
+char *
+register_name(int i,int byte)
+{
+    if (i<0) {
+	error(REG_ERR);
+	return "%eax";
+    }
+    if (byte && rname[i] <= REG_EDX) {
+	return reg_name_l[rname[i]];
+    } else {
+	return reg_name[rname[i]]; /* should be error */
+    }
+}
+
+extern int rname[MAX_MAX];
+extern int regs[MAX_MAX];       /* 使われているレジスタを示すフラグ */
+extern int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
+extern int regv[MAX_MAX];       /* 値が入っているかどうか */
+
+extern int creg_regvar;
+
+void
+gexpr_code_init(void){
+    use_register(creg,REG_EAX,0);
+    regv[dreg]=0;
+    creg_regvar = -1;
+}
+
+int
+register_var(int r) {
+    return virtual(r+REG_ESI);
+}
+
+int
+get_register_var(void)
+{
+    int i;
+    for(i=REG_ESI;i<REG_ESP;i++) {
+        if (! regs[i]) {    /* 使われていないなら */
+            regs[i]=1;      /* そのレジスタを使うことを宣言し */
+            regv[i]=0;
+            return i;       /* その場所を表す番号を返す */
+        }
+    }
+    return -1;
+}
+
+void 
+use_register(int virt, int real, int move)
+{
+    int real_v;
+    char *move_op;
+    if (rname[virt]==real)
+	return;
+    real_v = virtual(real);
+    move_op = regs[real_v]?"\txchg %s,%s\n":"\tmovl %s,%s\n";
+    if (move || (regv[real_v])) {
+	printf(move_op,reg_name[rname[virt]],reg_name[real]);
+    } 
+    rname[real_v] = rname[virt];
+    rname[virt] = real; 
+}
+
+void 
+use_pointer(int virt, int move)
+{
+    int i;
+    if (rname[virt]>=POINTER_REG)
+	return;
+    for(i=POINTER_REG;i<MAX_REGISTER;i++) {
+	if (!regs[virtual(i)]) {
+	    use_register(virt,i,move);
+	    return;
+	}
+    }
+    /* we prefer EBX */
+    use_register(virt,REG_EBX,move);
+}
+
+void 
+use_data_reg(int virt, int move)
+{
+    int i;
+    if (rname[virt]<MAX_DATA_REG)
+	return;
+    for(i=0;i<MAX_DATA_REG;i++) {
+	if (!regs[virtual(i)]) {
+	    use_register(virt,i,move);
+	    return;
+	}
+    }
+    /* we prefer EBX */
+    use_register(virt,REG_EBX,move);
+}
+
+
+void 
+emit_push(void)
+{
+    int new_reg;
+    new_reg = get_register();
+    if(new_reg<0) {                     /* もうレジスタがない */
+	reg_stack[reg_sp++] =  -1;
+	printf("\tpushl %s\n",register_name(creg,0));
+	/* creg is used soon, don't regv[creg]=0 */
+    } else {
+	reg_stack[reg_sp++] = creg;     /* push するかわりにレジスタを使う */
+	creg = new_reg;
+	regv[creg]=1;
+    }
+}
+
+void 
+emit_push_x(int xreg)
+{
+    int new_reg;
+    new_reg = get_register();
+    if(new_reg<0) {                     /* もうレジスタがない */
+	reg_stack[reg_sp++] =  -1;
+	printf("\tpushl %s\n",register_name(xreg,0));
+	/* creg is used soon, don't regv[xreg]=0 */
+    } else {
+	reg_stack[reg_sp++] = xreg;     /* push するかわりにレジスタを使う */
+	xreg = new_reg;
+	regv[xreg]=1;
+    }
+}
+
+int
+emit_pop(int type)
+{
+    int xreg;
+    if ((xreg=pop_register())==-1) {
+	if (type==POINTER_REG)
+	    use_pointer(dreg,0);
+	else if (type==DATA_REG)
+	    use_data_reg(dreg,0);
+if (regv[dreg]) {
+    printf("# emit_pop dreg conflict\n");
+}
+	printf("\tpopl %s\n",register_name(dreg,0));
+	xreg = dreg;
+	regv[xreg]=1;
+    } 
+    return xreg;
+}
+
+
+void
+code_gvar(int e1) {
+    printf("\tmovl $%s,%s\n",(char *)caddr(e1),register_name(creg,0));
+}
+
+
+void
+code_rgvar(int e1) {
+    printf("\tmovl %s,%s\n",(char *)caddr(e1),register_name(creg,0));
+}
+
+void
+code_crgvar(e1){
+    printf("\tmovsbl %s,%s\n",(char *)caddr(e1),register_name(creg,0));
+}
+
+
+void
+code_lvar(int e2) {
+    printf("\tlea %d(%%ebp),%s\n",e2,register_name(creg,0));
+}
+
+
+void
+code_register(int e2) {
+    printf("\tmovl %s,%s\n",register_name(e2,0),register_name(creg,0));
+}
+
+
+void
+code_rlvar(int e2) {
+    printf("\tmovl %d(%%ebp),%s\n",e2,register_name(creg,0));
+}
+
+
+void
+code_crlvar(int e2) {
+    printf("\tmovsbl %d(%%ebp),%s\n",lvar(e2),register_name(creg,0));
+}
+
+
+void
+code_fname(char *e2) {
+    printf("\tmovl $%s,%s\n",e2,register_name(creg,0));
+}
+
+
+void
+code_const(int e2) {
+    printf("\tmovl $%d,%s\n",e2,register_name(creg,0));
+}
+
+
+void
+code_neg() {
+    printf("\tnegl %s\n", register_name(creg,0));
+}
+
+
+void
+code_not() {
+    printf("\tnotl %s\n", register_name(creg,0));
+}
+
+
+void
+code_lnot() {
+    char *xrn;
+    use_data_reg(creg,1);
+    xrn = register_name(creg,1);
+    printf("\tcmpl $0,%s\n", register_name(creg,0));
+    printf("\tsete %s\n", xrn);
+    printf("\tmovzbl %s,%s\n", xrn,register_name(creg,0));
+}
+
+void
+code_preinc(int e1,int e2) {
+    char *xrn;
+    if (car(e2)==REGISTER) {
+	printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0));
+	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0));
+	return;
+    } 
+    g_expr(e2);
+    xrn = register_name(creg,0);
+    printf("\taddl $%d,(%s)\n",caddr(e1),xrn);
+    printf("\tmovl (%s),%s\n",xrn,xrn);
+}
+
+
+void
+code_postinc(int e1,int e2) {
+    char *xrn;
+    if (car(e2)==REGISTER) {
+	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0));
+	printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0));
+	return;
+    } 
+    g_expr(e2);
+    emit_push();  
+    xrn = register_name((e2=emit_pop(0)),0);
+    printf("\tmovl (%s),%s\n",xrn,register_name(creg,0));
+    printf("\taddl $%d,(%s)\n",caddr(e1),xrn);
+    emit_pop_free(e2);
+}
+
+
+void
+code_cpostinc(int e1,int e2) {
+    char *xrn;
+    if (car(e2)==REGISTER) {
+	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0));
+	printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0));
+	return;
+    } 
+    g_expr(e2);
+    emit_push();
+    xrn = register_name((e2=emit_pop(0)),1);
+    printf("\tmovsbl (%s),%s\n",xrn,register_name(creg,0));
+    printf("\tincl (%s)\n",xrn);
+    emit_pop_free(e2);
+}
+
+
+void
+code_cpreinc(int e1,int e2) {
+    if (car(e2)==REGISTER) {
+	printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0));
+	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0));
+	return;
+    } 
+    g_expr(e2);
+    printf("\tincl (%s)\n",register_name(creg,0));
+    printf("\tmovsbl (%s),%s\n",register_name(creg,0),register_name(creg,0));
+}
+
+
+void
+code_cpostdec(int e1,int e2) {
+    if (car(e2)==REGISTER) {
+	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0));
+	printf("\tdecl %s\n",register_name(cadr(e2),0));
+	return;
+    } 
+    g_expr(e2);
+    printf("\tmovsbl (%s),%s\n",register_name(creg,0),register_name(creg,0));
+    printf("\tdecl (%s)\n",register_name(creg,0));
+}
+
+
+void
+code_cpredec(int e1,int e2) {
+    if (car(e2)==REGISTER) {
+	printf("\tdecl %s\n",register_name(cadr(e2),0));
+	printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0));
+	return;
+    } 
+    g_expr(e2);
+    emit_push();
+    e2 = emit_pop(0);
+    printf("\tdecl (%s)\n",register_name(e2,0));
+    printf("\tmovsbl (%s),%s\n",register_name(e2,0),register_name(creg,0));
+    emit_pop_free(e2);
+}
+
+
+void
+code_return() {
+    printf("\tleal _%d,%s\n",retcont,register_name(creg,0));
+}
+
+
+void
+code_environment() {
+    printf("\tmovl %%ebp,%s\n",register_name(creg,0));
+}
+
+
+void
+code_bool(int e1) {
+    char *xrn;
+    int e2,e3;
+    b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
+    xrn = register_name(creg,0);
+    printf("\txorl %s,%s\n",xrn,xrn);
+    jmp(e3=fwdlabel());
+    fwddef(e2);
+    printf("\tmovl $1,%s\n",xrn);
+    fwddef(e3);
+}
+
+char *
+code_gt(int cond) {
+    return (cond?"g":"le");
+}
+
+char *
+code_ugt(int cond) {
+    return (cond?"a":"be");
+}
+
+char *
+code_ge(int cond) {
+    return (cond?"ge":"l");
+}
+
+char *
+code_uge(int cond) {
+    return (cond?"ae":"b");
+}
+
+char *
+code_eq(int cond) {
+    return (cond?"e":"ne");
+}
+
+void
+code_cmp_crgvar(int e1) {
+    printf("\tcmpb $0,%s\n",(char *)caddr(e1));
+}
+
+
+void
+code_cmp_crlvar(int e1) {
+    printf("\tcmpb $0,%d(%%ebp)\n",e1);
+}
+
+
+void
+code_cmp_rgvar(int e1) {
+    printf("\tcmpl $0,%s\n",(char *)caddr(e1));
+}
+
+
+void
+code_cmp_rlvar(int e1) {
+    printf("\tcmpl $0,%d(%%ebp)\n",e1);
+}
+
+
+void
+code_cmp_register(int e2) {
+    printf("\tcmpl $0,%s\n",register_name(e2,0));
+}
+
+
+void
+ascii(char *s)
+{
+    printf("\t.string \"");
+    while(*s) {
+	if (*s=='\n')
+	    printf("%cn",92);
+	else if (*s<' ')
+	    printf("%c%03o",92,*s);
+	else if (*s==34)
+	    printf("%c%c",92,34);
+	else 
+	    printf("%c",*s);
+	s++;
+    }
+    printf("%c\n",34);
+}
+
+void
+string(int e1)
+{
+    char *s;
+    int i,lb;
+
+    if (0) {
+	s=(char *)cadr(e1);
+	lb=fwdlabel();
+	printf("\tjmp _%d\n",lb);
+	i=backdef();
+	ascii(s);
+	printf("\t.align 2\n");
+	fwddef(lb);
+	printf("\tlea _%d,%s\n",i,register_name(creg,0));
+    } else {
+	s=(char *)cadr(e1);
+	printf(".section\t.rodata\n");
+	lb=fwdlabel();
+	printf("_%d:\n",lb);
+	ascii(s);
+	if (output_mode==TEXT_EMIT_MODE) {
+	    printf(".text\n");
+	} else {
+	    text_mode();
+	}
+	printf("\tlea _%d,%s\n",lb,register_name(creg,0));
+    }
+}
+
+#define MAX_COPY_LEN 20
+
+void 
+emit_copy(int from,int  to,int length,int offset,int value,int det)
+{
+    int fix = 0;
+    /* length <0 means upward direction copy */
+    switch (length) {
+    case 0:	break;
+    case 1: case -1:
+	printf("\tmovb %d(%s),%s\n",offset,
+	    register_name(from,0), reg_name_l[rname[dreg]] );
+	printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset,
+	    register_name(to,0));
+	break;
+    case 2: case -2:
+	printf("\tmovw %d(%s),%s\n",offset,
+	    register_name(from,0), reg_name_w[rname[dreg]] );
+	printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset,
+	    register_name(to,0));
+	break;
+    case 4: case -4:
+	printf("\tmovl %d(%s),%s\n",offset,
+	    register_name(from,0), register_name(dreg,0));
+	printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset,
+	    register_name(to,0));
+	break;
+    default:
+	if (-MAX_COPY_LEN<length && length <0) {
+	    for(;length<=4;length+=4,offset-=4)
+		emit_copy(from,to,4,offset,0,det);
+	    for(;length<=2;length+=2,offset-=2)
+		emit_copy(from,to,2,offset,0,det);
+	    if(length>0)
+		emit_copy(from,to,length,offset,0,det);
+	    break;
+	} else if (length <=MAX_COPY_LEN) {
+	    for(;length>=4;length-=4,offset+=4)
+		emit_copy(from,to,4,offset,0,det);
+	    for(;length>=2;length-=2,offset+=2)
+		emit_copy(from,to,2,offset,0,det);
+	    if(length>0)
+		emit_copy(from,to,length,offset,0,det);
+	    break;
+	}
+	if (det) {
+/*
+   call bcopy
+	    g_expr(list3(FUNCTION,,);
+	    break;
+ */
+	}
+	use_register(from,REG_ESI,1);
+	use_register(to,  REG_EDI,1);
+	use_register(dreg,REG_ECX,0);
+	if (length<0) {
+	    printf("\tmovl $%d,%%ecx\n",-length/4);
+	    printf("\taddl $%d,%%esi\n",-length);
+	    printf("\taddl $%d,%%edi\n",-length);
+	    printf("\tstd\n\trep\n\tmovsl\n");
+	    if(length%4) {
+		emit_copy(from,to,length,offset+length/4,0,det);
+	    }
+	} else {
+	    printf("\tmovl $%d,%%ecx\n",length/4);
+	    fix = (length/4)*4;
+	    printf("\tcld\n\trep\n\tmovsl\n");
+	    if(length%4) {
+		emit_copy(from,to,length,offset+length/4,0,det);
+	    }
+	}
+    }
+    if (value) {
+    /* creg must point top of the destination data */
+    /* this code is necessary for the value of assignment or function call */
+    /* otherwise we don't need this */
+	if (fix) printf("\tsubl $%d,%s\n",fix,register_name(to,0));
+	if(creg!=to) {
+	    if (to==dreg) 
+		printf("\tmovl %s,%s\n",register_name(to,0),register_name(creg,0));
+	    else {
+		free_register(creg); creg=to;
+	    }
+	}
+    }
+    regv[from]=regv[to]=regv[dreg]=0;
+    regv[creg]=1;
+}
+
+int
+struct_push(int e4,int t) 
+{
+    int length,xreg,save,lreg;
+    g_expr(e4);
+    length=size(t); 
+    if(length%size_of_int) {
+	length += size_of_int - (length%size_of_int);
+    }
+    if (length==4) {
+	printf("\tpushl (%s)\n",register_name(creg,0)); return 1;
+    }
+    if (length==8) {
+	printf("\tpushl 4(%s)\n",register_name(creg,0));
+	printf("\tpushl (%s)\n",register_name(creg,0)); return 2;
+    }
+    printf("\tsubl $%d,%%esp\n",length);
+    if (register_full()) {
+	save = 1;
+	for(lreg=0;lreg==creg||lreg==dreg;lreg++);
+	printf("\tpushl %s\n",register_name(lreg,0));
+	xreg = lreg; regv[xreg]=0;
+    } else {
+	save=0;
+	xreg = get_register();
+    }
+    if (save) 
+	printf("\tlea %d(%%esp),%s\n",size_of_int,register_name(xreg,0));
+    else
+	printf("\tmovl %%esp,%s\n",register_name(xreg,0));
+    regv[xreg]=1;
+    /* downward direction copy */
+    emit_copy(creg,xreg,length,0,0,1);
+    /* we have value in creg, it may be changed */
+    if (save) {
+	if(creg==xreg) {
+	    creg = get_register();   /* creg is freed in emit_copy */
+	}
+	printf("\tpopl %s\n",register_name(xreg,0));
+	regv[xreg]=1;
+    } else
+	free_register(xreg);
+    return length/size_of_int;
+}
+
+void
+function(int e1)
+{
+    int e2,e3,e4,e5,nargs,t;
+    NMTBL *n;
+    int save,saved;
+    if (free_register_count()<1) {
+        for(save = 0;save==dreg||save==creg;save++);
+	printf("\tpushl %s\n",register_name(save,0));
+        saved = 1;
+    } else {
+        save = get_register();
+        saved = 0;
+    }
+    regv[save]=0;
+    e2 = cadr(e1);
+    nargs = 0;
+    for (e3 = caddr(e1); e3; e3 = cadr(e3)) {	
+	t=caddr(e3);
+	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
+	if(scalar(t)) {
+	    g_expr(e4);
+	    printf("\tpushl %s\n",register_name(creg,0));
+	} else if (car(t)==STRUCT||car(t)==UNION) {
+	    nargs += struct_push(e4,t);
+	    continue;
+	} else {
+	    error(TYERR);
+	}
+	++nargs;
+    }
+    if (car(e2) == FNAME) {	
+	n=(NMTBL *)cadr(e2);
+    } else {	
+        use_register(creg,REG_EAX,0);
+	g_expr(e2);
+    }
+
+    /* we don't have to save creg nor dreg */
+    regs[creg]=0; regs[dreg]=0;
+    regv[creg]= regv[dreg]= regv[save]= 0;
+    use_register(creg,REG_EAX,0);
+    use_register(dreg,REG_EDX,0);  /* will be destroyed */
+    use_register(save,REG_ECX,0);  /* will be destroyed */
+    regs[creg]=1; regs[dreg]=1;
+
+    if (car(e2) == FNAME) {	
+	printf("\tcall\t%s\n",n->nm);
+    } else {
+	printf("\tcall\t*%s\n",register_name(creg,0));
+    }
+    if (nargs) printf("\taddl $%d,%%esp\n",size_of_int*nargs);
+    if (saved) {
+	printf("\tpopl %s\n",register_name(save,0));
+    } else {
+        free_register(save);
+    }
+    regv[save]=0;
+    regv[creg]=1;
+}
+
+void
+code_frame_pointer(int e3) {
+    printf("\tmovl %s,%%ebp\n",register_name(e3,0));
+}
+
+
+void
+code_fix_frame_pointer(disp_offset) {
+    printf("\tlea %d(%%ebp),%%ebp\n",disp_offset);
+}
+
+
+void
+code_jmp(char *s) {
+    printf("\tjmp %s\n",s);
+}
+
+
+void
+code_indirect_jmp(int e2) {
+    printf("\tjmp *%s\n",register_name(e2,0));
+}
+
+void
+rindirect(int e1)   /* *(p +5 ) */
+{
+    char *op;
+    int e2,e3,byte;
+
+    op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl");
+    e3 = cadr(e2 = cadr(e1));
+    g_expr(e2);
+    printf("\t%s (%s),%s\n",op,register_name(creg,0),register_name(creg,0));
+}
+
+char *
+move(int byte)
+{
+    return byte?"movb":"movl";
+}
+
+void
+code_assign_gvar(int e2,int byte) {
+    if (byte) use_data_reg(creg,1);
+    printf("\t%s %s,%s\n",move(byte),register_name(creg,byte),(char *)caddr(e2));
+}
+
+void
+code_assign_lvar(int e2,int byte) {
+    if (byte) use_data_reg(creg,1);
+    printf("\t%s %s,%d(%%ebp)\n",move(byte),register_name(creg,byte),e2);
+}
+
+void
+code_assign_register(int e2,int byte) {
+    printf("\tmovl %s,%s\n",register_name(creg,0),register_name(e2,0));
+}
+
+void
+code_assign(int e2,int byte) {
+    printf("\t%s %s,(%s)\n",move(byte),register_name(creg,byte),register_name(e2,0));
+}
+
+
+void
+code_register_assop(int e2,int op,int byte) {
+    int reg;
+    int xreg = creg;
+    creg = reg = e2;
+    tosop(op,xreg);
+    creg = xreg;
+    printf("\tmovl %s,%s\n",register_name(reg,0),register_name(creg,0));
+}
+
+
+void
+code_assop(int op,int byte) {
+    char *xrn;
+    int xreg;
+    int edx = edx_setup();
+    xrn = register_name(xreg = emit_pop(0),0);       /* pop e3 value */
+    regv[xreg]=regs[xreg]=1;
+    printf("\tmovl %s,%s  # assop \n",register_name(creg,0),register_name(edx,0));
+    regv[edx]=1;
+    ld_indexx(byte,0,edx);
+    tosop(op,xreg);
+    printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",register_name(creg,byte),register_name(edx,0));
+    edx_cleanup();
+    emit_pop_free(xreg);
+}
+
+
+void
+tosop(int op,int oreg)
+{
+    int dx;
+    char *orn,*crn;
+
+    switch(op) {
+    case LSHIFT:
+    case ULSHIFT:
+	shift("sall",oreg);
+	return;
+    case RSHIFT:
+	shift("sarl",oreg);
+	return;
+    case URSHIFT:
+	shift("shrl",oreg);
+	return;
+    }
+    if(oreg==-1) {
+        printf("\tpopl %s\n",register_name(dreg,0));
+	oreg = dreg;
+	regv[dreg]=1;
+    }
+    regv[oreg]=1; regs[oreg]=1;
+    orn = register_name(oreg,0);
+    crn = register_name(creg,0);
+    switch(op) {
+    case ADD:
+	printf("\taddl %s,%s\n",orn,crn);
+	break;
+    case SUB:
+	printf("\tsubl %s,%s\n",orn,crn);
+	break;
+    case BAND: 
+	printf("\tandl %s,%s\n",orn,crn);
+	break;
+    case EOR: 
+	printf("\txorl %s,%s\n",orn,crn);
+	break;
+    case BOR:
+	printf("\torl %s,%s\n",orn,crn);
+	break;
+    case MUL:
+    case UMUL:
+	printf("\t%s %s,%s\n","imull",orn,crn);
+	break;
+    case DIV:
+    case UDIV:
+	use_register(creg,REG_EAX,1);
+	edx_setup();
+	orn = register_name(oreg,0);
+	if (op==DIV)
+	    printf("\tcltd\n\tdivl %s\n",orn);
+	else 
+	    printf("\txor %%edx,%%edx\n\tidivl %s\n",orn);
+	edx_cleanup();
+	break;
+    case MOD:
+    case UMOD:
+	use_register(creg,REG_EAX,1);
+	edx_setup();
+	orn = register_name(oreg,0);
+	if (op==DIV)
+	    printf("\tcltd\n\tdivl %s\n",orn);
+	else 
+	    printf("\txor %%edx,%%edx\n\tidivl %s\n",orn);
+        dx = virtual(REG_EDX);	
+	if (dx!=creg) {
+	    rname[dx]=rname[creg];
+	    rname[creg]=REG_EDX;
+	}
+	edx_cleanup();
+	break;
+    }
+    if (oreg!=dreg&&oreg>=0)
+	free_register(oreg);
+}
+
+static int edx_stack=0;
+
+int
+edx_setup()
+{
+    int edx_save;
+    /* make real EDX register empty */
+    if (free_register_count()<1) {
+        for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++);
+	printf("\tpushl %s\n",register_name(edx_save,0));
+        edx_stack = list3(edx_save,edx_stack,0);
+    } else {
+        edx_save = get_register();
+        edx_stack = list3(edx_save,edx_stack,1);
+    }
+    regv[edx_save]=0;
+    use_register(edx_save,REG_EDX,0);
+    return edx_save;
+}
+
+
+void
+edx_cleanup()
+{
+    if (caddr(edx_stack)==0) {
+	printf("\tpopl %s\n",register_name(car(edx_stack),0));
+    } else
+	free_register(car(edx_stack));
+    edx_stack = cadr(edx_stack);
+}
+
+void
+shift(char *op, int reg)
+{
+    if (reg>=0) {
+	use_register(reg,REG_ECX,1);
+    } else {
+	use_register(dreg,REG_ECX,0);
+	printf("\tpopl %%ecx\n");
+    }
+    printf("\t%s %%cl,%s\n",op,register_name(creg,0));
+}
+
+void
+ld_indexx(int byte, int n, int xreg)
+{	
+    char *op;
+
+    op = byte ? "movsbl" : "movl";
+    if (n) 
+	    printf("\t%s %d(%s),%s\n",op,n,register_name(xreg,0),register_name(creg,byte));
+    else
+	    printf("\t%s (%s),%s\n",op,register_name(xreg,0),register_name(creg,byte));
+}
+
+void
+cmpdimm(int e, int csreg)
+{
+    /* used in dosiwtch() */
+    use_register(creg,csreg,0);
+    printf("\tcmpl $%d,%s\n",e,register_name(creg,0));
+}
+
+void
+opening(char *filename)
+{
+    printf("\t.file \"%s\"\n",filename);
+    printf("\t.version\t\"01.01\"\n");
+    printf("gcc2_compiled.:\n");
+    printf(".text\n");
+    emit_init();
+}
+
+void
+closing(void)
+{
+    global_table();
+    printf("\t.ident \"Micro-C compiled\"\n");
+}
+
+void
+rexpr(int e1, int l1, char *s)
+{       
+    g_expr(list3(SUB,cadr(e1),caddr(e1)));
+    printf("\tj%s\t_%d\n",s,l1);
+}
+
+void
+jcond(int l, char cond)
+{       
+    printf("\tj%s\t_%d\n",cond?"ne":"e",l);
+}
+
+void
+jmp(int l)
+{       
+    control=0;
+    printf("\tjmp\t_%d\n",l);
+    /* align? */
+    /*
+      this is not allowed because of ? operator
+    regv[creg]=regv[dreg]=0; 
+    use_register(creg,REG_EAX,0);
+    use_register(dreg,REG_EBX,0);
+     */
+}
+
+void
+gen_comment(char *s)
+{
+     printf("## %s",s);
+}
+
+
+void
+code_enter(char *name)
+{
+    printf("\t.align 4\n");
+    if (stmode!=STATIC)
+	printf(".globl %s\n",name);
+    printf("\t.type\t%s,@function\n",name);
+    printf("%s:\n",name);
+}
+
+void
+code_enter1(int args)
+{
+    code_disp_label=fwdlabel();
+    printf("\tlea _%d(%%ebp),%%esp\n",code_disp_label);
+
+    printf("## args %d disp %d code_arg_offset=%d code_disp_offset=%d\n",args,disp,code_arg_offset,code_disp_offset); 
+}
+
+void
+code_leave(char *name)
+{
+    printf("\t.set _%d,%d\n",code_disp_label,disp+code_disp_offset);
+    printf("_%d:\n",labelno);
+    printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
+    local_table();
+    labelno++;
+    free_all_register();
+}
+
+void
+enter(char *name)
+{
+    printf("\t.align 2\n");
+    if (stmode!=STATIC)
+	printf(".globl %s\n",name);
+    printf("%s:\n",name);
+    printf("\t.type\t%s,@function\n",name);
+    printf("\tpushl %%ebp\n");
+    printf("\tmovl %%esp,%%ebp\n");
+    printf("\tpushl %%ebx\n");
+    printf("\tpushl %%esi\n");
+    printf("\tpushl %%edi\n");
+}
+
+void
+enter1()
+{
+    func_disp_label=fwdlabel();
+    printf("\tlea _%d(%%ebp),%%esp\n",func_disp_label); 
+    /* if(disp) printf("\tsubl $%d,%%esp\n",-disp); */
+}
+
+void
+leave(int control, char *name)
+{
+    if (control)
+	use_register(creg,REG_EAX,1);
+    if (retcont) {
+	if (control)
+	    jmp(retlabel);
+	fwddef(retcont);
+	use_register(creg,REG_EAX,0);
+	printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg,0));
+	/* printf("\tleave\n"); */
+    }
+    fwddef(retlabel);
+    /* use_register(creg,REG_EAX,0); too late */
+    /* if(disp) printf("\taddl $%d,%%esp\n",-disp);  */
+    printf("\tlea %d(%%ebp),%%esp\n",disp_offset);
+    printf("\tpopl %%edi\n");
+    printf("\tpopl %%esi\n");
+    printf("\tpopl %%ebx\n");
+    printf("\tleave\n");
+    printf("\tret\n");
+    printf("\t.set _%d,%d\n",func_disp_label,disp+disp_offset);
+    printf("_%d:\n",labelno);
+    printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
+    local_table();
+    labelno++;
+    free_all_register();
+}
+
+
+void
+code_set_fixed_creg(int mode) {
+    use_register(creg,REG_EAX,mode);
+}
+
+void
+gen_gdecl(char *n, int gpc)
+{
+    /*
+    if (stmode!=STATIC)
+	printf(".globl %s\n",n); 
+     */
+}
+
+void 
+align(int t)
+{
+    if (t!=CHAR) {
+	if (data_alignment & 1)
+	    printf("\t.align 2\n");
+	data_alignment = 0;
+    }
+}
+
+void
+emit_data(int e, int t, NMTBL *n)
+{
+    int l;
+    char *name;
+    name = n->nm; 
+    if(mode!=GDECL)  { 
+	error(-1); return;
+    }
+    if (n->dsp != -1) {
+	n->dsp = -1;   /* initiallized flag */
+	printf(".globl\t%s\n",name);
+	data_mode(name);
+	align(t);
+	printf("%s:\n",name); 
+    } else {
+	data_mode(0);
+    }
+    if(car(e)==CONST) {       
+	if (t==CHAR) {
+	    printf("\t.byte %d\n",cadr(e));
+	    if (data_alignment>0)
+		data_alignment++;
+	    gpc += 1;
+	} else {
+	    printf("\t.long %d\n",cadr(e));
+	    gpc += size_of_int;
+	}
+    } else if(t!=CHAR) {       
+	gpc += size_of_int;
+	if(car(e)==ADDRESS&&car(cadr(e))==GVAR) {
+	    printf("\t.long %s\n",(char *)caddr(cadr(e)));
+	} else if(car(e)==FNAME) {
+	    printf("\t.long %s\n",((NMTBL *)cadr(e))->nm);
+	} else if(car(e)==STRING) {       
+	    if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
+		l = fwdlabel();
+		printf("\t.long _%d\n",l);
+		printf(".section\t.rodata\n");
+		printf("_%d:\n",l);
+		output_mode = RODATA_EMIT_MODE;
+	    }
+	    ascii((char *)cadr(e));
+	} else error(TYERR);
+    }
+}
+
+void
+emit_data_closing(NMTBL *n)
+{
+    int lb;
+    if (mode==GDECL) {
+	data_mode(0);
+	lb=fwdlabel();
+	printf("_%d:\n",lb);
+	printf("\t.size\t%s,_%d-%s\n",n->nm,lb,n->nm);
+    }
+}
+
+void
+global_table(void)
+{
+    NMTBL *n;
+    int init;
+    init=0;
+    for(n=ntable;n < &ntable[GSYMS];n++) {
+	if (n->sc == GVAR && n->dsp != -1) {
+	    /* n->dsp = -1 means initialized global */
+	    if (init==0) {
+		data_mode(0);
+		init=1;
+	    }
+	    printf(".comm %s,%d\n",n->nm,size(n->ty));
+	}
+    }
+}
+
+void
+local_table(void)
+{
+    NMTBL *n;
+    int init;
+    init=0;
+    /* static local variables */
+    for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) {
+	if (n->sc == GVAR) {
+	    if (init==0) {
+		data_mode(0);
+		init=1;
+	    }
+	    printf(".lcomm %s,%d\n",n->nm,size(n->ty));
+	}
+    }
+}
+
+void
+text_mode(void)
+{
+    if (output_mode!=TEXT_EMIT_MODE) {
+	printf(".text\n");
+	printf("\t.align 2\n");
+	output_mode = TEXT_EMIT_MODE;
+    }
+}
+
+void
+data_mode(char *name)
+{
+    if (output_mode!=DATA_EMIT_MODE) {
+	printf(".data\n");
+	output_mode = DATA_EMIT_MODE;
+    }
+    if (name)
+	printf("\t.type\t%s,@object\n",name);
+}
+
+int
+lvar(int l)
+{
+    if (fnptr->sc==CODE) {
+	return l+code_disp_offset;
+    } else if (l<0) {
+	return l+disp_offset;
+    } else {
+	return l+arg_offset;
+    }
+}
+
+/* end */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mc-code.h	Thu Feb 20 03:29:15 2003 +0900
@@ -0,0 +1,67 @@
+/* function required by mc-codegen.c 
+     mc-code-*.c have to provied these
+ */
+
+extern char *register_name(int i,int byte);
+extern void gexpr_code_init(void);
+extern int register_var(int r);
+extern int get_register_var(void);
+extern void use_data_reg(int virt, int move);
+extern void emit_push(void);
+extern void emit_push_x(int xreg);
+extern int emit_pop(int type);
+extern void gexpr_code_init();
+extern void code_gvar(int e1);
+extern void code_rgvar(int e1);
+extern void code_crgvar(int e1);
+extern void code_lvar(int e2);
+extern void code_register(int e2);
+extern void code_rlvar(int e2);
+extern void code_crlvar(int e2);
+extern void code_fname(char *e2);
+extern void code_const(int e2);
+extern void code_neg();
+extern void code_not();
+extern void code_lnot();
+extern void code_preinc(int e1,int e2);
+extern void code_postinc(int e1,int e2);
+extern void code_cpostinc(int e1,int e2);
+extern void code_cpreinc(int e1,int e2);
+extern void code_cpostdec(int e1,int e2);
+extern void code_cpredec(int e1,int e2);
+extern void code_return();
+extern void code_environment();
+extern void code_bool(int e1);
+extern char *code_gt(int cond);
+extern char *code_ugt(int cond);
+extern char *code_ge(int cond);
+extern char *code_uge(int cond);
+extern char *code_eq(int cond);
+extern void code_cmp_crgvar(int e1);
+extern void code_cmp_crlvar(int e1);
+extern void code_cmp_rgvar(int e1);
+extern void code_cmp_rlvar(int e1);
+extern void code_cmp_register(int e2);
+extern void string(int e1);
+extern void emit_copy(int from,int  to,int length,int offset,int value,int det);
+extern void function(int e1);
+extern void code_frame_pointer(int e3);
+extern void code_fix_frame_pointer(int disp_offset);
+extern void code_jmp(char *s);
+extern void code_indirect_jmp(int e2);
+extern void rindirect(int e1);
+extern void code_assign_gvar(int e2,int byte);
+extern void code_assign_lvar(int e2,int byte);
+extern void code_assign_register(int e2,int byte);
+extern void code_assign(int e2,int byte);
+extern void code_register_assop(int e2,int op,int byte);
+extern void code_assop(int op,int byte);
+extern void tosop(int op,int oreg);
+extern void opening(char *filename);
+extern void rexpr(int e1, int l1, char *s);
+extern void jcond(int l, char cond);
+extern void jmp(int l);
+extern void code_set_fixed_creg(int mode);
+extern void text_mode(void);
+extern int lvar(int l);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mc-codegen.c	Thu Feb 20 03:29:15 2003 +0900
@@ -0,0 +1,909 @@
+/* Micro-C Generic Code Generatation Part */
+/* $Id$ */
+
+#define EXTERN extern
+#include "mc.h"
+#include "mc-codegen.h"
+#include "mc-code.h"
+
+int  creg;     /* current register */
+int  dreg;     /* temporary register */
+int  reg_sp;   /* REGister Stack-Pointer */
+
+/*
+    creg   currrent virtual register
+    dreg   spare virtual register
+
+    rname[creg]   currrent real register
+    rname[dreg]   spare real register
+
+    regs[]        virtual register usage
+    regv[]        value in virtual register flag
+
+    reg_name[rname[creg]]
+ */
+
+void remove0(int *parent,int e) ;
+void remove0_all(int *parent,int e) ;
+int is_same_type(int e1,int e2);
+void jump(int e1, int env);
+void machinop(int e1);
+void sassign(int e1);
+void assign(int e1);
+void assop(int e1);
+
+int 
+get_register(void)
+{    /* 使われていないレジスタを調べる */
+    int i;
+    for(i=0;i<MAX_REGISTER;i++) {
+	if (! regs[i]) {    /* 使われていないなら */
+	    regs[i]=1;      /* そのレジスタを使うことを宣言し */
+	    return i;       /* その場所を表す番号を返す */
+	}
+    }
+    return -1;    /* 空いている場所がないなら、それを表す -1 を返す */
+}
+
+void 
+free_register(int i) {    /* いらなくなったレジスタを開放 */
+    regv[i]=regs[i]=0;
+}
+
+int
+register_full(void)
+{
+    int i;
+    for(i=0;i<MAX_REGISTER;i++) {
+	if (! regs[i]) { 
+	    return 0;  
+	}
+    }
+    return 1;    
+}
+
+int
+free_register_count(void)
+{
+    int i,count;
+    count = 0;
+    for(i=0;i<MAX_REGISTER;i++) {
+	if (! regs[i] && ! regv[i]) count++;
+    }
+    return count;    
+}
+
+void
+free_all_register(void)
+{
+    int i;
+    for(i=0;i<MAX_REGISTER;i++) {
+	regs[i]=regv[i]=0;
+    }
+    creg = get_register();
+    dreg = get_register();
+    return;
+}
+
+void
+use_register_var(int i) {
+    regv[i]=1;
+}
+
+int creg_regvar = -1;
+static int creg_regvar_back;
+static int creg_back;
+
+void
+creg_destroy() {
+    creg_back = creg; creg_regvar_back = creg_regvar;
+    if (creg_regvar>=0)
+	creg = creg_regvar;
+    creg_regvar=-1;
+}
+
+void
+creg_un_destroy() {
+    creg = creg_back; creg_regvar = creg_regvar_back;
+}
+
+void
+register_usage(char *s)
+{
+    int i;
+    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++) {
+	printf("%d",regs[i]);
+    }
+    printf(":");
+    for(i=0;i<MAX_REGISTER;i++) {
+	printf("%d",regv[i]);
+    }
+#if 0
+    printf(" regs_stack",register_name(creg,0),register_name(dreg,0));
+    for(i=reg_sp;i>=0;i--) {
+	if(reg_stack[i]>=0)
+	    printf(" %s",register_name(reg_stack[i],0));
+    }
+#endif
+    printf("\n");
+}
+
+void 
+gexpr_init(void)
+{
+    while(reg_sp > 0) {
+	free_register(reg_stack[--reg_sp]);
+    }
+    text_mode();
+    gexpr_code_init();
+    register_usage("gexpr_init");
+}
+
+
+void 
+emit_init(void)
+{
+    int i;
+    for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;}
+    free_all_register();
+    reg_sp = 0;
+    text_mode();
+}
+
+int
+virtual(int real)
+{
+    int real_v,i;
+    real_v = -1;
+    for(i=0;i<MAX_REGISTER;i++) {
+	if (rname[i]==real) {
+	    real_v=i;
+	    break;
+	}
+    }
+    return real_v;
+}
+
+int 
+pop_register(void)
+{     /* レジスタから値を取り出す */
+    return reg_stack[--reg_sp];
+}
+
+int
+stack_used(void) {
+    return reg_stack[--reg_sp]<0;
+}
+
+void
+emit_pop_free(int xreg)
+{
+    if (xreg==dreg) {
+	regv[dreg]=0;
+    } else if (xreg!=-1) {
+	free_register(xreg);
+    }
+}
+
+void
+gexpr(int e1)
+{
+    gexpr_init();
+#if 0
+    if(lineno==2862) {
+        g_expr(e1); /*break here*/
+        return;
+    } 
+#endif
+    g_expr(e1);
+}
+
+int
+csvalue()
+{
+    return rname[creg]; /* for switch value */
+}
+
+void
+g_expr(int e1)
+{
+    int e2,e3/*,e4*/;
+    NMTBL *n;
+
+    if (chk) return;
+    e2 = cadr(e1);
+    switch (car(e1)){
+    case GVAR:   
+	code_gvar(e1);
+	regv[creg]=1;
+	return;
+    case RGVAR:
+	code_rgvar(e1);
+	regv[creg]=1;
+	return;
+    case CRGVAR:
+	code_crgvar(e1);
+	regv[creg]=1;
+	return;
+    case LVAR:
+	code_lvar(lvar(e2));
+	regv[creg]=1;
+	return;
+    case REGISTER:
+	/* this is of course redundant... */
+	/* we can use rname for this? */
+	/* or why not creg=e2? */
+	code_register(e2);
+	regv[creg]=1;
+	return;
+    case RLVAR:
+	code_rlvar(lvar(e2));
+	regv[creg]=1;
+	return;
+    case CRLVAR:
+	code_crlvar(lvar(e2));
+	regv[creg]=1;
+	return;
+    case FNAME:
+	code_fname(((NMTBL *)(e2))->nm);
+	regv[creg]=1;
+	return;
+    case CONST:  /* 代入する値が0でも特別な処理はしない */
+	code_const(e2);
+	regv[creg]=1;
+	return;
+    case STRING:
+	string(e1);
+	regv[creg]=1;
+	return;
+    case FUNCTION:
+	function(e1);
+	regv[creg]=1;
+	return;
+    case CODE:
+	jump(e2,caddr(e1));
+	return;
+    case INDIRECT:
+	g_expr(e2);
+	return;
+    case RINDIRECT: case CRINDIRECT:
+	rindirect(e1);
+	return;
+    case ADDRESS:
+	g_expr(e2);
+	return;
+    case MINUS:  /* レジスタに対し、neglを実行すれば実現可能 */
+	g_expr(e2);
+	code_neg();
+	return;
+    case BNOT:   /* ~ */
+	g_expr(e2);
+	code_not();
+	return;
+    case LNOT:   /* !  */
+	g_expr(e2);
+	code_lnot();
+	return;
+    case PREINC:
+	code_preinc(e1,e2);
+	return;
+    case POSTINC:
+	code_postinc(e1,e2);
+	return;
+    case CPOSTINC:
+	/*   char *p; *p++ */
+	code_cpostinc(e1,e2);
+	return;
+    case CPREINC:
+	code_cpreinc(e1,e2);
+	return;
+    case CPOSTDEC:
+	code_cpostdec(e1,e2);
+	return;
+    case CPREDEC:
+	code_cpredec(e1,e2);
+	return;
+    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:
+	machinop(e1);
+	return;
+    case COND:
+	e2=fwdlabel();
+	b_expr(cadr(e1),0,e2,0);
+	code_set_fixed_creg(0);
+	g_expr(caddr(e1));
+	/* e4 = rname[creg]; this is a bad idea */
+	code_set_fixed_creg(1);
+	jmp(e3=fwdlabel());
+	fwddef(e2);
+	code_set_fixed_creg(0);
+	g_expr(cadddr(e1));
+	code_set_fixed_creg(1);
+	fwddef(e3);
+	return;
+    case SASS: 
+	sassign(e1);
+	return;
+    case ASS: case CASS:
+	assign(e1);
+	return;
+    case ASSOP: case CASSOP:
+	assop(e1);
+	return;
+    case RSTRUCT:
+	g_expr(e2);
+	return;
+    case COMMA:
+	g_expr(e2);
+	g_expr(caddr(e1));
+	return;
+    case RETURN:
+	n = (NMTBL *)e2;
+	if (retcont==0)
+	    retcont=fwdlabel();
+	code_return(creg);
+	regv[creg]=1;
+	return;
+    case ENVIRONMENT:
+	code_environment(creg);
+	regv[creg]=1;
+	return;
+    default:
+	code_bool(e1);
+	regv[creg]=1;
+    }
+}
+
+void
+bexpr(int e1, char cond, int l1)
+{
+    gexpr_init();
+    b_expr(e1,cond,l1,0);
+}
+
+void
+b_expr(int e1, char cond, int l1,int err)
+{
+    int e2,l2;
+    if (chk) return;
+    e2=cadr(e1);
+    switch(car(e1)) {
+    case LNOT:
+	b_expr(e2,!cond,l1,0);
+	return;
+    case GT:
+	rexpr(e1,l1,code_gt(cond));
+	return;
+    case UGT:
+	rexpr(e1,l1,code_ugt(cond));
+	return;
+    case GE:
+	rexpr(e1,l1,code_ge(cond));
+	return;
+    case UGE:
+	rexpr(e1,l1,code_uge(cond));
+	return;
+    case LT:
+	rexpr(e1,l1,code_ge(!cond));
+	return;
+    case ULT:
+	rexpr(e1,l1,code_uge(!cond));
+	return;
+    case LE:
+	rexpr(e1,l1,code_gt(!cond));
+	return;
+    case ULE:
+	rexpr(e1,l1,code_ugt(!cond));
+	return;
+    case EQ:
+	rexpr(e1,l1,code_eq(cond));
+	return;
+    case NEQ:
+	rexpr(e1,l1,code_eq(!cond));
+	return;
+    case LAND:
+	b_expr(e2,0,cond?(l2=fwdlabel()):l1,0);
+	b_expr(caddr(e1),cond,l1,0);
+	if(cond) fwddef(l2);
+	return;
+    case LOR:
+	b_expr(e2,1,cond?l1:(l2=fwdlabel()),0);
+	b_expr(caddr(e1),cond,l1,0);
+	if(!cond) fwddef(l2);
+	return;
+    case CRGVAR:
+	code_cmp_crgvar(e1);
+	jcond(l1,cond);
+	return;
+    case CRLVAR:
+	code_cmp_crlvar(lvar(e2));
+	jcond(l1,cond);
+	return;
+    case RGVAR:
+	code_cmp_rgvar(e1);
+	jcond(l1,cond);
+	return;
+    case RLVAR:
+	code_cmp_rlvar(lvar(e2));
+	jcond(l1,cond);
+	return;
+    case REGISTER:
+	code_cmp_register(e2);
+	jcond(l1,cond);
+	return;
+    case CONST:
+	if((cond&&e2)||(!cond&&!e2)) jmp(l1);
+	return;
+    default:
+	if(err) {
+	    error(-1); return; /* recursice g_expr/b_expr */
+	}
+	g_expr(e1);
+	code_cmp_register(creg);
+	jcond(l1,cond);
+	return;
+    }
+}
+
+
+/* goto arguments list                                      */
+/* target         list4(list2(tag,disp),cdr,ty,source_expr) */
+/*     source         expr=listn(tag,...)                   */
+/*     source (after) list2(tag,disp)                       */
+/* source list    list3(e,cdr,sz)                           */
+
+#define DEBUG_PARALLEL_ASSIGN 1
+
+int
+overrap(int t,int sz,int source)
+{
+    int s,s0,s1;
+    int t0=cadr(t);
+    int t1=t0+sz;
+    for(;source;source=cadr(source)) {
+	s=car(source); s0=cadr(s); 
+	if(car(s)==REGISTER && car(t)==REGISTER) {
+	    if(s0==t0) return s;
+	} else if (is_same_type(s,t)) {
+	    s1=s0+caddr(source);
+#if DEBUG_PARALLEL_ASSIGN>1 
+printf("# ovedrrap source %d t0 %d t1 %d\n",car(car(t)),t0,t1);
+printf("# ovedrrap target %d s0 %d s1 %d\n",car(car(source)),s0,s1);
+printf("# ovedrrap   equal = %d\n",((t0<=s0&&s0<t1)||(t0<s1&&s1<=t1)));
+#endif
+	    if((t0<=s0&&s0<t1)||(t0<s1&&s1<=t1)) return s;
+	}
+    }
+    return 0;
+}
+
+void
+remove_target(int *target,int t,int *use)
+{
+    int use0=*use;
+    while(use0) {
+	if (car(use0)==t) {
+	    free_register(caddr(use0));
+	    break;
+	}
+	use0 = cadr(use0);
+    }
+    remove0(target,t);
+}
+
+void
+save_target(int t,int s,int *target,int *use,int sz,int ty)
+{
+    int e1;
+    /*新しいレジスタ(or スタック)を取得する*/
+    if (sz==size_of_int && (e1=get_register())!=-1) {
+	*use=list3(t,*use,e1);
+	e1=list2(REGISTER,e1);
+	g_expr(assign_expr0(e1,s,ty,ty));
+	*target = append4(*target,t,ty,e1);
+    } else {
+	disp-=sz;
+	g_expr(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty));
+	*target = append4(*target,t,ty,e1);
+    }
+}
+
+int
+circular_dependency(int t,int s,int *target,int *source)
+{
+    int target0=*target;
+    int t1,sz,ty,s1;
+    while(target0) {
+	if (cadddr(target0)==s) {
+	    t1=car(target0); 
+	    s=cadddr(target0);
+	    sz=size(ty=caddr(target0)); 
+	    if(t==t1) {
+#if DEBUG_PARALLEL_ASSIGN
+printf("# circular dependency %d ty %d+%d sz %d\n",car(t1),ty,cadr(t1),sz);
+#endif
+		return 1;
+	    }
+	    if ((s1=overrap(t1,sz,*source))) {
+		/* another overrap start over */
+		return circular_dependency(t,s1,target,source);
+	    }
+	}
+	target0=cadr(target0);
+    }
+    return 0;
+}
+
+void
+parallel_assign(int *target,int *source,int *processing,int *use)
+{
+    int t,s,sz,ty,target0,s1;
+    while(*target) {
+	target0=*target;
+	while(target0) {
+	    t=car(target0); s=cadddr(target0);
+	    sz=size(ty=caddr(target0)); 
+	    if(car(t)==car(s) && cadr(t)==cadr(s)) {
+		/*書き込み先が自分自身*/
+#if DEBUG_PARALLEL_ASSIGN
+printf("# remove same %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz);
+#endif
+		remove_target(target,t,use);
+		/* 破壊されては困るので、source listからは除かない */
+	    } else if (!(s1=overrap(t,sz,*source))) {
+		/* 重なってないので安心して書き込める */
+#if DEBUG_PARALLEL_ASSIGN
+printf("# normal assign %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz);
+#endif
+		g_expr(assign_expr0(t,s,ty,ty));
+		remove_target(target,t,use); remove0(source,s);
+	    } else {
+		if(circular_dependency(t,s1,target,source)) {
+#if DEBUG_PARALLEL_ASSIGN
+    printf("# saving %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz);
+#endif
+		    remove_target(target,t,use); remove0(source,s);
+		    save_target(t,s,target,use,sz,ty);
+		}
+	    }
+	    target0=cadr(target0);
+	}
+    }
+}
+
+void 
+remove0(int *parent,int e) 
+{
+    int list;
+    while ((list=*parent)) {
+	if (car(list)==e) {
+	    *parent= cadr(list); return;
+	} else {
+	     parent=&cadr(list);
+	}
+    }
+}
+
+void 
+remove0_all(int *parent,int e) 
+{
+    int list;
+    while ((list=*parent)) {
+	if (car(list)==e) {
+	    *parent= cadr(list);
+	} else {
+	     parent=&cadr(list);
+	}
+    }
+}
+
+int
+is_simple(int e1) 
+{
+    return (
+	e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER ||
+	e1==GVAR || e1==RGVAR || e1==RLVAR || e1==CRLVAR || e1==CRGVAR
+    );
+}
+
+int
+is_same_type(int e1,int e2)
+{
+    int ce1=car(e1);
+    int ce2=car(e2);
+    return (   
+         (ce1==LVAR && (ce2==RLVAR||ce2==CRLVAR))
+      || (ce2==LVAR && (ce1==RLVAR||ce1==CRLVAR))
+      || (ce1==GVAR && (ce2==RGVAR||ce2==CRGVAR))
+      || (ce2==GVAR && (ce1==RGVAR||ce1==CRGVAR))
+    );
+}
+
+int
+is_memory(int e1)
+{
+    int ce1=car(e1);
+    return (   
+         ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR ||
+         ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR ||
+         ce1==REGISTER
+    );
+}
+
+void
+jump(int e1, int env)
+{
+    int e2,e3,e4,sz,arg_size,ty,max_regs,regs;
+    int t0,s0;
+    NMTBL *code0;
+    int target = 0;
+    int source = 0;
+    int processing = 0;
+    int use = 0;
+
+    /* まず、サイズを計算しながら、決まった形に落す。 */
+
+    arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR-1;
+    for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
+	e2 = car(e3); sz = size(ty=caddr(e3)); 
+	if (regs <= max_regs&&scalar(ty)) {
+	    target=list4(list2(REGISTER,register_var(regs++)), target,ty,e2);
+	} else {
+	    target=list4(list2(LVAR,0), target,ty,e2);
+	    arg_size += sz;
+	}
+#if DEBUG_PARALLEL_ASSIGN
+printf("# target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz);
+#endif
+    }
+
+    /* disp を飛び先似合わせて修正 */
+    if (fnptr->sc==CODE) {
+	if (-arg_size<disp) disp = -arg_size;
+    } else {
+	if (disp_offset-arg_size<disp) disp = disp_offset-arg_size;
+    }
+
+    /*  複雑な式を前もって計算しておく     */
+    /*  必要なら局所変数を用いる。         */
+    /*  局所変数へのオフセットを覚えておく */
+
+    for (e2 = target; e2; e2 = cadr(e2)) {	
+	t0=car(e2); s0=cadddr(e2);
+	sz=size(ty=caddr(e2));
+	if(car(t0)==LVAR) {
+	    /* ここで、書込先アドレスを決める */
+	    cadr(t0)=-arg_size;
+	    arg_size-=sz;
+	}
+	if (!is_simple(car(s0))) {
+	    disp-=sz;
+	    g_expr(assign_expr0((e4=list2(LVAR,disp)),s0,ty,ty));
+	    cadddr(e2)=e4;
+	    s0=e4;
+        } else if (is_same_type(t0,s0)) {
+            if(cadr(t0)==cadr(s0)) {
+#if DEBUG_PARALLEL_ASSIGN
+printf("# remove same memory %d ty %d+%d sz %d\n",car(t0),ty,cadr(t0),sz);
+#endif
+                /* we should check size also (but currently useless */
+                remove0(&target,t0);
+                /* still we have source to avoid overwrite */
+	    }
+        }
+	if(is_memory(s0)) {
+	    source=list3(s0,source,sz);
+#if DEBUG_PARALLEL_ASSIGN
+printf("# source %d ty %d+%d sz %d\n",car(car(source)),ty,cadr(car(source)),sz);
+#endif
+	}
+    }
+
+    /* compute jump address */
+    e2 = cadr(e1);
+    if (car(e2) == FNAME) {	
+	code0=(NMTBL *)cadr(e2);
+	if (code0->sc!=CODE) {
+	    error(TYERR); return;
+	}
+    } else {	/* indirect */
+	g_expr(e2);
+	emit_push();
+    }
+    if (env) {
+	g_expr(env);
+	emit_push();
+    }
+
+    /* 並列代入を実行 */
+
+    parallel_assign(&target,&source,&processing,&use);
+    while (use) {
+	free_register(caddr(use)); use=cadr(use);
+    }
+    if(target) error(-1);
+
+    if (env) {
+	/* change the frame pointer */
+	e3 = emit_pop(0);
+	code_frame_pointer(e3);
+	emit_pop_free(e3);
+    } else if (fnptr->sc==FUNCTION) {
+	code_fix_frame_pointer(disp_offset);
+    } 
+
+    if (car(e2) == FNAME) {	
+	code_jmp(code0->nm);
+    } else {
+	e2 = emit_pop(0);
+	code_indirect_jmp(e2);
+	emit_pop_free(e2);
+    }
+}
+
+void
+machinop(int e1)
+{
+    int e2,e3,op;
+
+    e2 = cadr(e1);
+    op = car(e1);
+    e3 = caddr(e1);
+    g_expr(e3);
+    emit_push();
+    g_expr(e2);
+    tosop(car(e1),(e2=pop_register()));
+    emit_pop_free(e2);
+    regv[creg]=1;
+    return;
+}
+
+
+void
+sassign(int e1)
+{
+    int e2,e3,e4,sz,xreg,det;
+
+    /* structure assignment */
+    e2 = cadr(e1);  /* pointer variable to the struct */
+    e3 = cadr(e2);  /* offset of the variable (distination) */
+    e4 = caddr(e1); /* right value (source) */
+    sz = cadddr(e1);  /* size of struct or union */
+    g_expr(e4);
+    emit_push();
+    g_expr(e2);
+    xreg = emit_pop(0);
+    /* 一般的にはコピーのオーバラップの状況は実行時にしかわからない */
+    /* しかし、わかる場合もある */
+    if (car(e4)==RSTRUCT) e4=cadr(e4);
+    if (is_same_type(e2,e4)) {
+	if(cadr(e2)<cadr(e4)) sz=-sz;
+	det=1;
+    } else {
+	det = 0;
+    }
+    emit_copy(xreg,creg,sz,0,1,det);
+    emit_pop_free(xreg);
+    return;
+}
+
+void
+assign(int e1)
+{
+    int e2,e3,e4,byte;
+
+    byte=(car(e1) == CASS);
+    /*    e2=e4 */
+    e2 = cadr(e1);
+    e3 = cadr(e2);
+    e4 = caddr(e1);
+    switch(car(e2)) {
+    case GVAR:      /*   i=3 */
+            g_expr(e4);
+	    code_assign_gvar(e2,byte);
+            return;
+    case LVAR:
+            g_expr(e4);
+	    code_assign_lvar(lvar(cadr(e2)),byte);
+            return;
+    case REGISTER:
+            g_expr(e4);
+	    if (creg!=cadr(e2))
+		code_assign_register(cadr(e2),byte);
+            return;
+    }
+    g_expr(e2);
+    emit_push();
+    use_data_reg(creg,0);
+    g_expr(e4);
+    if (byte) use_data_reg(creg,1);
+    e2 = emit_pop(0);
+    code_assign(e2,byte);
+    emit_pop_free(e2);
+    regv[creg]=1;
+    return;
+}
+
+void
+assop(int e1)
+{
+    int e2,e3,byte,op;
+
+    /*   e2 op= e3 */
+    byte = (car(e1) == CASSOP);
+    e2 = cadr(e1);
+    if (car(e2)==INDIRECT) e2=cadr(e2);
+    e3 = caddr(e1);
+    op = cadddr(e1);
+
+    g_expr(e3);
+    if (car(e2)==REGISTER) {
+	code_register_assop(cadr(e2),op,byte);
+	regv[creg]=1;
+	return;
+    }
+    emit_push();
+    g_expr(e2);
+    code_assop(op,byte);
+    regv[creg]=1;
+    return;
+}
+
+
+int
+fwdlabel(void)
+{       
+    return labelno++;
+}
+
+void
+fwddef(int l)
+{       
+    control=1;
+    printf("_%d:\n",l);
+}
+
+int
+backdef(void)
+{       
+    control=1;
+    printf("_%d:\n",labelno);
+    return labelno++;
+}
+
+void
+def_label(int cslabel, int dlabel)
+{
+    int fl;
+
+    fl = 0;
+    if (control) {
+	jmp(fl=fwdlabel());
+    }
+    fwddef(cslabel);
+    if (dlabel)
+	jmp(dlabel);
+    if (fl) {
+	fwddef(fl);
+    }
+}
+
+void
+gen_source(char *s)
+{
+     printf("%s",s);
+}
+
+void
+ret(void)
+{       
+    code_set_fixed_creg(1);
+    jmp(retlabel); 
+}
+
+/* end */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mc-codegen.h	Thu Feb 20 03:29:15 2003 +0900
@@ -0,0 +1,63 @@
+
+extern int  creg;     /* current register */
+extern int  dreg;     /* temporary register */
+extern int  reg_sp;   /* REGister Stack-Pointer */
+
+extern int rname[];
+extern int regs[];       /* 使われているレジスタを示すフラグ */
+extern int reg_stack[];  /* 実際のレジスタの領域 */
+extern int regv[];       /* 値が入っているかどうか */
+extern int MAX_REGISTER;
+
+extern int creg_regvar;
+
+/* function provided by mc-codegen.c */
+
+
+extern void def_label(int cslabel, int dlabel);
+extern int backdef(void);
+extern int csvalue();
+extern int free_register_count(void);
+extern int fwdlabel(void);
+extern int get_register(void);
+extern int pop_register(void);
+extern int register_full(void);
+extern int virtual(int real);
+extern void use_register_var(int i) ;
+extern void b_expr(int e1, char cond, int l1,int err);
+extern void bexpr(int e1, char cond, int l1);
+extern void emit_init(void);
+extern void emit_pop_free(int xreg);
+extern void free_all_register(void);
+extern void free_register(int i);
+extern void fwddef(int l);
+
+extern int csvalue();
+extern void closing(void);
+extern void cmpdimm(int e, int csreg);
+extern void code_enter(char *name) ;
+extern void code_enter1(int args);
+extern void code_init(void);
+extern void code_leave(char *name) ;
+extern void emit_data(int e, int t, NMTBL *n);
+extern void emit_data_closing(NMTBL *n);
+extern void emit_init(void);
+extern void enter(char *name);
+extern void enter1();
+extern void g_expr(int e1);
+extern void gen_comment(char *s);
+extern void gen_gdecl(char *n, int gpc);
+extern void gen_source(char *s);
+extern void gexpr(int e1);
+extern void gexpr_init(void);
+extern void jcond(int l, char cond);
+extern void jmp(int l);
+extern void jmp_eq_label(int l);
+extern void jmp_label(int l);
+extern void leave(int control, char *name);
+extern void opening(char *filename);
+extern void ret(void);
+extern void use_register_var(int);
+
+
+/* end */
--- a/mc-nop-386.c	Wed Feb 19 21:22:49 2003 +0900
+++ b/mc-nop-386.c	Thu Feb 20 03:29:15 2003 +0900
@@ -62,7 +62,7 @@
 static void emit_copy(int from,int to,int length,int offset,int value,int det);
 static int is_same_type(int s,int t);
 
-extern int error(int n);
+extern void error(int n);
 extern int fwdlabel(void);
 extern void fwddef(int l);
 extern int backdef(void);
@@ -491,7 +491,7 @@
 int
 csvalue()
 {
-    return rname[creg]; /* for siwtch value */
+    return rname[creg]; /* for switch value */
 }
 
 void
@@ -954,10 +954,8 @@
 	printf("\tpushl 4(%s)\n",register_name(creg,0));
 	printf("\tpushl (%s)\n",register_name(creg,0)); return 2;
     }
-    /* I think, after g_expr, at least two registers are free */
     printf("\tsubl $%d,%%esp\n",length);
     if (register_full()) {
-	/* this is wrong assumption */
 	save = 1;
 	for(lreg=0;lreg==creg||lreg==dreg;lreg++);
 	printf("\tpushl %s\n",register_name(lreg,0));
@@ -1336,13 +1334,6 @@
 	printf("\tlea %d(%%ebp),%%ebp\n",disp_offset);
     } 
 
-	/* shrink stack if necessary */
-    /*
-    if (!env && -arg_size<disp) {
-	printf("\tleal %d(%%ebp),%%esp\n",-arg_size);
-    }  Why we need this?
-     */
-
     if (car(e2) == FNAME) {	
 	printf("\tjmp %s\n",code0->nm);
     } else {
@@ -1625,26 +1616,6 @@
 	    printf("\t%s (%s),%s\n",op,register_name(xreg,0),register_name(creg,byte));
 }
 
-/*
-void
-st_indexx(int byte, int n, int xreg)
-{	
-    char *op;
-
-    op = byte ? "movb" : "movl";
-    if (n) 
-	    printf("\t%s %s,%d(%s)\n",op,register_name(creg,byte),n,register_name(xreg,0));
-    else
-	    printf("\t%s %s,(%s)\n",op,register_name(creg,byte),register_name(xreg,0));
-}
-
-void
-indexy(char *op, char *gvar)
-{
-    printf("\t%s %s,%s\n",op,register_name(creg,0),gvar);
-}
- */
-
 void
 cmpdimm(int e, int csreg)
 {
--- a/mc-parse.c	Wed Feb 19 21:22:49 2003 +0900
+++ b/mc-parse.c	Thu Feb 20 03:29:15 2003 +0900
@@ -3,36 +3,30 @@
 
 #define EXTERN /**/
 #include "mc.h"
+#include "mc-codegen.h"
 
-void ntable_consistency();
-static void adecl(NMTBL *n);
-static int decl_data(int t, NMTBL *n,int offset);
+static NMTBL *decl0(void),*decl1(void),*lsearch(char *name),*gsearch(void);
+static NMTBL *def(NMTBL *n);
+static NMTBL *free_nptr();
+static NMTBL *msearch(char *name);
+static NMTBL *msearch0(char *name);
+static char * mappend(int lists);
 static int alpha(char c);
+static int append3(int p,int a1,int a2);
 static int binop(int op, int e1, int e2, int t1, int t2);
-static void compatible(int t1, int t2);
-static void decl(void);
-static NMTBL *def(NMTBL *n);
+static int cexpr(int e);
+static int decl_data(int t, NMTBL *n,int offset);
 static int digit(char c);
-static void docase(void);
-static void docomp(void);
-static void dodefault(void);
-static void dodo(void);
-static void dofor(void);
-static void dogoto(void);
-static void doif(void);
-static void dolabel(void);
-static void doswitch(void);
-static void doreturn(void);
-static void dowhile(void);
-static void errmsg(void);
-static void macro_processing();
-static void macro_define();
-static void macro_define0();
-static void copy(NMTBL *nptr, char *s);
-void error(int n);
 static int expr(void);
 static int expr0(void);
 static int expr1(void);
+static int expr10(void);
+static int expr11(void);
+static int expr12(void);
+static int expr13(void);
+static int expr14(void);
+static int expr15(int e1);
+static int expr16(int e1);
 static int expr2(void);
 static int expr3(void);
 static int expr4(void);
@@ -41,101 +35,61 @@
 static int expr7(void);
 static int expr8(void);
 static int expr9(void);
-static int expr10(void);
-static int expr11(void);
-static int expr12(void);
-static int expr13(void);
-static int expr14(void);
-static int expr15(int e1);
-static int expr16(int e1);
-static void fcheck(NMTBL *n);
-static void fdecl(NMTBL *n);
 static int getch(void);
 static int getfree(int n);
-static void getline(void);
-static void getstring(void);
 static int getsym(void);
 static int indop(int e);
-static void init(void);
-extern int integral(int t);
-static void lcheck(int e);
-extern int glist2(int e1,int e2);
-extern int list2(int e1, int e2);
-extern int list3(int e1, int e2, int e3);
-extern int list4(int e1, int e2, int e3, int e4);
-extern int rplacad(int e, int n);
-extern int rplacadd(int e, int n);
-static void reserve(char *s, int d);
+static int macro_args(char **pcheapp,char* max,char **pchptr);
+static int macro_eval(int macrop,char *body,int history);
+static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history);
 static int macroeq(char *s);
 static int ndecl0(void);
 static int ndecl1(void);
 static int neqname(char *p,char *name);
-static void newfile(void);
 static int postequ(int s1, int s2);
-static void reverse(int t1);
-int reverse0(int t1);
 static int rvalue(int e);
-extern int rvalue_t(int e,int type);
-int scalar(int t);
 static int sdecl(int s);
 static int skipspc(void);
-static void statement(void);
 static int strop(int e);
 static int typeid(int s);
 static int typename(void);
 static int typespec(void);
-static int cexpr(int e);
+static void adecl(NMTBL *n);
 static void code_decl(NMTBL *n);
-static int macro_args(char **pcheapp,char* max,char **pchptr);
-static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history);
+static void compatible(int t1, int t2);
+static void copy(NMTBL *nptr, char *s);
+static void decl(void);
+static void docase(void);
+static void docomp(void);
+static void dodefault(void);
+static void dodo(void);
+static void dofor(void);
+static void dogoto(void);
+static void doif(void);
+static void dolabel(void);
+static void doreturn(void);
+static void doswitch(void);
+static void dowhile(void);
+static void errmsg(void);
+static void fcheck(NMTBL *n);
+static void fdecl(NMTBL *n);
+static void fdecl_struct(int type);
+static void getline(void);
+static void getstring(void);
+static void init(void);
+static void lcheck(int e);
 static void local_define();
 static void local_undef();
-static int macro_eval(int macrop,char *body,int history);
-static char * mappend(int lists);
-static NMTBL *free_nptr();
+static void macro_define();
+static void macro_define0();
+static void macro_processing();
+static void newfile(void);
 static void replace_return_struct(int func,int left);
-static void fdecl_struct(int type);
-static int append3(int p,int a1,int a2);
-extern int append4(int p,int a1,int a2,int a3);
+static void reserve(char *s, int d);
+static void reverse(int t1);
 static void set_converter(char *s);
+static void statement(void);
 
-extern void display_ntable(NMTBL *n, char *s);
-extern void closing(void);
-extern void opening(char *filename);
-extern void gen_gdecl(char *n, int gpc);
-extern void emit_init(void);
-extern void enter(char *name);
-extern void enter1();
-extern void leave(int control, char *name);
-extern void ret(void);
-extern void jmp(int l);
-extern void gexpr(int e1);
-extern void g_expr(int e1);
-extern int get_register_var(void);
-extern void use_register_var(int);
-extern void bexpr(int e1, char cond, int l1);
-extern int fwdlabel(void);
-extern void fwddef(int l);
-extern int backdef(void);
-extern int def_label(int cslabel, int dlabel);
-extern void jmp_label(int l);
-extern void cmpdimm(int e, int csreg);
-extern void jcond(int l, char cond);
-extern void jmp_eq_label(int l);
-extern void gen_comment(char *s);
-extern void gen_source(char *s);
-extern void code_init(void);
-extern void code_enter(char *name) ;
-extern void code_leave(char *name) ;
-extern void code_enter1(int args);
-extern int csvalue();
-extern int assign_expr(int e1,int e2,int t,int type);
-extern int assign_expr0(int e1,int e2,int t,int type);
-
-extern void emit_data_closing(NMTBL *n);
-extern void emit_data(int e, int t, NMTBL *n);
-
-extern void exit(int l);
 
 static int struct_return  = 0;
 static int arglist = 0;
@@ -246,7 +200,7 @@
     exit(1);
 }
 
-void
+static void
 errmsg(void)
 {
     char *p,*lim;
@@ -262,7 +216,7 @@
     fprintf (stderr,"^\n");
 }
 
-void
+static void
 checksym(int s)
 {
     char *p;
@@ -277,7 +231,7 @@
 	getsym();
 }
 
-void
+static void
 init(void)
 {
     NMTBL *nptr;
@@ -330,7 +284,7 @@
     getch();
 }
 
-void
+static void
 newfile(void)
 {
     char *s;
@@ -343,7 +297,7 @@
     while((*cheapp++ = *s++));
 }
 
-void
+static void
 set_converter(char *s)
 {
     chptr = s;
@@ -353,7 +307,7 @@
     else conv=&null_converter;
 }
 
-void
+static void
 reserve(char *s, int d)
 {
     NMTBL *nptr;
@@ -377,7 +331,7 @@
 static
 NMTBL null_nptr;
 
-void
+static void
 decl(void)
 {
     NMTBL *n;
@@ -444,7 +398,7 @@
 	mode=LDECL;
 }
 
-int
+static int
 typespec(void)
 {
     int t;
@@ -500,7 +454,7 @@
     return t;
 }
 
-struct nametable *
+static struct nametable *
 decl0(void)
 {
     NMTBL *n;
@@ -514,7 +468,7 @@
 }
 
 
-NMTBL *
+static NMTBL *
 decl1(void)
 {
     NMTBL *n;
@@ -581,7 +535,7 @@
 }
 
 
-void
+static void
 adecl(NMTBL *n)
 {
     NMTBL *arg,*sfnptr;
@@ -637,7 +591,7 @@
     return;
 }
 
-void 
+static void 
 reverse(int t1)
 {
     int t2,t3;
@@ -684,7 +638,7 @@
     return 0;
 }
 
-NMTBL *
+static NMTBL *
 def(NMTBL *n)
 {
     int sz,nsc,ndsp,t;
@@ -832,7 +786,7 @@
     return n;
 }
 
-void
+static void
 emit_init_vars(void)
 {
     if (!init_vars) return;
@@ -869,7 +823,7 @@
     return 0; /* not reached */
 }
 
-int
+static int
 decl_data(int t, NMTBL *n,int offset)
 {
     int t1,e,i,mode_save;
@@ -939,7 +893,7 @@
     return offset; /* not reached */
 }
 
-int
+static int
 sdecl(int s)
 {
     int smode,sdisp,type0;
@@ -994,7 +948,7 @@
     return type0;
 }
 
-void
+static void
 code_decl(NMTBL *n)
 {
     int t;
@@ -1039,7 +993,7 @@
 
 static NMTBL *tmp_struct;
 
-void
+static void
 fdecl(NMTBL *n)
 {
     enter(n->nm);
@@ -1080,7 +1034,7 @@
 
 static NMTBL str_ret;
 
-void
+static void
 fdecl_struct(int fntype)
 {
     int type_save,mode_save,t,sz;
@@ -1131,7 +1085,7 @@
     }
 }
 
-void
+static void
 compatible(int t1, int t2)
 {
     if(integral(t1)) {	
@@ -1157,7 +1111,7 @@
     return(t==INT||t==CHAR||t==UNSIGNED);
 }
 
-void
+static void
 checkret(void)
 {
     if (retpending) {
@@ -1167,7 +1121,7 @@
     }
 }
 
-void
+static void
 statement(void)
 {
     int slfree;
@@ -1232,7 +1186,7 @@
     }
 }
 
-void
+static void
 doif(void)
 {
     int l1,l2,slfree;
@@ -1256,7 +1210,7 @@
     else fwddef(l1);
 }
 
-void
+static void
 dowhile(void)
 {
     int sbreak,scontinue,slfree,e;
@@ -1287,7 +1241,7 @@
     blabel=sbreak;
 }
 
-void
+static void
 dodo(void)
 {
     int sbreak,scontinue,l,slfree;
@@ -1313,7 +1267,7 @@
     blabel=sbreak;
 }
 
-void
+static void
 dofor(void)
 {
     int sbreak,scontinue,l,e,slfree;
@@ -1358,7 +1312,7 @@
     blabel=sbreak;
 }
 
-void
+static void
 doswitch(void)
 {
     int sbreak,scase,sdefault,slfree,svalue;
@@ -1389,7 +1343,7 @@
     blabel=sbreak;
 }
 
-void
+static void
 docomp(void)
 {
     getsym();
@@ -1397,7 +1351,7 @@
     getsym();
 }
 
-void
+static void
 docase(void)
 {
     int c,l,slfree;
@@ -1426,7 +1380,7 @@
     fwddef(l);
 }
 
-void
+static void
 dodefault(void)
 {
     getsym();
@@ -1436,7 +1390,7 @@
     dlabel = backdef();
 }
 
-void
+static void
 doreturn(void)
 {
     int slfree,e,e1;
@@ -1481,7 +1435,7 @@
     rplacad(e,left);
 }
 
-void
+static void
 dogoto(void)
 {
     NMTBL *nptr0;
@@ -1525,7 +1479,7 @@
     return;
 }
 
-void
+static void
 dolabel(void)
 {
     if(nptr->sc == FLABEL) 
@@ -1574,7 +1528,7 @@
     return(rvalue(expr0()));
 }
 
-int
+static int
 expr0(void)
 {
     int e;
@@ -1586,7 +1540,7 @@
     return e;
 }
 
-int
+static int
 expr1(void)
 {
     int e1,e2,t,op;
@@ -1624,7 +1578,7 @@
     }
 }
 
-int
+static int
 expr2(void)
 {
     int e1,e2,e3,t;
@@ -1650,7 +1604,7 @@
     return(e1);
 }
 
-int
+static int
 expr3(void)
 {
     int e;
@@ -1665,7 +1619,7 @@
     return(e);
 }
 
-int
+static int
 expr4(void)
 {
     int e;
@@ -1680,7 +1634,7 @@
     return(e);
 }
 
-int
+static int
 expr5(void)
 {
     int e1,e2,t;
@@ -1696,7 +1650,7 @@
     return(e1);
 }
 
-int
+static int
 expr6(void)
 {
     int e1,e2,t;
@@ -1712,7 +1666,7 @@
     return(e1);
 }
 
-int
+static int
 expr7(void)
 {
     int e1,e2,t;
@@ -1728,7 +1682,7 @@
     return(e1);
 }
 
-int
+static int
 expr8(void)
 {
     int e,op;
@@ -1743,7 +1697,7 @@
     return e;
 }
 
-int
+static int
 expr9(void)
 {
     int e1,e2,t,op;
@@ -1763,7 +1717,7 @@
     return e1;
 }
 
-int
+static int
 expr10(void)
 {
     int e1,e2,t,op;
@@ -1779,7 +1733,7 @@
     return e1;
 }
 
-int
+static int
 expr11(void)
 {
     int e1,e2,t,op;
@@ -1795,7 +1749,7 @@
     return e1;
 }
 
-int
+static int
 expr12(void)
 {
     int e1,e2,t,op;
@@ -1811,7 +1765,7 @@
     return e1;
 }
 
-int
+static int
 expr13(void)
 {
     int e,op;
@@ -1910,7 +1864,7 @@
     return e;
 }
 
-int
+static int
 expr14(void)
 {
     int e1,t;
@@ -2003,7 +1957,7 @@
     return expr16(e1);
 }
 
-int
+static int
 expr16(int e1)
 {
     int e2,t;
@@ -2026,7 +1980,7 @@
     return e1;
 }
 
-int
+static int
 rvalue(int e)
 {
     int t;
@@ -2076,7 +2030,7 @@
     return e;
 }
 
-void
+static void
 lcheck(int e)
 {
     int t;
@@ -2086,7 +2040,7 @@
 	    error(LVERR);
 }
 
-int
+static int
 indop(int e)
 {
     if(type!=INT&&type!=UNSIGNED) {
@@ -2100,7 +2054,7 @@
     return(list2(INDIRECT,e));
 }
 
-int
+static int
 strop(int e)
 {
     getsym();
@@ -2134,7 +2088,7 @@
     return e;
 }
 
-int
+static int
 binop(int op, int e1, int e2, int t1, int t2)
 {
     int e;
@@ -2240,7 +2194,7 @@
     return(list3(type==UNSIGNED?op+US:op,e1,e2));
 }
 
-int
+static int
 expr15(int e1)
 {
     int t,arglist,e,sz;
@@ -2294,7 +2248,7 @@
     return list3(FUNCTION,e1,arglist);
 }
 
-int
+static int
 typeid(int s)
 {
     return (integral(s) || s==CODE || s==SHORT || 
@@ -2302,7 +2256,7 @@
     (s==IDENT && nptr->sc==TYPE));
 }
 
-int
+static int
 typename(void)
 {
     int t;
@@ -2313,7 +2267,7 @@
     return type;
 }
 
-int
+static int
 ndecl0(void)
 {
     if(sym==MUL) {	
@@ -2323,7 +2277,7 @@
     return ndecl1();
 }
 
-int
+static int
 ndecl1(void)
 {
     int i,t,arglist;
@@ -2360,16 +2314,16 @@
     }
 }
 
-int
+static int
 cexpr(int e)
 {       
     if (car(e) != CONST) error(CNERR);
     return (cadr(e));
 }
 
-int in_comment = 0;
+static int in_comment = 0;
 
-int
+static int
 getsym(void)
 {
     NMTBL *nptr0,*nptr1,*nptrm;
@@ -2560,20 +2514,20 @@
     }
 }
 
-int
+static int
 postequ(int s1, int s2)
 {
     if(ch=='=') {getch();return sym=s2;}
     return sym=s1;
 }
 
-int
+static int
 alpha(char c)
 {
     return(('a'<=c&&c<='z')||('A'<=c&&c<='Z')||c=='_');
 }
 
-int
+static int
 digit(char c)
 {
     return('0'<=c&&c<='9');
@@ -2581,7 +2535,7 @@
 
 int dummy_count = 0;
 
-NMTBL *
+static NMTBL *
 free_nptr()
 {
     NMTBL *nptr,*iptr;
@@ -2602,7 +2556,7 @@
     return nptr;
 }
 
-NMTBL *
+static NMTBL *
 gsearch(void)
 {
     NMTBL *nptr,*iptr;
@@ -2620,7 +2574,7 @@
     return nptr;
 }
 
-NMTBL *
+static NMTBL *
 lsearch(char *name)
 {
     NMTBL *nptr,*iptr;
@@ -2639,7 +2593,7 @@
     return nptr;
 }
 
-NMTBL *
+static NMTBL *
 msearch(char *name)
 {
     NMTBL *nptr,*iptr;
@@ -2659,7 +2613,7 @@
     return nptr;
 }
 
-NMTBL *
+static NMTBL *
 msearch0(char *name)
 {
     NMTBL *nptr,*iptr;
@@ -2685,14 +2639,14 @@
 }
 
 
-void
+static void
 copy(NMTBL *nptr, char *s)
 {
     nptr->nm = cheapp;
     while((*cheapp++ = *s++));
 }
 
-int
+static int
 neqname(char *p,char *q)
 {
     if (!p)
@@ -2702,7 +2656,7 @@
     return (*q!=0);
 }
 
-void
+static void
 getstring(void)
 {
     getch();
@@ -2718,7 +2672,7 @@
     symval++;
 }
 
-int
+static int
 skipspc(void)
 {
     while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') 
@@ -2726,7 +2680,7 @@
     return ch;
 }
 
-int
+static int
 getch(void)
 {
     if(*chptr) return ch = *chptr++;
@@ -2778,7 +2732,7 @@
     return c;
 }
 
-FILE *
+static FILE *
 getfname(void)
 {
     int i;
@@ -2803,7 +2757,7 @@
 static int macro_if_current ;
 static int macro_if_skip ;
 
-void
+static void
 getline(void)
 {
     int i;
@@ -2829,7 +2783,7 @@
     } while(macro_if_skip || linebuf[0] == '#');
 }
 
-void
+static void
 macro_processing()
 {
     int i;
@@ -2922,7 +2876,7 @@
     else error(MCERR);
 }
 
-int
+static int
 macroeq(char *s)
 {
     char *p;
@@ -2932,7 +2886,7 @@
     return 1;
 }
 
-void
+static void
 macro_define(char *macro)
 {
     char *chptr_save;
@@ -2946,7 +2900,7 @@
     ch = chsave;
 }
 
-void
+static void
 macro_define0()
 {
     int i,args,c;
@@ -2980,7 +2934,7 @@
     mode=i;
 }
 
-int 
+static int 
 macro_args(char **pcheapp,char *maxcheap,char **pchptr)
 {
     int c;
@@ -3063,7 +3017,7 @@
 
 /* output macro expansion result into macrobuf (macropp) */
 
-int
+static int
 macro_function(int macrop,char **pchptr,NMTBL *nptr,int history)
 {
     int args,sargs,values,evalues;
@@ -3094,7 +3048,7 @@
     return macrop;
 }
 
-void
+static void
 local_define(char *macro,char *value)
 {
     NMTBL *nptr0;
@@ -3104,7 +3058,7 @@
     nptr0->dsp=list2((int)value,0); 
 }
 
-void
+static void
 local_undef(char *macro)
 {
     NMTBL *nptr0;
@@ -3116,7 +3070,7 @@
     nptr0->ty=cadr(save); 
 }
 
-int
+static int
 macro_eval(int macrop,char *body,int history)
 {
     int c;
@@ -3207,7 +3161,7 @@
     return e;
 }
 
-int
+static int
 getfree(int n)
 {
     int e;
@@ -3273,7 +3227,7 @@
     return p1;
 }
 
-char *
+static char *
 mappend(int lists)
 {
     char *p;
--- a/mc.h	Wed Feb 19 21:22:49 2003 +0900
+++ b/mc.h	Thu Feb 20 03:29:15 2003 +0900
@@ -206,15 +206,26 @@
 EXTERN NMTBL mtable[MSYMS];
 EXTERN NMTBL ntable[GSYMS+LSYMS];
 EXTERN NMTBL *nptr,*gnptr;
-EXTERN NMTBL *decl0(void),*decl1(void),*lsearch(char *name),*gsearch(void);
 EXTERN NMTBL *fnptr;
-EXTERN NMTBL *msearch(char *name);
-EXTERN NMTBL *msearch0(char *name);
 
 EXTERN struct {int fd,ln;char *name0;FILE *fcb;} *filep,filestack[FILES];
 EXTERN char cheap[CHEAPSIZE];
 EXTERN char *macropp,macro_buf[MACROSIZE];
 
+extern void error(int n);
+extern int size(int t);
+extern int scalar(int t);
+extern int list2(int e1, int e2);
+extern int list3(int e1, int e2, int e3);
+extern int list4(int e1, int e2, int e3,int e4);
+extern int reverse0(int t1);
+extern int assign_data(int e, int t, NMTBL *n,int offset);
+extern int assign_expr0(int e1,int e2,int t,int type) ;
+extern int assign_expr(int e1,int e2,int t,int type) ;
+extern int append4(int p,int a1,int a2,int a3);
+
+
+
 #define car(e) (heap[(int)(e)])
 
 #define cadr(e) (heap[((int)(e))+1])
@@ -234,4 +245,28 @@
 
 EXTERN Converter *conv;
 
+
+EXTERN void error(int n);
+EXTERN int append4(int p,int a1,int a2,int a3);
+EXTERN int assign_expr(int e1,int e2,int t,int type);
+EXTERN int assign_expr0(int e1,int e2,int t,int type);
+EXTERN int backdef(void);
+EXTERN int fwdlabel(void);
+EXTERN int get_register_var(void);
+EXTERN int glist2(int e1,int e2);
+EXTERN int integral(int t);
+EXTERN int list2(int e1, int e2);
+EXTERN int list3(int e1, int e2, int e3);
+EXTERN int list4(int e1, int e2, int e3, int e4);
+EXTERN int reverse0(int t1);
+EXTERN int rplacad(int e, int n);
+EXTERN int rplacadd(int e, int n);
+EXTERN int rvalue_t(int e,int type);
+EXTERN int scalar(int t);
+EXTERN void bexpr(int e1, char cond, int l1);
+EXTERN void def_label(int cslabel, int dlabel);
+EXTERN void display_ntable(NMTBL *n, char *s);
+EXTERN void exit(int l);
+EXTERN void fwddef(int l);
+
 /* end */
--- a/stdio.h	Wed Feb 19 21:22:49 2003 +0900
+++ b/stdio.h	Thu Feb 20 03:29:15 2003 +0900
@@ -1,9 +1,12 @@
+#ifndef __micro_c__
+#include "/usr/include/stdio.h"
+#else
+
 typedef	struct {
 	/* this is all wrong, but so what? */
 	/* char	pad[96];	 */
 	char	pad[148];	
 } FILE;
-
 #ifdef __APPLE__
 
 extern FILE __sF[];
@@ -110,3 +113,4 @@
 char	*tempnam(const char *, const char *);
 FILE	*tmpfile(void);
 char	*tmpnam(char *);
+#endif