changeset 89:917947ffeb7c

power pc version
author kono
date Thu, 06 Mar 2003 23:47:42 +0900 (2003-03-06)
parents 5c8553d7f984
children 07e3113c3c13
files Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc.h test/basic.c
diffstat 8 files changed, 2122 insertions(+), 248 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Wed Mar 05 23:07:00 2003 +0900
+++ b/Changes	Thu Mar 06 23:47:42 2003 +0900
@@ -1920,3 +1920,91 @@
 FCONST �Ȥ���3���ǽ��褿�͡�
 
 (gcc �������ä������������ʤ�...)
+ goto.c ���̤�ʤ��ʤäƤ�ʡ�
+
+Thu Mar  6 14:00:13 JST 2003
+
+PowerPC��non-lazy pointer�äơ��ơ��֥�����äƤ��Ƥ������
+�߹�������ʤΤ͡����ä��󡢥쥸�������ɤ߹�����顢������
+���Ѥ�������ɤ��餷�����Ȥ������Ȥϡ�code_gvar �˥���å���
+����ʤ��Ȥ����ʤ��������� RLU �Ǥ���? (���ɤ�����)
+�Ǥ⡢�������ʤ��ȡ�
+   i = i+1;
+�ʤ�ƤΤǤ⡢�Ҥɤ��ܤˤ��äƤ��ޤ���
+
+local variable ��ǽ�� move mutilple register ����Ⱦ��
+�쥸�������ɤ߹��󤸤㤦�ߤ����͡�pointer �ǻ��Ȥ�����
+�����Ǥ��礦���ɡ��ޤ���31�Ĥ⤢��С������������Ȥ�
+���Ƥ⤢�ޤ�����ʤ��Τ����Τ�ʤ����ɡ�
+
+creg ���˲����ʤ������ˤ���С������Ϥޤ��ˤʤ�󤸤�ʤ�?
+(IA32�Ǥϡ�������񤷤�����)
+
+Thu Mar  6 20:50:24 JST 2003
+
+��äѤꡢ�Ȥä�ʬ����register����¸����褦�ʥ����ɤ�
+�ʤ�ߤ�����one path �ǡ�����򤹤뤿��ˤϡ�
+        .align 2
+_main0__:
+        lwz r5,2136(r1)
+        addi r1,r1,2128
+        lmw r23,-36(r1)
+        mtlr r5
+        blr
+        .align 2
+        .globl _main0
+_main0:
+        mflr r2
+        stmw r30,-8(r1)
+        stw r2,8(r1)
+        li r11,0
+        stwu r1,-480(r1)
+        li r2,100
+        mtctr r2
+        mr r30,r3
+        addi r0,r1,64
+        mr r9,r0
+        b _main0__;
+�Ȥ����������ˤ��뤷���ʤ��͡�
+
+���Ȱ����ϡ��쥸�������Ѥ�褦�ˤʤäƤ���ߤ���������... r3 ����?
+
+        mflr r31
+        li r0,7
+        stw r0,56(r1)
+
+������8�ĤޤǤϥ쥸�������Ѥ�ߤ����͡�
+r3-r10 ���͡�
+
+��¤�Τ�register�˥��ԡ������Τ��������ơ�����¦�Ǽ����
+���ԡ���Ԥ��櫓���͡���Ƭ��return struct�ؤΥݥ��󥿤�����Τ�
+Ʊ����
+
+(������memcpy���ޤ����...)
+
+��ư��������쥸�����Ϥ���������f1���顣(�ʤ�ۤ�)
+
+saveFP�äƤΤ�ƤӽФ��ơ� f24-f31��save����餷����
+(31-24)*8 �����ʤ���?
+
+pointer �Τ��Ȥ�ͤ���ȡ��쥸�������Ȥޤ�����Τ⤢��
+�櫓�����ɡ����ɥ쥹�����Ƥ���Ǵ֤˹礦�󤸤�ʤ�?
+����ʤɤϡ���Ȥ�Ȥ��������������(?)�ϳ��ݤ���Ȥ��ơ�
+
+���������դˡ�r3-r10 �ϰ����Ǥʤ���в����Ƥ��ɤ��櫓����
+(�����r9�Ȥ��ɤ��Ȥ��Ƥ���櫓��...)
+�Ȥ������Ȥ�­��ʤ��ʤä��顢�����򥻡��֤�����ɤ��櫓�͡�
+(�äƤ��Ȥϡ�LVAR ���� REGISTER �äƤ�������������󤸤��...
+�ޤ������������ɤ�...)
+����� get_register �����ɤ�������
+
+�ɤ��⡢r11-r12  ������ϼ�ͳ�˻ȤäƤ���餷����
+
+�������äƤ�������Ǵؿ��ƽФ�����Ȥ��ϡ��ɤ������?
+r30�ʤɤ˰�ư����Τ�?
+
+�ʤ��Τ�󤱤ɡ�in file call name �� out file call name ��
+�㤦�ߤ����͡�(sigh...) ����ʤΤʤ�Ȥ��ʤ�Τ��ʤ���
+������stub �ˤ��Ƥ����ơ�.set �ǽ񤭴�����Ȥ�����⤢�뤱�ɡ�
+
+(�������˰����ǤϤǤ��ʤ���...)
--- a/mc-code-ia32.c	Wed Mar 05 23:07:00 2003 +0900
+++ b/mc-code-ia32.c	Thu Mar 06 23:47:42 2003 +0900
@@ -100,8 +100,7 @@
 void code_leave(char *name);
 int lvar(int l);
 void global_table(void);
-
-char * fstore(int d);
+int virtual(int real);
 char * fload(int d);
 int code_d1(double d);
 int code_d2(double d);
@@ -163,6 +162,170 @@
     return virtual(r+REG_ESI);
 }
 
+
+
+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;
+}
+
+void
+set_register_var() {
+}
+
+void
+code_arg_register(int args)
+{
+    NMTBL *n;
+    if (args) {
+	/* process in reverse order */
+        n = (NMTBL*)caddr(args);
+        if(n->sc==REGISTER) {
+            if ((n->dsp = get_register_var()) <0) {
+                error(-1); return;
+            }
+            use_register_var(n->dsp); /* it has now value in it */
+        }
+	code_arg_register(cadr(args));
+    }
+}
+
+
+void
+register_usage(char *s)
+{
+    int i;
+    if (chk) return;
+    printf("# %d: %s:",lineno,s);
+    printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0));
+    for(i=0;i<MAX_REGISTER;i++) {
+	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);
+    }
+}
+
+
 int
 get_register_var(void)
 {
@@ -374,7 +537,8 @@
 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("\tmovbl (%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;
     } 
@@ -391,7 +555,8 @@
 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));
+	printf("\tmovsbl (%s),%s\n",register_name(cadr(e2),0),
+		register_name(creg,0));
 	return;
     } 
     g_expr(e2);
@@ -403,7 +568,8 @@
 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("\tmovsbl (%s),%s\n",register_name(cadr(e2),0),
+		register_name(creg,0));
 	printf("\tdecl %s\n",register_name(cadr(e2),0));
 	return;
     } 
@@ -417,8 +583,8 @@
 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;
+	printf("\tmovsbl (%s),%s\n",register_name(cadr(e2),0),
+		register_name(creg,0));
     } 
     g_expr(e2);
     emit_push();
@@ -894,7 +1060,7 @@
     case ADD:
 	printf("\taddl %s,%s\n",orn,crn);
 	break;
-    case SUB:
+    case SUB: case CMP:
 	printf("\tsubl %s,%s\n",orn,crn);
 	break;
     case BAND: 
@@ -1023,9 +1189,9 @@
 }
 
 void
-rexpr(int e1, int l1, char *s)
+rexpr(int e1, int l1, char *s,int t)
 {       
-    g_expr(list3(SUB,cadr(e1),caddr(e1)));
+    g_expr(list3(CMP,cadr(e1),caddr(e1)));
     printf("\tj%s\t_%d\n",s,l1);
 }
 
@@ -1472,8 +1638,7 @@
     case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break;
     case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break;
     case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break;
-    case DCOMP: 
-	/* printf("\tfxch\t%%st(1)\n"); */
+    case DCMP: 
 	printf("\tfucompp\n");
 	printf("\tfnstsw\t%%ax\n");
 	break;
@@ -1517,7 +1682,7 @@
 void
 drexpr(int e1, int e2,int l1, int op)
 {       
-    g_expr(list3(DCOMP,e1,e2));
+    g_expr(list3(DCMP,e1,e2));
     switch(op) {
 	case DOP+GE:
 	    printf("\ttestb\t$5,%%ah\n");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mc-code-powerpc.c	Thu Mar 06 23:47:42 2003 +0900
@@ -0,0 +1,1733 @@
+/* Micro-C Code Generatation Part for Power PC (Mac OS X) */
+/* $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   <-- r30
+                                           -12  -4 local1
+                                            -8  8  arg3
+                                            -4  4  arg2
+                                             0  0  arg1
+         local2     -20 4                    0    (r5)
+         local1 <-- -16 0 local variable     0    (r4)
+                    -12  <- disp_offset          %ebp
+        r30 (sp)     -8
+                      0   <- r1
+        r1  (fp)      8   <- arg_offset
+          arg1        8 0
+          arg2       12 4
+            see enter/enter1/leave           see code_enter
+
+     r0    link register
+     r30   stack pointer
+     r31   0
+     r1    frame pointer
+ */
+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 size_of_float = 4;
+int size_of_double = 8;
+int size_of_longlong = 8;
+int endian = 0;
+int MAX_REGISTER=30;         /* PowerPC�Υ쥸������10�ĤޤǻȤ�*/
+int REAL_MAX_REGISTER=32;    /* PowerPC�Υ쥸������32�Ȥ�������*/
+int MAX_REGISTGER_VAR=30-10;    
+int MAX_FREGISTER=30;
+
+#define REG_fp   1
+#define REG_sp   30
+#define REG_VAR_BASE 30
+#define REG_ARG_BASE 3 
+#define REG_ARG_MAX  10 
+#define FREG_ARG_BASE 1 
+#define FREG_ARG_MAX  13 
+
+int reg_sp=REG_sp;
+
+static char *reg_name[] = {
+    "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9",
+    "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19",
+    "r20","r21","r22","r23","r24","r25","r26","r27","r28","r29",
+    "r30","r31"
+}; 
+
+static char *freg_name[] = {
+    "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9",
+    "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19",
+    "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29",
+    "f30","f31"
+}; 
+
+static char *creg_name[] = {
+    "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
+}; 
+
+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 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);
+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 code_opening(char *filename);
+void code_closing();
+void code_leave(char *name);
+int lvar(int l);
+void global_table(void);
+
+char * fstore(int d);
+char * fload(int d);
+int code_d1(double d);
+int code_d2(double d);
+
+void
+code_init(void)
+{
+    arg_offset = 8;
+    func_disp_offset = -12;
+    disp_offset = -12;
+    size_of_int = 4;
+    endian = 1;
+}
+
+#define register_name(i) reg_name[i]
+
+void
+gexpr_code_init(void){
+    regv[creg]=0;
+}
+
+int virtual(int real);
+char * fload(int d);
+int code_d1(double d);
+int code_d2(double d);
+
+
+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;
+}
+
+void
+set_register_var() {
+}
+
+void
+code_arg_register(int args)
+{
+    NMTBL *n;
+    if (args) {
+	/* process in reverse order */
+        n = (NMTBL*)caddr(args);
+        if(n->sc==REGISTER) {
+            if ((n->dsp = get_register_var()) <0) {
+                error(-1); return;
+            }
+            use_register_var(n->dsp); /* it has now value in it */
+        }
+	code_arg_register(cadr(args));
+    }
+}
+
+
+void
+register_usage(char *s)
+{
+    int i;
+    if (chk) return;
+    printf("# %d: %s:",lineno,s);
+    printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0));
+    for(i=0;i<MAX_REGISTER;i++) {
+	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
+register_var(int r) {
+    return virtual(REG_VAR_BASE-r);
+}
+
+int
+get_register_var(void)
+{
+    int i;
+    for(i=0;i<MAX_REGISTGER_VAR;i++) {
+	if (REG_VAR_Base-i<=REG_ARG_MAX)
+	    return -1;
+        if (! regs[REG_VAR_Base-i]) {    /* �Ȥ��Ƥ��ʤ��ʤ� */
+            regs[REG_VAR_Base-i]=1;      /* ���Υ쥸������Ȥ����Ȥ������ */
+            regv[REG_VAR_Base-i]=0;
+            return i;                    /* ���ξ���ɽ���ֹ���֤� */
+        }
+    }
+    return -1;
+}
+
+void 
+emit_push(void)
+{
+    int new_reg;
+    new_reg = get_register();
+    if(new_reg<0) {                     /* �⤦�쥸�������ʤ� */
+	if (reg_sp>=MAX_MAX) error(-1);
+	reg_stack[reg_sp++] =  -1;
+	printf("\tstwu %s,-%d(%s)\n",register_name(creg),
+             size_of_int,register_name(reg_sp));
+	/* creg is used soon, don't regv[creg]=0 */
+    } else {
+	reg_stack[reg_sp++] = creg;     /* push ���뤫���˥쥸������Ȥ� */
+	creg = new_reg;
+	regv[creg]=1;
+    }
+}
+
+int
+emit_pop()
+{
+    int xreg;
+    if ((xreg=pop_register())==-1) {
+	xreg=get_register();
+	if(!xreg) error(-1);
+	printf("\tlwz %s,(%s)\n",register_name(xreg),register_name(reg_sp);
+	printf("\taddis %s,%s,%d\n",
+                 register_name(reg_sp),register_name(reg_sp),size_of_int;
+	regv[xreg]=1;
+    } 
+    return xreg;
+}
+
+static char *code_base;
+
+#define MAX_PTR_CACHE 10
+
+int ptr_cache=0;
+
+int
+clear_ptr_cache()
+{
+    int ptcptr=ptr_cache;
+    while(ptcptr) {
+	if(car(ptcptr))
+	    free_register(caddr(ptcptr));
+	car(ptcptr)=0;
+	caddr(ptcptr)=0;
+	ptcptr=cadr(ptcptr);
+    }
+}
+
+int
+init_ptr_cache()
+{
+    int i;
+    for(i=0;i<MAX_PTR_CACHE;i++) {
+	ptr_cache=glist3(0,ptr_cache,0);
+    }
+}
+
+
+int
+get_ptr_cache(char *name)
+{
+    int r;
+    int ptcptr=ptr_cache;
+    int cache;
+    int i = 0;
+    int g = (int)name;
+    int p,p1;
+
+    while(ptcptr) {
+	if(car(ptcptr)==g) return caddr(ptcptr);
+	p1=p; p=ptcptr;
+	ptcptr=cadr(ptcptr);
+    }
+    cadr(p1)=0;            /* remove the last one */
+    cadr(p) = ptr_cache;   /* connect current queue to the last one */
+    ptr_cache = p;         /* now the last one is the top */
+    if (!caddr(p)) {
+	if((r=get_register())) {
+	    caddr(p)=r;
+	else
+	    r=creg;
+    }
+    rrn = register_name(r);
+    printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-%s)\n",
+	     rrn,(char *)g,code_base);
+    printf("\tlzw %s,lo16(L_%s$non_lazy_ptr-%s)(%s)\n",
+	     rrn,(char *)g,code_base,rrn);
+    return r;
+}
+
+void
+code_gvar(int e1) {
+    int r;
+    r = get_ptr_cache((char*)caddr(e1));
+    if(r!=creg)
+	printf("\tmr %s,%s\n",register_name(creg),register_name(r));
+    return;
+}
+
+void
+code_rgvar(int e1) {
+    printf("\tlwz %s,(%s)\n",register_name(creg),
+                             register_name(get_ptr_cache((char*)caddr(e1))));
+}
+
+void
+code_crgvar(e1){
+    printf("\tlbz %s,(%s)\n",register_name(creg),
+                             register_name(get_ptr_cache((char*)caddr(e1))));
+    printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
+}
+
+void
+code_lvar(int e2) {
+    printf("\tla %d(r1),%s\n",e2,register_name(creg));
+}
+
+
+void
+code_register(int e2) {
+    printf("\tmr %s,%s\n",register_name(creg),register_name(e2));
+}
+
+
+void
+code_rlvar(int e2) {
+    printf("\tlwz %d(r1),%s\n",e2,register_name(creg));
+}
+
+
+void
+code_crlvar(int e2) {
+    printf("\tlbz %d(r1),%s\n",e2,register_name(creg));
+    printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
+}
+
+
+void
+code_fname(char *e2) {
+    int r;
+    r = get_ptr_cache(e2);
+    if(r!=creg)
+	printf("\tmr %s,%s\n",register_name(creg),register_name(e2));
+    return;
+}
+
+
+void
+code_const(int e2) {
+    char *crn = register_name(creg);
+    if (-32768<e2&&e2<32768)
+	printf("\tli %s,%d\n",crn,e2);
+    else {
+	printf("\tlis %s,ha16(%d)\n",crn,e2);
+	printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2);
+    }
+}
+
+
+void
+code_neg() {
+    printf("\tneg %s,%s\n", register_name(creg), register_name(creg);
+}
+
+
+void
+code_not() {
+    printf("\tnor %s,%s,%s\n", 
+	register_name(creg), register_name(creg),register_name(creg));
+}
+
+
+void
+code_lnot() {
+    printf("\tsubfic r0,%s,0\n", register_name(creg));
+    printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg));
+}
+
+void
+code_preinc(int e1,int e2) {
+    char *xrn,*drn;
+    int i,dreg;
+    if (car(e2)==REGISTER) {
+	printf("\taddi %s,%s,%d\n", register_name(cadr(e2)));
+	printf("\tmr %s,%s\n",register_name(cadr(creg)),register_name(e2));
+	return;
+    } 
+    g_expr(e2);
+    xrn = register_name(creg);
+    dreg=get_register(); if (!dreg) error(-1);
+    drn = register_name(dreg);
+    printf("\tlwz %s,(%s)\n",drn,xrn);
+    printf("\taddi %s,%s,%d\n",drn,drn,caddr(e1));
+    printf("\tstw %s,(%s)\n",drn,xrn);
+    i=creg;creg=dreg;dreg=i;
+    regv[creg=1];
+    free_register(dreg);
+}
+
+
+void
+code_postinc(int e1,int e2) {
+    char *xrn,*crn,*nrn;
+    int dreg,nreg;
+    if (car(e2)==REGISTER) {
+	printf("\tmr %s,%s\n",register_name(creg),register_name(cadr(e2)));
+	printf("\taddi %s,%s,%d\n", 
+	    register_name(cadr(e2)),register_name(cadr(e2)));
+	return;
+    } 
+    g_expr(e2);
+    dreg=get_register(); if (!dreg) error(-1);
+    xrn = register_name(dreg);
+    nreg=get_register(); if (!nreg) error(-1);
+    nrn = register_name(nreg);
+    printf("\tlwz %s,(%s)\n",xrn,crn);
+    printf("\taddi %s,%s,%d\n",nrn,xrn,caddr(e1));
+    printf("\tstw %s,(%s)\n",nrn,crn);
+    i=creg;creg=dreg;dreg=i; 
+    free_register(nreg);
+    free_register(dreg);
+    regv[creg]=1;
+}
+
+
+void
+code_cpostinc(int e1,int e2) {
+    char *xrn,*crn;
+    int i,nreg,dreg;
+    if (car(e2)==REGISTER) {
+	printf("\tlbz %s,(%s)\n",register_name(creg),register_name(cadr(e2)));
+	printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
+	printf("\taddi %s,%s,%d\n", 
+	    register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
+	return;
+    } 
+    g_expr(e2);
+    crn = register_name(creg);
+    dreg=get_register(); if (!dreg) error(-1);
+    xrn = register_name(dreg);
+    nreg=get_register(); if (!nreg) error(-1);
+    nrn = register_name(nreg);
+    printf("\tlwz %s,(%s)\n",xrn,crn);
+    printf("\tlbz %s,(%s)\n",nrn,xrn);
+    printf("\textsb %s,%s\n",nrn,nrn);
+    printf("\taddi %s,%s,%d\n", xrn,xrn);
+    printf("\tstw %s,(%s)\n",xrn,crn);
+    i=creg;creg=nreg;nreg=i; 
+    free_register(nreg);
+    free_register(dreg);
+    regv[creg]=1;
+}
+
+
+void
+code_cpreinc(int e1,int e2) {
+    char *xrn,*crn;
+    int i,nreg,dreg;
+    if (car(e2)==REGISTER) {
+	printf("\tlbzu %s,%d(%s)\n",register_name(creg),caddr(e1),register_name(cadr(e2)));
+	printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
+	return;
+    } 
+    g_expr(e2);
+    crn = register_name(creg);
+    dreg=get_register(); if (!dreg) error(-1);
+    xrn = register_name(dreg);
+    nreg=get_register(); if (!nreg) error(-1);
+    nrn = register_name(nreg);
+    printf("\tlwz %s,(%s)\n",xrn,crn);
+    printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn);
+    printf("\tstw %s,(%s)\n",xrn,crn);
+    printf("\textsb %s,%s\n",nrn,nrn);
+    i=creg;creg=nreg;nreg=i; 
+    free_register(nreg);
+    free_register(dreg);
+    regv[creg]=1;
+}
+
+
+void
+code_cpostdec(int e1,int e2) {
+    char *xrn,*crn;
+    int i,nreg,dreg;
+    if (car(e2)==REGISTER) {
+	crn=register_name(creg);
+	xrn=register_name(cadr(e2));
+	printf("\tlbz %s,(%s)\n",crn,xrn);
+	printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1));
+	printf("\textsb %s,%s\n",crn,crn);
+	return;
+    } 
+    g_expr(e2);
+    crn = register_name(creg);
+    dreg=get_register(); if (!dreg) error(-1);
+    xrn = register_name(dreg);
+    nreg=get_register(); if (!nreg) error(-1);
+    nrn = register_name(nreg);
+    printf("\tlwz %s,(%s)\n",xrn,crn);
+    printf("\tlbz %s,(%s)\n",nrn,xrn);
+    printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1));
+    printf("\tstw %s,(%s)\n",xrn,crn);
+    printf("\textsb %s,%s\n",nrn,nrn);
+    i=creg;creg=nreg;nreg=i; 
+    free_register(nreg);
+    free_register(dreg);
+    regv[creg]=1;
+}
+
+
+void
+code_cpredec(int e1,int e2) {
+    char *xrn,*crn;
+    int i,nreg,dreg;
+    if (car(e2)==REGISTER) {
+	crn=register_name(creg);
+	xrn=register_name(cadr(e2));
+	printf("\tlbzu %s,%d(%s)\n",crn,caddr(e1),xrn);
+	printf("\textsb %s,%s\n",crn,crn);
+	return;
+    } 
+    g_expr(e2);
+    crn = register_name(creg);
+    dreg=get_register(); if (!dreg) error(-1);
+    xrn = register_name(dreg);
+    nreg=get_register(); if (!nreg) error(-1);
+    nrn = register_name(nreg);
+    printf("\tlwz %s,(%s)\n",xrn,crn);
+    printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn);
+    printf("\tstw %s,(%s)\n",xrn,crn);
+    printf("\textsb %s,%s\n",nrn,nrn);
+    i=creg;creg=nreg;nreg=i; 
+    free_register(nreg);
+    free_register(dreg);
+    regv[creg]=1;
+}
+
+
+void
+code_return() {
+    int r;
+    printf("\taddis %s,r31,ha16(_%d-%s)\n",crn,retcont,code_base);
+    printf("\tla %s,lo16(_%d-%s)(%s)\n",crn,retcont,code_base,crn);
+}
+
+
+void
+code_environment() {
+    printf("\tmr %s,r1\n",register_name(creg));
+}
+
+
+void
+code_bool(int e1) {
+    char *xrn;
+    int e2,e3;
+    b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
+    xrn = register_name(creg);
+    printf("\tli %s,0\n",xrn);
+    jmp(e3=fwdlabel());
+    fwddef(e2);
+    printf("\tli %s,1\n",xrn);
+    fwddef(e3);
+}
+
+char *
+code_gt(int cond) {
+    return (cond?"gt":"le");
+}
+
+char *
+code_ugt(int cond) {
+    return (cond?"gt":"le");
+}
+
+char *
+code_ge(int cond) {
+    return (cond?"ge":"lt");
+}
+
+char *
+code_uge(int cond) {
+    return (cond?"ge":"lt");
+}
+
+char *
+code_eq(int cond) {
+    return (cond?"eq":"ne");
+}
+
+void
+code_cmp_crgvar(int e1) {
+    int r;
+    char *crn = register_name(creg);
+    r = get_ptr_cache((char *)caddr(e1));
+    printf("\tlbz %s,(%s)\n",crn,register_name(r));
+    printf("\tcmpwi cr0,%s,0\n",crn);
+}
+
+
+void
+code_cmp_crlvar(int e1) {
+    char *crn = register_name(creg);
+    printf("\tlbz %s,%d(r1)\n",crn,e1);
+    printf("\tcmpwi cr0,%s,0\n",crn);
+}
+
+
+void
+code_cmp_rgvar(int e1) {
+    int r;
+    char *crn = register_name(creg);
+    r = get_ptr_cache((char *)caddr(e1));
+    printf("\tlwz %s,(%s)\n",crn,register_name(r));
+    code_cmp_register(creg);
+}
+
+
+void
+code_cmp_rlvar(int e1) {
+    char *crn = register_name(creg);
+    printf("\tlwz %s,%d(r1)\n",crn,e1);
+    code_cmp_register(creg);
+}
+
+
+void
+code_cmp_register(int e2) {
+    printf("\tcmpwi cr0,%s,0\n",register_name(e2));
+}
+
+
+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("\\0%c\n",34);
+}
+
+void
+string(int e1)
+{
+    char *s;
+    int i,lb;
+
+    s=(char *)cadr(e1);
+    printf(".data\t.cstring\n\t.align 2\n");
+    lb=fwdlabel();
+    printf("_%d:\n",lb);
+    ascii(s);
+    if (output_mode==TEXT_EMIT_MODE) {
+	printf(".text\n");
+    } else {
+	text_mode();
+    }
+    printf("\taddis %s,r31,ha16(_%d-%s)\n",crn,lb,code_base);
+    printf("\tla %s,lo16(_%d-%s)(%s)\n",crn,lb,code_base,crn);
+}
+
+#define MAX_COPY_LEN 20
+
+void 
+emit_copy(int from,int  to,int length,int offset,int value,int det)
+{
+    char *frn =	register_name(from);
+    char *trn =	register_name(to);
+    char *drn;
+    int fix = 0;
+    char *bcopy = "bcopy";
+    int dreg = get_regiter(); if (!dreg) error(-1);
+    drn	 = register_name(dreg);
+
+    /* length <0 means upward direction copy */
+    switch (length) {
+    case 0:	break;
+    case 1: case -1:
+	printf("\tlbz %s,%d(%s)\n",drn,offset,frn);
+	printf("\tstb %s,%d(%s)\n",drn,offset,trn);
+	break;
+    case 2: case -2:
+	printf("\tlhz %s,%d(%s)\n",drn,offset,frn);
+	printf("\tsth %s,%d(%s)\n",drn,offset,trn);
+	break;
+    case 4: case -4:
+	printf("\tlwz %s,%d(%s)\n",drn,offset,frn);
+	printf("\tstw %s,%d(%s)\n",drn,offset,trn);
+	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) {
+	    printf("\tli r5,%d\n",length);
+	    printf("\tmr r4,%s\n",trn);
+	    printf("\tmr r3,%s\n",frn);
+	    printf("\tbl L_%s$stub\n",bcopy);
+	    regist_extern_function(bcopy);
+	    break;
+	}
+    }
+    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("\taddi %s,%s,%d\n",trn,trn,fix);
+	if(creg!=to) {
+	    free_register(creg); creg=to;
+	}
+    }
+    free_register(dreg);
+    regv[from]=regv[to]=regv[dreg]=0;
+    regv[creg]=1;
+}
+
+int
+struct_push(int e4,int t) 
+{
+    int length,save,count;
+    int dreg; char *drn,*crn,*srn;
+    g_expr(e4);
+    length=size(t); 
+    if(length%size_of_int) {
+	length += size_of_int - (length%size_of_int);
+    }
+    dreg = get_regiter(); if (!dreg) error(-1);
+    drn = register_name(dreg);
+    crn = register_name(dreg);
+    srn = register_name(reg_sp);
+    for(count=0;length<MAX_COPY_LEN;count++,length-=size_of_int) {
+	if (length==0) {
+	    free_register(dreg);
+	    return count;
+	} else {
+	    printf("\tlwz %s,%d(%s)\n",drn,length-size_of_int,crn);
+	    printf("\tstwu %s,%d(%s)\n",drn,-size_of_int,srn);
+	}
+    }
+    printf("\taddis %s,%s,ha16(%d)\n",srn,,srn,length);
+    printf("\taddi %s,%s,lo16(%d)\n",srn,,srn,length);
+    /* downward direction copy */
+    printf("\tmr %s,%s\n",drn,srn);
+    emit_copy(creg,dreg,length,0,0,1);
+    /* we have value in creg, it may be changed */
+    if (dreg!=creg) free_register(dreg);
+    return length/size_of_int;
+}
+
+int
+arg_offset(int arg)
+{
+}
+
+void
+function(int e1)
+{
+    int e2,e3,e4,e5,nargs,t;
+    int reg_arg,freg_arg;
+    NMTBL *n;
+    e2 = cadr(e1);
+    nargs = 0;
+    reg_arg = REG_ARG_BASE;
+    freg_arg = FREG_ARG_BASE;
+    for (e3 = caddr(e1); e3; e3 = cadr(e3)) {	
+	t=caddr(e3);
+	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
+	if(scalar(t)) {
+	    g_expr(e4);
+	    if (reg_arg<REG_ARG_MAX)
+		printf("\tmr %s,%s\n",register_name(reg_arg),
+                                register_name(creg));
+	    else {
+		printf("\tstw %s,%d(r1)\n",register_name(creg),
+                                arg_offset(nargs));
+	    }
+	    nargs ++ ; reg_arg++;
+	} else if (t==DOUBLE||t==FLOAT) {
+	    g_expr(e4);
+	    nargs += size_of_double/size_of_int;
+	    if (fregv[freg_arg])
+		save_freg(freg_arg);
+	    fregv[freg_arg]=1;
+	    if (freg_arg<FREG_ARG_MAX)
+		printf("\tmr %s,%s\n",register_name(reg_arg++),
+                                register_name(freg));
+	    else if(t==DOUBLE) {
+		printf("\tstfd %s,%d(r1)\n",register_name(freg),
+                                arg_offset(nargs));
+		nargs+=size_of_double/size_of_int; 
+	    } else {
+		printf("\tstfs %s,%d(r1)\n",register_name(freg),
+                                arg_offset(nargs));
+		nargs+=size_of_float/size_of_int; 
+	    }
+	    freg_arg++;
+	    continue;
+	} 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);
+	regv[creg]=0;
+    } else {	
+	g_expr(e2);
+	regv[creg]=1;
+    }
+
+    if (car(e2) == FNAME) {	
+	printf("\tbl\tL_%s$stub\n",n->nm);
+    } else {
+	jmp=get_tmp_register();
+        jrn = register_name(jmp);
+	printf("\tmr %s,%s\n",jrn,crn);
+        printf("\tmtctr %s\n",jrn);
+        printf("\tbctrl\n");
+	free_register(jmp);
+    }
+    regv[creg]=1;
+}
+
+void
+code_frame_pointer(int e3) {
+    printf("\tmovl %s,r1\n",register_name(e3,0));
+}
+
+
+void
+code_fix_frame_pointer(int disp_offset) {
+    printf("\tla r1,%d(r1)\n",disp_offset);
+}
+
+
+void
+code_jmp(char *s) {
+    printf("\tb L_%s$stub\n",s);
+}
+
+
+void
+code_indirect_jmp(int e2) {
+    printf("\tmtctr %s\n",register_name(e2));
+    printf("\tbctr\n");
+}
+
+void
+rindirect(int e1)   /* *(p +5 ) */
+{
+    char *op;
+    int e2,e3,byte;
+    e3 = cadr(e2 = cadr(e1));
+    g_expr(e2);
+    switch (car(e1)) {
+    case FRINDIRECT: case DRINDIRECT:
+    printf("\t%s (%s)\n",fload(car(e1)==DRINDIRECT),register_name(creg));
+    break;
+    case CRINDIRECT: case RINDIRECT:
+    op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl");
+    printf("\t%s (%s),%s\n",op,register_name(creg),register_name(creg));
+    }
+}
+
+
+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),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));
+}
+
+
+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),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);
+    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));
+}
+
+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() */
+    if(chk) return;
+    use_register(creg,csreg,0);
+    printf("\tcmpl $%d,%s\n",e,register_name(creg));
+}
+
+void
+code_opening(char *filename)
+{
+    printf("\t.file \"%s\"\n",filename);
+    printf("\t.version\t\"01.01\"\n");
+    /* printf("gcc2_compiled.:\n"); */
+    printf(".text\n");
+}
+
+void
+code_closing()
+{
+    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)
+{       
+    if (chk) return;
+    printf("\tj%s\t_%d\n",cond?"ne":"e",l);
+}
+
+void
+jmp(int l)
+{       
+    control=0;
+    if (chk) return;
+    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)
+{
+    if (chk) return;
+    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&= -size_of_int;
+    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));
+	/* printf("\tleave\n"); */
+    }
+    fwddef(retlabel);
+    /* use_register(creg,REG_EAX,0); too late */
+    /* if(disp) printf("\taddl $%d,%%esp\n",-disp);  */
+    disp &= -size_of_int;
+
+    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;
+    double d;
+    float f;
+    char *name;
+    name = n->nm; 
+    if(mode!=GDECL)  { 
+	error(-1); return;
+    }
+    if (chk) 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 if (t==SHORT) {
+	    printf("\t.word %d\n",cadr(e));
+	    if (data_alignment>0) data_alignment++;
+	    gpc += 2;
+	} else {
+	    printf("\t.long %d\n",cadr(e));
+	    gpc += size_of_int;
+	}
+    } else if(t==DOUBLE) {       
+	d = dcadr(e);
+	printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d));
+    } else if(t==FLOAT) {       
+	f = dcadr(e);
+	printf("\t.long\t0x%x\n",*(int *)&f);
+    } 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 (chk) return;
+    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;
+    }
+}
+
+/* floating point */
+
+
+char *
+fstore(int d)
+{
+    return use?
+	(d?"fstl":"fsts"):
+	(d?"fstpl":"fstps")
+    ;
+}
+
+char *
+fstore_u(int d)
+{
+    return d?"fstpl":"fstps";
+}
+
+char *
+fload(int d)
+{
+    return d?"fldl":"flds";
+}
+
+
+void code_dassign_gvar(int e2,int d)
+{ 
+    printf("\t%s %s\n",fstore(d),(char *)caddr(e2)) ;
+}
+
+void code_dassign_lvar(int e2,int d)
+{ 
+    printf("\t%s %d(%%ebp)\n",fstore(d),e2);
+}
+
+void code_dassign(int e2,int d)
+{ 
+    printf("\t%s (%s)\n",fstore(d),register_name(e2,0));
+}
+
+static double d0 = 1.0;
+
+int
+code_d1(double d)
+{
+    int *i = (int *)&d0; int *j = (int *)&d;
+    return (i[1] == 0x3ff00000)?j[0]:j[1];
+}
+
+int
+code_d2(double d)
+{
+    int *i = (int *)&d0; int *j = (int *)&d;
+    return (i[1] == 0x3ff00000)?j[1]:j[0];
+}
+
+void code_dconst(int e2)
+{ 
+    int lb;
+    double d = dcadr(e2);
+
+    if (d==0.0) {
+	printf("\tfldz\n"); return;
+    }
+    if (d==1.0) {
+	printf("\tfld1\n"); return;
+    }
+    printf(" \t.section\t.rodata\n\t.align 8\n");
+    lb=fwdlabel();
+    printf("_%d:\n",lb);
+    printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d));
+    if (output_mode==TEXT_EMIT_MODE) {
+	printf(".text\n");
+    } else {
+	text_mode();
+    }
+    printf("\tfldl _%d\n",lb);
+}
+
+void code_dneg()
+{ 
+    printf("\tfchs\n");
+}
+
+void code_d2i()
+{ 
+    /* fuck you! */
+    printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2);
+    printf("\tfnstcw  (%%esp)\n");
+    printf("\tmovl    (%%esp), %s\n",register_name(creg));
+    printf("\tmovb    $12, 1(%%esp)\n");
+    printf("\tfldcw   (%%esp)\n");
+    printf("\tmovl    %s, (%%ebp)\n",register_name(creg));
+    printf("\tfistpl  %d(%%esp)\n",size_of_int);
+    printf("\tfldcw   (%%esp)\n");
+    printf("\tpopl    %s\n",register_name(creg));
+    printf("\tpopl    %s\n",register_name(creg));
+}
+
+void code_i2d()
+{ 
+    printf("\tpushl %s\n",register_name(creg));
+    printf("\tfildl (%%esp)\n");
+    printf("\tlea %d(%%esp),%%esp\n",size_of_int);
+}
+
+void code_d2u()
+{ 
+    /* fuck you! */
+    printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3);
+    printf("\tfnstcw  (%%esp)\n");
+    printf("\tmovl    (%%esp), %s\n",register_name(creg));
+    printf("\tmovb    $12, 1(%%esp)\n");
+    printf("\tfldcw   (%%esp)\n");
+    printf("\tmovl    %s, (%%ebp)\n",register_name(creg));
+    printf("\tfistpll %d(%%esp)\n",size_of_int);
+    printf("\tfldcw   (%%esp)\n");
+    printf("\tmovl    %d(%%esp),%s\n",size_of_int,register_name(creg));
+    printf("\tlea %d(%%esp),%%esp\n",size_of_int*3);
+}
+
+void code_u2d()
+{ 
+    printf("\tpushl  %s\n",register_name(creg));
+    printf("\tpushl  %s\n",register_name(creg));
+    printf("\tmovl   $0, %d(%%esp)\n",size_of_int);
+    printf("\tfildll (%%esp)\n");
+    printf("\tlea %d(%%esp),%%esp\n",size_of_int*2);
+}
+
+void code_drgvar(int e2,int d)
+{ 
+    printf("\t%s %s\n",fload(d),(char *)caddr(e2)) ;
+}
+
+
+void code_drlvar(int e2,int d)
+{ 
+    printf("\t%s %d(%%ebp)\n",fload(d),e2);
+}
+
+void code_cmp_drgvar(int e2)
+{ 
+    printf("\tfcomp %s\n",(char *)caddr(e2)) ;
+}
+
+void code_cmp_drlvar(int e2)
+{ 
+    printf("\tfcomp %d(%%ebp)\n",e2);
+}
+
+void dtosop(int op,int e1)
+{ 
+    switch(op) {
+    case DADD: printf("\tfaddp %%st,%%st(1)\n"); break;
+    case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break;
+    case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break;
+    case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break;
+    case DCOMP: 
+	/* printf("\tfxch\t%%st(1)\n"); */
+	printf("\tfucompp\n");
+	printf("\tfnstsw\t%%ax\n");
+	break;
+    }
+}
+
+void
+code_dassop(int op,int d) {
+    /* we have lvalue in creg, applied floating value is in %st(0) */
+    printf("\t%s (%s)\n",fload(d),register_name(creg));
+    dtosop(op,0);
+    printf("\t%s (%s)\n",fstore(d),register_name(creg));
+}
+
+void
+code_dpreinc(int e1,int e2,int d) {
+    g_expr(e2);
+    printf("\t%s (%s)\n",fload(d),register_name(creg));
+    printf("\tfld1\n");
+    if (caddr(e1)>0)
+	printf("\tfaddp %%st,%%st(1)\n");
+    else
+	printf("\tfsubrp %%st,%%st(1)\n");
+    printf("\t%s (%s)\n",fstore(d),register_name(creg));
+}
+
+void
+code_dpostinc(int e1,int e2,int d) {
+    g_expr(e2);
+    printf("\t%s (%s)\n",fload(d),register_name(creg));
+    if (use)
+	printf("\t%s (%s)\n",fload(d),register_name(creg));
+    printf("\tfld1\n");
+    if (caddr(e1)>0)
+	printf("\tfaddp %%st,%%st(1)\n");
+    else
+	printf("\tfsubrp %%st,%%st(1)\n");
+    printf("\t%s (%s)\n",(use?fstore_u(d):fstore(d)),register_name(creg));
+}
+
+void
+drexpr(int e1, int e2,int l1, int op)
+{       
+    g_expr(list3(DCOMP,e1,e2));
+    switch(op) {
+	case DOP+GE:
+	    printf("\ttestb\t$5,%%ah\n");
+	    printf("\tjne\t_%d\n",l1);
+	    break;
+	case DOP+GT:
+	    printf("\ttestb\t$69,%%ah\n");
+	    printf("\tjne\t_%d\n",l1);
+	    break;
+	case DOP+EQ:
+	    printf("\tandb\t$69,%%ah\n");
+	    printf("\txorb\t$64,%%ah\n");
+	    printf("\tjne\t_%d\n",l1);
+	    break;
+	case DOP+NEQ:
+	    printf("\tandb\t$69,%%ah\n");
+	    printf("\txorb\t$64,%%ah\n");
+	    printf("\tje\t_%d\n",l1);
+	    break;
+    }
+}
+
+int dpop_register()
+{ 
+    return 1;
+}
+
+int emit_dpop(int e1)
+{ 
+    return 1;
+}
+
+void emit_dpop_free(int e1)
+{ 
+}
+
+void emit_dpush()
+{ 
+}
+
+/* end */
+
--- a/mc-code.h	Wed Mar 05 23:07:00 2003 +0900
+++ b/mc-code.h	Thu Mar 06 23:47:42 2003 +0900
@@ -68,7 +68,7 @@
 extern void tosop(int op,int oreg);
 extern void code_opening(char *filename);
 extern void code_closing();
-extern void rexpr(int e1, int l1, char *s);
+extern void rexpr(int e1, int l1, char *s,int t);
 extern void drexpr(int e1, int e2,int l1, int op);
 extern void jcond(int l, char cond);
 extern void jmp(int l);
@@ -101,3 +101,13 @@
 extern void code_dpreinc(int e1,int e2,int d);
 extern void code_dpostinc(int e1,int e2,int d);
 extern void code_dassop(int op,int d);
+
+extern void code_arg_register(int);
+
+extern int get_register(void);
+extern void free_register(int i) ;
+extern int virtual(int real);
+extern int pop_register(void);
+extern void emit_pop_free(int xreg);
+
+/* */
--- a/mc-codegen.c	Wed Mar 05 23:07:00 2003 +0900
+++ b/mc-codegen.c	Thu Mar 06 23:47:42 2003 +0900
@@ -54,172 +54,6 @@
 void assop(int e1);
 void g_expr0(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;
-}
-
-void
-set_register_var() {
-}
-
-void
-arg_register0(int args)
-{
-    NMTBL *n;
-    if (args) {
-	/* process in reverse order */
-        n = (NMTBL*)caddr(args);
-        if(n->sc==REGISTER) {
-            if ((n->dsp = get_register_var()) <0) {
-                error(-1); return;
-            }
-            use_register_var(n->dsp); /* it has now value in it */
-        }
-	arg_register0(cadr(args));
-    }
-}
-
-void
-arg_register(NMTBL *fnptr)
-{
-    arg_register0(fnptr->dsp);
-}
-
-void
-register_usage(char *s)
-{
-    int i;
-    if (chk) return;
-    printf("# %d: %s:",lineno,s);
-    printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0));
-    for(i=0;i<MAX_REGISTER;i++) {
-	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,int use0)
 {
@@ -409,7 +243,7 @@
 	return;
     case DMUL: case DDIV:
     case DADD: case DSUB:
-    case DCOMP:
+    case DCMP:
 	dmachinop(e1);
 	return;
     case COND:
@@ -483,34 +317,34 @@
 	b_expr(e2,!cond,l1,0);
 	return;
     case GT:
-	rexpr(e1,l1,code_gt(cond));
+	rexpr(e1,l1,code_gt(cond),INT);
 	return;
     case UGT:
-	rexpr(e1,l1,code_ugt(cond));
+	rexpr(e1,l1,code_ugt(cond),UNSIGNED);
 	return;
     case GE:
-	rexpr(e1,l1,code_ge(cond));
+	rexpr(e1,l1,code_ge(cond),INT);
 	return;
     case UGE:
-	rexpr(e1,l1,code_uge(cond));
+	rexpr(e1,l1,code_uge(cond),UNSIGNED);
 	return;
     case LT:
-	rexpr(e1,l1,code_ge(!cond));
+	rexpr(e1,l1,code_ge(!cond),INT);
 	return;
     case ULT:
-	rexpr(e1,l1,code_uge(!cond));
+	rexpr(e1,l1,code_uge(!cond),UNSIGNED);
 	return;
     case LE:
-	rexpr(e1,l1,code_gt(!cond));
+	rexpr(e1,l1,code_gt(!cond),INT);
 	return;
     case ULE:
-	rexpr(e1,l1,code_ugt(!cond));
+	rexpr(e1,l1,code_ugt(!cond),UNSIGNED);
 	return;
     case EQ:
-	rexpr(e1,l1,code_eq(cond));
+	rexpr(e1,l1,code_eq(cond),INT);
 	return;
     case NEQ:
-	rexpr(e1,l1,code_eq(!cond));
+	rexpr(e1,l1,code_eq(!cond),INT);
 	return;
 
     case DOP+GT:
@@ -588,6 +422,12 @@
 }
 
 
+void
+arg_register(NMTBL *fnptr)
+{
+    code_arg_register(fnptr->dsp);
+}
+
 /* goto arguments list                                      */
 /* target         list4(list2(tag,disp),cdr,ty,source_expr) */
 /*     source         expr=listn(tag,...)                   */
--- a/mc-codegen.h	Wed Mar 05 23:07:00 2003 +0900
+++ b/mc-codegen.h	Thu Mar 06 23:47:42 2003 +0900
@@ -31,17 +31,9 @@
 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();
@@ -69,10 +61,8 @@
 extern void opening(char *filename);
 extern void closing();
 extern void ret(void);
-extern void use_register_var(int);
-extern void arg_register(NMTBL *);
 extern void creg_destroy();
-extern void regvar_creg(int);
+extern void arg_register(NMTBL *fnptr);
 
 /* floating point */
 
--- a/mc.h	Wed Mar 05 23:07:00 2003 +0900
+++ b/mc.h	Thu Mar 06 23:47:42 2003 +0900
@@ -108,57 +108,58 @@
 #define UMOD	29
 #define ADD	30
 #define SUB	31
-#define RSHIFT	32
-#define URSHIFT 33
-#define LSHIFT	34
-#define ULSHIFT 35
-#define GT	36
-#define UGT	37
-#define GE	38
-#define UGE	39
-#define LT	40
-#define ULT	41
-#define LE	42
-#define ULE	43
-#define EQ	44
-#define NEQ	45
-#define BAND	46
-#define EOR	47
-#define BOR	48
-#define LAND	49
-#define LOR	50
-#define COND	51
-#define ASS	52
-#define CASS	53
-#define ASSOP	54
-#define CASSOP	55
-#define COMMA	56
-#define LPAR	57
-#define RPAR	58
-#define LBRA	59
-#define RBRA	60
-#define LC	61
-#define RC	62
-#define COLON	63
-#define SM	64
-#define PERIOD	65
-#define ARROW	66
-#define CNAME	67
-#define SASS	68
-#define RSTRUCT	69
+#define CMP     32	
+#define RSHIFT	33
+#define URSHIFT 34
+#define LSHIFT	35
+#define ULSHIFT 36
+#define GT	37
+#define UGT	38
+#define GE	39
+#define UGE	40
+#define LT	41
+#define ULT	42
+#define LE	43
+#define ULE	44
+#define EQ	45
+#define NEQ	46
+#define BAND	47
+#define EOR	48
+#define BOR	49
+#define LAND	50
+#define LOR	51
+#define COND	52
+#define ASS	53
+#define CASS	54
+#define ASSOP	55
+#define CASSOP	56
+#define COMMA	57
+#define LPAR	58
+#define RPAR	59
+#define LBRA	60
+#define RBRA	61
+#define LC	62
+#define RC	63
+#define COLON	64
+#define SM	65
+#define PERIOD	66
+#define ARROW	67
+#define CNAME	68
+#define SASS	69
+#define RSTRUCT	70
 
-#define FASSOP	70
-#define DASSOP	71
-#define DCOMP	72
-#define DMINUS	73
+#define FASSOP	71
+#define DASSOP	(DOP+ASSOP)
+#define DCMP	(DOP+CMP)
+#define DMINUS	(DOP+MINUS)
 #define DMUL	(DOP+MUL)
 #define DDIV	(DOP+DIV)
 #define DADD	(DOP+ADD)
 #define DSUB	(DOP+SUB)
-#define LMUL	78
-#define LDIV	79
-#define LADD	80
-#define LSUB	81
+#define LMUL	72
+#define LDIV	73
+#define LADD	74
+#define LSUB	75
 
 #define FRGVAR	82
 #define FRLVAR	83
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/basic.c	Thu Mar 06 23:47:42 2003 +0900
@@ -0,0 +1,47 @@
+
+int i;
+print(double d)
+{
+    float f;
+    int *dd;
+
+    f = d;
+
+    dd = (int*) &d;
+    printf("d %g\n",d);
+    printf("dx %08x %08x\n",*(dd),*(dd+1));
+
+    dd = (int*) &f;
+    printf("f %g\n",f);
+    printf("dx %08x \n",*(dd));
+}
+
+void
+tmp () {
+    char c;
+    int i;
+    c=-1;
+    i=c;
+    printf("%d %d %d\n",!i,~i,-i);
+    printf("%d\n",i);
+}
+
+void 
+tmp1 () { 
+
+    printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d \n",
+0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49
+);
+    printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g \n",
+0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,49.0
+);
+
+}
+
+
+main() {
+    print(1.0);
+    print(0.1234);
+    print(1.234e10);
+    print(1.234e-10);
+}