diff mc-code-powerpc.c @ 375:91849fdeea60

PowerPC large offset.
author kono
date Mon, 12 Jul 2004 07:33:23 +0900
parents 238c3704ee3d
children 832e1f6bba82
line wrap: on
line diff
--- a/mc-code-powerpc.c	Sun Jul 11 20:59:52 2004 +0900
+++ b/mc-code-powerpc.c	Mon Jul 12 07:33:23 2004 +0900
@@ -263,8 +263,9 @@
      f24-f31 saved register variable
 
  function call stack frame
-                       <------r1_offset------------------------------>
-                                      <------------lvar_offset------->
+                      <-------r1_offset------------------------------>
+                                      <------------lvar_offset0------>
+                      <--lvar_offset-->
  r+  +------------+---+---------------+----------+--------------+----+    -
       callee arg   xx   register save   local      caller arg     xx
                           reg_save      disp       max_func_args*SIZE_OF_INT
@@ -299,14 +300,16 @@
     int l;
 #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);
+    // int r1_offsetv = -disp+max_func_args*SIZE_OF_INT-reg_save+r1_offset;
+    int r1_offsetv = lvar_offsetv-reg_save+12;
+    printf(".set L_%d,%d\n",lvar_offset_label,r1_offsetv-lvar_offsetv);
     printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv);
     if (max_func_arg_label) {
 	printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24);
 	max_func_arg_label = 0;
     }
 
+printf("# reg_save %d\n",reg_save);
 #if 0
 printf("# function %s\n",fnptr->nm);
     l = ARG_LVAR_OFFSET;
@@ -327,21 +330,40 @@
 #endif
 }
 
+static int large_offset_reg;
 
 static void
-lvar8(int l)
+lvar(int l)
 {
-    if (fnptr->sc==CODE) {
-	if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-	    printf("lo16(%d)(r1)\n",CODE_CALLER_ARG);
-	} else
-	    printf("lo16(%d)(r30)\n",CODE_LVAR);
-    } 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 */
-	printf("lo16(%d)(r1)\n",CALLER_ARG);
-    } else { /* callee's arguments */
-	printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label);
+    char *rn;
+    if (!large_offset_reg) {
+	if (fnptr->sc==CODE) {
+	    if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
+		printf("lo16(%d)(r1)\n",CODE_CALLER_ARG);
+	    } else
+		printf("lo16(%d)(r30)\n",CODE_LVAR);
+	} else if (l<0) {  /* local variable */
+	    printf("lo16(%d)(r30)\n",FUNC_LVAR);
+	} else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
+	    printf("lo16(%d)(r1)\n",CALLER_ARG);
+	} else { /* callee's arguments */
+	    printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,lvar_offset_label);
+	}
+    } else {
+        rn = register_name(large_offset_reg);
+        if (fnptr->sc==CODE) {
+            if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
+                printf("lo16(%d)(%s)\n",CODE_CALLER_ARG,rn);
+            } else
+                printf("lo16(%d)(%s)\n",CODE_LVAR,rn);
+        } else if (l<0) {  /* local variable */
+            printf("lo16(%d)(%s)\n",FUNC_LVAR,rn);
+        } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
+            printf("lo16(%d)(%s)\n",CALLER_ARG,rn);
+        } else { /* callee's arguments */
+            printf("lo16(%d+L_%d)(%s)\n",CALLEE_ARG,lvar_offset_label,rn);
+        }
+        free_register(large_offset_reg);
     }
 }
 
@@ -352,49 +374,44 @@
    smaller offset. But who cares who use very large local variables?
  */
 
-#define LARGE_LVAR (disp<-32765||max_func_args>32765)
-
-static void
-lvar16ha(int l)
-{
-    if (fnptr->sc==CODE) {
-	if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-	    printf("la r0,ha16(%d)(r1)\n",CODE_CALLER_ARG);
-	} else
-	    printf("la r0,ha16(%d)(r30)\n",CODE_LVAR);
-    } 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 */
-	if (CALLER_ARG>32765)
-	    printf("la r0,ha16(%d)(r1)\n",CALLER_ARG);
-    } else { /* callee's arguments */
-	printf("la r0,ha16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label);
-    }
-}
+#define LARGE_OFFSET(l) (l<-32000||l>32000)
 
 static void
-lvar16lo(int l)
+lvar_intro(int l)
 {
+    char *rn;
+    large_offset_reg=0;
     if (fnptr->sc==CODE) {
-	if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-	    printf("lo16(%d)(r0)\n",CODE_CALLER_ARG);
-	} else
-	    printf("lo16(%d)(r0)\n",CODE_LVAR);
+        if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
+            if (LARGE_OFFSET(CODE_CALLER_ARG)) {
+                rn=register_name(large_offset_reg=get_register());
+                printf("\taddis %s,r1,ha16(%d)\n",rn,CODE_CALLER_ARG);
+            }
+        } else {
+            if (LARGE_OFFSET(CODE_LVAR)) {
+                rn=register_name(large_offset_reg=get_register());
+                printf("\taddis %s,r30,ha16(%d)\n",rn,CODE_LVAR);
+            }
+        }
     } else if (l<0) {  /* local variable */
-	printf("lo16(%d+L_%d)(r0)\n",FUNC_LVAR,lvar_offset_label);
+        if (LARGE_OFFSET(FUNC_LVAR)) {
+            rn=register_name(large_offset_reg=get_register());
+            printf("\taddis %s,r30,ha16(%d)\n",rn,FUNC_LVAR);
+        }
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-	if (CALLER_ARG>32765)
-	    printf("lo16(%d)(r0)\n",CALLER_ARG);
-	else
-	    printf("lo16(%d)(r1)\n",CALLER_ARG);
+        if (LARGE_OFFSET(CALLER_ARG)) {
+            rn=register_name(large_offset_reg=get_register());
+            printf("\taddis %s,r1,ha16(%d)\n",rn,CALLER_ARG);
+        }
     } else { /* callee's arguments */
-	printf("lo16(%d+L_%d)(r0)\n",CALLEE_ARG,r1_offset_label);
+        if (LARGE_OFFSET(CALLEE_ARG)) {
+            rn=register_name(large_offset_reg=get_register());
+            printf("\taddis %s,r30,lo16(%d+L_%d)\n",
+		rn,CALLEE_ARG,lvar_offset_label);
+        }
     }
 }
 
-#define lvar_intro(i) if (LARGE_LVAR) lvar16ha(i)
-
-#define lvar(i) if (LARGE_LVAR) lvar16lo(i); else lvar8(i)
 
 void
 code_lvar(int e2,int reg) {
@@ -1116,7 +1133,7 @@
     if (offset==0) {
 	if(r!=reg)
 	    printf("\tmr %s,%s\n",crn,rrn);
-    } else if (offset<-32768||32767<offset) {
+    } else if (LARGE_OFFSET(offset)) {
 	printf("\tla   %s,ha16(%d)(%s)\n",crn,offset,rrn);
 	printf("\taddi %s,%s,lo16(%d)\n",crn,crn,offset);
     } else
@@ -1128,7 +1145,7 @@
 {
     char *crn = register_name(reg);
     char *rrn = register_name(r);
-    if (offset<-32768||32767<offset) {
+    if (LARGE_OFFSET(offset)) {
 	printf("\tla   %s,ha16(%d)(%s)\n",crn,offset,rrn);
 	printf("\t%s %s,%s,lo16(%d)\n",ld,crn,crn,offset);
     } else
@@ -2239,7 +2256,7 @@
 code_fix_frame_pointer(int disp_offset) {
     int l = 0;
     printf("\tla r30,");
-    printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label);
+    printf("lo16(%d)(r30)\n",FUNC_LVAR);
 }
 
 void
@@ -2270,7 +2287,10 @@
     crn=register_name(creg);
     use_int(reg);
     rrn=register_name(reg);
-    printf("\t%s %s,%d(%s)\n",cload(sz),rrn,offset,crn);
+    if (LARGE_OFFSET(offset)) {
+        printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset);
+    }
+    printf("\t%s %s,lo16(%d)(%s)\n",cload(sz),rrn,offset,crn);
     cext(sign,sz,reg);
 }
 
@@ -2283,8 +2303,12 @@
     if (!is_int_reg(creg)) error(-1);
     crn=register_name(creg);
     use_float(d,reg);
-    printf("\t%s %s,%d(%s)\n",fload(d),
+    if (LARGE_OFFSET(offset)) {
+        printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset);
+    }
+    printf("\t%s %s,lo16(%d)(%s)\n",fload(d),
 	fregister_name(reg),offset,crn);
+
     return d?DOUBLE:FLOAT;
 }
 #endif
@@ -2293,12 +2317,15 @@
 lload(int creg,int reg,int offset)
 {
     char *crn = register_name(creg);
+    if (LARGE_OFFSET(offset)) {
+	printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset);
+    }
     if (creg!=regv_h(reg)) {
-	printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset,crn);
-	printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
+	printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn);
+	printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
     } else {
-	printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
-	printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset,crn);
+	printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
+	printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn);
     }
 }
 
@@ -2762,8 +2789,16 @@
     fwddef(code_base);
     r1_offset_label = fwdlabel();
     lvar_offset_label = fwdlabel();
+#if 0
+    printf("\taddi r30,r1,lo16(-L_%d)\n",lvar_offset_label);
     printf("\tstwu r1,lo16(-L_%d)(r1)\n",r1_offset_label);
-    printf("\tmr r30,r1\n");
+    // printf("\tmr r30,r1\n");
+#else
+    printf("\taddi r30,r1,lo16(-L_%d)\n",lvar_offset_label);
+    printf("\tlis r31,ha16(-L_%d)\n",r1_offset_label);
+    printf("\taddi r31,r31,lo16(-L_%d)\n",r1_offset_label);
+    printf("\tstwux r1,r1,r31\n");
+#endif
     printf("\tmflr r31\n");
     max_func_args = 0;
 }
@@ -3384,10 +3419,10 @@
 "        mflr r10",
 "        mtlr r0",
 "        xoris r3,r3,0x8000",
-"        stw r3,-28(r30)",
+"        stw r3,-28(r1)",
 "        lis r0,0x4330",
-"        stw r0,-32(r30)",
-"        lfd f0,-32(r30)",
+"        stw r0,-32(r1)",
+"        lfd f0,-32(r1)",
 "        addis r9,r10,ha16(__i2dLC0-__i2dL1$pb)",
 "        lfd f1,lo16(__i2dLC0-__i2dL1$pb)(r9)",
 "        fsub f1,f0,f1",
@@ -3427,16 +3462,16 @@
 "        cror 2,1,2",
 "        beq- cr0,__d2uL2",
 "        fctiwz f0,f1",
-"        stfd f0,-32(r30)",
-"        lwz r3,-28(r30)",
+"        stfd f0,-32(r1)",
+"        lwz r3,-28(r1)",
 "        blr",
 "__d2uL2:",
 "        addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)",
 "        lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)",
 "        fsub f0,f1,f0",
 "        fctiwz f0,f0",
-"        stfd f0,-24(r30)",
-"        lwz r3,-20(r30)",
+"        stfd f0,-24(r1)",
+"        lwz r3,-20(r1)",
 "        xoris r3,r3,0x8000",
 "        blr",
 0
@@ -3469,10 +3504,10 @@
 "__u2dL2$pb:",
 "        mflr r10",
 "        mtlr r0",
-"        stw r3,-28(r30)",
+"        stw r3,-28(r1)",
 "        lis r0,0x4330",
-"        stw r0,-32(r30)",
-"        lfd f0,-32(r30)",
+"        stw r0,-32(r1)",
+"        lfd f0,-32(r1)",
 "        addis r9,r10,ha16(__u2dLC1-__u2dL2$pb)",
 "        lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)",
 "        fsub f1,f0,f1",