changeset 378:b3c6c479c522

ARM continue...
author kono
date Wed, 14 Jul 2004 14:37:37 +0900
parents b23568be1155
children c7abd48191b3
files Changes mc-code-arm.c mc-code-mips.c stdio.h
diffstat 4 files changed, 206 insertions(+), 346 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Tue Jul 13 21:43:58 2004 +0900
+++ b/Changes	Wed Jul 14 14:37:37 2004 +0900
@@ -5843,3 +5843,17 @@
 レジスタも一つだしね。
 
 もう少しかかりそうだね。
+
+Wed Jul 14 12:45:01 JST 2004
+
+やっぱり浮動小数点ありとなしを一緒に実装するのはめんどい。
+
+あれ、? mc-code-mips.c の
+    rexpr_bool(int e1, int reg)
+    {       
+	int e2,reg0;
+	int op = car(e1);
+    return 0;
+
+ってなんだ? せっかく作ったのに?
+
--- a/mc-code-arm.c	Tue Jul 13 21:43:58 2004 +0900
+++ b/mc-code-arm.c	Wed Jul 14 14:37:37 2004 +0900
@@ -177,7 +177,7 @@
 char *lh(i) { return lregister_name_high(i); }
 
 #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_float_reg(i)  (arch_mode==Linux_Zaurus?(REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER):is_int_reg(i))
 #define is_longlong_reg(i)  (LREG_OFFSET<=i&&i<LREG_OFFSET+REAL_MAX_LREGISTER+LREG_V)
 #define is_double_reg(i)  (arch_mode==GameBoyAdvance?is_longlong_reg(i):is_float_reg(i))
 
@@ -397,19 +397,19 @@
 }
 
 static void
-lvar(int l)
+lvar(int l,char *cext)
 {
     if (fnptr->sc==CODE) {
         if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-            printf("[sp, #%d]\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
+            printf("[sp, #%d]%s\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),cext);
         } else
-            printf("[fp, #%d]\n",CODE_LVAR(l));
+            printf("[fp, #%d]%s\n",CODE_LVAR(l),cext);
     } else if (l<0) {  /* local variable */
-        printf("[fp, #%d+.L%d]\n",FUNC_LVAR(l),lvar_offset_label);
+        printf("[fp, #%d+.L%d]%s\n",FUNC_LVAR(l),lvar_offset_label,cext);
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-        printf("[sp, #%d]\n",CALLER_ARG(l-ARG_LVAR_OFFSET));
+        printf("[sp, #%d]%s\n",CALLER_ARG(l-ARG_LVAR_OFFSET),cext);
     } else { /* callee's arguments */
-        printf("[fp, #%d+.L%d]\n",CALLEE_ARG(l),r1_offset_label);
+        printf("[fp, #%d+.L%d]%s\n",CALLEE_ARG(l),r1_offset_label,cext);
     }
 }
 
@@ -1234,7 +1234,7 @@
 #define mask8(d,bit)   (d & (255 << bit))
 
 static int
-make_const(int c,int *p1,int *p2,int *p3)
+make_const(int c,int *p1,int *p2,int *p3,int mode)
 {
     int sign,im,jm,km;
     int min_stage = 4;
@@ -1243,7 +1243,7 @@
     int i,j,k;
     for(sign=1;sign>=-1;sign-=2) {
 	int d;
-        if (sign==1) { d = c; } else { d = -c; }
+        if (sign==1) { d = c; } else { d = mode==CMP?-c:~c; }
 	if (min_stage==1) break;
         for(i=24;i>=0;i-=2) {
 	    jm = km = 0;
@@ -1283,6 +1283,15 @@
     } else return 0;
 }
 
+static int
+is_stage1_const(int c,int mode)
+{
+    int sign,p1,p2,p3;
+    sign = make_const(c,&p1,&p2,&p3,mode);
+    return (*p1&&!*p2&&!*p3)?sign:0;
+}
+
+
 static void 
 code_const(int e2,int reg)
 {
@@ -1292,7 +1301,7 @@
 
     use_int(reg);
     crn = register_name(reg);
-    if ((s=make_const(e2,&p1,&p2,&p3))) {
+    if ((s=make_const(e2,&p1,&p2,&p3,0))) {
 	add = s>0?"add":"sub";
 	mov = s>0?"mov":"mvn";
 	if (p1) printf("\t%s\t%s, %s, #%d\n",mov,crn,rrn,p1);
@@ -1316,7 +1325,7 @@
         if(r!=reg)
             printf("\tmov %s,%s\n",crn,rrn);
     }
-    if ((s=make_const(offset,&p1,&p2,&p3))) {
+    if ((s=make_const(offset,&p1,&p2,&p3,0))) {
 	add = s>0?"add":"sub";
 	if (p1) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p1);
 	if (p2) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p2);
@@ -1408,43 +1417,32 @@
     use_int(reg);
     lvar_intro(e2);
     printf("\tldr\t%s, ",register_name(reg));
-    lvar(e2);
+    lvar(e2,"");
 }
 
 extern void
 code_i2c(int reg)
 {
-    int reg1;
-    use_int(reg);
-    reg1 = get_register();
-    printf("sll %s,%s,24\n",register_name(reg1),register_name(reg));
-    printf("sra %s,%s,24\n",register_name(reg),register_name(reg1));
-    free_register(reg1);
 }
 
 extern void
 code_i2s(int reg)
 {
-    int reg1;
-    use_int(reg);
-    reg1 = get_register();
-    printf("sll %s,%s,16\n",register_name(reg1),register_name(reg));
-    printf("sra %s,%s,16\n",register_name(reg),register_name(reg1));
-    free_register(reg1);
 }
 
 extern void
 code_u2uc(int reg)
 {   
     use_int(reg);
-    printf("andi %s,%s,0xff\n",register_name(reg),register_name(reg));
+    printf("and\t%s, %s, #255\n",register_name(reg),register_name(reg));
 }
 
 extern void
 code_u2us(int reg)
 {   
     use_int(reg);
-    printf("andi %s,%s,0xffff\n",register_name(reg),register_name(reg));
+    printf("bic %s, %s, #16711680\n",register_name(reg),register_name(reg));
+    printf("bic %s, %s, #-16777216\n",register_name(reg),register_name(reg));
 }
 
 void
@@ -1452,7 +1450,7 @@
     use_int(reg);
     lvar_intro(e2);
     printf("\t%s %s,",cload(sz,sign),register_name(reg));
-    lvar(e2);
+    lvar(e2,sz==1?"  @ zero_extendqisi2":"");
     cext(sign,sz,reg);
 }
 
@@ -1462,35 +1460,20 @@
     use_int(reg);
     r = get_ptr_cache(n);
     if(r!=reg)
-	printf("\tmove %s,%s\n",register_name(reg),register_name(r));
+	printf("\tmov %s,%s\n",register_name(reg),register_name(r));
     return;
 }
 
 void
 code_label_value(int label,int reg) {
+    int lb,disp;
     use_int(reg);
-    printf("\tldr %s,.L%d\n",register_name(reg),
-	make_const_ptr(label));
+    disp = search_const(LABEL,label,&lb);
+    printf("\tldr\t%s, .L%d+%d\n",crn,lb,disp);
     return;
 }
 
 void
-code_const(int e2,int reg) {
-    char *crn,*add;
-    int p1,p2,p3;
-    use_int(reg);
-    crn = register_name(reg);
-    if ((s=make_const(e2,&p1,&p2,&p3))) {
-	add = s>0?"add":"sub";
-	if (p1) printf("\tmov\t%s, %s, #%d\n",crn,rrn,offset);
-	if (p2) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,offset);
-	if (p3) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,offset);
-    } else {
-	printf("\tldr\t%s, .L%d\n",crn,new_const_ref(r,e2));
-    }
-}
-
-void
 code_neg(int creg) {
     use_int(creg);
     printf("\trsb\t%s, %s, #0\n", register_name(creg), register_name(creg));
@@ -1573,10 +1556,13 @@
 
 void
 code_return(int creg) {
+    int label,disp;
     char *crn;
     use_int(creg);
     crn = register_name(creg);
-    printf("\tla %s,$L_%d\n",crn,retcont);
+
+    disp = search_const(LABEL,retcont,&label);
+    printf("\tldr\t%s, .L%d+%d\n",crn,label,disp);
 }
 
 #define R1SAVE 0
@@ -1589,8 +1575,7 @@
     printf("\tldr\t%s,[fp, #0]\n",register_name(creg));
 #else
     use_int(creg);
-    printf("\taddu %s,",register_name(creg));
-    printf("$fp,%d+$L_%d\n",FUNC_LVAR(0),lvar_offset_label);
+    printf("\tmov\t%s,fp\n",register_name(creg));
 #endif
 }
 
@@ -1624,37 +1609,37 @@
 
 char *
 code_gt(int cond) {
-  return (cond?"ne":"eq");
+  return (cond?"le":"gt");
 }
 
 char *
 code_ugt(int cond) {
-  return code_gt(cond);
+  return (cond?"ls":"hi");
 }
 
 char *
 code_ge(int cond) {
-  return code_gt(!cond);
+  return (cond?"lt":"ge");
 }
 
 char *
 code_uge(int cond) {
-  return code_gt(!cond);
+  return (cond?"lo":"hs");
 }
 
 char *
 code_eq(int cond) {
-  return cond?"":0;
+  return (cond?"ne":"eq");
 }
 
 
 void
 code_cmp_crgvar(int e1,int reg,int sz,int label,int cond) {
     use_int(reg);
-    code_ld(cload(sz,0),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1)));
+    code_ld(cload(sz,0),reg,cadr(e1),xreg,get_ptr_cache((NMTBL*)caddr(e1)),
+	sz==1?"  @ zero_extendqisi2":"");
     cext(0,sz,r);
     cmpreg = reg;
-    // printf("\tcmpwi cr0,%s,0\n",crn);
     jcond(label,cond);
 }
 
@@ -1666,7 +1651,7 @@
     crn = register_name(reg);
     lvar_intro(e2);
     printf("\t%s %s,",cload(sz,0),crn);
-    lvar(e2);
+    lvar(e2,sz==1?"  @ zero_extendqisi2":"");
     cext(0,sz,reg);
     code_cmp_register(reg,label,cond);
 }
@@ -1675,7 +1660,7 @@
 void
 code_cmp_rgvar(int e1,int reg,int label,int cond) {
     use_int(reg);
-    code_ld("lw",reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1)));
+    code_ld("ldr",reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1)),"");
     code_cmp_register(reg,label,cond);
 }
 
@@ -1686,8 +1671,8 @@
     use_int(reg);
     crn = register_name(reg);
     lvar_intro(e2);
-    printf("\tlw %s,",crn);
-    lvar(e2);
+    printf("\tldr %s,",crn);
+    lvar(e2,"");
     code_cmp_register(reg,label,cond);
 }
 
@@ -1695,7 +1680,6 @@
 void
 code_cmp_register(int e2,int label,int cond) {
     use_int(e2);
-    cmpreg = e2;  // used by jcond,  beq $reg,$0,L_xx
     jcond(label,cond);
 }
 
@@ -1704,7 +1688,7 @@
 code_string(int e1,int creg)
 {
     char *s,*crn;
-    int lb;
+    int lb,disp,label;
 
     use_int(creg);
     crn = register_name(creg);
@@ -1713,7 +1697,9 @@
     lb = emit_string_label();
     ascii(s);
     text_mode(2);
-    printf("\tla %s,$L_%d\n",crn,lb);
+
+    disp = search_const(LABEL,lb,&label);
+    printf("\tldr\t%s, .L%d+%d\n",crn,label,disp);
 }
 
 #define MAX_COPY_LEN 20
@@ -1738,16 +1724,16 @@
     switch (length) {
     case 0:	break;
     case 1: case -1:
-	printf("\tlb %s,%d(%s)\n",drn,offset,frn);
-	printf("\tsb %s,%d(%s)\n",drn,offset,trn);
+	printf("\tldrb\t%s, [%s,#%d]\n",drn,frn,offset);
+	printf("\tstrb\t%s, [%s,#%d]\n",drn,frn,offset);
 	break;
     case 2: case -2:
-	printf("\tlh %s,%d(%s)\n",drn,offset,frn);
-	printf("\tsh %s,%d(%s)\n",drn,offset,trn);
+	printf("\tldrh\t%s, [%s,#%d]\n",drn,frn,offset);
+	printf("\tstrh\t%s, [%s,#%d]\n",drn,frn,offset);
 	break;
     case 4: case -4:
-	printf("\tlw %s,%d(%s)\n",drn,offset,frn);
-	printf("\tsw %s,%d(%s)\n",drn,offset,trn);
+	printf("\tldr\t%s, [%s,#%d]\n",drn,frn,offset);
+	printf("\tstr\t%s, [%s,#%d]\n",drn,frn,offset);
 	break;
     default:
         if (length <0) {
@@ -1771,11 +1757,11 @@
 	}
 	clear_ptr_cache();
 	code_save_stacks();
-	printf("\tli $6,%d\n",length);
-	printf("\tmove $5,%s\n",frn);
-	printf("\tmove $4,%s\n",trn);
+	code_code_register(from,0);
+	code_code_register(to,1);
+	code_const(length,2);
         /* overrap must be allowed */
-	printf("\tjal %s\n",memmove);
+	printf("\tbl %s\n",memmove);
 	extern_define(memmove,0,FUNCTION,1);
         fix=0;
 	set_ireg(RET_REGISTER,0);
@@ -1815,8 +1801,8 @@
         srn = register_name(sreg);
         code_lvar(cadr(arg),dreg);
         for(count=0;count<length;count+=SIZE_OF_INT) {
-            printf("\tlw %s,%d(%s)\n",srn,count,crn);
-            printf("\tsw %s,%d(%s)\n",srn,count,drn);
+            printf("\tldr %s, [%s, #%d]\n",srn,crn,count);
+            printf("\tstr %s, [%s, #%d]\n",srn,crn,count);
         }
         free_register(sreg);
         free_register(dreg);
@@ -1839,7 +1825,7 @@
 	if (ireg && reg!=ireg ) {
 	    free_register(ireg);
 	    if (mode) {
-		printf("\tmove %s,%s\n",register_name(reg),register_name(ireg));
+		printf("\tmov %s,%s\n",register_name(reg),register_name(ireg));
 	    }
 	}
 	free_register(creg);
@@ -1856,7 +1842,9 @@
 	if (freg && reg!=freg) {
 	    free_register(freg);
 	    if (mode) {
-		printf("\tmov.s %s,%s\n",fregister_name(reg),fregister_name(freg));
+		printf("\t%s %s,%s\n",
+		    arch_mode==Linux_Zaurus?"mvfd":mov",
+		    fregister_name(reg),fregister_name(freg));
 	    }
 	}
 	// if (creg!=ireg) free_register(creg);
@@ -1871,9 +1859,9 @@
     if (reg!=creg) {
 	if (lreg && reg!=lreg) {
 	    if (mode) {
-		printf("\tmove %s,%s\n",
+		printf("\tmov %s,%s\n",
 		    lregister_name_low(reg),lregister_name_low(lreg));
-		printf("\tmove %s,%s\n",
+		printf("\tmov %s,%s\n",
 		    lregister_name_high(reg),lregister_name_high(lreg));
 	    }
 	    free_register(lreg);
@@ -2136,7 +2124,7 @@
 	break;
     case FRLVAR:
 	lvar_intro(cadr(e2));
-	printf("\tlw %s,",frn); lvar(cadr(e2));
+	printf("\tlw %s,",frn); lvar(cadr(e2),"");
     default:
 	g_expr(e2);
     case FREGISTER:
@@ -2234,24 +2222,12 @@
 static void
 code_call(int e2,NMTBL *fn,int jmp)
 {
-    // char *jrn;
-    if (fnptr->sc==CODE) {
-	if (car(e2) == FNAME) {
-	    printf("\tla\t$25,%s\n",fn->nm);
-	} else {
-	    // jrn = register_name(cadr(jmp));
-	    // printf("\tmove\t$25,%s\n",jrn);
-	}
-	printf("\tjalr\t$25\n");
-	printf("\tlw\t$gp,$L_%d($sp)\n",cprestore_label);
+    if (car(e2) == FNAME) {
+	printf("\tbl\t%s\n",fn->nm);
     } else {
-	if (car(e2) == FNAME) {
-	    printf("\tjal\t%s\n",fn->nm);
-	} else {
-	    // jrn = register_name(cadr(jmp));
-	    // printf("\tmove $25,%s\n",jrn);
-	    printf("\tjal\t$31,$25\n");
-	}
+	printf("\tmov\tlr, pc\n");
+	printf("\tmov\tpc, %s\n",register_name(jmp));
+	printf("\tldmea\tfp, {fp, sp, pc}\n");
     }
 }
 
@@ -2288,7 +2264,7 @@
 	fn=(NMTBL *)cadr(e2);
     } else {	
 	if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case
-	jmp = list2(REGISTER,25);
+	jmp = get_register_var(0);
 	if (!simple_arg(e2)) {
 	    e3=get_register_var(0);
 	    g_expr_u(assign_expr0(e3,e2,INT,INT));
@@ -2458,8 +2434,8 @@
     g = get_register();
     crn = register_name(reg);
     grn = register_name(g);
-    printf("\tsubu $sp,$sp,%s\n",crn);
-    printf("\taddu %s,$sp,$L_%d\n",crn,cprestore_label);
+    printf("\trsb\tsp, %s, sp,%s\n",crn);
+    printf("\tmov\t%s, sp\n",crn);
     free_register(g);
 }
 
@@ -2467,17 +2443,15 @@
 code_frame_pointer(int e3) {
     use_int(e3);
 #if R1SAVE
-    printf("\tmove $fp,%s\n",register_name(e3));
+    printf("\tmov fp, %s\n",register_name(e3));
 #else
-    printf("\tmove $fp,%s\n",register_name(e3));
+    printf("\tmov fp, %s\n",register_name(e3));
 #endif
 }
 
 
 void
 code_fix_frame_pointer(int offset) {
-    printf("\tla $fp,");
-    printf("%d+$L_%d($sp)\n",FUNC_LVAR(0),lvar_offset_label);
 }
 
 void
@@ -2485,8 +2459,7 @@
     // jump to continuation means use all register variable
     max_reg_var = REG_VAR_BASE-REG_VAR_MIN;
     max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN;
-    printf("\tla $25,%s\n",s);
-    printf("\tj\t$25\n");
+    printf("\tb\t%s\n",s);
     control=0;
 }
 
@@ -2496,21 +2469,19 @@
     max_reg_var = REG_VAR_BASE-REG_VAR_MIN;
     max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN;
     use_int(e2);
-    printf("\tmove $25,%s\n",register_name(e2));
-    printf("\tj\t$25\n");
+    printf("\tmov\tpc, %s\n",s); // ?!
     control=0;
 }
 
 void
 code_rindirect(int e1, int reg,int offset, int sign,int sz)
 {
-    char *crn,*rrn;
+    int lreg;
     g_expr(e1);
     if (!is_int_reg(creg)) error(-1);
-    crn=register_name(creg);
+    lreg = creg;
     use_int(reg);
-    rrn=register_name(reg);
-    printf("\t%s %s,%d(%s)\n",cload(sz,sign),rrn,offset,crn);
+    code_ld(cload(sz,sign),reg,offset,lreg,sz==1?"  @ zero_extendqisi2":"");
     cext(sign,sz,reg);
 }
 
@@ -2518,20 +2489,22 @@
 int
 code_drindirect(int e1, int reg,int offset, int d)
 {
-     char *crn;
-    if (d) {
-        code_lrindirect(e1,reg,offset,1);
-	use_float(d,reg);
-	// regs[reg==USE_CREG?lreg:reg]=USING_DREG;
-	return DOUBLE;
+    int xreg;
+    if(arch_mode==GameBoyAdvance) {
+	if (d) {
+	    code_lrindirect(e1,reg,offset,1);
+	    return DOUBLE;
+	} else {
+	    code_rindirect(e1,reg,offset,0,0);
+	    return FLOAT;
+	}
     }
     g_expr(e1);
     if (!is_int_reg(creg)) error(-1);
-    crn=register_name(creg);
+    xreg = creg;
     use_float(d,reg);
-    printf("\tl.s %s,%d(%s)\n",
-	fregister_name(reg),offset,crn);
-    return FLOAT;
+    code_ldf(d?"ldfd":"ldfs,reg,offset,xreg,"");
+    return d?DOUBLE:FLOAT;
 }
 #endif
 
@@ -2543,19 +2516,19 @@
     char *crn=register_name(creg);
 #if ENDIAN==0
     if (creg!=regv_l(reg)) {
-	printf("\tlw %s,%d(%s)\n",lregister_name_low(reg),offset,crn);
-	printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn);
+	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset);
+	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_high(reg),crn,offset+SIZE_OF_INT);
     } else {
-	printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn);
-	printf("\tlw %s,%d(%s)\n",lregister_name_low(reg),offset,crn);
+	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_high(reg),crn,offset+SIZE_OF_INT);
+	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset);
     }
 #else
     if (creg!=regv_l(reg)) {
-	printf("\tlw %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
-	printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),offset,crn);
+	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset+SIZE_OF_INT);
+	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_high(reg),crn,offset);
     } else {
-	printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),offset,crn);
-	printf("\tlw %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
+	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_high(reg),crn,offset);
+	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset+SIZE_OF_INT);
     }
 #endif
 }
@@ -2591,11 +2564,11 @@
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
 #if ENDIAN==0
-    printf("\tsw %s,0(%s)\n",crn_l,drn);
-    printf("\tsw %s,%d(%s)\n",crn_h,SIZE_OF_INT,drn);
+    printf("\tstr\t%s, [%s, #0]\n",crn_l,drn);
+    printf("\tstr\t%s, [%s, #%d]\n",crn_h,drn,SIZE_OF_INT);
 #else
-    printf("\tsw %s,0(%s)\n",crn_h,drn);
-    printf("\tsw %s,%d(%s)\n",crn_l,SIZE_OF_INT,drn);
+    printf("\tstr\t%s, [%s, #0]\n",crn_h,drn);
+    printf("\tstr\t%s, [%s, #%d]\n",crn_l,drn,SIZE_OF_INT);
 #endif
 }
 
@@ -2613,12 +2586,21 @@
 }
 #endif
 
+static char *
+cstore(int sz)
+{
+    swithc(sz) {
+    case 1: return "strb";
+    case SIZE_OF_SHORT: return "strh";
+    default: return "str";
+    }
+}
 
 void
 code_assign_gvar(int e2,int creg,int byte) {
     use_int(creg);
     code_ldf(cstore(byte),register_name(creg),cadr(e2),
-        get_ptr_cache((NMTBL*)caddr(e2)));
+        get_ptr_cache((NMTBL*)caddr(e2)),byte==SIZE_OF_SHORT?" @ movhi");
 }
 
 void
@@ -2627,21 +2609,15 @@
     use_int(creg);
     crn=register_name(creg);
     lvar_intro(e2);
-    if (byte==1) {
-	printf("\tsb %s,",crn);
-    } else if (byte==SIZE_OF_SHORT) {
-	printf("\tsh %s,",crn);
-    } else {
-	printf("\tsw %s,",crn);
-    }
-    lvar(e2);
+    printf("\t%s\t%s,",cstore(byte),crn);
+    lvar(e2,"");
 }
 
 void
 code_assign_register(int e2,int byte,int creg) {
     use_int(creg);
     if (e2!=creg)
-	printf("\tmove %s,%s\n",register_name(e2),register_name(creg));
+	printf("\tmov %s,%s\n",register_name(e2),register_name(creg));
 }
 
 void
@@ -2653,13 +2629,7 @@
     use_int(creg);
     crn=register_name(creg);
 
-    if (byte==1) {
-	printf("\tsb %s,0(%s)\n",crn,drn);
-    } else if (byte==SIZE_OF_SHORT) {
-	printf("\tsh %s,0(%s)\n",crn,drn);
-    } else {
-	printf("\tsw %s,0(%s)\n",crn,drn);
-    }
+    printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn);
 }
 
 
@@ -2685,13 +2655,7 @@
     tosop(op,ireg,xreg);
     crn = register_name(ireg);
     drn = register_name(creg);
-    if (byte==1) {
-	printf("\tsb %s,0(%s)\n",crn,drn);
-    } else if (byte==SIZE_OF_SHORT) {
-	printf("\tsh %s,0(%s)\n",crn,drn);
-    } else {
-	printf("\tsw %s,0(%s)\n",crn,drn);
-    }
+    printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn);
     free_register(edx);
     emit_pop_free(xreg);
 #else
@@ -2700,13 +2664,7 @@
     tosop(op,creg,xreg);
     crn = register_name(creg);
     drn = register_name(edx);
-    if (byte==1) {
-	printf("\tsb %s,0(%s)\n",crn,drn);
-    } else if (byte==SIZE_OF_SHORT) {
-	printf("\tsh %s,0(%s)\n",crn,drn);
-    } else {
-	printf("\tsw %s,0(%s)\n",crn,drn);
-    }
+    printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn);
     free_register(edx);
     emit_pop_free(xreg);
 #endif
@@ -2733,7 +2691,7 @@
     switch(op) {
     case LSHIFT:
     case ULSHIFT:
-	shift("sll",creg,oreg);
+	shift("asl",creg,oreg);
 	if(ox!=-1) free_register(ox);
 	return;
     case RSHIFT:
@@ -2741,7 +2699,7 @@
 	if(ox!=-1) free_register(ox);
 	return;
     case URSHIFT:
-	shift("srl",creg,oreg);
+	shift("asr",creg,oreg);
 	if(ox!=-1) free_register(ox);
 	return;
     }
@@ -2749,49 +2707,32 @@
     crn = register_name(creg);
     switch(op) {
     case ADD:
-	printf("\taddu %s,%s,%s\n",crn,crn,orn);
+	printf("\tadd %s,%s,%s\n",crn,crn,orn);
 	break;
     case SUB:
-	printf("\tsubu %s,%s,%s\n",crn,crn,orn);
-	break;
-    case CMPGE:
-        printf("\tslt %s,%s,%s\n",crn,crn,orn);
-	cmpreg = creg;
+	printf("\tsub %s,%s,%s\n",crn,crn,orn);
 	break;
     case CMP:
-        printf("\tslt %s,%s,%s\n",crn,orn,crn);
-	cmpreg = creg;
-	break;
-    case UCMPGE:
-        printf("\tsltu %s,%s,%s\n",crn,crn,orn);
-	cmpreg = creg;
-	break;
-    case UCMP:
-        printf("\tsltu %s,%s,%s\n",crn,orn,crn);
-	cmpreg = creg;
-	break;
-    case CMPEQ:
-        printf("\tbeq %s,%s",crn,orn);  // beq  $2,$3,L1
-	break;
-    case CMPNEQ:
-	printf("\tbne %s,%s",crn,orn);  // beq  $2,$3,L1
+        printf("\tcmp %s,%s\n",crn,orn);
 	break;
     case BAND: 
 	printf("\tand %s,%s,%s\n",crn,crn,orn);
 	break;
     case EOR: 
-	printf("\txor %s,%s,%s\n",crn,crn,orn);
+	printf("\teor %s,%s,%s\n",crn,crn,orn);
 	break;
     case BOR:
-	printf("\tor %s,%s,%s\n",crn,crn,orn);
+	printf("\torr %s,%s,%s\n",crn,crn,orn);
 	break;
     case MUL:
-	printf("\tmult %s,%s,%s\n",crn,crn,orn);
-	break;
     case UMUL:
-	printf("\tmultu %s,%s,%s\n",crn,crn,orn);
+	printf("\tmul %s,%s,%s\n",crn,crn,orn);
 	break;
     case DIV: case UDIV: case MOD: case UMOD:
+        bl      __modsi3
+        bl      __udivsi3
+        bl      __umodsi3
+
         printf("\t%s $0,%s,%s\n",(op==UDIV||op==UMOD)?"divu":"div",crn,orn);
         printf("\t%s %s\n",(op==MOD||op==UMOD)?"mfhi":"mflo",crn);
         printf("\t.set    noreorder\n");
@@ -2812,10 +2753,20 @@
 {
     if (car(v)!=CONST) return 0;
     v = cadr(v);
-    if (op==MUL||op==UMUL) return ilog(v) ;
-    if (op==DIV||op==UDIV) return ilog(v) ;
-    if (!(op==LSHIFT|| op==ULSHIFT|| op==RSHIFT|| op==URSHIFT|| op==ADD|| op==SUB|| op==CMP|| op==BOR)) return 0;
-    return (-32766<v&&v<32767);
+    switch(op) {
+    case MUL: case UMUL: case DIV: case UDIV:
+	return ilog(v);
+    case ADD: case SUB;
+	return 1;
+    case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT:
+	return 0<v&&v<=32;
+    case CMP:
+	return is_stage1_const(v,CMP);
+    case EOR: case BOR: case BAND:
+	return is_stage1_const(v,0);
+    default:
+	return 0;
+    }
 }
 
 void
@@ -2827,38 +2778,32 @@
     v = cadr(v);
     
     switch(op) {
+    case MUL: case UMUL:
+	v=ilog(v);
     case LSHIFT:
     case ULSHIFT:
-	printf("\tsll %s,%s,%d\n",crn,crn,v);
+	printf("\tmov\t%s, %s, asl #%d\n",crn,crn,v);
 	return;
+    case DIV:
+	v=ilog(v);
     case RSHIFT:
-	printf("\tsra %s,%s,%d\n",crn,crn,v);
+	printf("\tmov\t%s, %s, asr #%d\n",crn,crn,v);
 	return;
+    case UDIV:
+	v=ilog(v);
     case URSHIFT:
-	printf("\tsrl %s,%s,%d\n",crn,crn,v);
+	printf("\tmov\t%s, %s, lsr #%d\n",crn,crn,v);
 	return;
     case ADD:
-	printf("\taddu %s,%s,%d\n",crn,crn,v);
+	code_add(creg,v,creg);
 	break;
     case SUB:
-	printf("\taddu %s,%s,-%d\n",crn,crn,v);
-	break;
-    case CMP:
-        printf("\tslt %s,%s,%d\n",crn,crn,v);
-        cmpreg = creg;
-	break;
-    case BOR:
-	printf("\tori %s,%s,%d\n",crn,crn,v);
+	code_add(creg,-v,creg);
 	break;
-    case MUL: case UMUL:
-	printf("\tsll %s,%s,%d\n",crn,crn,ilog(v));
-	break;
-    case UDIV:
-	printf("\tsrl %s,%s,%d\n",crn,crn,ilog(v));
-	break;
-    case DIV:
-	printf("\tsra %s,%s,%d\n",crn,crn,ilog(v));
-	break;
+    case CMP: printf("\tcmp\t%s,%d\n",crn,v); break;
+    case BOR: printf("\torr\t%s, %s, #%d\n",crn,crn,v); break;
+    case EOR: printf("\teor\t%s, %s, #%d\n",crn,crn,v); break;
+    case BAND: printf("\tand\t%s, %s, #%d\n",crn,crn,v); break;
     default:
 	error(-1);
     }
@@ -2871,17 +2816,14 @@
     char *rrn = register_name(reg);
     use_int(creg);
     crn = register_name(creg);
-    printf("\t%s %s,%s,%s\n",op,crn,crn,rrn);
+    printf("\tmov %s, %s, %s %s\n",crn,crn,op,rrn);
 }
 
 void
 ld_indexx(int byte, int n, int xreg,int creg, int sign)
 {	
-    char *crn;
     use_int(creg);
-    crn = register_name(creg);
-    printf("\t%s %s,%d(%s)\n",cload(byte,sign),register_name(creg),n,
-	    register_name(xreg));
+    code_ld(cload(byte,sign),creg,n,xreg,byte==1?"  @ zero_extendqisi2":"");
 }
 
 int
@@ -2894,37 +2836,25 @@
 code_cmpdimm(int e, int csreg,int label,int cond)
 {
     /* used in dosiwtch() */
-    int reg=-1;
+    int sign,reg=-1;
     char *rn,*crn;
     if(chk) return;
     crn = register_name(csreg);
 
-    if (e<-32767||32766<e) {
+    if (!(sign=is_stage1_const(e,CMP))) {
 	rn = register_name(reg= get_register());
 	code_const(list2(CONST,e),reg);
-	switch(cond) {
-	case 1:
-	    printf("\tbne\t%s,%s,$L_%d\n",crn,rn,label); break;
-	case 0:
-	    printf("\tbeq\t%s,%s,$L_%d\n",crn,rn,label); break;
-	case LT:
-	    use_reg(csreg);
-	    printf("\tslt\t%s,%s,%s\n",rn,crn,rn);
-	    printf("\tbne\t%s,$0,$L_%d\n",rn,label); break;
-	default: error(-1);
-	}
-	free_register(reg);
+	printf("\tcmp\t%s, %s\n",crn,rn);
+    } else {
+	printf("\t%s\t%s, #%d\n",sign?"cmp":"cmn",crn,e);
     }
     switch(cond) {
     case 1:
-	printf("\tbne\t%s,%d,$L_%d\n",crn,e,label); break;
+	printf("\tbne\t.L%d\n",label); break;
     case 0:
-	printf("\tbeq\t%s,%d,$L_%d\n",crn,e,label); break;
+	printf("\tbeq\t.L%d\n",label); break;
     case LT:
-	use_reg(csreg);
-	rn = register_name(reg= get_register());
-	printf("\tslt\t%s,%s,%d\n",rn,crn,e);
-	printf("\tbne\t%s,$0,$L_%d\n",rn,label); break;
+	printf("\tblt\t.L%d\n",label); break;
     default: error(-1);
     }
     if (reg!=-1) free_register(reg);
@@ -2933,11 +2863,10 @@
 void
 code_opening(char *filename)
 {
-    static int count=0;
     /* this is called once per file */
-    printf("\t.file %d \"%s\"\n",count++,filename);
+    printf("@ Generated by mc for ARM/elf\n");
+    printf("\t.file \"%s\"\n",filename);
     printf(".text\n");
-
 }
 
 // should have pcond_const
@@ -3076,39 +3005,6 @@
 }
 
 static int
-code_mask_offset()
-{
-    /* used regsister var */
-    int i;
-    int offset=0;
-    int min = reg_var_num(max_reg_var);
-    int max = reg_var_num(0);
-    for(i=0;i<32;i++) {
-	if (i==28||i==31||(max>i&&i>=min)) {
-	    offset++;
-	}
-    }
-    if (offset>2) offset-=1;
-    return -offset*SIZE_OF_INT;
-}
-
-static unsigned int
-code_mask()
-{
-    /* used regsister var */
-    int i;
-    unsigned int mask=0;
-    int min = reg_var_num(max_reg_var);
-    int max = reg_var_num(0);
-    for(i=0;i<32;i++) {
-	if (i==28||i==31||(max>i&&i>=min)) {
-	    mask |= (1<<i);
-	}
-    }
-    return mask;
-}
-
-static int
 code_register_save(int reg_save,int freg_save,int disp)
 {
     int i;
@@ -3142,36 +3038,6 @@
     return disp;
 }
 
-static int
-code_fmask_offset()
-{
-    int i;
-    int offset=0;
-    int min = freg_var_num(max_reg_var);
-    int max = freg_var_num(0);
-    for(i=0;i<32;i++) {
-	if (i==28||i==31||(max>i&&i>=min)) {
-	    offset++;
-	}
-    }
-    if (offset>2) offset-=1;
-    return -offset*SIZE_OF_FLOAT;
-}
-
-static unsigned int
-code_fmask()
-{
-    int i;
-    unsigned int mask=0;
-    int min = freg_var_num(max_reg_var);
-    int max = freg_var_num(0);
-    for(i=0;i<32;i++) {
-	if (i==28||i==31||(max>i&&i>=min)) {
-	    mask |= (1<<i);
-	}
-    }
-    return mask;
-}
 
 void
 code_enter(char *name)
@@ -3692,7 +3558,7 @@
     use_float(d,freg);
     lvar_intro(e2);
     printf("\ts.s %s,",fregister_name(freg));
-    lvar(e2);
+    lvar(e2,"");
 }
 
 void
@@ -3989,7 +3855,7 @@
     }
     use_float(d,freg);
     lvar_intro(e2);
-    printf("\tl.s %s,",fregister_name(freg)); lvar(e2);
+    printf("\tl.s %s,",fregister_name(freg)); lvar(e2,"");
 }
 
 void
@@ -4607,11 +4473,11 @@
     crn_l = lregister_name_low(creg);
     lvar_intro(e2);
 #if ENDIAN==0
-    printf("\tsw %s,",crn_l);lvar(e2);
-    printf("\tsw %s,",crn_h);lvar(e2+SIZE_OF_INT);
+    printf("\tsw %s,",crn_l);lvar(e2,"");
+    printf("\tsw %s,",crn_h);lvar(e2+SIZE_OF_INT,"");
 #else
-    printf("\tsw %s,",crn_h);lvar(e2);
-    printf("\tsw %s,",crn_l);lvar(e2+SIZE_OF_INT);
+    printf("\tsw %s,",crn_h);lvar(e2,"");
+    printf("\tsw %s,",crn_l);lvar(e2+SIZE_OF_INT,"");
 #endif
 }
 
@@ -4700,8 +4566,8 @@
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
     lvar_intro(e1);
-    printf("\tlw %s,",crn_l); lvar(e1);
-    printf("\tlw %s,",crn_h); lvar(e1+SIZE_OF_INT);
+    printf("\tlw %s,",crn_l); lvar(e1,"");
+    printf("\tlw %s,",crn_h); lvar(e1+SIZE_OF_INT,"");
 }
 
 
--- a/mc-code-mips.c	Tue Jul 13 21:43:58 2004 +0900
+++ b/mc-code-mips.c	Wed Jul 14 14:37:37 2004 +0900
@@ -2442,13 +2442,7 @@
     use_int(creg);
     crn=register_name(creg);
     lvar_intro(e2);
-    if (byte==1) {
-	printf("\tsb %s,",crn);
-    } else if (byte==SIZE_OF_SHORT) {
-	printf("\tsh %s,",crn);
-    } else {
-	printf("\tsw %s,",crn);
-    }
+    printf("\t%s %s,",cstore(byte),crn);
     lvar(e2);
 }
 
@@ -2468,13 +2462,7 @@
     use_int(creg);
     crn=register_name(creg);
 
-    if (byte==1) {
-	printf("\tsb %s,0(%s)\n",crn,drn);
-    } else if (byte==SIZE_OF_SHORT) {
-	printf("\tsh %s,0(%s)\n",crn,drn);
-    } else {
-	printf("\tsw %s,0(%s)\n",crn,drn);
-    }
+    printf("\t%s %s,0(%s)\n",cstore(byte),crn,drn);
 }
 
 
@@ -2500,13 +2488,7 @@
     tosop(op,ireg,xreg);
     crn = register_name(ireg);
     drn = register_name(creg);
-    if (byte==1) {
-	printf("\tsb %s,0(%s)\n",crn,drn);
-    } else if (byte==SIZE_OF_SHORT) {
-	printf("\tsh %s,0(%s)\n",crn,drn);
-    } else {
-	printf("\tsw %s,0(%s)\n",crn,drn);
-    }
+    printf("\t%s %s,0(%s)\n",cstore(byte),crn,drn);
     free_register(edx);
     emit_pop_free(xreg);
 #else
@@ -2515,13 +2497,7 @@
     tosop(op,creg,xreg);
     crn = register_name(creg);
     drn = register_name(edx);
-    if (byte==1) {
-	printf("\tsb %s,0(%s)\n",crn,drn);
-    } else if (byte==SIZE_OF_SHORT) {
-	printf("\tsh %s,0(%s)\n",crn,drn);
-    } else {
-	printf("\tsw %s,0(%s)\n",crn,drn);
-    }
+    printf("\t%s %s,0(%s)\n",cstore(byte),crn,drn);
     free_register(edx);
     emit_pop_free(xreg);
 #endif
--- a/stdio.h	Tue Jul 13 21:43:58 2004 +0900
+++ b/stdio.h	Wed Jul 14 14:37:37 2004 +0900
@@ -1,3 +1,4 @@
+#define __micro_c__ 1
 #ifndef __micro_c__
 #include "/usr/include/stdio.h"
 long long strtoll(const char *, char **, int);
@@ -5,7 +6,10 @@
 void * realloc(void *ptr, size_t size);
 #else
 
+typedef int size_t;
+
 long long strtoll(const char *, char **, int);
+void * realloc(void *ptr, size_t size);
 
 #ifdef __APPLE__