changeset 268:3a368fc37559

MIPS binary continue...
author kono
date Tue, 18 May 2004 14:20:46 +0900
parents e7ab23c992e5
children d9f4026de4e3
files .gdbinit Changes mc-code-mips.c mc-code-powerpc.c
diffstat 4 files changed, 124 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Mon May 17 11:41:51 2004 +0900
+++ b/.gdbinit	Tue May 18 14:20:46 2004 +0900
@@ -1,6 +1,6 @@
 tb main
-# run  -s -ob00.s test/basic.c
-run  -s -ob00.s mc-parse.c
+run  -s -ob00.s test/basic.c
+# run  -s -ob00.s mc-parse.c
 # run -s test/code-gen-all.c
 define regs 
 printf "pc =%08x lr =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$pc,$lr,$r0,$r1,$r3,$r4
--- a/Changes	Mon May 17 11:41:51 2004 +0900
+++ b/Changes	Tue May 18 14:20:46 2004 +0900
@@ -4313,4 +4313,9 @@
 あと、int の後のdouble/longlong は、$3 のあと、$5,$6 と
 来るみたいですね。
 
-
+さて、いよいよ、オフセット合わせか。
+
+Tue May 18 13:05:24 JST 2004
+
+なんかレジスタセーブがぼろぼろじゃん。max_reg_var とかが、
+ちゃんとレジスタの個数を表すようにしろよ。
--- a/mc-code-mips.c	Mon May 17 11:41:51 2004 +0900
+++ b/mc-code-mips.c	Tue May 18 14:20:46 2004 +0900
@@ -45,9 +45,6 @@
 static int    max_func_args = 0;
 
 
-static int reg_save;
-static int freg_save;
-
 static int freg,ireg,lreg;
 static int cmpreg;
 
@@ -87,10 +84,10 @@
 
 #define PTRC_REG 3
 
-#define FREG_VAR_BASE 29
-#define FREG_VAR_MIN  18
-#define MIN_TMP_FREG 4
-#define MAX_TMP_FREG 17
+#define FREG_VAR_BASE 31
+#define FREG_VAR_MIN  20
+#define MIN_TMP_FREG 0
+#define MAX_TMP_FREG 11
 
 int MAX_REGISTER=30;             /* PowerPCのレジスタを10個まで使う*/
 int MAX_FREGISTER=31;
@@ -104,7 +101,7 @@
 int MAX_INPUT_REGISTER_VAR = 4;
 int MAX_CODE_INPUT_REGISTER_VAR = 7-MIN_TMP_REG;
 int MAX_INPUT_DREGISTER_VAR = 2;
-int MAX_INPUT_FREGISTER_VAR = 1;
+int MAX_INPUT_FREGISTER_VAR = 4;
 int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG;
 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG;
 
@@ -292,7 +289,7 @@
      $f20-$f31 saved register variable
 
  function call stack frame
-                       <------r1_offset------------------------------>
+                   <----------r1_offset------------------------------>
                                       <------------lvar_offset------->
  r+  +------------+---+---------------+----------+--------------+----+    -
       callee arg   xx   register save   local      caller arg     xx
@@ -312,10 +309,10 @@
                  prev $sp=$fp                 $fp                        $sp
 
  */
-int arg_offset = 24; int arg_offset1 = 24; int disp_offset = -12;
-// #define func_disp_offset 60
-#define func_disp_offset 68
-#define r1_offset func_disp_offset+12 
+static int arg_offset = 0,arg_offset1 = 0,disp_offset = 0;
+
+#define func_disp_offset 8
+#define r1_offset func_disp_offset
 int code_disp_offset = 0; int jump_offset = 0;
 #define CODE_LVAR l+code_disp_offset
 #define CODE_CALLER_ARG (l-ARG_LVAR_OFFSET)+arg_offset1
@@ -332,8 +329,8 @@
 #endif
     int lvar_offsetv = -disp+max_func_args*SIZE_OF_INT+func_disp_offset;
     int r1_offsetv = -disp+max_func_args*SIZE_OF_INT-reg_save+r1_offset;
-    printf(".set $L_%d,%d\n",lvar_offset_label,lvar_offsetv);
-    printf(".set $L_%d,%d\n",r1_offset_label,r1_offsetv);
+    fprintf(asi,"$L_%d=%d\n",lvar_offset_label,lvar_offsetv);
+    fprintf(asi,"$L_%d=%d\n",r1_offset_label,r1_offsetv);
 #if 0
 printf("# function %s\n",fnptr->nm);
     l = ARG_LVAR_OFFSET;
@@ -711,11 +708,11 @@
 	if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0;
 	i = FREG_VAR_BASE-i+FREG_OFFSET;
     } else {
-	if (i<0||i>=MAX_INPUT_FREGISTER_VAR) return 0;
-	if (i==1) i = 6;
-	else if (i==2) i = 7;
-	else
-	    i = i+MIN_TMP_FREG+FREG_OFFSET;
+	if (i==0) i=12+FREG_OFFSET;
+	else if (i==1) i=14+FREG_OFFSET;
+	else if (i==2) return list3(REGISTER,6,(int)n);
+	else if (i==3) return list3(REGISTER,7,(int)n);
+	else return 0;
     }
     return list3(FREGISTER,i,(int)n);
 }
@@ -1631,7 +1628,6 @@
     NMTBL *n;
     int reg;
     int tag;
-    int lvar;
     int t;
     /* fnptr->dsp=list4(type,fnptr->dsp,(int)n,0); */
     int reg_offset = 0;
@@ -1652,7 +1648,12 @@
 	    /* regs[reg]==INPUT_REG case should be considered */
 	    n->dsp = offset;
 	    t = n->ty;
-	    if(t==FLOAT) { offset+=SIZE_OF_FLOAT; reg_offset+=1; }
+	    if(t==FLOAT) {
+		offset+=SIZE_OF_FLOAT; reg_offset+=1;
+		if (reg==6||reg==7) {   // int register case
+		    tag = REGISTER; t = INT;
+		}
+	    }
 	    else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; reg_offset+=2; }
 	    else error(-1);
 	} else if (tag==DREGISTER) {
@@ -1670,8 +1671,7 @@
 	    continue;
 	}
 	n->sc  = LVAR;
-	lvar = list2(LVAR,n->dsp);
-	g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t));
+	g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),t,t));
 	if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) {
 	    free_register(reg);
 	}
@@ -1767,7 +1767,7 @@
 	break;
     case FRLVAR:
 	lvar_intro(cadr(e2));
-	printf("\tlw %s,",fregister_name(freg)); lvar(cadr(e2));
+	printf("\tlw %s,",frn); lvar(cadr(e2));
     default:
 	g_expr(e2);
     case FREGISTER:
@@ -1795,7 +1795,7 @@
     int t=caddr(e3);
     if(scalar(t)) {
 	nargs ++ ; reg_arg++;
-    } else if (t==LONGLONG||t==ULONGLONG||DOUBLE) {
+    } else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) {
 	nargs ++ ; reg_arg++;
 	nargs ++ ; reg_arg++;
     } else if (t==FLOAT) {
@@ -1897,8 +1897,8 @@
 	code_register(creg,cadr(jmp));
         /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */
     }
-    /* first we execute complex argument to avoid interaction with
-       input variables */
+    /* First we execute complex argument to avoid interaction with
+       input variables. Remain the last complex argument in complex_. */
     stargs = 0;
     complex_ = 0;
     nargs = reg_arg = freg_arg = 0;
@@ -1940,21 +1940,37 @@
     set_freg(FREG_FREGISTER,0);
     set_ireg(CREG_REGISTER,0);
 
-    if (complex_) {
-	arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg);
-	compute_complex_arg(complex_,reg_arg_list,arg);
-    }
-    for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) {
-	e3 = car(stargs);
-	e4 = car(e3);
-	t  = caddr(e3);
-	arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0);
-	struct_push(e4,t,arg);
-	car(e3)=0;  // done
+    //  Struct arguments need emit_copy. it destructs 3 input registers.
+    //  But it returns no value on a register. So calcurate it here.
+    //  We cannot do this in the previous loop, because the copied struct may be
+    //  override by other complex arguments. But bofore this we have to check
+    //  complex_.
+
+    if (stargs) {
+	if (complex_) {
+	    arg = get_input_arg(caddr(complex_),AS_SAVE,
+				    pnargs,preg_arg,pfreg_arg);
+	    compute_complex_arg(complex_,reg_arg_list,arg);
+	}
+	for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) {
+	    e3 = car(stargs);
+	    e4 = car(e3);
+	    t  = caddr(e3);
+	    arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0);
+	    struct_push(e4,t,arg);
+	    car(e3)=0;  // done
+	}
+    } else {
+	//  last complex argument can use input register
+	if (complex_) {
+	    arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg);
+	    compute_complex_arg(complex_,reg_arg_list,arg);
+	}
     }
 
     nargs = reg_arg = freg_arg = arg_assign = 0;
-    // calc stack arguments first
+    // calc stack arguments first, it may requires extra registers,
+    // and we can still use input registers now.
     for (e3 = e1; e3; 
 		increment_function_arg(e3,&nargs,&reg_arg,&freg_arg),
 		e3 = cadr(e3)) {	
@@ -2542,38 +2558,42 @@
 }
 
 static int
-code_register_save(reg_save,freg_save,disp)
+code_register_save(int reg_save,int freg_save,int disp)
 {
     int i;
     for(i=0;i<32;i++) {
-	if (reg_var_num(0)>i&&i>reg_var_num(max_reg_var)) {
-	    printf("\tsw    %s,%d($sp)\n",register_name(i),disp);
-	    disp += SIZE_OF_INT;
+	if (reg_var_num(0)>i&&i>reg_var_num(reg_save)) {
+	    printf("\tsw    %s,$L_%d+%d($sp)\n",register_name(i),
+		r1_offset_label,disp);
+	    disp -= SIZE_OF_INT;
 	}
     }
     for(i=0;i<32;i++) {
-	if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) {
-	    printf("\ts.s    %s,%d($sp)\n",register_name(i),disp);
-	    disp += SIZE_OF_FLOAT;
+	if (freg_var_num(0)>i&&i>freg_var_num(freg_save)) {
+	    printf("\ts.s    %s,$L_%d+%d($sp)\n",register_name(i),
+		r1_offset_label,disp);
+	    disp -= SIZE_OF_FLOAT;
 	}
     }
     return disp;
 }
 
 static int
-code_register_restore(reg_save,freg_save,disp)
+code_register_restore(int reg_save,int freg_save,int disp)
 {
     int i;
     for(i=0;i<32;i++) {
-	if (reg_var_num(0)>i&&i>reg_var_num(max_reg_var)) {
-	    printf("\tlw    %s,%d($sp)\n",register_name(i),disp);
-	    disp += SIZE_OF_INT;
+	if (reg_var_num(0)>i&&i>reg_var_num(reg_save)) {
+	    printf("\tlw    %s,$L_%d+%d($sp)\n",register_name(i),
+		r1_offset_label,disp);
+	    disp -= SIZE_OF_INT;
 	}
     }
     for(i=0;i<32;i++) {
-	if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) {
-	    printf("\tl.s    %s,%d($sp)\n",register_name(i),disp);
-	    disp += SIZE_OF_FLOAT;
+	if (freg_var_num(0)>i&&i>freg_var_num(freg_save)) {
+	    printf("\tl.s    %s,$L_%d+%d($sp)\n",register_name(i),
+		r1_offset_label,disp);
+	    disp -= SIZE_OF_FLOAT;
 	}
     }
     return disp;
@@ -2651,7 +2671,7 @@
     disp&= -SIZE_OF_INT;
     r1_offsetv = -disp+max_func_args*SIZE_OF_INT+code_disp_offset;
 
-    printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv);
+    printf("L_%d=%d\n",r1_offset_label,r1_offsetv);
 
     local_table();
     printf("\t.end    %s\n",name);
@@ -2673,15 +2693,17 @@
     printf("\t.globl\t%s\n",name);
     printf(".ent %s\n",name);
     printf("%s:\n",name);
-    printf("\t.frame $fp,$L_%d,$31\t",r1_offset_label=fwdlabel());
-    printf("\t.mask  0x%x,%d\n",mask_label=fwdlabel(),
+    printf("\t.frame $fp,$L_%d,$31\n",r1_offset_label=fwdlabel());
+    printf("\t.mask  $L_%d,$L_%d\n",mask_label=fwdlabel(),
 	mask_offset_label=fwdlabel());
-    printf("\t.fmask  0x%x,%d\n",fmask_label=fwdlabel(),
+    printf("\t.fmask  $L_%d,$L_%d\n",fmask_label=fwdlabel(),
 	fmask_offset_label=fwdlabel());
     printf("\t.set noreorder\n");
     printf("\t.cpload $25\n");
     printf("\t.set reorder\n");
     printf("\tsubu $sp,$sp,$L_%d\n",r1_offset_label);
+    printf("\tsw      $31,$L_%d+%d($sp)\n",r1_offset_label,r1_offset);
+    printf("\tsw      $fp,$L_%d+%d($sp)\n",r1_offset_label,r1_offset-SIZE_OF_INT);
     printf("\t.cprestore $L_%d\n",cprestore_label=fwdlabel());
     printf("\tj $L_%d\n",register_save_label=fwdlabel());
     register_save_return_label = backdef();
@@ -2706,12 +2728,6 @@
     int r1_offsetv;
     int lvar_offsetv;
 
-    // if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; 
-    reg_save = 
-	(REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*SIZE_OF_INT;
-    freg_save = 
-	(REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*SIZE_OF_FLOAT;
-
     if (control) {
 	code_set_return_register(1);
     } else
@@ -2748,18 +2764,19 @@
 
 
     disp &= -SIZE_OF_INT;
-    r1_offsetv = round16(-disp) +
-	max_reg_var*SIZE_OF_INT+max_freg_var*SIZE_OF_FLOAT+
-	round16(max_func_args);
+    lvar_offsetv = round16(-disp) +
+	round16(max_func_args)+r1_offset;
+    r1_offsetv = lvar_offsetv +
+	max_reg_var*SIZE_OF_INT+max_freg_var*SIZE_OF_FLOAT+2*SIZE_OF_INT;
 	
     fprintf(asi,"$L_%d=%d\n",r1_offset_label,r1_offsetv);
     fprintf(asi,"$L_%d=%d\n",lvar_offset_label,lvar_offsetv);
 
     printf("\tmove    $sp,$fp\n");
+    printf("\tlw      $31,$L_%d+%d($sp)\n",r1_offset_label,r1_offset);
+    printf("\tlw      $fp,$L_%d+%d($sp)\n",r1_offset_label,r1_offset-SIZE_OF_INT);
     if (max_reg_var+max_freg_var)
-	code_register_restore(disp);
-    printf("\tlw      $31,%d($sp)\n",-disp);
-    printf("\tlw      $fp,%d($sp)\n",-disp-4);
+	code_register_restore(max_reg_var,max_freg_var,r1_offset-SIZE_OF_INT*2);
     printf("\taddu    $sp,$sp,%d\n",r1_offsetv);
     printf("\tj       $31\n");
 
@@ -2781,7 +2798,7 @@
 		register_save_label,register_save_return_label);
     } else {
 	code_label(register_save_label);
-	code_register_save(disp);
+	code_register_save(max_reg_var,max_freg_var,r1_offset-SIZE_OF_INT*2);
 	jmp(register_save_return_label);
     }
 
--- a/mc-code-powerpc.c	Mon May 17 11:41:51 2004 +0900
+++ b/mc-code-powerpc.c	Tue May 18 14:20:46 2004 +0900
@@ -1866,21 +1866,37 @@
     set_freg(FREG_FREGISTER,0);
     set_ireg(CREG_REGISTER,0);
 
-    if (complex_) {
-	arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg);
-	compute_complex_arg(complex_,reg_arg_list,arg);
-    }
-    for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) {
-	e3 = car(stargs);
-	e4 = car(e3);
-	t  = caddr(e3);
-	arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0);
-	struct_push(e4,t,arg);
-	car(e3)=0;  // done
+    //  Struct arguments need emit_copy. it destructs 3 input registers.
+    //  But it returns no value on a register. So calcurate it here.
+    //  We cannot do this in the previous loop, because the copied struct may be
+    //  override by other complex arguments. But bofore this we have to check
+    //  complex_.
+
+    if (stargs) {
+        if (complex_) {
+            arg = get_input_arg(caddr(complex_),AS_SAVE,
+                                    pnargs,preg_arg,pfreg_arg);
+            compute_complex_arg(complex_,reg_arg_list,arg);
+        }   
+        for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) {
+            e3 = car(stargs);
+            e4 = car(e3);
+            t  = caddr(e3);
+            arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0);
+            struct_push(e4,t,arg);
+            car(e3)=0;  // done
+        }
+    } else {
+	//  last complex argument can use input register
+	if (complex_) {
+	    arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg);
+	    compute_complex_arg(complex_,reg_arg_list,arg);
+	}
     }
 
     nargs = reg_arg = freg_arg = arg_assign = 0;
-    // calc stack arguments first
+    // calc stack arguments first, it may requires extra registers,
+    // and we can still use input registers now.
     for (e3 = e1; e3; 
 		increment_function_arg(e3,&nargs,&reg_arg,&freg_arg),
 		e3 = cadr(e3)) {