diff 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
line wrap: on
line diff
--- a/mc-code-mips.c	Fri May 21 05:29:53 2004 +0900
+++ b/mc-code-mips.c	Fri May 21 14:00:02 2004 +0900
@@ -108,8 +108,8 @@
 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG;
 
 #define LREG_V 3    /* for virtual long long/double register */
-static int mips_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+
-   REAL_MAX_LREGISTER+LREG_V];
+#define REGS_MAX (REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_LREGISTER+LREG_V)
+static int mips_regs[REGS_MAX];
 static int regv_h0[REAL_MAX_LREGISTER+LREG_V];
 static int regv_l0[REAL_MAX_LREGISTER+LREG_V];
 #define regv_h(i)  regv_h0[(i)-LREG_OFFSET]
@@ -175,7 +175,7 @@
 char *ll(i) { return lregister_name_low(i); }
 char *lh(i) { return lregister_name_high(i); }
 
-#define is_int_reg(i)  (0<=i&&i<REAL_MAX_REGISTER)
+#define is_int_reg(i)  (0<i&&i<REAL_MAX_REGISTER)
 #define is_float_reg(i)  (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER)
 #define is_longlong_reg(i)  (LREG_OFFSET<=i&&i<LREG_OFFSET+REAL_MAX_LREGISTER+LREG_V)
 #define is_double_reg(i)  is_longlong_reg(i)
@@ -335,7 +335,7 @@
 #define CODE_CALLER_ARG(l) ((l)+arg_offset1)
 #define FUNC_LVAR(l) (l+disp_offset)
 #define CALLER_ARG(l) ((l)+arg_offset1)
-#define CALLEE_ARG(l) ((l)+arg_offset)
+#define CALLEE_ARG(l) ((l)+arg_offset1)
 
 static void
 code_offset_set(int *lvar_offsetv_p,int *r1_offsetv_p)
@@ -1119,7 +1119,7 @@
     if (sign) {
         return sz==1?"lb":sz==SIZE_OF_SHORT?"lh":"lw"; 
     } else {
-        return sz==1?"lbu":sz==SIZE_OF_SHORT?"lhu":"lhu"; 
+        return sz==1?"lbu":sz==SIZE_OF_SHORT?"lhu":"lw"; 
     }
 }
 
@@ -1710,7 +1710,7 @@
 use_reg(int arg)
 {
 // printf("# use reg %d\n",arg);
-    if (arg<0||arg> REAL_MAX_REGISTER+REAL_MAX_FREGISTER+ REAL_MAX_LREGISTER)
+    if (arg<0||arg> REGS_MAX)
 	error(-1);
     clear_ptr_cache_reg(arg);
     regs[arg]=USING_REG;
@@ -1891,10 +1891,10 @@
     int t=caddr(e3);
     int e4 = car(e3);
     reg_arg_list = list2(arg,reg_arg_list);
-    g_expr_u(assign_expr0(arg,e4,t,t));
     if (car(arg)==REGISTER||car(arg)==DREGISTER||
 	car(arg)==FREGISTER||car(arg)==LREGISTER)
 	use_input_reg(cadr(arg),1);
+    g_expr_u(assign_expr0(arg,e4,t,t));
     car(e3) = arg;
     return reg_arg_list;
 }
@@ -1909,7 +1909,7 @@
 	nargs ++ ; reg_arg++;
 	nargs ++ ; reg_arg++;
     } else if (t==FLOAT) {
-	nargs ++ ; reg_arg ++ ; freg_arg++;
+	reg_arg ++ ; freg_arg++;
 	nargs += size(t)/SIZE_OF_INT;
     } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
 	nargs += round4(size(t))/SIZE_OF_INT;
@@ -2143,7 +2143,8 @@
         printf("\tjal\t%s\n",fn->nm);
     } else {
         jrn = register_name(cadr(jmp));
-        printf("\tj %s\n",jrn);
+        printf("\tmove $25,%s\n",jrn);
+        printf("\tjal\t$31,$25\n");
     }
     for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) {
 	arg = car(reg_arg_list);
@@ -2587,6 +2588,10 @@
     return creg;
 }
 
+#define CMP_IMM (-2)
+static char * cmpreg_1;
+static char * cmpreg_2;
+
 void
 code_cmpdimm(int e, int csreg)
 {
@@ -2594,10 +2599,12 @@
     int reg;
     char *rn;
     if(chk) return;
+    use_reg(csreg);
     rn = register_name(reg = get_register());
     printf("\tli %s,%d\n",rn,e);
-    printf("\tsltu %s,%s,%s\n",rn,register_name(csreg),rn);
-    cmpreg=csreg;
+    cmpreg_1 = rn;
+    cmpreg_2 = register_name(csreg);
+    cmpreg=CMP_IMM;
     free_register(reg);
 }
 
@@ -2658,9 +2665,11 @@
 jcond(int l, char cond)
 {       
     if (chk) return;
-    if (cmpreg==CMP_C1T) 
+    if (cmpreg==CMP_C1T)  {
       printf("\tbc1%s $L_%d\n",cond?"f":"t",l);
-    else
+    } else if (cmpreg==CMP_IMM)  {
+      printf("\tb%s %s,%s,$L_%d\n",cond?"ne":"eq",cmpreg_1,cmpreg_2,l);
+    } else
       printf("\tb%s %s,$0,$L_%d\n",cond?"ne":"eq",register_name(cmpreg),l);
 }
 
@@ -4473,7 +4482,8 @@
 	printf("\tmove    %s,%s\n",crn_l,drn_l);
 	break;
     case LDIV:
-	code_ldiv_lib(reg,oreg); // ___divdi3$stub
+	code_ldiv_lib(reg,oreg)
+;  // ___divdi3$stub
 	check_lreg(reg);
 	break;
     case LUDIV: