changeset 125:e537da31dce3 struct-push

struct push
author kono
date Mon, 24 Mar 2003 12:15:53 +0900
parents f52805504ffa
children 1d1612fe705a
files Changes mc-code-powerpc.c mc-parse.c
diffstat 3 files changed, 70 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Mon Mar 24 03:11:14 2003 +0900
+++ b/Changes	Mon Mar 24 12:15:53 2003 +0900
@@ -2462,3 +2462,37 @@
 Intel 側にもだいぶ embug してしまったようだ。
 
 basicとかfloatの難易度を上げすぎたか?
+
+mc-code-power.c のlvar は、
+     input arg > 0
+     local var < 0
+     output arg > ARG_OFF
+とするべきだね。
+
+Mon Mar 24 12:08:43 JST 2003
+
+        addi r27,r1,56
+        addi r29,r28,28
+        mr r3,r27
+        mr r4,r29
+        li r5,372
+        bl L_memcpy$stub
+        lwz r4,0(r28)
+        lwz r5,4(r28)
+        lwz r6,8(r28)
+        lwz r7,12(r28)
+        lwz r8,16(r28)
+        lwz r9,20(r28)
+        lwz r10,24(r28)
+        mr r3,r28
+        bl _main3
+
+
+うーむ、最低な奴。最初の28byteだけレジスタ渡しなのか。アドレス
+は変わらないんでしょうけど。まぁ、合わせなくても害は無いけどさ。
+そのうちね。(そんなに難しくは無いが... また、function が複雑
+怪奇になるな) しかし浮動小数点レジスタも使うとかそんなんじゃなくて
+良かったかも。
+
+
+
--- a/mc-code-powerpc.c	Mon Mar 24 03:11:14 2003 +0900
+++ b/mc-code-powerpc.c	Mon Mar 24 12:15:53 2003 +0900
@@ -193,7 +193,7 @@
 	printf("lo16(%d+L_%d)(r30)\n",CODE_LVAR,lvar_offset_label);
     } else if (l<0) {  /* local variable */
 	printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label);
-    } else if (l>ARG_LVAR_OFFSET) {  /* caller's arguments */
+    } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
 	printf("lo16(%d)(r30)\n",CALLER_ARG);
     } else { /* callee's arguments */
 	printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label);
@@ -216,7 +216,7 @@
 	printf("la r0,ha16(%d+L_%d)(r30)\n",CODE_LVAR,lvar_offset_label);
     } else if (l<0) {  /* local variable */
 	printf("la r0,ha16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label);
-    } else if (l>ARG_LVAR_OFFSET) {  /* caller's arguments */
+    } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
 	if (CALLER_ARG>32765)
 	    printf("la r0,ha16(%d)(r30)\n",CALLER_ARG);
     } else { /* callee's arguments */
@@ -231,7 +231,7 @@
 	printf("lo16(%d+L_%d)(r0)\n",CODE_LVAR,lvar_offset_label);
     } else if (l<0) {  /* local variable */
 	printf("lo16(%d+L_%d)(r0)\n",FUNC_LVAR,lvar_offset_label);
-    } else if (l>ARG_LVAR_OFFSET) {  /* caller's arguments */
+    } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
 	if (CALLER_ARG>32765)
 	    printf("lo16(%d)(r0)\n",CALLER_ARG);
 	else
@@ -1050,7 +1050,7 @@
     char *trn =	register_name(to);
     char *drn;
     int fix = 0;
-    char *bcopy = "bcopy";
+    char *memmove = "memmove";
     int dreg = get_register(); if (!dreg) error(-1);
     drn	 = register_name(dreg);
 
@@ -1087,14 +1087,20 @@
 		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);
-	    extern_define(bcopy,0,FUNCTION,1);
-	    break;
+	clear_ptr_cache();
+	code_save_stacks();
+	printf("\tli r5,%d\n",length);
+	printf("\tmr r4,%s\n",frn);
+	printf("\tmr r3,%s\n",trn);
+        /* overrap must be allowed */
+	printf("\tbl L_%s$stub\n",memmove);
+	extern_define(memmove,0,FUNCTION,1);
+        fix=0;
+	set_creg(RET_REGISTER,0);
+	if (creg!=to) {
+	    free_register(to); to = creg;
 	}
+	break;
     }
     if (value) {
     /* creg must point top of the destination data */
@@ -1121,27 +1127,27 @@
 	length += size_of_int - (length%size_of_int);
     }
     dreg = get_register(); if (!dreg) error(-1);
-    sreg = get_register(); if (!sreg) error(-1);
     drn = register_name(dreg);
     crn = register_name(creg);
-    srn = register_name(sreg);
-    code_lvar(arg,sreg);
-    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);
+    if (length<MAX_COPY_LEN) {
+	sreg = get_register(); if (!sreg) error(-1);
+	srn = register_name(sreg);
+	code_lvar(cadr(arg),sreg);
+	for(count=0;length<MAX_COPY_LEN;count++,length-=size_of_int) {
+	    if (length==0) {
+		free_register(sreg);
+		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);
+    code_lvar(cadr(arg),dreg);
     /* downward direction copy */
-    printf("\tmr %s,%s\n",drn,srn);
     emit_copy(creg,dreg,length,0,0,1);
     if (dreg) free_register(dreg);
-    if (sreg) free_register(sreg);
     return length/size_of_int;
 }
 
@@ -1271,6 +1277,7 @@
     return 
 	!contains_in_list(e3,FUNCTION) &&
 	!contains_in_list(e3,CONV) &&
+	!contains_in_list(e3,RSTRUCT) &&
 	!contains_in_list(e3,SASS)
     ;
 }
--- a/mc-parse.c	Mon Mar 24 03:11:14 2003 +0900
+++ b/mc-parse.c	Mon Mar 24 12:15:53 2003 +0900
@@ -1217,7 +1217,7 @@
     int type_save,mode_save,t,sz;
     NMTBL *n;
 
-    t = fntype;
+    t = cadr(fntype);
     if (!scalar(t) && (car(t)==STRUCT||car(t)==UNION)) {
 	mode_save = mode;
 	mode=ADECL;
@@ -1234,11 +1234,11 @@
 	    n->dsp += sz;
 	}
 	fnptr->dsp = reverse0(fnptr->dsp);
-	if ((t=size(fntype))==-1) error(TYERR);
+	if ((sz=size(cadr(fntype)))==-1) error(TYERR);
 	else {
 	    args = 0;
 	    def(&str_ret);
-	    struct_return = list3(list2(LVAR,str_ret.dsp),t,type);
+	    struct_return = list3(list2(LVAR,str_ret.dsp),sz,type);
 	}
 	type = type_save;
 	mode = mode_save;
@@ -1626,7 +1626,6 @@
 		    rvalue_t(car(struct_return),caddr(struct_return)));
 		gexpr(cadr(e),0);
 	    } else {
-		e = rvalue(e);
 		type = caddr(struct_return);
 		e1 = rvalue_t(cadr(struct_return),INT); /* size */
 		gexpr(list4(SASS,rvalue(car(struct_return)),e,e1),0);
@@ -2428,6 +2427,7 @@
 	    if(car(e)==INDIRECT) return cadr(e);
 	    return list2(ADDRESS,e);
 	} else if(t==STRUCT || t==UNION) {
+	    if(car(e)==RSTRUCT) return e; /* ??? */
 	    t = cadr(type); /* size */
 	    return list3(RSTRUCT,e,t);
 	} else if(t==FUNCTION) {