diff mc-code-powerpc.c @ 313:f73b93de216a alloca

alloca done for ia32, powerpc, mips
author kono
date Tue, 15 Jun 2004 00:11:26 +0900
parents e1d17d6adfcc
children 22d92986c7f7
line wrap: on
line diff
--- a/mc-code-powerpc.c	Sat Jun 12 15:58:56 2004 +0900
+++ b/mc-code-powerpc.c	Tue Jun 15 00:11:26 2004 +0900
@@ -11,6 +11,16 @@
     0
 };
 
+char *init_src = "\
+#define __ppc__ 1\n\
+#define __BIG_ENDIAN__ 1\n\
+#define __STDC__ 1\n\
+#define __builtin_va_list int\n\
+#define __builtin_va_start(ap,arg) ap=(((int)(&arg))+sizeof(arg))\n\
+#define __builtin_va_arg(ap,type)  (*((type *)ap)++)\n\
+#define alloca __builtin_alloca\n\
+";
+
 #define TEXT_EMIT_MODE 0
 #define DATA_EMIT_MODE 1
 #define RODATA_EMIT_MODE 2
@@ -32,6 +42,7 @@
 static int code_setup;
 static int r1_offset_label;
 static int lvar_offset_label;
+static int max_func_arg_label;
 
 static int reg_save;
 static int freg_save;
@@ -294,6 +305,11 @@
     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);
+    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;
+    }
+
 #if 0
 printf("# function %s\n",fnptr->nm);
     l = ARG_LVAR_OFFSET;
@@ -326,7 +342,7 @@
     } 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)(r30)\n",CALLER_ARG);
+	printf("lo16(%d)(r1)\n",CALLER_ARG);
     } else { /* callee's arguments */
 	printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label);
     }
@@ -353,7 +369,7 @@
 	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)(r30)\n",CALLER_ARG);
+	    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);
     }
@@ -373,7 +389,7 @@
 	if (CALLER_ARG>32765)
 	    printf("lo16(%d)(r0)\n",CALLER_ARG);
 	else
-	    printf("lo16(%d)(r30)\n",CALLER_ARG);
+	    printf("lo16(%d)(r1)\n",CALLER_ARG);
     } else { /* callee's arguments */
 	printf("lo16(%d+L_%d)(r0)\n",CALLEE_ARG,r1_offset_label);
     }
@@ -391,15 +407,6 @@
     lvar(e2);
 }
 
-char *init_src = "\
-#define __ppc__ 1\n\
-#define __BIG_ENDIAN__ 1\n\
-#define __STDC__ 1\n\
-#define __builtin_va_list int\n\
-#define __builtin_va_start(ap,arg) ap=(((int)(&arg))+sizeof(arg))\n\
-#define __builtin_va_arg(ap,type)  (*((type *)ap)++)\n\
-";
-
 void
 code_init(void)
 {
@@ -1784,7 +1791,7 @@
 {
     return e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| 
 	e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT||
-	e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD||e3==LASSOP;
+	e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD||e3==LASSOP||e3==ALLOCA;
 }
 
 static int
@@ -1950,6 +1957,7 @@
     }
 #else
     ret_type = function_type(cadddr(e1),&dots);
+    if (caddr(cadddr(e1))==0) dots=1;
 #endif
 
     arg_assign = 0;
@@ -2180,6 +2188,28 @@
 }
 
 void
+code_alloca(int e1,int reg)
+{
+    char *crn,*grn;
+    int g;
+  
+    g_expr(list3(BAND,list3(ADD,e1,list2(CONST,30)),list2(CONST,~15))); 
+    use_int(reg);
+    g = get_register();
+    crn = register_name(reg);
+    grn = register_name(g);
+//    printf("\trlwinm r0,%s,0,0,27\n",crn);
+    printf("\tlwz %s,0(r1)\n",grn);
+    printf("\tneg %s,%s\n",crn,crn);
+    printf("\tstwux %s,r1,%s\n",grn,crn);
+//    printf("\tstw %s,0(r1)\n",grn);
+    if (!max_func_arg_label) max_func_arg_label = fwdlabel();
+    printf("\taddis r1,r1,ha16(L_%d)\n",max_func_arg_label);
+    printf("\taddi %s,r1,lo16(L_%d)\n",crn,max_func_arg_label);
+    free_register(g);
+}
+
+void
 code_frame_pointer(int e3) {
     use_int(e3);
 #if R1SAVE