Mercurial > hg > CbC > old > device
comparison mc-code-mips.c @ 275:8f09f8bbc494
MIPS switch statement. basic.c passed.
author | kono |
---|---|
date | Fri, 21 May 2004 14:00:02 +0900 |
parents | 3ae68af07fce |
children | ebaec1ae566e |
comparison
equal
deleted
inserted
replaced
274:3ae68af07fce | 275:8f09f8bbc494 |
---|---|
106 int MAX_INPUT_FREGISTER_VAR = 4; | 106 int MAX_INPUT_FREGISTER_VAR = 4; |
107 int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; | 107 int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; |
108 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; | 108 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; |
109 | 109 |
110 #define LREG_V 3 /* for virtual long long/double register */ | 110 #define LREG_V 3 /* for virtual long long/double register */ |
111 static int mips_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+ | 111 #define REGS_MAX (REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_LREGISTER+LREG_V) |
112 REAL_MAX_LREGISTER+LREG_V]; | 112 static int mips_regs[REGS_MAX]; |
113 static int regv_h0[REAL_MAX_LREGISTER+LREG_V]; | 113 static int regv_h0[REAL_MAX_LREGISTER+LREG_V]; |
114 static int regv_l0[REAL_MAX_LREGISTER+LREG_V]; | 114 static int regv_l0[REAL_MAX_LREGISTER+LREG_V]; |
115 #define regv_h(i) regv_h0[(i)-LREG_OFFSET] | 115 #define regv_h(i) regv_h0[(i)-LREG_OFFSET] |
116 #define regv_l(i) regv_l0[(i)-LREG_OFFSET] | 116 #define regv_l(i) regv_l0[(i)-LREG_OFFSET] |
117 | 117 |
173 char *r(i) { return register_name(i); } | 173 char *r(i) { return register_name(i); } |
174 char *f(i) { return fregister_name(i); } | 174 char *f(i) { return fregister_name(i); } |
175 char *ll(i) { return lregister_name_low(i); } | 175 char *ll(i) { return lregister_name_low(i); } |
176 char *lh(i) { return lregister_name_high(i); } | 176 char *lh(i) { return lregister_name_high(i); } |
177 | 177 |
178 #define is_int_reg(i) (0<=i&&i<REAL_MAX_REGISTER) | 178 #define is_int_reg(i) (0<i&&i<REAL_MAX_REGISTER) |
179 #define is_float_reg(i) (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER) | 179 #define is_float_reg(i) (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER) |
180 #define is_longlong_reg(i) (LREG_OFFSET<=i&&i<LREG_OFFSET+REAL_MAX_LREGISTER+LREG_V) | 180 #define is_longlong_reg(i) (LREG_OFFSET<=i&&i<LREG_OFFSET+REAL_MAX_LREGISTER+LREG_V) |
181 #define is_double_reg(i) is_longlong_reg(i) | 181 #define is_double_reg(i) is_longlong_reg(i) |
182 | 182 |
183 #define use_int(reg) if (reg==USE_CREG) reg=use_int0() | 183 #define use_int(reg) if (reg==USE_CREG) reg=use_int0() |
333 | 333 |
334 #define CODE_LVAR(l) ((l)+code_disp_offset) | 334 #define CODE_LVAR(l) ((l)+code_disp_offset) |
335 #define CODE_CALLER_ARG(l) ((l)+arg_offset1) | 335 #define CODE_CALLER_ARG(l) ((l)+arg_offset1) |
336 #define FUNC_LVAR(l) (l+disp_offset) | 336 #define FUNC_LVAR(l) (l+disp_offset) |
337 #define CALLER_ARG(l) ((l)+arg_offset1) | 337 #define CALLER_ARG(l) ((l)+arg_offset1) |
338 #define CALLEE_ARG(l) ((l)+arg_offset) | 338 #define CALLEE_ARG(l) ((l)+arg_offset1) |
339 | 339 |
340 static void | 340 static void |
341 code_offset_set(int *lvar_offsetv_p,int *r1_offsetv_p) | 341 code_offset_set(int *lvar_offsetv_p,int *r1_offsetv_p) |
342 { | 342 { |
343 int lvar_offsetv,r1_offsetv; | 343 int lvar_offsetv,r1_offsetv; |
1117 | 1117 |
1118 static char *cload(int sz,int sign) { | 1118 static char *cload(int sz,int sign) { |
1119 if (sign) { | 1119 if (sign) { |
1120 return sz==1?"lb":sz==SIZE_OF_SHORT?"lh":"lw"; | 1120 return sz==1?"lb":sz==SIZE_OF_SHORT?"lh":"lw"; |
1121 } else { | 1121 } else { |
1122 return sz==1?"lbu":sz==SIZE_OF_SHORT?"lhu":"lhu"; | 1122 return sz==1?"lbu":sz==SIZE_OF_SHORT?"lhu":"lw"; |
1123 } | 1123 } |
1124 } | 1124 } |
1125 | 1125 |
1126 static char *cstore(int sz) { return sz==1?"sb":sz==SIZE_OF_SHORT?"sh":"sw"; } | 1126 static char *cstore(int sz) { return sz==1?"sb":sz==SIZE_OF_SHORT?"sh":"sw"; } |
1127 | 1127 |
1708 | 1708 |
1709 void | 1709 void |
1710 use_reg(int arg) | 1710 use_reg(int arg) |
1711 { | 1711 { |
1712 // printf("# use reg %d\n",arg); | 1712 // printf("# use reg %d\n",arg); |
1713 if (arg<0||arg> REAL_MAX_REGISTER+REAL_MAX_FREGISTER+ REAL_MAX_LREGISTER) | 1713 if (arg<0||arg> REGS_MAX) |
1714 error(-1); | 1714 error(-1); |
1715 clear_ptr_cache_reg(arg); | 1715 clear_ptr_cache_reg(arg); |
1716 regs[arg]=USING_REG; | 1716 regs[arg]=USING_REG; |
1717 if (is_longlong_reg(arg)) { | 1717 if (is_longlong_reg(arg)) { |
1718 clear_ptr_cache_reg(regv_l(arg)); | 1718 clear_ptr_cache_reg(regv_l(arg)); |
1889 static int | 1889 static int |
1890 compute_complex_arg(int e3,int reg_arg_list,int arg) { | 1890 compute_complex_arg(int e3,int reg_arg_list,int arg) { |
1891 int t=caddr(e3); | 1891 int t=caddr(e3); |
1892 int e4 = car(e3); | 1892 int e4 = car(e3); |
1893 reg_arg_list = list2(arg,reg_arg_list); | 1893 reg_arg_list = list2(arg,reg_arg_list); |
1894 g_expr_u(assign_expr0(arg,e4,t,t)); | |
1895 if (car(arg)==REGISTER||car(arg)==DREGISTER|| | 1894 if (car(arg)==REGISTER||car(arg)==DREGISTER|| |
1896 car(arg)==FREGISTER||car(arg)==LREGISTER) | 1895 car(arg)==FREGISTER||car(arg)==LREGISTER) |
1897 use_input_reg(cadr(arg),1); | 1896 use_input_reg(cadr(arg),1); |
1897 g_expr_u(assign_expr0(arg,e4,t,t)); | |
1898 car(e3) = arg; | 1898 car(e3) = arg; |
1899 return reg_arg_list; | 1899 return reg_arg_list; |
1900 } | 1900 } |
1901 | 1901 |
1902 static void | 1902 static void |
1907 nargs ++ ; reg_arg++; | 1907 nargs ++ ; reg_arg++; |
1908 } else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) { | 1908 } else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) { |
1909 nargs ++ ; reg_arg++; | 1909 nargs ++ ; reg_arg++; |
1910 nargs ++ ; reg_arg++; | 1910 nargs ++ ; reg_arg++; |
1911 } else if (t==FLOAT) { | 1911 } else if (t==FLOAT) { |
1912 nargs ++ ; reg_arg ++ ; freg_arg++; | 1912 reg_arg ++ ; freg_arg++; |
1913 nargs += size(t)/SIZE_OF_INT; | 1913 nargs += size(t)/SIZE_OF_INT; |
1914 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | 1914 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { |
1915 nargs += round4(size(t))/SIZE_OF_INT; | 1915 nargs += round4(size(t))/SIZE_OF_INT; |
1916 } else { | 1916 } else { |
1917 error(TYERR); | 1917 error(TYERR); |
2141 clear_ptr_cache(); | 2141 clear_ptr_cache(); |
2142 if (car(e2) == FNAME) { | 2142 if (car(e2) == FNAME) { |
2143 printf("\tjal\t%s\n",fn->nm); | 2143 printf("\tjal\t%s\n",fn->nm); |
2144 } else { | 2144 } else { |
2145 jrn = register_name(cadr(jmp)); | 2145 jrn = register_name(cadr(jmp)); |
2146 printf("\tj %s\n",jrn); | 2146 printf("\tmove $25,%s\n",jrn); |
2147 printf("\tjal\t$31,$25\n"); | |
2147 } | 2148 } |
2148 for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { | 2149 for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { |
2149 arg = car(reg_arg_list); | 2150 arg = car(reg_arg_list); |
2150 if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER | 2151 if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER |
2151 ||car(arg)==LREGISTER) | 2152 ||car(arg)==LREGISTER) |
2585 code_csvalue() | 2586 code_csvalue() |
2586 { | 2587 { |
2587 return creg; | 2588 return creg; |
2588 } | 2589 } |
2589 | 2590 |
2591 #define CMP_IMM (-2) | |
2592 static char * cmpreg_1; | |
2593 static char * cmpreg_2; | |
2594 | |
2590 void | 2595 void |
2591 code_cmpdimm(int e, int csreg) | 2596 code_cmpdimm(int e, int csreg) |
2592 { | 2597 { |
2593 /* used in dosiwtch() */ | 2598 /* used in dosiwtch() */ |
2594 int reg; | 2599 int reg; |
2595 char *rn; | 2600 char *rn; |
2596 if(chk) return; | 2601 if(chk) return; |
2602 use_reg(csreg); | |
2597 rn = register_name(reg = get_register()); | 2603 rn = register_name(reg = get_register()); |
2598 printf("\tli %s,%d\n",rn,e); | 2604 printf("\tli %s,%d\n",rn,e); |
2599 printf("\tsltu %s,%s,%s\n",rn,register_name(csreg),rn); | 2605 cmpreg_1 = rn; |
2600 cmpreg=csreg; | 2606 cmpreg_2 = register_name(csreg); |
2607 cmpreg=CMP_IMM; | |
2601 free_register(reg); | 2608 free_register(reg); |
2602 } | 2609 } |
2603 | 2610 |
2604 void | 2611 void |
2605 code_opening(char *filename) | 2612 code_opening(char *filename) |
2656 | 2663 |
2657 void | 2664 void |
2658 jcond(int l, char cond) | 2665 jcond(int l, char cond) |
2659 { | 2666 { |
2660 if (chk) return; | 2667 if (chk) return; |
2661 if (cmpreg==CMP_C1T) | 2668 if (cmpreg==CMP_C1T) { |
2662 printf("\tbc1%s $L_%d\n",cond?"f":"t",l); | 2669 printf("\tbc1%s $L_%d\n",cond?"f":"t",l); |
2663 else | 2670 } else if (cmpreg==CMP_IMM) { |
2671 printf("\tb%s %s,%s,$L_%d\n",cond?"ne":"eq",cmpreg_1,cmpreg_2,l); | |
2672 } else | |
2664 printf("\tb%s %s,$0,$L_%d\n",cond?"ne":"eq",register_name(cmpreg),l); | 2673 printf("\tb%s %s,$0,$L_%d\n",cond?"ne":"eq",register_name(cmpreg),l); |
2665 } | 2674 } |
2666 | 2675 |
2667 void | 2676 void |
2668 jmp(int l) | 2677 jmp(int l) |
4471 printf("\tmult %s,%s,%s\n",crn_l,crn_l,orn_h); | 4480 printf("\tmult %s,%s,%s\n",crn_l,crn_l,orn_h); |
4472 printf("\taddu %s,%s,%s\n",crn_h,drn_h,crn_l); | 4481 printf("\taddu %s,%s,%s\n",crn_h,drn_h,crn_l); |
4473 printf("\tmove %s,%s\n",crn_l,drn_l); | 4482 printf("\tmove %s,%s\n",crn_l,drn_l); |
4474 break; | 4483 break; |
4475 case LDIV: | 4484 case LDIV: |
4476 code_ldiv_lib(reg,oreg); // ___divdi3$stub | 4485 code_ldiv_lib(reg,oreg) |
4486 ; // ___divdi3$stub | |
4477 check_lreg(reg); | 4487 check_lreg(reg); |
4478 break; | 4488 break; |
4479 case LUDIV: | 4489 case LUDIV: |
4480 code_ludiv_lib(reg,oreg); // ___udivdi3$stub | 4490 code_ludiv_lib(reg,oreg); // ___udivdi3$stub |
4481 check_lreg(reg); | 4491 check_lreg(reg); |