changeset 99:53899975154c

*** empty log message ***
author kono
date Fri, 14 Mar 2003 21:33:03 +0900
parents 07c2554e1cfa
children a9e6f2a2946f
files Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h
diffstat 6 files changed, 221 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Fri Mar 14 12:34:47 2003 +0900
+++ b/Changes	Fri Mar 14 21:33:03 2003 +0900
@@ -2141,3 +2141,15 @@
 なんか、emit_pop_free のxregがLVARの時のバグを取るのに苦労した...
 gdb は top level でのwhile を受け付けなくて、define してやなんないと
 だめみたいね。
+
+Fri Mar 14 15:50:28 JST 2003
+
+なぁ... 書いても書いても書いても、終らん!
+
+Fri Mar 14 19:43:44 JST 2003
+
+jump の中で input register を割り振るときに floating point register の
+ことを考えてなかった。これは  register_var とは異なるので異なる
+仕組みで割り振る必要がある。ってことは、get_input_register_var
+が要るってこと?
+
--- a/mc-code-ia32.c	Fri Mar 14 12:34:47 2003 +0900
+++ b/mc-code-ia32.c	Fri Mar 14 21:33:03 2003 +0900
@@ -53,6 +53,9 @@
 int MAX_REGISTGER_VAR=2;    
 int MAX_FREGISTER=1;
 
+int max_input_register_var = 2;
+int max_input_fregister_var = 0;
+
 /*
     creg   currrent virtual register
     dreg   spare virtual register
@@ -193,6 +196,30 @@
     regv[i]=regs[i]=0;
 }
 
+int 
+get_input_register_var(int i)
+{
+    return virtual(i+REG_ESI);
+}
+int 
+
+get_input_fregister_var(int i)
+{
+    error(-1);
+    return -1;
+}
+
+int 
+get_fregister(void)
+{
+    return -1;
+}
+
+void 
+free_fregister(int i) {
+    error(-1);
+}
+
 int
 register_full(void)
 {
--- a/mc-code-powerpc.c	Fri Mar 14 12:34:47 2003 +0900
+++ b/mc-code-powerpc.c	Fri Mar 14 21:33:03 2003 +0900
@@ -66,8 +66,6 @@
 #define REG_sp   30
 #define REG_VAR_BASE 29
 #define REG_VAR_MIN  22
-#define REG_ARG_BASE 3 
-#define REG_ARG_MAX  10 
 #define MIN_TMP_REG 3
 #define MAX_TMP_REG 12
 
@@ -77,8 +75,6 @@
 
 #define FREG_VAR_BASE 31
 #define FREG_VAR_MIN  24
-#define FREG_ARG_BASE 1 
-#define FREG_ARG_MAX  13 
 #define MIN_TMP_FREG 1
 #define MAX_TMP_FREG 12
 
@@ -86,8 +82,9 @@
 int MAX_FREGISTER=30;
 #define  REAL_MAX_REGISTER 32    /* PowerPCのレジスタが32ということ*/
 #define  REAL_MAX_FREGISTER 32    /* PowerPCのレジスタが32ということ*/
-int MAX_REGISTGER_VAR=REG_VAR_BASE-REG_VAR_MIN;    
-int MAX_FREGISTGER_VAR=FREG_VAR_BASE-FREG_VAR_MIN;    
+
+int max_input_register_var = MAX_TMP_REG-MIN_TMP_REG;
+int max_input_fregister_var = MAX_TMP_FREG-MIN_TMP_FREG;
 
 int powerpc_regs[REAL_MAX_REGISTER];
 int powerpc_regv[REAL_MAX_REGISTER];
@@ -127,6 +124,7 @@
 int fregister_var(int r);
 int get_fregister_var(void);
 void use_fregister_var(int r);
+int arg_offset_v(int arg);
 
 void
 code_init(void)
@@ -148,9 +146,24 @@
 }
 
 int
-replace_arg_var(int n,int type)
+replace_arg_var(int reg,int type)
 {
-    fnptr->dsp;
+    int arglist=fnptr->dsp;
+    int nargs=0;
+    int lvar;
+    NMTBL *n;
+    while(arglist) {
+	n = (NMTBL*)caddr(arglist);
+	if (n->sc==REGISTER && n->dsp==reg) {
+	    if (n->ty!=type) error(-1);
+	    lvar = arg_offset_v(nargs);
+	    n->sc=LVAR; n->dsp = lvar;
+	    return lvar;
+	}
+	nargs++;
+    }
+    error(-1);
+    return 0;
 }
 
 int 
@@ -237,6 +250,18 @@
 }
 
 int
+get_input_fregister_var(int i)
+{
+    return i+MIN_TMP_FREG;
+}
+
+int
+get_input_register_var(int i)
+{
+    return i+MIN_TMP_REG;
+}
+
+int
 register_full(void)
 {
     int i;
@@ -270,27 +295,21 @@
 }
 
 void
-set_register_var() {
-}
-
-void
-set_fregister_var() {
-}
-
-void
 code_arg_register(int args)
 {
     NMTBL *n;
+    /* all registers are freed at this time */
+    /* set up input regsiters */
     if (args) {
 	/* process in reverse order */
         n = (NMTBL*)caddr(args);
         if(n->sc==REGISTER) {
-            if ((n->dsp = get_register_var()) <0) {
+            if ((n->dsp = get_register()) <0) {
                 error(-1); return;
             }
             use_register_var(n->dsp); /* it has now value in it */
         } else if(n->sc==DREGISTER) {
-            if ((n->dsp = get_fregister_var()) <0) {
+            if ((n->dsp = get_fregister()) <0) {
                 error(-1); return;
             }
             use_fregister_var(n->dsp); /* it has now value in it */
@@ -348,7 +367,7 @@
 
 int
 register_var(int r) {
-    return REG_VAR_BASE-r;
+    return r;
 }
 
 
@@ -356,7 +375,7 @@
 get_register_var(void)
 {
     int i;
-    for(i=0;i<MAX_REGISTGER_VAR;i++) {
+    for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
         if (! regs[REG_VAR_BASE-i]) {       /* 使われていないなら */
             regs[REG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */
             regv[REG_VAR_BASE-i]=0;
@@ -369,14 +388,14 @@
 
 int
 fregister_var(int r) {
-    return FREG_VAR_BASE-r;
+    return r;
 }
 
 int
 get_fregister_var(void)
 {
     int i;
-    for(i=0;i<MAX_FREGISTGER_VAR;i++) {
+    for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) {
         if (! regs[FREG_VAR_BASE-i]) {       /* 使われていないなら */
             regs[FREG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */
             regv[FREG_VAR_BASE-i]=0;
@@ -980,54 +999,51 @@
 int
 arg_offset_v(int arg)
 {
-    return arg;
+    return arg*size_of_int+0;
 }
 
 int
 function(int e1)
 {
     int e2,e3,e4,e5,nargs,t;
-    int reg_arg,freg_arg;
+    int arg,reg_arg,freg_arg;
+    int reg_arg_list;
     NMTBL *n;
     int jmp;
     char *jrn,*crn;
 
     code_save_stacks();
     code_save_registers();
+    /* now all input register vars are free */
     e2 = cadr(e1);
-    nargs = 0;
-    reg_arg = REG_ARG_BASE;
-    freg_arg = FREG_ARG_BASE;
+    reg_arg_list = nargs = reg_arg = freg_arg = 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);
-	    if (reg_arg<REG_ARG_MAX) {
-		printf("\tmr %s,%s\n",register_name(reg_arg),
-                                register_name(creg));
-		regs[reg_arg]=1;
+	    if (reg_arg<max_input_register_var) {
+		arg = list2(LVAR,arg_offset_v(nargs));
+	    } else if (contains(e3,FUNCTION)) {
+		arg = list2(REGISTER,get_register_var()); regv[cadr(arg)]=1;
 	    } else {
-		printf("\tstw %s,%d(r1)\n",register_name(creg),
-                                arg_offset_v(nargs));
+		arg = list2(REGISTER,get_register()); regv[cadr(arg)]=1;
 	    }
+	    reg_arg_list = list2(arg,reg_arg_list);
+	    g_expr_u(assign_expr0(arg,e4,t,t));
 	    nargs ++ ; reg_arg++;
+	    continue;
 	} else if (t==DOUBLE||t==FLOAT) {
-	    g_expr(e4);
+	    if (freg_arg<max_input_fregister_var) {
+		arg = list2(LVAR,arg_offset_v(nargs));
+	    } else if (contains(e3,FUNCTION)) {
+		arg = list2(DREGISTER,get_fregister_var()); fregv[cadr(arg)]=1;
+	    } else {
+		arg = list2(DREGISTER,get_fregister()); fregv[cadr(arg)]=1;
+	    }
+	    reg_arg_list = list2(arg,reg_arg_list);
+	    g_expr_u(assign_expr0(arg,e4,t,t));
+	    freg_arg++;
 	    nargs += size_of_double/size_of_int;
-	    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_v(nargs));
-		nargs+=size_of_double/size_of_int; 
-	    } else {
-		printf("\tstfs %s,%d(r1)\n",register_name(freg),
-                                arg_offset_v(nargs));
-		nargs+=size_of_float/size_of_int; 
-	    }
-	    freg_arg++;
 	    continue;
 	} else if (car(t)==STRUCT||car(t)==UNION) {
 	    nargs += struct_push(e4,t);
@@ -1057,10 +1073,11 @@
         printf("\tbctrl\n");
 	free_register(jmp);
     }
-    for(;reg_arg>=REG_ARG_BASE;reg_arg--) 
-	regs[reg_arg]=regv[reg_arg]=0;
-    for(;freg_arg>=FREG_ARG_BASE;freg_arg--) 
-	fregs[freg_arg]=fregv[freg_arg]=0;
+    for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) {
+	if (car(reg_arg_list)==DREGISTER) free_fregister(cadr(reg_arg_list));
+	else if (car(reg_arg_list)==REGISTER) free_register(cadr(reg_arg_list));
+    }
+
     if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) {
         fregv[freg]=1; regv[creg]=0;
     } else if (fnptr->ty==VOID) {
@@ -1423,16 +1440,14 @@
 
 void
 code_set_fixed_creg(int mode) {
-    creg=11;
+    creg=0;
 }
 
 void
 gen_gdecl(char *n, int gpc)
 {
-    /*
     if (stmode!=STATIC)
-	printf(".globl %s\n",n); 
-     */
+	printf(".globl _%s\n",n); 
 }
 
 void 
@@ -1482,7 +1497,7 @@
 	}
     } else if(t==DOUBLE) {       
 	d = dcadr(e);
-	printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d));
+	printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d));
     } else if(t==FLOAT) {       
 	f = dcadr(e);
 	printf("\t.long\t0x%x\n",*(int *)&f);
@@ -1666,11 +1681,23 @@
 void
 code_cmp_fregister(int e2)
 {
+    char *frn,*rrn,*grn;
+    int greg,r;
+    grn =  register_name(greg = get_fregister());
+    frn = register_name(freg);
+    float_zero_lib_used=1;
+    r = get_ptr_cache("_float_zero");
+    rrn = register_name(r);
+    printf("\tfls %s,(%s)\n",grn,rrn);
+    printf("\tfcmpu cr0,%s,%s\n",grn,frn);
+    free_fregister(greg);
+    return;
 }
 
 void
 code_fregister(int e2)
 {
+    printf("\tfmr %s,%s\n",register_name(freg),register_name(e2));
 }
 
 void code_dassign_gvar(int e2,int d)
@@ -1696,14 +1723,14 @@
 code_d1(double d)
 {
     int *i = (int *)&d0; int *j = (int *)&d;
-    return (i[1] == 0x3ff00000)?j[1]:j[0];
+    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[0]:j[1];
+    return (i[1] == 0x3ff00000)?j[1]:j[0];
 }
 
 void code_dconst(int e2)
@@ -1731,7 +1758,7 @@
     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));
+    printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d));
     if (output_mode==TEXT_EMIT_MODE) {
 	printf(".text\n");
     } else {
--- a/mc-code.h	Fri Mar 14 12:34:47 2003 +0900
+++ b/mc-code.h	Fri Mar 14 21:33:03 2003 +0900
@@ -10,12 +10,17 @@
 extern int MAX_REGISTER; 
 extern int MAX_REGISTGER_VAR;
 extern int MAX_FREGISTER;
+extern int max_input_register_var;
+extern int max_input_fregister_var;
+
 #define REG_LVAR_OFFSET 2
 
 extern char *register_name(int i,int byte);
 extern void gexpr_code_init(void);
 extern int register_var(int r);
 extern int get_register_var(void);
+extern int get_input_register_var(int);
+extern int get_input_fregister_var(int);
 extern void emit_push(void);
 extern void emit_push_x(int xreg);
 extern int emit_pop(int type);
@@ -111,7 +116,9 @@
 extern void code_arg_register(int);
 
 extern int get_register(void);
+extern int get_fregister(void);
 extern void free_register(int i) ;
+extern void free_fregister(int i) ;
 extern int pop_register(void);
 extern void emit_pop_free(int xreg);
 
--- a/mc-codegen.c	Fri Mar 14 12:34:47 2003 +0900
+++ b/mc-codegen.c	Fri Mar 14 21:33:03 2003 +0900
@@ -480,7 +480,10 @@
     int use0=*use;
     while(use0) {
 	if (car(use0)==t) {
-	    free_register(caddr(use0));
+	    if (car(caddr(use0))==REGISTER)
+		free_register(cadr(caddr(use0)));
+	    else if (car(caddr(use0))==DREGISTER)
+		free_fregister(cadr(caddr(use0)));
 	    break;
 	}
 	use0 = cadr(use0);
@@ -494,8 +497,13 @@
     int e1;
     /*新しいレジスタ(or スタック)を取得する*/
     if (sz==size_of_int && (e1=get_register())!=-1) {
+	e1=list2(REGISTER,e1);
 	*use=list3(t,*use,e1);
-	e1=list2(REGISTER,e1);
+	g_expr_u(assign_expr0(e1,s,ty,ty));
+	*target = append4(*target,t,ty,e1);
+    } else if (sz==size_of_double && (e1=get_fregister())!=-1) {
+	e1=list2(DREGISTER,e1);
+	*use=list3(t,*use,e1);
 	g_expr_u(assign_expr0(e1,s,ty,ty));
 	*target = append4(*target,t,ty,e1);
     } else {
@@ -597,7 +605,7 @@
 is_simple(int e1) 
 {
     return (
-	e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER ||
+	e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER ||e1==DREGISTER ||
 	e1==GVAR || e1==RGVAR || e1==RLVAR || e1==CRLVAR || e1==CRGVAR ||
 	e1==DRLVAR || e1==FRLVAR 
     );
@@ -623,7 +631,7 @@
     return (   
          ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || ce1==DRLVAR ||
          ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || ce1==DRGVAR ||
-         ce1==REGISTER
+         ce1==REGISTER|| ce1==DREGISTER
     );
 }
 
@@ -645,7 +653,7 @@
 void
 jump(int e1, int env)
 {
-    int e2,e3,e4,sz,arg_size,ty,max_regs,regs;
+    int e2,e3,e4,sz,arg_size,ty,regs,fregs;
     int t0,s0;
     NMTBL *code0;
     int target = 0;
@@ -655,11 +663,16 @@
 
     /* まず、サイズを計算しながら、決まった形に落す。 */
 
-    arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR-1;
+    arg_size = 0; regs = 0;
+    fregs = 0;
     for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
 	e2 = car(e3); sz = size(ty=caddr(e3)); 
-	if (regs <= max_regs&&sz==size_of_int) {
-	    target=list4(list2(REGISTER,register_var(regs++)), target,ty,e2);
+	if (scalar(ty) && regs < max_input_register_var&&sz==size_of_int) {
+	    target=list4(list2(REGISTER,get_input_register_var(regs++)), 
+		    target,ty,e2);
+	} else if ((ty==DOUBLE||ty==FLOAT) && fregs < max_input_fregister_var) {
+	    target=list4(list2(DREGISTER,get_input_fregister_var(fregs++)), 
+		    target,ty,e2);
 	} else {
 	    target=list4(list2(LVAR,0), target,ty,e2);
 	    arg_size += sz;
@@ -730,7 +743,11 @@
 
     parallel_assign(&target,&source,&processing,&use);
     while (use) {
-	free_register(caddr(use)); use=cadr(use);
+	if (car(caddr(use))==REGISTER)
+	    free_register(cadr(caddr(use)));
+	else if (car(caddr(use))==DREGISTER)
+	    free_fregister(cadr(caddr(use)));
+	use=cadr(use);
     }
     if(target) error(-1);
 
@@ -1005,4 +1022,63 @@
 	code_closing();
 }
 
+int
+contains_in_list(int e,int type)
+{
+    while(e) {
+	if(contains(car(e),type)) return 1;
+	e = cadr(e);
+    }
+    return 0;
+}
+
+int
+contains(int e,int type)
+{
+    while(e) {
+	if (car(e)==type) return 1;
+	switch (car(e)){
+        /* list arguments */
+	case FUNCTION: case CODE:
+	    return contains_in_list(caddr(e),type);
+        /* unary operators */
+	case INDIRECT: case RINDIRECT:  case CRINDIRECT:
+	case DRINDIRECT: case FRINDIRECT: case ADDRESS: case MINUS: case DMINUS: 
+	case I2D: case D2I: case U2D: case D2U: case BNOT: case LNOT:
+	case PREINC: case POSTINC: case DPREINC: case DPOSTINC:
+	case FPREINC: case FPOSTINC: case CPOSTINC:
+	case CPREINC: case CPOSTDEC: case CPREDEC:
+	case RSTRUCT:
+	    e = cadr(e);
+	    continue;
+        /* biary operators */
+	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: case CMP:
+	case DMUL: case DDIV: case DADD: case DSUB: case DCMP: case DCMPGE:
+	case SASS: case ASS: case CASS: case FASS: case DASS: case LASS: 
+	case ASSOP: case CASSOP: case DASSOP: case FASSOP: case COMMA:
+	    if (contains(cadr(e),type)) return 1;
+	    e = caddr(e);
+	    continue;
+        /* tarary operators */
+	case COND:
+	    if (contains(cadr(e), type)) return 1;
+	    if (contains(caddr(e),type)) return 1;
+	    e = cadddr(e);
+	    continue;
+	default:
+        /* nullary operators 
+	case GVAR:   case RGVAR: case CRGVAR: case LVAR:
+	case REGISTER: case DREGISTER:
+	case RLVAR: case CRLVAR: case FRLVAR: case FRGVAR:
+	case DRLVAR: case DRGVAR:
+	case FNAME: case CONST:  case DCONST: case STRING:
+	case RETURN: case ENVIRONMENT: */
+	    return 0;
+	}
+    }
+    return 0;
+}
+
 /* end */
--- a/mc-codegen.h	Fri Mar 14 12:34:47 2003 +0900
+++ b/mc-codegen.h	Fri Mar 14 21:33:03 2003 +0900
@@ -46,6 +46,7 @@
 extern void enter(char *name);
 extern void enter1();
 extern int g_expr(int e1);
+extern int g_expr_u(int e1);
 extern void gen_comment(char *s);
 extern void gen_gdecl(char *n, int gpc);
 extern void gen_source(char *s);
@@ -62,6 +63,8 @@
 extern void creg_destroy();
 extern void arg_register(NMTBL *fnptr);
 
+extern int contains(int e,int type);
+
 /* floating point */
 
 extern void dassop(int e1);