diff mc-code-powerpc.c @ 255:8cd8d72286ae

PowerPC long long complex function call fix. MIPS entry frame calc.
author kono
date Fri, 14 May 2004 20:57:52 +0900
parents 1452eb0eab20
children d80e6387c539
line wrap: on
line diff
--- a/mc-code-powerpc.c	Wed May 12 21:44:45 2004 +0900
+++ b/mc-code-powerpc.c	Fri May 14 20:57:52 2004 +0900
@@ -636,7 +636,7 @@
     int i,j,ll;
     int max_reg_var_save=max_reg_var;
     ll = get_lregister0();
-    if (ll==-1) return -1;
+    if (ll==-1) goto not_found;
     if (regs[ll]==0) {
 	for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
 	    if (! regs[REG_VAR_BASE-i]) {       /* 使われていないなら */
@@ -1554,6 +1554,19 @@
     // save_stack,clear_ptr_cache is assmued    
     if (!is_longlong_reg(reg)) { error(-1); return; }
     if (mode) {
+	if (regv_l(reg)!=3)
+	    printf("\tmr r3,%s\n", lregister_name_high(reg));
+	if (regv_l(reg)!=4)
+	    printf("\tmr r4,%s\n", lregister_name_low(reg));
+    }
+}
+
+void
+set_lreg_operand1(int reg,int mode)
+{
+    // save_stack,clear_ptr_cache is assmued    
+    if (!is_longlong_reg(reg)) { error(-1); return; }
+    if (mode) {
 	if (regv_l(reg)!=5)
 	    printf("\tmr r5,%s\n", lregister_name_high(reg));
 	if (regv_l(reg)!=6)
@@ -1630,8 +1643,9 @@
 static int
 not_simple_p(int e3)
 {
-    return (e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| 
-	(((e3/100)==LOP)&&(e3!=LREGISTER||e3!=LADD||e3!=LSUB)));
+    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;
 }
 
 int
@@ -1764,11 +1778,26 @@
 		use_input_reg(cadr(r0),1);
 	    } else if (!simple_args(e3) && cadr(e3)) {
 		arg = get_lregister_var(0); 
-		arg_assign = list2(
-		    assign_expr0(r0=get_input_lregister_var(reg_arg,0,0),
-			arg,t,t),
-		    arg_assign);
-		use_input_reg(cadr(r0),1);
+		if (car(arg)==LREGISTER) {
+		    // r0=get_input_lregiste... is not preserved
+		    // we cannot mark r0 used, it consumes unused register
+		    // but get_input_register is preserved.
+		    arg_assign = list2(
+			assign_expr0(get_input_register_var(reg_arg,0,0),
+			    list2(REGISTER,regv_h(cadr(arg))),INT,INT), 
+			list2(
+			assign_expr0(get_input_register_var(reg_arg+1,0,0),
+			    list2(REGISTER,regv_l(cadr(arg))),INT,INT), 
+			arg_assign));
+		} else {
+		    arg_assign = list2(
+			assign_expr0(get_input_register_var(reg_arg,0,0),
+			    list2(LVAR,cadr(arg)+SIZE_OF_INT),INT,INT), 
+			list2(
+			assign_expr0(get_input_register_var(reg_arg+1,0,0),
+			    list2(LVAR,cadr(arg)),INT,INT), 
+			arg_assign));
+		}
 	    } else {
 		arg = get_input_lregister_var(reg_arg,0,0); 
 		use_input_reg(cadr(arg),1);
@@ -3724,12 +3753,13 @@
 #endif
 
 static void
-code_asld_lib(int oreg)
+code_asld_lib(int reg,int oreg)
 { 
     code_save_stacks();
     clear_ptr_cache();
     asld_lib_used = 1;
-    set_lreg(RET_LREGISTER,1);
+    set_lreg_operand(reg,1);
+    set_lreg(RET_LREGISTER,0);
     if (regv_l(oreg)!=5) {
 	printf("\tmr r5,%s\n", lregister_name_low(oreg));
     }
@@ -3737,12 +3767,13 @@
 }
 
 static void
-code_asrd_lib(int oreg) // ___ashrdi3$stub
+code_asrd_lib(int reg,int oreg) // ___ashrdi3$stub
 {
     code_save_stacks();
     clear_ptr_cache();
     asrd_lib_used = 1;
-    set_lreg(RET_LREGISTER,1);
+    set_lreg_operand(reg,1);
+    set_lreg(RET_LREGISTER,0);
     if (regv_l(oreg)!=5) {
 	printf("\tmr r5,%s\n", lregister_name_low(oreg));
     }
@@ -3750,12 +3781,13 @@
 }
 
 static void
-code_lsrd_lib(int oreg) // ___lshrdi3$stub
+code_lsrd_lib(int reg,int oreg) // ___lshrdi3$stub
 {
     code_save_stacks();
     clear_ptr_cache();
     lsrd_lib_used = 1;
-    set_lreg(RET_LREGISTER,1);
+    set_lreg_operand(reg,1);
+    set_lreg(RET_LREGISTER,0);
     if (regv_l(oreg)!=5) {
 	printf("\tmr r5,%s\n", lregister_name_low(oreg));
     }
@@ -3763,42 +3795,46 @@
 }
 
 static void
-code_ldiv_lib(int oreg) // ___divdi3$stub
+code_ldiv_lib(int reg,int oreg) // ___divdi3$stub
 {
     code_save_stacks();
     clear_ptr_cache();
-    set_lreg(RET_LREGISTER,1);
-    set_lreg_operand(oreg,1);
+    set_lreg_operand(reg,1);
+    set_lreg(RET_LREGISTER,0);
+    set_lreg_operand1(oreg,1);
     extern_conv("__divdi3");
 }
 
 static void
-code_ludiv_lib(int oreg) // ___udivdi3$stub
+code_ludiv_lib(int reg,int oreg) // ___udivdi3$stub
 {
     code_save_stacks();
     clear_ptr_cache();
-    set_lreg(RET_LREGISTER,1);
-    set_lreg_operand(oreg,1);
+    set_lreg_operand(reg,1);
+    set_lreg(RET_LREGISTER,0);
+    set_lreg_operand1(oreg,1);
     extern_conv("__udivdi3");
 }
 
 static void
-code_lmod_lib(int oreg) // ___moddi3$stub
+code_lmod_lib(int reg,int oreg) // ___moddi3$stub
 {
     code_save_stacks();
     clear_ptr_cache();
-    set_lreg(RET_LREGISTER,1);
-    set_lreg_operand(oreg,1);
+    set_lreg_operand(reg,1);
+    set_lreg(RET_LREGISTER,0);
+    set_lreg_operand1(oreg,1);
     extern_conv("__moddi3");
 }
 
 static void
-code_lumod_lib(int oreg) // ___umoddi3$stub
+code_lumod_lib(int reg,int oreg) // ___umoddi3$stub
 {
     code_save_stacks();
     clear_ptr_cache();
-    set_lreg(RET_LREGISTER,1);
-    set_lreg_operand(oreg,1);
+    set_lreg(RET_LREGISTER,0);
+    set_lreg_operand(reg,1);
+    set_lreg_operand1(oreg,1);
     extern_conv("__umoddi3");
 }
 
@@ -3826,17 +3862,17 @@
     switch(op) {
     case LLSHIFT:
     case LULSHIFT:
-	code_asld_lib(oreg); // ___ashldi3$stub
+	code_asld_lib(reg,oreg); // ___ashldi3$stub
 	check_lreg(reg);
 	if(ox!=-1) free_register(ox);
 	return;
     case LRSHIFT:
-	code_asrd_lib(oreg); // ___ashrdi3$stub
+	code_asrd_lib(reg,oreg); // ___ashrdi3$stub
 	check_lreg(reg);
 	if(ox!=-1) free_register(ox);
 	return;
     case LURSHIFT:
-	code_lsrd_lib(oreg); // ___lshrdi3$stub
+	code_lsrd_lib(reg,oreg); // ___lshrdi3$stub
 	check_lreg(reg);
 	if(ox!=-1) free_register(ox);
 	return;
@@ -3895,19 +3931,19 @@
 	printf("\tmr %s,%s\n",       crn_l,drn_l);
 	break;
     case LDIV:
-	code_ldiv_lib(oreg); // ___divdi3$stub
+	code_ldiv_lib(reg,oreg); // ___divdi3$stub
 	check_lreg(reg);
 	break;
     case LUDIV:
-	code_ludiv_lib(oreg); // ___udivdi3$stub
+	code_ludiv_lib(reg,oreg); // ___udivdi3$stub
 	check_lreg(reg);
 	break;
     case LMOD:
-	code_lmod_lib(oreg); // ___moddi3$stub
+	code_lmod_lib(reg,oreg); // ___moddi3$stub
 	check_lreg(reg);
 	break;
     case LUMOD:
-	code_lumod_lib(oreg); // ___umoddi3$stub
+	code_lumod_lib(reg,oreg); // ___umoddi3$stub
 	check_lreg(reg);
 	break;
     default: