changeset 412:6b3385124e5e arm-self-compile

ARM regsiter var pattern fix.
author kono
date Tue, 19 Oct 2004 23:39:42 +0900
parents 32c1914308db
children d4dc6d99ffdb
files Changes mc-code-arm.c
diffstat 2 files changed, 52 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Tue Oct 19 18:15:41 2004 +0900
+++ b/Changes	Tue Oct 19 23:39:42 2004 +0900
@@ -6155,3 +6155,13 @@
 混在させるとだめだね。
 
 浮動小数点関係の Endian がおかしい
+
+Tue Oct 19 19:07:57 JST 2004
+
+        stmfd   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
+
+ってわけで、r0-r3 がinput registerで、r4-sl がregister_var とtmp
+を兼ねるわけだね。r4から全部をregister_var に割り振ると破綻するだろう。
+
+ってことは、一時変数ではなく積極的にレジスタ変数を使った方が
+良いわけだけど...
--- a/mc-code-arm.c	Tue Oct 19 18:15:41 2004 +0900
+++ b/mc-code-arm.c	Tue Oct 19 23:39:42 2004 +0900
@@ -93,10 +93,12 @@
 #define REG_ip   13
 #define REG_fp   14
 #define REG_sp   15
-#define REG_VAR_BASE 11
-#define REG_VAR_MIN  9
-#define MIN_TMP_REG 2          /* only one tmp register? */
-#define MAX_TMP_REG 8
+#define REG_VAR_BASE 5
+#define REG_VAR_MIN  5
+#define REG_VAR_USER_MAX  9     /* at leat 6 tmp var */
+#define REG_VAR_MAX 12
+#define MIN_TMP_REG 1
+#define MAX_TMP_REG 4
 
 #define PTRC_REG 3              /* mark for pointer cache */
 
@@ -651,8 +653,8 @@
 	}
     }
 #endif
-    for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
-        reg =REG_VAR_BASE-i;
+    for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) {
+        reg =REG_VAR_BASE+i;
         if (! regs[reg]) {       /* 使われていないなら */
             regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */
 	    if (i+1>max_reg_var) max_reg_var=i+1;
@@ -668,8 +670,8 @@
 	regs[i]=USING_REG;      /* そのレジスタを使うことを宣言し */
 	return i;   /* その場所を表す番号を返す */
     }
-    for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
-        reg =REG_VAR_BASE-i;
+    for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) {
+        reg =REG_VAR_BASE+i;
 	/* PTR_CACHE をつぶす */
 	if (regs[reg]==PTRC_REG) {
 	    clear_ptr_cache_reg(reg);
@@ -788,26 +790,26 @@
     ll = get_lregister0();
     if (ll==-1) return -1;
     if (regs[ll]==0) {
-	for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
-	    if (! regs[REG_VAR_BASE-i]) {       /* 使われていないなら */
+	for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) {
+	    if (! regs[REG_VAR_BASE+i]) {       /* 使われていないなら */
 		/* そのレジスタを使うことを宣言し */
-		regs[REG_VAR_BASE-i]=USING_REG; 
+		regs[REG_VAR_BASE+i]=USING_REG; 
 		if (i+1>max_reg_var) max_reg_var=i+1;
-		for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) {
-		    if (! regs[REG_VAR_BASE-j]) {       
+		for(j=0;j<REG_VAR_MAX-REG_VAR_MIN;j++) {
+		    if (! regs[REG_VAR_BASE+j]) {       
 			/* 使われていないなら */
 			/* そのレジスタを使うことを宣言し */
-			regs[REG_VAR_BASE-j]=USING_REG; 
+			regs[REG_VAR_BASE+j]=USING_REG; 
 			if (j+1>max_reg_var) max_reg_var=j+1;
 			/* その場所を表す番号を返す */
 			regs[ll]=USING_REG;
-			regv_l(ll) = REG_VAR_BASE-j;
-			regv_h(ll) = REG_VAR_BASE-i;
+			regv_l(ll) = REG_VAR_BASE+j;
+			regv_h(ll) = REG_VAR_BASE+i;
 			return list3(LREGISTER,ll,(int)n); 
 		    }
 		}
 		/* ひとつしかなかった */
-		regs[REG_VAR_BASE-i]=0; 
+		regs[REG_VAR_BASE+i]=0; 
 		max_reg_var=max_reg_var_save;
 		goto not_found;
 	    }
@@ -876,8 +878,8 @@
     ll = get_lregister0();
     if (ll!=-1) {
 	if (is_code) {
-	    if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0;
-	    i = REG_VAR_BASE-i;
+	    if(!(i<REG_VAR_MAX-REG_VAR_MIN)) return 0;
+	    i = REG_VAR_BASE+i;
 	} else {
 	    if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0;
 	    i++;
@@ -897,8 +899,8 @@
 get_input_register_var(int i,NMTBL *n,int is_code)
 {
     if (is_code) {
-	if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0;
-	i = REG_VAR_BASE-i;
+	if(!(i<REG_VAR_MAX-REG_VAR_MIN)) return 0;
+	i = REG_VAR_BASE+i;
     } else {
 	if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0;
 	i = i+1;
@@ -1105,13 +1107,14 @@
     text_mode(3);
 }
 
-#define reg_var_num(i) (REG_VAR_BASE-i)
+#define reg_var_num(i) (REG_VAR_BASE+i)
 
 int
 get_register_var(NMTBL *n)
 {
     int i,j;
-    for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
+    int max = n?REG_VAR_USER_MAX-REG_VAR_BASE:REG_VAR_MAX-REG_VAR_BASE;
+    for(i=0;i<max;i++) {
 	j = reg_var_num(i);
 	if (! regs[j]) {       /* 使われていないなら */
 	    /* そのレジスタを使うことを宣言し */
@@ -1466,8 +1469,7 @@
     if (offset==0) {
         if(r!=reg)
             printf("\tmov\t%s, %s\n",crn,rrn);
-    }
-    if ((s=make_const(offset,&p1,&p2,&p3,0))) {
+    } else if ((s=make_const(offset,&p1,&p2,&p3,0))) {
 	add = s>0?"add":"sub";
 	printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p1);
 	if (p2) printf("\t%s\t%s, %s, #%d\n",add,crn,crn,p2);
@@ -2679,7 +2681,7 @@
 void
 code_jmp(char *s) {
     // jump to continuation means use all register variable
-    max_reg_var = REG_VAR_BASE-REG_VAR_MIN;
+    max_reg_var = REG_VAR_MAX-REG_VAR_MIN;
     max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN;
     inc_inst(1);
     printf("\tb\t%s\n",s);
@@ -2689,7 +2691,7 @@
 void
 code_indirect_jmp(int e2) {
     // jump to continuation means use all register variable
-    max_reg_var = REG_VAR_BASE-REG_VAR_MIN;
+    max_reg_var = REG_VAR_MAX-REG_VAR_MIN;
     max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN;
     use_int(e2);
     inc_inst(1);
@@ -2874,17 +2876,17 @@
 code_assop(int op,int creg, int byte,int sign) {
     char *xrn,*crn,*drn;
     int xreg;
-    int edx = get_register(); if(!edx) error(-1);
+    int edx = get_register_var(0);
+    if (car(edx)!=REGISTER) error(-1);
     //  (*creg) op = pop()
 
+    drn = register_name(edx=cadr(edx));
     use_int(creg);
     xrn = register_name(xreg = emit_pop(0));       /* pop e3 value */
-    set_ireg(edx,0);
-    ld_indexx(byte,0,creg,ireg,sign);
-    use_reg(creg);
-    tosop(op,ireg,xreg);
-    crn = register_name(ireg);
-    drn = register_name(creg);
+    code_register(creg,edx);
+    ld_indexx(byte,0,edx,creg,sign);
+    tosop(op,creg,xreg);
+    crn = register_name(creg);
     printf("\t%s\t%s, [%s, #0]\n",cstore(byte),crn,drn);
     free_register(edx);
     free_register(creg);
@@ -2956,13 +2958,15 @@
     case MUL:
     case UMUL:
 	inc_inst(1);
-	drn = register_name(dx = get_register());
+	drn = register_name(cadr(dx = get_register_var(0)));
+	if (car(dx)!=REGISTER) error(-1);
 	printf("\tmul\t%s, %s, %s\n",drn,crn,orn);
 	if (creg0==USE_CREG) {
-	    set_ireg(dx,0); dx = -1;
+	    set_ireg(cadr(dx),0); dx = -1;
 	} else {
 	    printf("\tmov\t%s, %s\n",crn,drn);
 	}
+	free_register(cadr(dx));
 	break;
     case DIV:
 	code_int_lib("__divsi3",creg,oreg); break;
@@ -2975,7 +2979,6 @@
     default:
 	error(-1);
     }
-    if(dx!=-1) free_register(dx);
     if(ox!=-1) free_register(ox);
 }
 
@@ -3222,7 +3225,7 @@
     int i;
     inc_inst(1);
     printf("\tstmfd\tsp!, {");
-    for (i=reg_var_num(reg_save);i<reg_var_num(0);i++) {
+    for (i=reg_var_num(0);i<reg_var_num(reg_save);i++) {
 	    printf("%s, ",register_name(i));
     }
     printf("fp, ip, lr, pc}\n");
@@ -3245,7 +3248,7 @@
     }
     inc_inst(1);
     printf("\tldmea\tfp, {");
-    for (i=reg_var_num(reg_save);i<reg_var_num(0);i++) {
+    for (i=reg_var_num(0);i<reg_var_num(reg_save);i++) {
 	    printf("%s, ",register_name(i));
     }
     printf("fp, sp, pc}\n");