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);