diff mc-code-powerpc.c @ 128:d497c39add36 args-works

arg.c works (?)
author kono
date Thu, 03 Apr 2003 03:04:16 +0900
parents eb4d8975926c
children 948977254fa6
line wrap: on
line diff
--- a/mc-code-powerpc.c	Tue Apr 01 10:31:40 2003 +0900
+++ b/mc-code-powerpc.c	Thu Apr 03 03:04:16 2003 +0900
@@ -140,7 +140,7 @@
 code segment stack frame
 
                  * gotoを呼び出した関数のr1 ! r1(goto前のr1)
-   #             *          r30 <---------------r1_offset---------------> r1
+   #             *                           r30 <---r1_offset---------> r1
 r+ +----------+--+----------+----------------+-----------+----------+----+
     cousin arg xx  reg save !callee arg      !code local  caller arg  xx
                    r20-r29     lvar>0         lvar<0      lvar>0x1000 000
@@ -920,14 +920,20 @@
     printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,retcont,code_base,crn);
 }
 
+#define R1SAVE 1
 
 void
 code_environment(int creg) {
     /* save frame pointer */
-    printf("\tmr %s,r30\n",register_name(creg));
+#if R1SAVE
+    printf("\tlwz %s,0(r1)\n",register_name(creg));
+#else
+    int l = 0;
+    printf("\tla %s,",register_name(creg));
+    printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label);
+#endif
 }
 
-
 void
 code_bool(int e1) {
     char *xrn;
@@ -1449,23 +1455,33 @@
 
 void
 code_frame_pointer(int e3) {
+#if R1SAVE
+    printf("\tmr r1,%s\n",register_name(e3));
+#else
     printf("\tmr r30,%s\n",register_name(e3));
+#endif
 }
 
 
 void
 code_fix_frame_pointer(int disp_offset) {
-    printf("\tla r1,%d(r30)\n",disp_offset);
+    int l = 0;
+    printf("\tla r30,");
+    printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label);
 }
 
 void
 code_jmp(char *s) {
+    max_reg_var = REG_VAR_BASE-REG_VAR_MIN;
+    max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN;
     printf("\tb L_%s$stub\n",s);
 }
 
 
 void
 code_indirect_jmp(int e2) {
+    max_reg_var = REG_VAR_BASE-REG_VAR_MIN;
+    max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN;
     printf("\tmtctr %s\n",register_name(e2));
     printf("\tbctr\n");
 }
@@ -1755,7 +1771,7 @@
 #endif
     printf("_%s:\n",name);
     code_disp_label=fwdlabel();
-    printf("\tstwu r1,lo16(L_%d)(r30)\n",code_disp_label);
+    printf("\tla r1,lo16(L_%d)(r30)\n",code_disp_label);
     printf("\tbcl 20,31,L_%d\n",code_base = fwdlabel());
     fwddef(code_base);
     printf("\tmflr r31\n");
@@ -1766,7 +1782,6 @@
 void
 code_enter1(int args)
 {
-    printf("## args %d disp %d code_arg_offset=%d code_disp_offset=%d\n",args,disp,code_arg_offset,code_disp_offset); 
     set_creg(CREG_REGISTER,0);
     set_freg(FREG_FREGISTER,0);
 }
@@ -1774,10 +1789,12 @@
 void
 code_leave(char *name)
 {
+    int r1_offsetv;
     disp&= -size_of_int;
-    printf(".set L_%d,%d\n",code_disp_label,disp+code_disp_offset);
+    r1_offsetv = -disp+max_func_args*size_of_int+code_disp_offset;
+
+    printf(".set L_%d,%d\n",code_disp_label,-r1_offsetv);
     local_table();
-    labelno++;
     free_all_register();
 }
 
@@ -1826,24 +1843,42 @@
 void
 leave(int control, char *name)
 {
+    int retcont1,sz;
+
+    if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; 
+    reg_save = reg_save_offset();
 
     if (control) {
 	code_set_return_register(1);
     }
     if (retcont) { 
 	if (control) jmp(retlabel);
+	retcont1 = fwdlabel();
 	fwddef(retcont);
-	printf("\tmr r1,r30\n");
 	if (cadr(fnptr->ty)==FLOAT||cadr(fnptr->ty)==DOUBLE) {
 	    printf("\tfmr f1,f31\n");
+	} else if (cadr(fnptr->ty)>0&&(
+	    car(cadr(fnptr->ty))==STRUCT ||
+	    car(cadr(fnptr->ty))==UNION)) {
+	    sz = size(cadr(fnptr->ty));
+	    printf("\tli r7,%d\n",sz);
+	    printf("\tsubl r6,r7,r30\n");
+	    printf("\tlwz r3,lo16(%d)(r30)\n",(my_func_args-1)*size_of_int);
+	    emit_copy(6,3,sz,0,1,1);
 	} else if (cadr(fnptr->ty)!=VOID) {
 	    printf("\tmr r3,r29\n");
 	}
+#if !R1SAVE
+	printf("\tla r1,lo16(%d)(r30)\n",
+	    -reg_save+my_func_args*size_of_int);
+#endif
+	printf("\tb L_%d\n",retcont1);
     }
     fwddef(retlabel);
     printf("\tlwz r1,0(r1)\n");
-    if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; 
-    reg_save = reg_save_offset();
+    if (retcont) {
+	fwddef(retcont1);
+    }
     if (max_freg_var>=0) {
 	printf("\tlmw r%d,%d(r1)\n",
 			REG_VAR_BASE-max_reg_var,reg_save);