changeset 643:f5c0371c9401

*** empty log message ***
author kono
date Wed, 01 Nov 2006 15:55:24 +0900
parents e9622935a621
children ac1285a0f69f
files mc-mips.c mc-nop-386.c
diffstat 2 files changed, 0 insertions(+), 3515 deletions(-) [+]
line wrap: on
line diff
--- a/mc-mips.c	Wed Nov 01 15:33:37 2006 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1553 +0,0 @@
-/* Micro-C Code Generatation Part for Mips */
-
-#define EXTERN extern
-#include "mc.h"
-
-#define REGISTERS6   0
-
-void code_init(void);
-void free_register(int i);
-void emit_init(void);
-void emit_push(void);
-void gexpr(int e1);
-void g_expr(int e1);
-void bexpr(int e1, char cond, int l1);
-void b_expr(int e1, char cond, int l1);
-void string(int e1);
-void function(int e1);
-void machinop(int e1);
-void rindirect(int e1);
-void assign(int e1);
-void sassign(int e1);
-void assop(int e1);
-void tosop(int op);
-void shift(char *op, int reg) ;
-void ld_indexx(int byte, int n, char *xrn);
-void st_indexx(int byte, int n, char *xrn);
-void indexy(char *op, char *gvar);
-void cmpdimm(int e, int csreg);
-void global_table(void) ;
-void local_table(void) ;
-void opening(char *filename);
-void closing(void);
-void gen_gdecl(char *n, int gpc) ;
-void jmp_label(int l);
-void jmp_eq_label(int l);
-void rexpr(int e1, int l1, char *s);
-void jcond(int l, char cond);
-void jmp(int l);
-void def_label(int cslabel, int dlabel) ;
-void gen_comment(char *s);
-void gen_source(char *s);
-void code_enter(char *name) ;
-void code_leave(char *name) ;
-void enter(char *name, int disp) ;
-void enter_no(char *name,int disp);
-void enter1(int disp) ;
-void ret(void);
-void emit_data(int e, int t, NMTBL *n);
-void    text_mode(void);
-void    data_mode(char *name);
-int  get_register_var(void);
-void	jump(int e1, int env);
-int	lvar(int l);
-
-int cadr(int e);
-int car(int e);
-int caddr(int e);
-int fwdlabel(void);
-void fwddef(int l);
-int cadddr(int e);
-int backdef(void);
-int error(int n);
-int size(int t);
-int list3(int e1, int e2, int e3);
-extern int scalar(int);
-extern int reverse0(int);
-
-#define TEXT_EMIT_MODE 0
-#define DATA_EMIT_MODE 1
-#define RODATA_EMIT_MODE 2
-
-static output_mode = TEXT_EMIT_MODE;
-static data_alignment = 0;
-
-/*
-         local1 <----24 local variable
-                    -20  <- disp_offset
-        saved register
-        .mask  0...0,-8
-        .fmask 0
-        $fp = $sp     0
-        $ip           4   <- arg_offset
-          arg1        8
- */
-int arg_offset = 8;
-int code_arg_offset = -4;
-int disp_offset = -12;
-int func_disp_offset = -12;
-int code_disp_offset = -4;
-int size_of_int = 4;
-int endian = 0;
-int MAX_REGISTER=32;         /* Mipsのレジスタを32つまで使う*/
-int REAL_MAX_REGISTER=32;    /* Mipsのレジスタが32つということ*/
-int MAX_REGISTGER_VAR=20;    
-
-int save_reg = 0;   /*saveされたレジスタの回数*/
-int save_reg1 = 0;
-
-static int  creg;     /* current register */
-static char *crn;     /* current register name */
-static int  lreg;     /* operand register */
-static char *lrn;     /* operand register name */
-static int  dreg;     /* temporary register */
-static char *drn;     /* temporary register name */
-static int  xreg;     /* pointer register */
-static int  reg_sp;   /* REGister Stack-Pointer */
-
-
-#define REG_00   0
-#define REG_01   1
-#define REG_02   2
-#define REG_03   3
-#define REG_04   4
-#define REG_05   5
-#define REG_06   6
-#define REG_07   7
-#define REG_08   8
-#define REG_09   9
-#define REG_10  10
-#define REG_11  11
-#define REG_12  12
-#define REG_13  13
-#define REG_14  14
-#define REG_15  15
-#define REG_16  16
-#define REG_17  17
-#define REG_18  18
-#define REG_19  19
-#define REG_20  20
-#define REG_21  21
-#define REG_22  22
-#define REG_23  23
-#define REG_24  24
-#define REG_25  25
-#define REG_26  26
-#define REG_27  27
-#define REG_28  28
-#define REG_29  29
-#define REG_30  30
-#define REG_31  31
-
-static char *reg_name[32]; 
-
-/*
-    creg   currrent virtual register
-    lreg   operand virtual register
-    dreg   spare virtual register
-
-    rname[creg]   currrent real register
-    rname[lreg]   operand real register
-    rname[dreg]   spare real register
-
-    regs[]        virtual register usage
-
-    reg_name[rname[creg]]
- */
-
-#define MAX_MAX 40
-static int rname[MAX_MAX];
-static int regs[MAX_MAX];       /* 使われているレジスタを示すフラグ */
-static int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
-
-void
-code_init(void)
-{
-    int i;
-
-    if (REGISTERS6) {
-	arg_offset = 8;
-	func_disp_offset = -20;
-	disp_offset = -20;
-	size_of_int = 4;
-	endian = 0;
-	MAX_REGISTER=32;
-    } else {
-	arg_offset = 8;
-	func_disp_offset = -12;
-	disp_offset = -12;
-	size_of_int = 4;
-	endian = 0;
-	MAX_REGISTER=32;
-    }
-    MAX_REGISTER_VAR=2;    
-
-    reg_name[REG_00] = "$0";
-    reg_name[REG_01] = "$1";
-    reg_name[REG_02] = "$2";
-    reg_name[REG_03] = "$3";
-    reg_name[REG_04] = "$4";
-    reg_name[REG_05] = "$5";
-    reg_name[REG_06] = "$6";
-    reg_name[REG_07] = "$7";
-    reg_name[REG_08] = "$8";
-    reg_name[REG_09] = "$9";
-    reg_name[REG_10] = "$10";
-    reg_name[REG_11] = "$11";
-    reg_name[REG_12] = "$12";
-    reg_name[REG_13] = "$13";
-    reg_name[REG_14] = "$14";
-    reg_name[REG_15] = "$15";
-    reg_name[REG_16] = "$16";
-    reg_name[REG_17] = "$17";
-    reg_name[REG_18] = "$18";
-    reg_name[REG_19] = "$19";
-    reg_name[REG_20] = "$20";
-    reg_name[REG_21] = "$21";
-    reg_name[REG_22] = "$22";
-    reg_name[REG_23] = "$23";
-    reg_name[REG_24] = "$24";
-    reg_name[REG_25] = "$25";
-    reg_name[REG_26] = "$26";
-    reg_name[REG_27] = "$27";
-    reg_name[REG_28] = "$28";
-    reg_name[REG_29] = "$29";
-    reg_name[REG_30] = "$30";
-    reg_name[REG_31] = "$31";
-
-}
-
-char *
-register_name(int i)
-{
-    return reg_name[rname[i]];
-}
-
-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) {    /* いらなくなったレジスタを開放 */
-    regs[i]=0;
-}
-
-int
-register_full(void)
-{
-    int i;
-    for(i=0;i<MAX_REGISTER;i++) {
-	if (! regs[i]) { 
-	    return 0;  
-	}
-    }
-    return 1;    
-}
-
-void 
-gexpr_init(void)
-{
-    int i;
-    while(reg_sp > 0) {
-	free_register(reg_stack[--reg_sp]);
-    }
-    text_mode();
-}
-
-void 
-emit_init(void)
-{
-    int i;
-    for(i=0;i<REAL_MAX_REGISTER;i++) regs[i]=0;
-    for(i=0;i<REAL_MAX_REGISTER;i++) rname[i]=i;
-    regs[REG_00] = 1;   /* reserved */
-    regs[REG_01] = 1;   /* reserved */
-    regs[REG_02] = 1;   /* $v0 */
-    regs[REG_03] = 1;   /* $v1 */
-    regs[REG_28] = 1;   /* reserved */
-    regs[REG_29] = 1;   /* reserved */
-    regs[REG_30] = 1;   /* reserved */
-    regs[REG_31] = 1;   /* reserved */
-    creg = get_register();
-    crn = reg_name[rname[creg]];
-    dreg = get_register();
-    drn = reg_name[rname[dreg]];
-    reg_sp = 0;
-    text_mode();
-}
-
-void 
-set_crn(int i)
-{
-    creg = i;
-    crn = reg_name[rname[creg]];
-}
-
-void 
-set_drn(int i)
-{
-    dreg = i;
-    drn = reg_name[rname[dreg]];
-}
-
-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;
-	}
-    }
-    if (real_v == -1)
-	error(-1);
-    return real_v;
-}
-
-void 
-use_register(int virt, int real, int move)
-{
-    int real_v;
-    char *move_op,*a,*b;
-    if (rname[virt]==real)
-	return;
-    real_v = virtual(real);
-    if (move || regs[real_v]) {
-	if(regs[real_v]) {
-	    a=reg_name[real];
-	    b=reg_name[rname[virt]];
-	    printf("\txor \t%s,%s,%s\n",a,a,b);
-	    printf("\txor \t%s,%s,%s\n",b,a,b);
-	    printf("\txor \t%s,%s,%s\n",a,a,b);
-	} else {
-	   printf("\tmove \t%s,%s\n",reg_name[real],reg_name[rname[virt]]);
-	}
-    } 
-    rname[real_v] = rname[virt];
-    rname[virt] = real; 
-    crn = reg_name[rname[creg]];
-    drn = reg_name[rname[dreg]];
-    lrn = reg_name[rname[lreg]];
-
-    save_reg++;
-}
-
-int 
-pop_register(void)
-{     /* レジスタから値を取り出す */
-    int i,j;
-
-    j = creg;
-    i = reg_stack[--reg_sp];
-
-    if(i<0) {
-	return i;
-    } else {
-	free_register(i);
-	lreg = i;
-	lrn = reg_name[rname[lreg]];
-	regs[i]=0;
-	return lreg;
-    }
-}
-
-int
-stack_used(void) {
-    return reg_stack[--reg_sp]<0;
-}
-
-void 
-emit_push(void)
-{
-    int new_reg;
-    new_reg = get_register();
-    if(new_reg<0) {                     /* もうレジスタがない */
-	reg_stack[reg_sp++] =  -1;
-	printf("\tsubu $sp,$sp,%d\n",size_of_int);
-	printf("\tsw \t%s,0($sp)\n",crn);
-    } else {
-	reg_stack[reg_sp++] = creg;     /* push するかわりにレジスタを使う */
-	set_crn(new_reg);
-    }
-}
-
-char *
-emit_pop(int type)
-{
-    char *xrn;
-    if (pop_register()==-1) {
-	printf("\tlw %s,0($sp)\n",drn);
-	printf("\taddu $sp,$sp,%d\n",size_of_int);
-	xrn = drn;
-	xreg = dreg;
-    } else {
-	xrn = lrn;
-	xreg = lreg;
-    }
-    return xrn;
-}
-
-int
-get_register_var(void)
-{
-    int i;
-    for(i=REG_05;i<REG_31;i++) {
-	if (! regs[i]) {    /* 使われていないなら */
-	    regs[i]=1;      /* そのレジスタを使うことを宣言し */
-	    return i;       /* その場所を表す番号を返す */
-	}
-    }
-    return -1;
-}
-
-void
-gexpr(int e1)
-{
-    gexpr_init();
-    g_expr(e1);
-    csvalue = rname[creg]; /* for siwtch value */
-}
-
-void
-g_expr(int e1)
-{
-    int e2,e3,e4;
-    char *xrn;
-    NMTBL *n;
-
-    if (chk) return;
-    e2 = cadr(e1);
-    switch (car(e1)){
-    case GVAR:   
-	printf("\tla\t%s,%s\n",crn,caddr(e1));
-	return;
-    case RGVAR:
-	printf("\tlw\t%s,%s\n",crn,caddr(e1));
-	return;
-    case CRGVAR:
-	printf("\tlb\t%s,%s\n",crn,caddr(e1));
-	return;
-    case LVAR:
-	printf("\taddu\t%s,$fp,%d\n",crn,lvar(e2));
-	return;
-    case REGISTER:
-	/* this is of course redundant... */
-	printf("\tmove\t%s,%s\n",crn,register_name(e2));
-	return;
-    case RLVAR:
-	printf("\tlw\t%s,%d($fp)\n",crn,lvar(e2));
-	return;
-    case CRLVAR:
-	printf("\tlb\t%s,%d($fp)\n",crn,lvar(e2));
-	return;
-    case FNAME:
-	printf("\tla\t%s,%s\n",crn,((NMTBL *)e2)->nm);
-	return;
-    case CONST:  /* 代入する値が0でも特別な処理はしない */
-	printf("\tli\t%s,%d\n",crn,e2);
-	return;
-    case STRING:
-	string(e1);
-	return;
-    case FUNCTION:
-	function(e1);
-	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:  /* レジスタに対し、引き算を実行すれば実現可能 */
-	g_expr(e2);
-	printf("\tsubu\t%s,$0,%s\n",crn,crn);
-	return;
-    case BNOT:   /* ~ */
-	g_expr(e2);
-	/* use_data_reg(creg,1); */
-	printf("\tnor\t%s,$0,%s\n",crn,crn);
-	return;
-    case LNOT:   /* !  */
-	g_expr(e2);
-	/*use_data_reg(creg,1);*/
-	printf("\txori\t%s,%s,0x0000\n",drn,crn);
-	printf("\tsltu\t%s,%s,1\n",crn,drn);
-	return;
-    case PREINC:/* ++q */
-	if (car(e2)==REGISTER) {
-	    printf("\taddu \t%s,%s,%d\n",register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
-	    return;
-	} 
-	g_expr(e2);
-	printf("\taddu \t%s,%s,%d\n",crn,crn,caddr(e1));
-	return;
-    case POSTINC:/* p++ */
-	if (car(e2)==REGISTER) {
-	    printf("\taddu \t%s,%s,%d\n",register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
-	    return;
-	} 
-	g_expr(e2);
-	emit_push();  
-    /* in case of register full we should copy crn to drn */
-	xrn = emit_pop(0);
-	printf("\taddu \t%s,%s,%d\n",crn,xrn,caddr(e1));
-	return;
-    case CPOSTINC:
-	/*   char *p; *p++ */
-	if (car(e2)==REGISTER) {
-            printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2)));
-            printf("\taddu\t%s,%s,%d\n",register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
-	    return;
-	} 
-	g_expr(e2);
-	emit_push(); /* in case of register full we should copy crn to drn */
-	xrn = emit_pop(0);
-	printf("\tmovsbl (%s),%s\n",xrn,crn);
-	printf("\tincl (%s)\n",xrn);
-	return;
-    case CPREINC: /* char *p; *++p */
-	if (car(e2)==REGISTER) {
-            printf("\taddu\t%s,%s,%d\n",register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
-            printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2)));
-	    return;
-	} 
-	g_expr(e2);
-        printf("\tincl (%s)\n",crn);
-        printf("\tmovsbl (%s),%s\n",crn,crn);
-	return;
-    case CPOSTDEC:/* char *p; *p-- */
-	if (car(e2)==REGISTER) {
-	    printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2)));
-	    printf("\tsubu\t%s,%s,1\n",register_name(cadr(e2)),register_name(cadr(e2)));
-	    return;
-	} 
-	g_expr(e2);
-	printf("\tmovsbl (%s),%s\n",crn,crn);
-	printf("\tdecl (%s)\n",crn);
-	return;
-    case CPREDEC:/* char *p; *--p */
-	if (car(e2)==REGISTER) {
-	    printf("\tdecl %s\n",register_name(cadr(e2)));
-	    printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2)));
-	    return;
-	} 
-	g_expr(e2);
-	emit_push();
-	xrn = emit_pop(0);
-	printf("\tdecl (%s)\n",xrn);
-	printf("\tmovsbl (%s),%s\n",xrn,crn);
-	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);
-	g_expr(caddr(e1));
-	e4 = rname[creg];
-	jmp(e3=fwdlabel());
-	fwddef(e2);
-	g_expr(cadddr(e1));
-	use_register(creg,e4,1);
-	fwddef(e3);
-	return;
-    case STASS: 
-	sassign(e1);
-	return;
-    case ASS: case CASS:
-	assign(e1);
-	return;
-    case ASSOP: case CASSOP:
-	assop(e1);
-	return;
-    case COMMA:
-	g_expr(e2);
-	g_expr(caddr(e1));
-	return;
-    case RETURN:
-	n = (NMTBL *)e2;
-	if (retcont==0)
-	    retcont=fwdlabel();
-	printf("\tla\t%s,$L%d\n",crn,retcont);
-	return;
-    case ENVIRONMENT:
-	printf("\tmove\t%s,$fp\n",crn);
-	return;
-    default:
-	b_expr(e1,1,e2=fwdlabel());  /* including > < ... */
-	/*printf("\txor \t%s,%s\n",crn,crn);*/
-	jmp(e3=fwdlabel());
-	fwddef(e2);
-	printf("\tli \t%s,%d\n",crn,lvar(e2));
-	fwddef(e3);
-    }
-}
-
-void
-bexpr(int e1, char cond, int l1)
-{
-    gexpr_init();
-    b_expr(e1,cond,l1);
-}
-
-void
-b_expr(int e1, char cond, int l1)
-{
-    int e2,l2;
-    if (chk) return;
-    e2=cadr(e1);
-    switch(car(e1)) {
-    case LNOT:
-	b_expr(e2,!cond,l1);
-	return;
-    case GT:
-	/*rexpr(e1,l1,cond?"bg":"ble");*/
-	return;
-    case UGT:
-	/*rexpr(e1,l1,cond?"ba":"bbe");*/
-	return;
-    case GE:
-	/*rexpr(e1,l1,cond?"bge":"bl");*/
-	return;
-    case UGE:
-	/*rexpr(e1,l1,cond?"bae":"bb");*/
-	return;
-    case LT:
-	/*rexpr(e1,l1,cond?"bl":"bge");*/
-	return;
-    case ULT:
-	/*rexpr(e1,l1,cond?"bb":"bae");*/
-	return;
-    case LE:
-	/*rexpr(e1,l1,cond?"ble":"bg");*/
-	return;
-    case ULE:
-	/*rexpr(e1,l1,cond?"bbe":"ba");*/
-	return;
-    case EQ:
-	rexpr(e1,l1,cond?"beq":"bne");
-	return;
-    case NEQ:
-	rexpr(e1,l1,cond?"bne":"beq");
-	return;
-    case LAND:
-	b_expr(e2,0,cond?(l2=fwdlabel()):l1);
-	b_expr(caddr(e1),cond,l1);
-	if(cond) fwddef(l2);
-	return;
-    case LOR:
-	b_expr(e2,1,cond?l1:(l2=fwdlabel()));
-	b_expr(caddr(e1),cond,l1);
-	if(!cond) fwddef(l2);
-	return;
-    case CRGVAR:
-	/*printf("\tcmpb $0,%s\n",caddr(e1));*/
-	jcond(l1,cond);
-	return;
-    case CRLVAR:
-	/*printf("\tcmpb $0,%d($fp)\n",lvar(e2));*/
-	jcond(l1,cond);
-	return;
-    case RGVAR:
-	/*printf("\tcmpl $0,%s\n",caddr(e1));*/
-	jcond(l1,cond);
-	return;
-    case RLVAR:
-	/*printf("\tlw \t%s,%d($fp)\n",crn,lvar(e2));*/
-	jcond(l1,cond);
-	return;
-    case REGISTER:
-	/*printf("\tcmpl $0,%s\n",register_name(e2));*/
-	jcond(l1,cond);
-	return;
-    case CONST:
-	if((cond&&e2)||(!cond&&!e2)) jmp(l1);
-	return;
-    default:
-	g_expr(e1);
-	/*printf("\tcmpl $0,%s\n",crn);*/
-	jcond(l1,cond);
-	return;
-    }
-}
-
-void
-ascii(char *s)
-{
-    printf("\t.ascii \"");
-    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);
-	printf("\t.rdata\n");
-	printf("\t.align\t2\n");
-	lb=fwdlabel();
-	printf("\tj\t$L%d\n",lb);
-	i=backdef();
-	ascii(s);
-	printf("\t.align 2\n");
-	fwddef(lb);
-	printf("\tla\t%s,$L%d\n",crn,i);
-    } else {
-	s=(char *)cadr(e1);
-        printf("\t.rdata\n");
-	printf("\t.align\t2\n");
-	lb=fwdlabel();
-	printf("$L%d:\n",lb);
-	ascii(s);
-	if (output_mode==TEXT_EMIT_MODE) {
-	    printf("\t.text\n");
-	} else {
-	    text_mode();
-	}
-	printf("\tla\t%s,$L%d\n",crn,lb);
-    }
-}
-
-void
-function(int e1)
-{
-    int e2,e3,e4,e5,nargs;
-    NMTBL *n;
-
-    e2 = cadr(e1);
-    nargs = 0;
-    for (e3 = caddr(e1); e3; e3 = cadr(e3)) {	
-	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
-	switch(car(e4)){
-	case FNAME:
-	    printf("\tlw\t%s,0(%s)\n",crn,n->nm);
-	    break;
-	case ADDRESS:
-	    g_expr(e5);
-	    break;
-	default:g_expr(e4);
-        }
-	++nargs;
-    }
-    if (car(e2) == FNAME) {	
-	n=(NMTBL *)cadr(e2);
-	use_register(creg,REG_04,0);
-	printf("\tjal\t%s\n",n->nm);
-    } else {	
-	g_expr(e2);
-	use_register(creg,REG_04,0);
-	printf("\tjal\t*%s\n",crn);
-    }
-    /*if (nargs) printf("\taddl $%d,%%esp\n",size_of_int*nargs);*/
-}
-
-int
-arg_size(int e3,int *nargs0)
-{
-    int i,nargs,offset_list,e,t;
-
-    offset_list = 0;
-    /* we should use prototypes's type */
-    for (i = nargs = 0; e3;e3 =cadr(e3)) {
-	e = car(e3); t = caddr(e3);
-	if (i < MAX_REGISTER_VAR && scalar(t)) {
-	     offset_list = list3(-(REG_05+i++),offset_list,e);
-	} else {
-	    offset_list = 
-	       list3(nargs,offset_list,e);
-	    nargs += (car(e3)==CHAR?size_of_int:size(t));
-	}
-    }
-    *nargs0 = -nargs;
-    return offset_list;
-}
-
-void
-jump(int e1, int env)
-{
-    int i,args,e2,e3,e4,e5,nargs,nargs0,regs;
-    NMTBL *n,*code0;
-    int new_disp,scode,disp1;
-    char *xrn;
-
-    /* We need three passes. Compute Stack size, Compute Arg, Copy it. */
-    /* count number of args */
-    args = caddr(e1);
-    args = reverse0(args);
-    nargs = arg_size(args,&new_disp);  /* compute in normal order */
-    disp1 = (fnptr->sc==CODE)?0:-size_of_int;
-    if (new_disp+disp1 < disp) {  /* have to extend stack */
-	if (fnptr->sc==CODE)
-	    printf("\tlw\t$sp,%d($fp)\n",new_disp-size_of_int);
-	else
-	    printf("\tlw\t$sp,%d($fp)\n",new_disp+disp_offset);
-    }
-    /* compute jump address */
-    e2 = cadr(e1);
-    if (car(e2) == FNAME) {	
-	code0=(NMTBL *)cadr(e2);
-	if (code0->sc!=CODE) {
-	    error(STERR); return;
-	}
-    } else {	/* indirect */
-	g_expr(e2);
-	emit_push();
-    }
-    /* compute arguments in reverse order */
-    regs = 0;
-    i=MAX_REGISTER_VAR;
-    for (e3=nargs; e3;e3 =cadr(e3)) {
-	n=(NMTBL *)(e5=(cadr(e4 = caddr(e3))));
-	switch(car(e4)) {
-	case FNAME:
-	    printf("\tlw\t%s,0(%s)\n",crn,n->nm);
-	    emit_push();
-	    break;
-	case ADDRESS:
-	    g_expr(e5);
-	    emit_push();
-	    break;
-	case RLVAR:
-	case CRLVAR:
-	    if (env==0 && fnptr->sc==CODE) {
-		if (e5>=0 && e5==car(e3)) {
-		/* The same positioned local variable. No need to copy */
-		    reg_stack[reg_sp++] = -2;
-		}
-		break;
-	    }
-	    g_expr(e4);
-	    emit_push();
-	    break;
-	case REGISTER:
-	    if (i>0 && rname[e5]==REG_05+ --i) {
-		/* The same register variable. No need to copy */
-		reg_stack[reg_sp++] = e5;
-		break;
-	    }
-	default:
-	    g_expr(e4);
-	    emit_push();
-	}
-	regs++;
-    }
-    if (env) {
-	/* change the frame pointer */
-	g_expr(env);
-	printf("\tmove\t%s,$fp\n",crn);
-    } else if (fnptr->sc==FUNCTION) {
-	printf("\tlw\t$fp,%d($fp)\n",disp_offset);
-    } 
-    /* force lvar offset mode to CODE */
-    scode = fnptr->sc; fnptr->sc = CODE;
-    /* copy arguments to destination environment if necessary */
-    nargs = reverse0(nargs); /* pop in normal order */
-    i=0;
-    for (e3=nargs; e3;e3 =cadr(e3)) {
-	if ((e4=car(e3))<0)  {
-	    /* register case */
-	    if (reg_stack[--reg_sp]>=REG_05) {
-		/* the same registger */
-	    } else {
-		if(reg_stack[reg_sp]<0) {
-		    /*printf("\tpopl %s\n",reg_name[rname[REG_05+i]]);*/ /* e4? */
-		} else {
-		    printf("\tmove\t%s,%s\n",
-			    reg_name[rname[REG_05+i]],
-			    reg_name[rname[reg_stack[reg_sp]]]); /* e4? */
-		    free_register(reg_stack[reg_sp]);
-		}
-		i++;
-	    }
-	} else {
-	    /* local variable case */
-	    if (reg_stack[reg_sp-1]== -2) {
-		/* same positioned variable */
-		reg_sp--;
-	    } else {
-		xrn=emit_pop(0);
-		printf("\tlw\t%s,%d($fp)\n",xrn, lvar(e4));
-	    }
-	}
-    }
-    if (car(e2) != FNAME) {	
-	xrn=emit_pop(0);
-    }
-    if (!env && new_disp+disp1>disp) {
-	/* shrink stack if necessary */
-	printf("\tlw\t$sp,%d($fp)\n",new_disp-size_of_int);
-    } 
-    if (car(e2) == FNAME) {	
-	printf("\tj\t%s\n",code0->nm);
-    } else {
-	printf("\tj\t*%s\n",xrn);
-    }
-    fnptr->sc = scode;
-}
-
-
-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));
-    return;
-}
-
-
-void
-rindirect(int e1)   /* *(p +5 ) */
-       
-{
-    char *op;
-    int e2,e3,byte;
-
-    op = ((byte = (car(e1) == CRINDIRECT)) ? "lb" : "lw");
-    e3 = cadr(e2 = cadr(e1));
-    g_expr(e2);
-    printf("\t%s \t%s,%d(%s)\n",op,crn,lvar(e3),crn);
-}
-
-void
-sassign(int e1)
-{
-    int e2,e3,e4,sz;
-    char *xrn;
-
-    e2 = cadr(e1);
-    e3 = cadr(e2);
-    e4 = caddr(e1);
-    sz = size(cadr(e2));  /* cld rep movsb */
-    g_expr(e4);
-    emit_push();
-    g_expr(e2);
-    xrn = emit_pop(0);
-    return;
-}
-
-void
-assign(int e1)
-{
-    char *op;
-    int e2,e3,e4,byte;
-    char *xrn;
-
-    op = ((byte=(car(e1) == CASS))? "sb" : "sw");
-    /*    e2=e4 */
-    e2 = cadr(e1);
-    e3 = cadr(e2);
-    e4 = caddr(e1);
-    switch(car(e2)) {
-    case GVAR:      /*   i=3 */
-            g_expr(e4);
-            /*if (byte) use_data_reg(creg,1);*/
-            printf("\t%s \t%s,%s\n",op,crn,caddr(e2));
-            return;
-    case LVAR:
-            g_expr(e4);
-            /*if (byte) use_data_reg(creg,1);*/
-            printf("\t%s \t%s,%d($fp)\n",op,crn,lvar(cadr(e2))*-1);
-            return;
-    case REGISTER:
-            g_expr(e4);
-	    if (creg!=cadr(e2))
-		printf("\t%s \t%s,%s\n",op,crn,register_name(cadr(e2)));
-            return;
-    }
-    g_expr(e4);
-    emit_push();
-    g_expr(e2);
-    xrn = emit_pop(0);
-    /*if (byte) use_data_reg(creg,1);*/
-    printf("\t%s %s,(%s)\n",op,xrn,crn);
-    printf("\tmove\t%s,%s\n",crn,xrn);
-    return;
-}
-
-void
-assop(int e1)
-{
-    int e2,e3,byte,op,new_reg;
-    char *xrn;
-
-    /*   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);
-    emit_push();
-    if (car(e2)==REGISTER) {
-	new_reg=creg;
-	set_crn(cadr(e2));
-	tosop(op);
-	set_crn(new_reg);
-	printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2)));
-	return;
-    }
-    g_expr(e2);
-    xrn = emit_pop(0);                           /* pop e3 value */
-    /*printf("\tpushl %s   # assop \n",crn);*/      /* push e2 address */
-    ld_indexx(byte,0,crn);
-    new_reg = get_register();
-    /* push e3 value */
-    if(new_reg<0) {                     /* もうレジスタがない */
-        reg_stack[reg_sp++] =  -1;
-        /*printf("\tpushl %s\n",xrn);*/
-    } else {
-        reg_stack[reg_sp++] = xreg;     /* push するかわりにレジスタを使う */
-    }
-    tosop(op);
-    if(new_reg>=0) free_register(new_reg);
-    /*printf("\tpopl %s   # assop \n",drn);*/
-    printf("\t%s\t%s,0(%s)\n",byte ? "lb" : "lw",crn,drn);
-    return;
-
-}
-
-
-void
-tosop(int op)
-{
-    int oreg;
-    char *orn;
-
-    oreg = pop_register();
-    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) {
-	oreg = dreg;
-    }
-    orn = reg_name[rname[oreg]];
-    switch(op) {
-    case ADD:
-	printf("\taddu \t%s,%s,%s\n",crn,crn,orn);
-	return;
-    case SUB:
-	printf("\tsubu \t%s,%s,%s\n",crn,crn,orn);
-	return;
-    case BAND: 
-	printf("\tand \t%s,%s,%s\n",crn,crn,orn);
-	return;
-    case EOR: 
-	printf("\txor \t%s,%s,%s\n",crn,crn,orn);
-	return;
-    case BOR:
-	printf("\tor \t%s,%s,%s\n",crn,crn,orn);
-	return;
-    case MUL:
-    case UMUL:
-	printf("\t%s\t%s,%s\n","mult",crn,orn);
-	printf("\tmflo\t%s\n",crn);
-	return;
-    case DIV:
-    case UDIV:
-	if (op==DIV)
-	    printf("\tdiv\t%s,%s,%s\n",crn,crn,orn);
-	else 
-	    printf("\txor\t%s,%s,%s\n\tdiv\t%s,%s,%s\n",crn,crn,orn,crn,crn,orn);
-	return;
-    case MOD:
-    case UMOD:
-        if (op==MOD)
-	    printf("\trem\t%s,%s,%s\n",crn,crn,orn);
-	else 
-	    printf("\txor\t%s,%s,%s\n\tdiv\t%s,%s,%s\n",crn,crn,orn,crn,crn,orn);
-	return;
-    }
-}
-
-void
-shift(char *op, int reg)
-{
-    if (reg>=0) {
-	use_register(lreg,REG_03,1);
-    } else {
-	use_register(dreg,REG_03,0);
-    }
-    /*printf("\t%s %%cl,%s\n",op,crn);*/
-}
-
-void
-ld_indexx(int byte, int n, char *xrn)
-{	
-    char *op;
-
-    op = byte ? "lb" : "lw";
-    if (n) 
-	    printf("\t%s\t%s,%d(%s)\n",op,crn,n,xrn);
-    else
-	    printf("\t%s\t%s,0(%s)\n",op,crn,xrn);
-}
-
-void
-st_indexx(int byte, int n, char *xrn)
-{	
-    char *op;
-
-    op = byte ? "sb" : "sw";
-    if (n) 
-	    printf("\t%s\t%s,%d(%s)\n",op,crn,n,xrn);
-    else
-	    printf("\t%s\t%s,0(%s)\n",op,crn,xrn);
-}
-
-void
-indexy(char *op, char *gvar)
-{
-    printf("\t%s %s,%s\n",op,crn,gvar);
-}
-
-void
-cmpdimm(int e, int csreg)
-{
-    /* used in dosiwtch() */
-    use_register(creg,csreg,0);
-    /*printf("\tcmpl $%d,%s\n",e,crn);*/
-}
-
-void
-opening(char *filename)
-{
-    printf("\t.file \t1 \"%s\"\n",filename);
-    printf(" # GNU C 2.7.2.2 [AL 1.1, MM 40] Sony PlayStation compiled by GNU C\n\n");
-    printf(" # Cc1 defaults:\n\n");
-    printf(" # Cc1 arguments (-G value = 8, Cpu = 3000, ISA = 1):\n");
-    printf(" # -msoft-float -quiet -dumpbase -o\n\n");
-    printf(" # gcc2_compiled.:\n");
-    printf(" # __gnu_compiled_c:\n");
-
-    printf("\t.text\n");
-    emit_init();
-}
-
-void
-closing(void)
-{
-    global_table();
-}
-
-void
-jmp_label(int l)
-{
-    printf("\tjmp\t_%d\n",l);
-}
-
-void
-jmp_eq_label(int l)
-{
-     printf("\tj\t_%d\n",l);
-}
-
-void
-rexpr(int e1, int l1, char *s)
-{       
-    g_expr(list3(SUB,cadr(e1),caddr(e1)));
-    printf("\t%s\t%s,%s,$L%d\n",s,crn,crn,l1);
-}
-
-void
-jcond(int l, char cond)
-{       
-    printf("\t%s\t%s,%s,$L%d\n",cond?"bne":"beq",crn,crn,l);
-}
-
-void
-jmp(int l)
-{       
-    control=0;
-    printf("\tj\t$L%d\n",l);
-    /* align? */
-}
-
-int
-fwdlabel(void)
-{       
-    return labelno++;
-}
-
-void
-fwddef(int l)
-{       
-    control=1;
-    printf("$L%d:\n",l);
-}
-
-int
-backdef(void)
-{       
-    control=1;
-    printf("$L%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_comment(char *s)
-{
-     printf("# %s",s);
-}
-
-void
-gen_source(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 disp0,int args)
-{
-    if(disp0) {
-	printf("\tsubl $%d,%%esp\n",-disp0);
-    }
-}
-
-void
-code_leave(char *name)
-{
-    local_table();
-    printf("$L%d:\n",labelno);
-    printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
-    labelno++;
-}
-
-void
-enter(char *name, int disp)
-{
-    int a,b,i;
-    a = b = 0;
-
-    /*printf("\t.text\n");
-    printf("\t.align \t2\n");
-    if (stmode!=STATIC)
-	printf("\t.globl \t%s\n",name);*/
-    printf("%s:\n",name);
-
-    printf("\t.frame \t$fp,%d,$31\n",-disp+save_reg*size_of_int);
-    
-
-    if(disp) a = 8;
-    
-    printf("\t.mask \t0x%d0000000,-8\n",a);
-    printf("\t.fmask \t0x00000000,0\n");
-
-    if(disp){
-	printf("\tsubu \t$sp,$sp,%d\n",-disp+save_reg*size_of_int);
-	printf("\tsw\t$31,%d($sp)\n",-disp+4*save_reg1);
-	save_reg1--;
-    }
-    for(i=save_reg1;i==0;i--) {
-        printf("\tsw\t$%d,%d($sp)\n",16+i,-disp+4*i);
-    }
-
-    /*if(strcmp("main",name))
-	printf("\tjal \t%s_0\n",name);
-    else 
-	printf("\tjal \t__%s_0\n",name);*/
-
-    printf("\tjal \t%s_0\n",name);
-
-    printf("\t.end \t%s\n",name);
-    printf("\t.sdata\n");
-    printf("\t.align 2\n");
-
-    save_reg = 0;
-    save_reg1 = 0;
-}
-
-/* void
-enter_no(char *name, int disp)
-{
-
-    printf("\t.align \t2\n");
-    if (stmode!=STATIC)
-    printf("\t.globl \t%s\n",name);
-
-    printf("\t.ent \t%s\n",name);
-    printf("%s_0:\n",name);
-}
-
-*/
-void
-enter1(int disp)
-{
-    if(disp) printf("\tsubu \t$sp,$sp,%d\n",-disp+save_reg*size_of_int);
-    
-}
-
-void
-leave(int control, char *name)
-{
-    int i;
-
-    if (control)
-	use_register(creg,REG_04,1);
-    if (retcont) {
-	if (control)
-	    jmp(retlabel);
-	fwddef(retcont);
-	use_register(creg,REG_04,0);
-	printf("\tmove\t%s,%s\n",crn,reg_name[REG_05]);
-    }
-    fwddef(retlabel);
-    use_register(creg,REG_04,0);
-    save_reg1 = save_reg;
-    printf("\tmove\t$sp,$fp\n");
-
-    printf("\tlw\t$31,%d($sp)\n",-disp+4*save_reg);
-    save_reg--;
-    for(i=save_reg;i==0;i--) {
-	printf("\tlw\t$%d,%d($sp)\n",16+i,-disp+4*i);
-    }
-
-
-    if(disp) printf("\taddu \t$sp,$sp,%d\n",-disp+save_reg*size_of_int);  
-    printf("\tj\t$31\n");
-
-    local_table();
-    printf("$L%d:\n",labelno);
-    labelno++;
-}
-
-
-void
-ret(void)
-{       
-    use_register(creg,REG_04,1);
-    jmp(retlabel); 
-}
-
-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)  { /* global */
-	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.word %s\n",caddr(cadr(e)));
-	    } else if(car(e)==FNAME) {
-		printf("\t.word %s\n",((NMTBL *)cadr(e))->nm);
-            } else if(car(e)==STRING) {       
-		if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
-		    l = fwdlabel();
-		    printf("\t.word _%d\n",l);
-		    printf("$L%d:\n",l);
-		    output_mode = RODATA_EMIT_MODE;
-		}
-		ascii((char *)cadr(e));
-	    } else error(TYERR);
-        }
-    } else {
-	/* if (n->sc!=LVAR) { error(TYERR); return; } */
-        if(car(e)==CONST) {       
-		printf("\tmove\t%s,%d\n",crn,cadr(e));
-		printf("\t%s\t%s,%d($fp)\n",t==CHAR?"lb":"lw",crn,n->dsp);
-        } else if(t!=CHAR) {       
-		if(car(e)==ADDRESS&&car(cadr(e))==GVAR)
-		    printf("\tlw\t%s,0(%s)\n",crn,caddr(e));
-                else if(car(e)==FNAME)
-		    printf("\tlw\t%s,0(%s)\n",crn,((NMTBL *)cadr(e))->nm);
-		else if(car(e)==STRING) {       
-		    string(e);
-                } else error(TYERR);
-		printf("\tlw\t%s,%d($fp)\n",crn,n->dsp);
-        }
-    }
-}
-
-void
-emit_data_closing(NMTBL *n)
-{
-    int lb;
-    if (mode=GDECL) {
-	data_mode(0);
-	lb=fwdlabel();
-	printf("$L%d:\n",lb);
-	printf("\t.size\t%s,_%d-%s\n",n->nm,lb,n->nm);
-    }
-}
-
-void
-global_table(void)
-{
-    NMTBL *n;
-    for(n=ntable;n < &ntable[GSYMS];n++) {
-	if (n->sc == GVAR && n->dsp != -1) {
-	    /* n->dsp = -1 means initialized global */
-	    printf("\n\t.comm \t%s,%d\n",n->nm,size(n->ty));
-	}
-    }
-}
-
-void
-local_table(void)
-{
-    NMTBL *n;
-    /* static local variables */
-    for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) {
-	if (n->sc == GVAR) {
-	    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 (l<0) {
-	if (fnptr->sc==CODE)
-	    return l+code_disp_offset;
-	else
-	    return l+disp_offset;
-    } else {
-	if (fnptr->sc==CODE)
-	    return -l+code_arg_offset;
-	else
-	    return l+arg_offset;
-    }
-}
-
-/* end */
--- a/mc-nop-386.c	Wed Nov 01 15:33:37 2006 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1962 +0,0 @@
-/* Micro-C Code Generatation Part for intel386 */
-/* $Id$ */
-
-#define EXTERN extern
-#include "mc.h"
-
-extern int  get_register_var(void);
-extern void bexpr(int e1, char cond, int l1);
-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 leave(int control,char *name) ;
-extern void def_label(int cslabel, int dlabel) ;
-extern void emit_data(int e, int t, 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 jcond(int l, char cond);
-extern void jmp(int l);
-extern void opening(char *filename);
-extern void ret(void);
-extern int assign_expr0(int e,int e1,int type,int type1);
-extern int integral(int t);
-extern void tree_print_t(int e,int t);
-extern int rvalue_t(int e,int t);
-
-static int edx_setup() ;
-static int	lvar(int l);
-static void	jump(int e1, int env);
-static void    data_mode(char *name);
-static void    text_mode(void);
-static void assign(int e1);
-static void assop(int e1);
-static void b_expr(int e1, char cond, int l1,int err);
-static void emit_push(void);
-static void free_register(int i);
-static void function(int e1);
-static void global_table(void) ;
-/* static void indexy(char *op, char *gvar); */
-/* static void jmp_eq_label(int l); */
-/* static void jmp_label(int l); */
-static void ld_indexx(int byte, int n, int xreg);
-static void local_table(void) ;
-static void machinop(int e1);
-static void rexpr(int e1, int l1, char *s);
-static void rindirect(int e1);
-static void sassign(int e1);
-static void shift(char *op, int xreg) ;
-/* static void st_indexx(int byte, int n, int xreg); */
-static void string(int e1);
-static void tosop(int op,int reg);
-static void edx_cleanup();
-static void use_register(int virt, int real, int move);
-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 void error(int n);
-extern int fwdlabel(void);
-extern void fwddef(int l);
-extern int backdef(void);
-extern int size(int t);
-extern int list4(int e1, int e2, int e3,int e4);
-extern int list3(int e1, int e2, int e3);
-extern int list2(int e1, int e2);
-extern int scalar(int);
-extern int reverse0(int);
-extern void remove0(int *list,int element); 
-extern int append4(int target,int t,int ty,int e1);
-
-#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;    
-
-static int  creg;     /* current register */
-static int  dreg;     /* temporary register */
-static 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];
-
-/*
-    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]]
- */
-
-#define MAX_MAX 10
-static int rname[MAX_MAX];
-static int regs[MAX_MAX];       /* 使われているレジスタを示すフラグ */
-static int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
-static int regv[MAX_MAX];       /* 値が入っているかどうか */
-
-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 */
-    }
-}
-
-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;    
-}
-
-static
-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;    
-}
-
-static 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;
-}
-
-static 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();
-    use_register(creg,REG_EAX,0);
-    regv[dreg]=0;
-    creg_regvar = -1;
-    register_usage("gexpr_init");
-}
-
-
-void 
-emit_init(void)
-{
-    int i;
-    for(i=0;i<REAL_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;
-	}
-    }
-    /* if (real_v == -1)
-	error(-1); */
-    return real_v;
-}
-
-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);
-}
-
-int 
-pop_register(void)
-{     /* レジスタから値を取り出す */
-    return reg_stack[--reg_sp];
-}
-
-int
-stack_used(void) {
-    return reg_stack[--reg_sp]<0;
-}
-
-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;
-}
-
-static void
-emit_pop_free(int xreg)
-{
-    if (xreg==dreg) {
-	regv[dreg]=0;
-    } else if (xreg!=-1) {
-	free_register(xreg);
-    }
-}
-
-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
-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*/;
-    char *xrn;
-    NMTBL *n;
-
-    if (chk) return;
-    e2 = cadr(e1);
-    switch (car(e1)){
-    case GVAR:   
-	/* use_pointer(creg,0); */
-	printf("\tmovl $%s,%s\n",(char *)caddr(e1),register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case RGVAR:
-	/* use_pointer(creg,0); */
-	printf("\tmovl %s,%s\n",(char *)caddr(e1),register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case CRGVAR:
-	printf("\tmovsbl %s,%s\n",(char *)caddr(e1),register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case LVAR:
-	/* use_pointer(creg,0); */
-	printf("\tlea %d(%%ebp),%s\n",lvar(e2),register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case REGISTER:
-	/* this is of course redundant... */
-	/* we can use rname for this? */
-	/* or why not creg=e2? */
-	printf("\tmovl %s,%s\n",register_name(e2,0),register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case RLVAR:
-	printf("\tmovl %d(%%ebp),%s\n",lvar(e2),register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case CRLVAR:
-	printf("\tmovsbl %d(%%ebp),%s\n",lvar(e2),register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case FNAME:
-	printf("\tmovl $%s,%s\n",((NMTBL *)e2)->nm,register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case CONST:  /* 代入する値が0でも特別な処理はしない */
-	printf("\tmovl $%d,%s\n",e2,register_name(creg,0));
-	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);
-	/* use_data_reg(creg,1); */
-	printf("\tnegl %s\n", register_name(creg,0));
-	return;
-    case BNOT:   /* ~ */
-	g_expr(e2);
-	/* use_data_reg(creg,1); */
-	printf("\tnotl %s\n", register_name(creg,0));
-	return;
-    case LNOT:   /* !  */
-	g_expr(e2);
-	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));
-	return;
-    case PREINC:
-	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);
-	return;
-    case POSTINC:
-	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);
-	return;
-    case CPOSTINC:
-	/*   char *p; *p++ */
-	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);
-	return;
-    case CPREINC:
-	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));
-	return;
-    case CPOSTDEC:
-	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));
-	return;
-    case CPREDEC:
-	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);
-	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);
-	use_register(creg,REG_EAX,0);
-	g_expr(caddr(e1));
-	/* e4 = rname[creg]; this is a bad idea */
-	use_register(creg,REG_EAX,1);
-	jmp(e3=fwdlabel());
-	fwddef(e2);
-	use_register(creg,REG_EAX,0);
-	g_expr(cadddr(e1));
-	/* use_register(creg,e4,1); */
-	use_register(creg,REG_EAX,1);
-	fwddef(e3);
-	return;
-    case STASS: 
-	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();
-	printf("\tleal _%d,%s\n",retcont,register_name(creg,0));
-	regv[creg]=1;
-	return;
-    case ENVIRONMENT:
-	printf("\tmovl %%ebp,%s\n",register_name(creg,0));
-	regv[creg]=1;
-	return;
-    default:
-	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);
-	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,cond?"g":"le");
-	return;
-    case UGT:
-	rexpr(e1,l1,cond?"a":"be");
-	return;
-    case GE:
-	rexpr(e1,l1,cond?"ge":"l");
-	return;
-    case UGE:
-	rexpr(e1,l1,cond?"ae":"b");
-	return;
-    case LT:
-	rexpr(e1,l1,cond?"l":"ge");
-	return;
-    case ULT:
-	rexpr(e1,l1,cond?"b":"ae");
-	return;
-    case LE:
-	rexpr(e1,l1,cond?"le":"g");
-	return;
-    case ULE:
-	rexpr(e1,l1,cond?"be":"a");
-	return;
-    case EQ:
-	rexpr(e1,l1,cond?"e":"ne");
-	return;
-    case NEQ:
-	rexpr(e1,l1,cond?"ne":"e");
-	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:
-	printf("\tcmpb $0,%s\n",(char *)caddr(e1));
-	jcond(l1,cond);
-	return;
-    case CRLVAR:
-	printf("\tcmpb $0,%d(%%ebp)\n",lvar(e2));
-	jcond(l1,cond);
-	return;
-    case RGVAR:
-	printf("\tcmpl $0,%s\n",(char *)caddr(e1));
-	jcond(l1,cond);
-	return;
-    case RLVAR:
-	printf("\tcmpl $0,%d(%%ebp)\n",lvar(e2));
-	jcond(l1,cond);
-	return;
-    case REGISTER:
-	printf("\tcmpl $0,%s\n",register_name(e2,0));
-	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);
-	printf("\tcmpl $0,%s\n",register_name(creg,0));
-	jcond(l1,cond);
-	return;
-    }
-}
-
-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;
-}
-
-/* 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,virtual((regs++)+REG_ESI)),
-		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;
-	jump_offset = 0;
-    } else {
-	if (disp_offset-arg_size<disp) disp = disp_offset-arg_size;
-	jump_offset = 0;
-    }
-
-    /*  複雑な式を前もって計算しておく     */
-    /*  必要なら局所変数を用いる。         */
-    /*  局所変数へのオフセットを覚えておく */
-
-    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+jump_offset;
-	    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);
-	printf("\tmovl %s,%%ebp\n",register_name(e3,0));
-	emit_pop_free(e3);
-    } else if (fnptr->sc==FUNCTION) {
-	printf("\tlea %d(%%ebp),%%ebp\n",disp_offset);
-    } 
-
-    if (car(e2) == FNAME) {	
-	printf("\tjmp %s\n",code0->nm);
-    } else {
-	e2 = emit_pop(0);
-	printf("\tjmp *%s\n",register_name(e2,0));
-	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
-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));
-}
-
-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)
-{
-    char *op;
-    int e2,e3,e4,byte;
-
-    op = ((byte=(car(e1) == CASS))? "movb" : "movl");
-    /*    e2=e4 */
-    e2 = cadr(e1);
-    e3 = cadr(e2);
-    e4 = caddr(e1);
-    switch(car(e2)) {
-    case GVAR:      /*   i=3 */
-            g_expr(e4);
-            if (byte) use_data_reg(creg,1);
-            printf("\t%s %s,%s\n",op,register_name(creg,byte),(char *)caddr(e2));
-            return;
-    case LVAR:
-            g_expr(e4);
-            if (byte) use_data_reg(creg,1);
-            printf("\t%s %s,%d(%%ebp)\n",op,register_name(creg,byte),lvar(cadr(e2)));
-            return;
-    case REGISTER:
-            g_expr(e4);
-	    if (creg!=cadr(e2))
-		printf("\tmovl %s,%s\n",register_name(creg,0),register_name(cadr(e2),0));
-            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);
-    printf("\t%s %s,(%s)\n",op,register_name(creg,byte),register_name(e2,0));
-    emit_pop_free(e2);
-    regv[creg]=1;
-    return;
-}
-
-void
-assop(int e1)
-{
-    int e2,e3,byte,op,reg;
-    char *xrn;
-    int xreg,edx;
-
-    /*   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) {
-	xreg = creg;
-	creg = reg = cadr(e2);
-	tosop(op,xreg);
-	creg = xreg;
-	printf("\tmovl %s,%s\n",register_name(reg,0),register_name(creg,0));
-	regv[creg]=1;
-	return;
-    }
-    emit_push();
-    g_expr(e2);
-    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);
-    regv[creg]=1;
-    return;
-}
-
-
-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);
-     */
-}
-
-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_comment(char *s)
-{
-     printf("## %s",s);
-}
-
-void
-gen_source(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)
-{
-    disp=(disp-(size_of_int-1))&(-(size_of_int-1));
-    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");
-    disp=(disp-(size_of_int-1))&(-(size_of_int-1));
-    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
-ret(void)
-{       
-    use_register(creg,REG_EAX,1);
-    jmp(retlabel); 
-}
-
-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 */