Mercurial > hg > CbC > old > device
comparison mc-code-arm.c @ 412:6b3385124e5e arm-self-compile
ARM regsiter var pattern fix.
author | kono |
---|---|
date | Tue, 19 Oct 2004 23:39:42 +0900 |
parents | 32c1914308db |
children | d4dc6d99ffdb |
comparison
equal
deleted
inserted
replaced
411:32c1914308db | 412:6b3385124e5e |
---|---|
91 static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | 91 static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ |
92 | 92 |
93 #define REG_ip 13 | 93 #define REG_ip 13 |
94 #define REG_fp 14 | 94 #define REG_fp 14 |
95 #define REG_sp 15 | 95 #define REG_sp 15 |
96 #define REG_VAR_BASE 11 | 96 #define REG_VAR_BASE 5 |
97 #define REG_VAR_MIN 9 | 97 #define REG_VAR_MIN 5 |
98 #define MIN_TMP_REG 2 /* only one tmp register? */ | 98 #define REG_VAR_USER_MAX 9 /* at leat 6 tmp var */ |
99 #define MAX_TMP_REG 8 | 99 #define REG_VAR_MAX 12 |
100 #define MIN_TMP_REG 1 | |
101 #define MAX_TMP_REG 4 | |
100 | 102 |
101 #define PTRC_REG 3 /* mark for pointer cache */ | 103 #define PTRC_REG 3 /* mark for pointer cache */ |
102 | 104 |
103 #define FREG_VAR_BASE 7 | 105 #define FREG_VAR_BASE 7 |
104 #define FREG_VAR_MIN 4 | 106 #define FREG_VAR_MIN 4 |
649 free_register(reg); | 651 free_register(reg); |
650 return get_register(); | 652 return get_register(); |
651 } | 653 } |
652 } | 654 } |
653 #endif | 655 #endif |
654 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | 656 for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { |
655 reg =REG_VAR_BASE-i; | 657 reg =REG_VAR_BASE+i; |
656 if (! regs[reg]) { /* 使われていないなら */ | 658 if (! regs[reg]) { /* 使われていないなら */ |
657 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ | 659 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ |
658 if (i+1>max_reg_var) max_reg_var=i+1; | 660 if (i+1>max_reg_var) max_reg_var=i+1; |
659 return reg; /* その場所を表す番号を返す */ | 661 return reg; /* その場所を表す番号を返す */ |
660 } | 662 } |
666 } else | 668 } else |
667 continue; | 669 continue; |
668 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | 670 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ |
669 return i; /* その場所を表す番号を返す */ | 671 return i; /* その場所を表す番号を返す */ |
670 } | 672 } |
671 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | 673 for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { |
672 reg =REG_VAR_BASE-i; | 674 reg =REG_VAR_BASE+i; |
673 /* PTR_CACHE をつぶす */ | 675 /* PTR_CACHE をつぶす */ |
674 if (regs[reg]==PTRC_REG) { | 676 if (regs[reg]==PTRC_REG) { |
675 clear_ptr_cache_reg(reg); | 677 clear_ptr_cache_reg(reg); |
676 regs[reg]=0; | 678 regs[reg]=0; |
677 return reg; /* その場所を表す番号を返す */ | 679 return reg; /* その場所を表す番号を返す */ |
786 int i,j,ll; | 788 int i,j,ll; |
787 int max_reg_var_save=max_reg_var; | 789 int max_reg_var_save=max_reg_var; |
788 ll = get_lregister0(); | 790 ll = get_lregister0(); |
789 if (ll==-1) return -1; | 791 if (ll==-1) return -1; |
790 if (regs[ll]==0) { | 792 if (regs[ll]==0) { |
791 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | 793 for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { |
792 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ | 794 if (! regs[REG_VAR_BASE+i]) { /* 使われていないなら */ |
793 /* そのレジスタを使うことを宣言し */ | 795 /* そのレジスタを使うことを宣言し */ |
794 regs[REG_VAR_BASE-i]=USING_REG; | 796 regs[REG_VAR_BASE+i]=USING_REG; |
795 if (i+1>max_reg_var) max_reg_var=i+1; | 797 if (i+1>max_reg_var) max_reg_var=i+1; |
796 for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) { | 798 for(j=0;j<REG_VAR_MAX-REG_VAR_MIN;j++) { |
797 if (! regs[REG_VAR_BASE-j]) { | 799 if (! regs[REG_VAR_BASE+j]) { |
798 /* 使われていないなら */ | 800 /* 使われていないなら */ |
799 /* そのレジスタを使うことを宣言し */ | 801 /* そのレジスタを使うことを宣言し */ |
800 regs[REG_VAR_BASE-j]=USING_REG; | 802 regs[REG_VAR_BASE+j]=USING_REG; |
801 if (j+1>max_reg_var) max_reg_var=j+1; | 803 if (j+1>max_reg_var) max_reg_var=j+1; |
802 /* その場所を表す番号を返す */ | 804 /* その場所を表す番号を返す */ |
803 regs[ll]=USING_REG; | 805 regs[ll]=USING_REG; |
804 regv_l(ll) = REG_VAR_BASE-j; | 806 regv_l(ll) = REG_VAR_BASE+j; |
805 regv_h(ll) = REG_VAR_BASE-i; | 807 regv_h(ll) = REG_VAR_BASE+i; |
806 return list3(LREGISTER,ll,(int)n); | 808 return list3(LREGISTER,ll,(int)n); |
807 } | 809 } |
808 } | 810 } |
809 /* ひとつしかなかった */ | 811 /* ひとつしかなかった */ |
810 regs[REG_VAR_BASE-i]=0; | 812 regs[REG_VAR_BASE+i]=0; |
811 max_reg_var=max_reg_var_save; | 813 max_reg_var=max_reg_var_save; |
812 goto not_found; | 814 goto not_found; |
813 } | 815 } |
814 } | 816 } |
815 } | 817 } |
874 { | 876 { |
875 int ll; | 877 int ll; |
876 ll = get_lregister0(); | 878 ll = get_lregister0(); |
877 if (ll!=-1) { | 879 if (ll!=-1) { |
878 if (is_code) { | 880 if (is_code) { |
879 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; | 881 if(!(i<REG_VAR_MAX-REG_VAR_MIN)) return 0; |
880 i = REG_VAR_BASE-i; | 882 i = REG_VAR_BASE+i; |
881 } else { | 883 } else { |
882 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; | 884 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; |
883 i++; | 885 i++; |
884 } | 886 } |
885 #if ENDIAN==0 | 887 #if ENDIAN==0 |
895 | 897 |
896 int | 898 int |
897 get_input_register_var(int i,NMTBL *n,int is_code) | 899 get_input_register_var(int i,NMTBL *n,int is_code) |
898 { | 900 { |
899 if (is_code) { | 901 if (is_code) { |
900 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; | 902 if(!(i<REG_VAR_MAX-REG_VAR_MIN)) return 0; |
901 i = REG_VAR_BASE-i; | 903 i = REG_VAR_BASE+i; |
902 } else { | 904 } else { |
903 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; | 905 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; |
904 i = i+1; | 906 i = i+1; |
905 } | 907 } |
906 return list3(REGISTER,i,(int)n); | 908 return list3(REGISTER,i,(int)n); |
1103 reg_sp = 0; | 1105 reg_sp = 0; |
1104 freg_sp = 0; | 1106 freg_sp = 0; |
1105 text_mode(3); | 1107 text_mode(3); |
1106 } | 1108 } |
1107 | 1109 |
1108 #define reg_var_num(i) (REG_VAR_BASE-i) | 1110 #define reg_var_num(i) (REG_VAR_BASE+i) |
1109 | 1111 |
1110 int | 1112 int |
1111 get_register_var(NMTBL *n) | 1113 get_register_var(NMTBL *n) |
1112 { | 1114 { |
1113 int i,j; | 1115 int i,j; |
1114 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | 1116 int max = n?REG_VAR_USER_MAX-REG_VAR_BASE:REG_VAR_MAX-REG_VAR_BASE; |
1117 for(i=0;i<max;i++) { | |
1115 j = reg_var_num(i); | 1118 j = reg_var_num(i); |
1116 if (! regs[j]) { /* 使われていないなら */ | 1119 if (! regs[j]) { /* 使われていないなら */ |
1117 /* そのレジスタを使うことを宣言し */ | 1120 /* そのレジスタを使うことを宣言し */ |
1118 regs[j]=USING_REG; | 1121 regs[j]=USING_REG; |
1119 if (i+1>=max_reg_var) max_reg_var=i+1; | 1122 if (i+1>=max_reg_var) max_reg_var=i+1; |
1464 int label,disp; | 1467 int label,disp; |
1465 inc_inst(3); | 1468 inc_inst(3); |
1466 if (offset==0) { | 1469 if (offset==0) { |
1467 if(r!=reg) | 1470 if(r!=reg) |
1468 printf("\tmov\t%s, %s\n",crn,rrn); | 1471 printf("\tmov\t%s, %s\n",crn,rrn); |
1469 } | 1472 } else if ((s=make_const(offset,&p1,&p2,&p3,0))) { |
1470 if ((s=make_const(offset,&p1,&p2,&p3,0))) { | |
1471 add = s>0?"add":"sub"; | 1473 add = s>0?"add":"sub"; |
1472 printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p1); | 1474 printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p1); |
1473 if (p2) printf("\t%s\t%s, %s, #%d\n",add,crn,crn,p2); | 1475 if (p2) printf("\t%s\t%s, %s, #%d\n",add,crn,crn,p2); |
1474 if (p3) printf("\t%s\t%s, %s, #%d\n",add,crn,crn,p3); | 1476 if (p3) printf("\t%s\t%s, %s, #%d\n",add,crn,crn,p3); |
1475 } else { | 1477 } else { |
2677 } | 2679 } |
2678 | 2680 |
2679 void | 2681 void |
2680 code_jmp(char *s) { | 2682 code_jmp(char *s) { |
2681 // jump to continuation means use all register variable | 2683 // jump to continuation means use all register variable |
2682 max_reg_var = REG_VAR_BASE-REG_VAR_MIN; | 2684 max_reg_var = REG_VAR_MAX-REG_VAR_MIN; |
2683 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; | 2685 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; |
2684 inc_inst(1); | 2686 inc_inst(1); |
2685 printf("\tb\t%s\n",s); | 2687 printf("\tb\t%s\n",s); |
2686 control=0; | 2688 control=0; |
2687 } | 2689 } |
2688 | 2690 |
2689 void | 2691 void |
2690 code_indirect_jmp(int e2) { | 2692 code_indirect_jmp(int e2) { |
2691 // jump to continuation means use all register variable | 2693 // jump to continuation means use all register variable |
2692 max_reg_var = REG_VAR_BASE-REG_VAR_MIN; | 2694 max_reg_var = REG_VAR_MAX-REG_VAR_MIN; |
2693 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; | 2695 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; |
2694 use_int(e2); | 2696 use_int(e2); |
2695 inc_inst(1); | 2697 inc_inst(1); |
2696 printf("\tmov\tpc, %s @ indirect jump\n",register_name(e2)); // ?! | 2698 printf("\tmov\tpc, %s @ indirect jump\n",register_name(e2)); // ?! |
2697 control=0; | 2699 control=0; |
2872 | 2874 |
2873 void | 2875 void |
2874 code_assop(int op,int creg, int byte,int sign) { | 2876 code_assop(int op,int creg, int byte,int sign) { |
2875 char *xrn,*crn,*drn; | 2877 char *xrn,*crn,*drn; |
2876 int xreg; | 2878 int xreg; |
2877 int edx = get_register(); if(!edx) error(-1); | 2879 int edx = get_register_var(0); |
2880 if (car(edx)!=REGISTER) error(-1); | |
2878 // (*creg) op = pop() | 2881 // (*creg) op = pop() |
2879 | 2882 |
2883 drn = register_name(edx=cadr(edx)); | |
2880 use_int(creg); | 2884 use_int(creg); |
2881 xrn = register_name(xreg = emit_pop(0)); /* pop e3 value */ | 2885 xrn = register_name(xreg = emit_pop(0)); /* pop e3 value */ |
2882 set_ireg(edx,0); | 2886 code_register(creg,edx); |
2883 ld_indexx(byte,0,creg,ireg,sign); | 2887 ld_indexx(byte,0,edx,creg,sign); |
2884 use_reg(creg); | 2888 tosop(op,creg,xreg); |
2885 tosop(op,ireg,xreg); | 2889 crn = register_name(creg); |
2886 crn = register_name(ireg); | |
2887 drn = register_name(creg); | |
2888 printf("\t%s\t%s, [%s, #0]\n",cstore(byte),crn,drn); | 2890 printf("\t%s\t%s, [%s, #0]\n",cstore(byte),crn,drn); |
2889 free_register(edx); | 2891 free_register(edx); |
2890 free_register(creg); | 2892 free_register(creg); |
2891 emit_pop_free(xreg); | 2893 emit_pop_free(xreg); |
2892 inc_inst(1); | 2894 inc_inst(1); |
2954 printf("\torr\t%s, %s, %s\n",crn,crn,orn); | 2956 printf("\torr\t%s, %s, %s\n",crn,crn,orn); |
2955 break; | 2957 break; |
2956 case MUL: | 2958 case MUL: |
2957 case UMUL: | 2959 case UMUL: |
2958 inc_inst(1); | 2960 inc_inst(1); |
2959 drn = register_name(dx = get_register()); | 2961 drn = register_name(cadr(dx = get_register_var(0))); |
2962 if (car(dx)!=REGISTER) error(-1); | |
2960 printf("\tmul\t%s, %s, %s\n",drn,crn,orn); | 2963 printf("\tmul\t%s, %s, %s\n",drn,crn,orn); |
2961 if (creg0==USE_CREG) { | 2964 if (creg0==USE_CREG) { |
2962 set_ireg(dx,0); dx = -1; | 2965 set_ireg(cadr(dx),0); dx = -1; |
2963 } else { | 2966 } else { |
2964 printf("\tmov\t%s, %s\n",crn,drn); | 2967 printf("\tmov\t%s, %s\n",crn,drn); |
2965 } | 2968 } |
2969 free_register(cadr(dx)); | |
2966 break; | 2970 break; |
2967 case DIV: | 2971 case DIV: |
2968 code_int_lib("__divsi3",creg,oreg); break; | 2972 code_int_lib("__divsi3",creg,oreg); break; |
2969 case UDIV: | 2973 case UDIV: |
2970 code_int_lib("__udivsi3",creg,oreg); break; | 2974 code_int_lib("__udivsi3",creg,oreg); break; |
2973 case UMOD: | 2977 case UMOD: |
2974 code_int_lib("__umodsi3",creg,oreg); break; | 2978 code_int_lib("__umodsi3",creg,oreg); break; |
2975 default: | 2979 default: |
2976 error(-1); | 2980 error(-1); |
2977 } | 2981 } |
2978 if(dx!=-1) free_register(dx); | |
2979 if(ox!=-1) free_register(ox); | 2982 if(ox!=-1) free_register(ox); |
2980 } | 2983 } |
2981 | 2984 |
2982 int | 2985 int |
2983 code_const_op_p(int op,int v) | 2986 code_const_op_p(int op,int v) |
3220 code_register_save(int reg_save,int freg_save,int disp) | 3223 code_register_save(int reg_save,int freg_save,int disp) |
3221 { | 3224 { |
3222 int i; | 3225 int i; |
3223 inc_inst(1); | 3226 inc_inst(1); |
3224 printf("\tstmfd\tsp!, {"); | 3227 printf("\tstmfd\tsp!, {"); |
3225 for (i=reg_var_num(reg_save);i<reg_var_num(0);i++) { | 3228 for (i=reg_var_num(0);i<reg_var_num(reg_save);i++) { |
3226 printf("%s, ",register_name(i)); | 3229 printf("%s, ",register_name(i)); |
3227 } | 3230 } |
3228 printf("fp, ip, lr, pc}\n"); | 3231 printf("fp, ip, lr, pc}\n"); |
3229 if (freg_save>0) { | 3232 if (freg_save>0) { |
3230 inc_inst(1); | 3233 inc_inst(1); |
3243 printf("\tlfm\tf4, %d, [fp, #%d]\n",freg_save,-i); | 3246 printf("\tlfm\tf4, %d, [fp, #%d]\n",freg_save,-i); |
3244 inc_inst(1); | 3247 inc_inst(1); |
3245 } | 3248 } |
3246 inc_inst(1); | 3249 inc_inst(1); |
3247 printf("\tldmea\tfp, {"); | 3250 printf("\tldmea\tfp, {"); |
3248 for (i=reg_var_num(reg_save);i<reg_var_num(0);i++) { | 3251 for (i=reg_var_num(0);i<reg_var_num(reg_save);i++) { |
3249 printf("%s, ",register_name(i)); | 3252 printf("%s, ",register_name(i)); |
3250 } | 3253 } |
3251 printf("fp, sp, pc}\n"); | 3254 printf("fp, sp, pc}\n"); |
3252 return disp; | 3255 return disp; |
3253 } | 3256 } |