changeset 593:c139d4d9307c

ltosop optimize implement throw in ARM
author kono
date Fri, 20 Jan 2006 18:48:45 +0900
parents 259a53737e25
children f49c825920c4
files Changes mc-code-arm.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c test/tmpb.code-out
diffstat 6 files changed, 99 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Fri Jan 20 14:05:48 2006 +0900
+++ b/Changes	Fri Jan 20 18:48:45 2006 +0900
@@ -8546,4 +8546,32 @@
 register stack overflow ってなかなかでないのね。ローカル
 変数をレジスタにマップしない限りレジスタって意味ないのか。
 
-
+Fri Jan 20 16:48:01 JST 2006
+
+なんか ARM の code segment の方のoffset がぼろぼろだ。
+つじつまはあっているんだろうけど。
+
+disp_offset==0 のシステムはいいんだよね。ARM だと、
+fp を設定してからregisterをsaveするので、不定の
+オフセットが存在する。jump with environment した
+時には、その分がずれてしまう。
+
+通常のfunction からの goto でも、このずれは存在する
+ので、fp の修正はいずれにせよ必要。
+
+だけど、jump はcodegenにあるので、汎用に修正しない
+といけない。
+
+fp を jump/leave 時に offset_label の分だけずらすことに
+しました。code_fix_frame_pointer で処理します。
+env を設定したときには、environment は、修正されたfp
+を持っているので、fix しないようにします。
+
+いずれにせよ、environment は、設定した環境の中で不定の
+場所に陣どるので注意が必要。
+
+
+
+
+
+
--- a/mc-code-arm.c	Fri Jan 20 14:05:48 2006 +0900
+++ b/mc-code-arm.c	Fri Jan 20 18:48:45 2006 +0900
@@ -393,8 +393,7 @@
 int disp_offset=0;    // fore mc-codegen.c
 #define disp_offset  0
 
-#define func_disp_offset 8
-#define code_disp_offset (-64)
+#define code_disp_offset 0
 
 #define CODE_LVAR(l) ((l)+code_disp_offset)
 #define CODE_CALLER_ARG(l) ((l)+arg_offset1)
@@ -1779,19 +1778,22 @@
     printf("\tldr\t%s, .L%d+%d\n",crn,label,disp);
 }
 
-#define R1SAVE 0
-
 void
 code_environment(int creg) {
     /* save frame pointer */
-    inc_inst(1);
-#if R1SAVE
-    use_int(creg);
-    printf("\tldr\t%s, [fp, #0]\n",register_name(creg));
-#else
-    use_int(creg);
-    printf("\tmov\t%s, fp\n",register_name(creg));
-#endif
+    if (is_code(fnptr)) {
+	inc_inst(1);
+	use_int(creg);
+	printf("\tmov\t%s, fp\n",register_name(creg));
+    } else {
+	int disp,label;
+	char *trn = register_name(REG_ip);
+	inc_inst(2);
+	use_int(creg);
+	disp = search_const(LVAR,glist2(lvar_offset_label,FUNC_LVAR(0)),&label);
+	printf("\tldr\t%s, .L%d+%d\n",trn,label,disp);
+	printf("\tadd\t%s, fp, %s\n",register_name(creg),trn);
+    }
 }
 
 static int rexpr_bool(int e1, int reg);
@@ -2720,11 +2722,7 @@
 code_frame_pointer(int e3) {
     use_int(e3);
     inc_inst(1);
-#if R1SAVE
     printf("\tmov\tfp, %s\n",register_name(e3));
-#else
-    printf("\tmov\tfp, %s\n",register_name(e3));
-#endif
 }
 
 int
@@ -2734,8 +2732,30 @@
 }
 
 void
-code_fix_frame_pointer(int offset) {
-}
+code_fix_frame_pointer(int env) {
+    char *trn;
+    int disp,label;
+
+    if (is_function(fnptr) && ! env) {
+	trn = register_name(REG_ip);
+	disp = search_const(LVAR,glist2(lvar_offset_label,FUNC_LVAR(0)),&label);
+	printf("\tldr\t%s, .L%d+%d\n",trn,label,disp);
+	printf("\tadd\tfp, fp, %s\n",trn);
+    }
+}
+
+static void
+code_unfix_frame_pointer()
+{
+    char *trn;
+    int disp,label;
+
+    trn = register_name(REG_ip);
+    disp = search_const(LVAR,glist2(lvar_offset_label,FUNC_LVAR(0)),&label);
+    printf("\tldr\t%s, .L%d+%d\n",trn,label,disp);
+    printf("\tsub\tfp, fp, %s\n",trn);
+}
+
 
 void
 code_jmp(char *s) {
@@ -3457,7 +3477,7 @@
 	    sz = size(cadr(fnptr->ty));
 	    inc_inst(3);
 	    code_const(sz,REGISTER_OPERAND);
-	    printf("\tsubl\tr1, r2, fp\n");
+	    printf("\tsub\tr1, r2, fp\n");
 	    printf("\tldr\tr0, [fp, #%d]\n",(my_func_args-1)*SIZE_OF_INT);
 	    emit_copy(6,3,sz,0,1,1);
 	} else if (cadr(fnptr->ty)!=VOID) {
@@ -3465,9 +3485,7 @@
 	    if (creg!=RET_REGISTER)
 		set_ireg(RET_REGISTER,1);
 	}
-#if R1SAVE
-#else
-#endif
+	code_unfix_frame_pointer();
     }
     fwddef(retlabel);
 
--- a/mc-code-mips.c	Fri Jan 20 14:05:48 2006 +0900
+++ b/mc-code-mips.c	Fri Jan 20 18:48:45 2006 +0900
@@ -4591,12 +4591,14 @@
     char *ch,*cl,*oh,*ol,*dh,*dl;
     //    5   4   7   3   2   6
     int dreg = get_lregister();
+    int sreg = get_register();
     ch = lregister_name_high(reg);
     cl = lregister_name_low(reg);
-    oh = lregister_name_high(oreg);
+    oh = register_name(sreg);
     ol = lregister_name_low(oreg);
     dh = lregister_name_high(dreg);
     dl = lregister_name_low(dreg);
+    printf("\tmove %s,%s\n",oh,lregister_name_high(oreg));
     
     printf("\tsll     %s,%s,26\n",dh,ol);
     printf("\tbgez    %s,1f\n",dh);
@@ -4620,6 +4622,7 @@
     // printf("\tmove    %s,%s\n",ch,oh);
     printf("\tmove    %s,%s\n",dh,oh);
     set_lreg(dreg,0);
+    free_register(sreg);
     // free_register(dreg);
 }
 
@@ -4629,12 +4632,14 @@
     char *ch,*cl,*oh,*ol,*dh,*dl;
     //    5   4   2   3   9   8
     int dreg = get_lregister();
+    int sreg = get_register();
     ch = lregister_name_high(creg);
     cl = lregister_name_low(creg);
-    oh = lregister_name_high(oreg);
+    oh = register_name(sreg);
     ol = lregister_name_low(oreg);
     dh = lregister_name_high(dreg);
     dl = lregister_name_low(dreg);
+    printf("\tmove %s,%s\n",oh,lregister_name_high(oreg));
 
     printf("\tsll     %s,%s,26\n",oh,ol);
     printf("\tbgez    %s,1f\n",oh);
@@ -4656,6 +4661,7 @@
     printf("\t3:\n");
     // printf("\tmove    %s,%s\n",cl,dl);
     // printf("\tmove    %s,%s\n",ch,dh);
+    free_register(sreg);
     set_lreg(dreg,0);
     // free_register(dreg);
 }
@@ -4666,12 +4672,14 @@
     char *ch,*cl,*oh,*ol,*dh,*dl;
     //    5   4   2   3   9   8
     int dreg = get_lregister();
+    int sreg = get_register();
     ch = lregister_name_high(reg);
     cl = lregister_name_low(reg);
-    oh = lregister_name_high(oreg);
+    oh = register_name(sreg);
     ol = lregister_name_low(oreg);
     dh = lregister_name_high(dreg);
     dl = lregister_name_low(dreg);
+    printf("\tmove %s,%s\n",oh,lregister_name_high(oreg));
     
     printf("\tsll     %s,%s,26\n",oh,ol);
     printf("\tbgez    %s,1f\n",oh);
@@ -4695,6 +4703,7 @@
     printf("\t3:\n");
     // printf("\tmove    %s,%s\n",cl,dl);
     // printf("\tmove    %s,%s\n",ch,dh);
+    free_register(sreg);
     set_lreg(dreg,0);
     // free_register(dreg);
 }
@@ -4797,8 +4806,8 @@
         /*
             drn_l 4 = l32( crn_l * orn_l);  6, 2
             drn_h 5 = h32( crn_l * orn_l);
-            orn_l 6 = l32( crn_h * orn_l);  7, 3
-	    drn_h 5 = drn_h + orn_l;  5, 6
+            crn_h 7 = l32( crn_h * orn_l);  7, 3
+	    drn_h 5 = drn_h + crn_h;  5, 7
             crn_l 2 = l32( crn_l * orn_h);  2, 6
 	    crn_h 5 = drn_h + crn_l;  5, 2
 	    crn_l = drn_l;
@@ -4807,8 +4816,8 @@
 	printf("\tmultu   %s,%s\n",crn_l,orn_l);
 	printf("\tmfhi    %s\n",drn_h);
 	printf("\tmflo    %s\n",drn_l);
-	printf("\tmult    %s,%s,%s\n",orn_l,crn_h,orn_l);
-	printf("\taddu    %s,%s,%s\n",drn_h,drn_h,orn_l);
+	printf("\tmult    %s,%s,%s\n",crn_h,crn_h,orn_l);
+	printf("\taddu    %s,%s,%s\n",drn_h,drn_h,crn_h);
 	printf("\tmult    %s,%s,%s\n",crn_l,crn_l,orn_h);
 	printf("\taddu    %s,%s,%s\n",crn_h,drn_h,crn_l);
 	printf("\tmove    %s,%s\n",crn_l,drn_l);
--- a/mc-code-powerpc.c	Fri Jan 20 14:05:48 2006 +0900
+++ b/mc-code-powerpc.c	Fri Jan 20 18:48:45 2006 +0900
@@ -4634,16 +4634,16 @@
         /*
             drn_l = l32( crn_l * orn_l);
             drn_h = h32( crn_l * orn_l);
-            orn_l = l32( crn_h * orn_l);
-	    drn_h = drn_h + orn_l;
+            crn_h = l32( crn_h * orn_l);
+	    drn_h = drn_h + crn_h;
             crn_l = l32( crn_l * orn_h);
 	    crn_h = drn_h + crn_l;
 	    crn_l = drn_l;
         */
 	printf("\tmulhwu %s,%s,%s\n",drn_h,crn_l,orn_l);
 	printf("\tmullw %s,%s,%s\n", drn_l,crn_l,orn_l);
-	printf("\tmullw %s,%s,%s\n", orn_l,crn_h,orn_l);
-	printf("\tadd %s,%s,%s\n",   drn_h,drn_h,orn_l);
+	printf("\tmullw %s,%s,%s\n", crn_h,crn_h,orn_l);
+	printf("\tadd %s,%s,%s\n",   drn_h,drn_h,crn_h);
 	printf("\tmullw %s,%s,%s\n", crn_l,orn_h,crn_l);
 	printf("\tadd %s,%s,%s\n",   crn_h,drn_h,crn_l);
 	printf("\tmr %s,%s\n",       crn_l,drn_l);
--- a/mc-codegen.c	Fri Jan 20 14:05:48 2006 +0900
+++ b/mc-codegen.c	Fri Jan 20 18:48:45 2006 +0900
@@ -1390,8 +1390,9 @@
 	    while(car(e2)==RSTRUCT) e2=cadr(e2);
 	/*
 	    envreg contains frame pointer, we need disp_offset. disp_offset
-	    for code segment and function should be the same value. That is
-	    fix_frame_pointer() is not allowed in this system.
+	    for code segment and function should be the same value. 
+	    If original frame pointer has indeterminate offset, these should
+	    fixed in code_fix_frame_pointer.
 	 */
 	    g_expr_u(assign_expr0(
 		list2(INDIRECT,
@@ -1437,7 +1438,7 @@
 #ifdef SAVE_ALL_NON_MEMORY
 	if (!is_simple(car(s0))) {
 #else
-	if (contains_p(s0,not_simple_p)) {
+	if (contains_p(s0,not_simple_p)) {   /* } */
 #endif
 	    /* complex case */
 	    g_expr_u(assign_expr0((e4=list3(LVAR,new_lvar(sz),0)),s0,ty,ty));
@@ -1520,12 +1521,13 @@
 	    free_lvar(cadr(caddr(use)));
 	use=cadr(use);
     }
-    if(target) error(-1);
+    // if(target) error(-1);
     if(env) {
 	if (car(envreg)==REGISTER)
 	    free_register(cadr(envreg));
 	else free_lvar(cadr(envreg));
     }
+    code_fix_frame_pointer(env);
 
     if (car(e2) == FNAME) {	
 	code_jmp(code0->nm);
@@ -1615,6 +1617,7 @@
 	return;
     }
     if (car(e3)==LREGISTER) {
+	// ltosop should not destory its operand (register e3)
 	g_expr(e2);
 	ltosop(op,USE_CREG,cadr(e3));
 	return;
@@ -1622,7 +1625,7 @@
     g_expr(e3);
     emit_lpush();
     g_expr(e2);
-    ltosop(car(e1),USE_CREG,(e2=emit_lpop()));
+    ltosop(op,USE_CREG,(e2=emit_lpop()));
     emit_lpop_free(e2);
     return;
 }
--- a/test/tmpb.code-out	Fri Jan 20 14:05:48 2006 +0900
+++ b/test/tmpb.code-out	Fri Jan 20 18:48:45 2006 +0900
@@ -1,2 +1,4 @@
 1  2 -1504
 1  2 -17890483
+1  2 -1504
+1  2 -17890483