Mercurial > hg > CbC > old > device
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; }