changeset 385:875582d14b26

ARM continue...
author kono
date Fri, 23 Jul 2004 14:56:44 +0900
parents 5fc059f1947d
children 5b59949adc02
files .gdbinit Changes mc-code-arm.c
diffstat 3 files changed, 203 insertions(+), 141 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Wed Jul 21 13:52:13 2004 +0900
+++ b/.gdbinit	Fri Jul 23 14:56:44 2004 +0900
@@ -4,8 +4,8 @@
 # run  -s nkf203/nkf.c
 # run  -s -ob01.s mc-switch.c
 # run  -s l.c
-run  -s test/bitfield.c
-# run -s test/code-gen-all.c
+# run  -s test/bitfield.c
+run -s test/code-gen-all.c
 define regs 
 printf "pc =%08x lr =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$pc,$lr,$r0,$r1,$r3,$r4
 printf "r10=%08x r11=%08x r12=%08x r13=%08x r14=%08x r15=%08x\n",$r10,$r11,$r12,$r13,$r14,$r15
--- a/Changes	Wed Jul 21 13:52:13 2004 +0900
+++ b/Changes	Fri Jul 23 14:56:44 2004 +0900
@@ -5890,3 +5890,9 @@
 Wed Jul 21 13:51:56 JST 2004
 
 さて、inc_inst を、どうやっていれるか....
+
+copmpile error は取ったけどさ。
+
+Fri Jul 23 13:28:24 JST 2004
+
+なんか頭が回らないな。
--- a/mc-code-arm.c	Wed Jul 21 13:52:13 2004 +0900
+++ b/mc-code-arm.c	Fri Jul 23 14:56:44 2004 +0900
@@ -46,14 +46,8 @@
 
 static int creg;
 static int output_mode = TEXT_EMIT_MODE;
-static int cprestore_label;
-static int fmask_label;
-static int fmask_offset_label;
-static int mask_label;
-static int mask_offset_label;
 static int register_save_return_label;
-static int register_save_label;
-
+static int code_size_label ;
 
 static int r1_offset_label;
 static int lvar_offset_label;
@@ -83,6 +77,7 @@
 static int  lreg_sp;  /* longlong  REGister Stack-Pointer */
 static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
 
+#define REG_ip   12
 #define REG_fp   13
 #define REG_sp   14
 #define REG_VAR_BASE 11
@@ -178,7 +173,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)  (arch_mode&UseFPP?(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&UseFPP?is_float_reg(i):is_longlong_reg(i))
@@ -271,6 +266,7 @@
 static void    set_dreg(int,int);
 static void    set_freg(int,int);
 static void    set_lreg(int,int);
+static void inc_inst(int count);
 
 static int max_func_args;
 static int my_func_args;
@@ -369,12 +365,6 @@
 	round16(max_func_args*SIZE_OF_INT),
 	0
 );
-    printf("# mask_label $L_%d=0x%x\n",mask_label,code_mask());
-    printf("# mask_offset$L_%d=%d\n",mask_offset_label,code_mask_offset());
-    printf("# fmask_label $L_%d=0x%x\n",fmask_label,code_fmask());
-    printf("# fmask_offset$L_%d=%d\n",fmask_offset_label,code_fmask_offset());
-    printf("# cprestore  $L_%d=%d\n",cprestore_label ,round16(max_func_args*SIZE_OF_INT));
-   printf("#\n");
    printf("# callee arg top=\t%d\n",CALLEE_ARG(0)+r1_offsetv);
    printf("# r1_offset=\t\t%d %d\n",r1_offsetv,r1_offsetv%16);
    printf("# reg_save_top=\t\t%d\n",r1_offsetv);
@@ -413,18 +403,19 @@
 static void
 lvar_address(int l,int creg)
 {
+    inc_inst(1);
     if (fnptr->sc==CODE) {
         if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
 	    code_add(creg,CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp);
         } else
 	    code_add(creg,CODE_LVAR(l),REG_fp);
     } else if (l<0) {  /* local variable */
-        printf("\tsub\t%s, fp, #%d+$L_%d\n",register_name(creg),
+        printf("\tsub\t%s, fp, #%d+.L%d\n",register_name(creg),
 		FUNC_LVAR(l),lvar_offset_label);
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
 	code_add(creg,CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp);
     } else { /* callee's arguments */
-        printf("\tsub\t%s, fp, #%d+$L_%d\n",
+        printf("\tsub\t%s, fp, #%d+.L%d\n",
 		register_name(creg),CALLEE_ARG(l),r1_offset_label);
     }
 }
@@ -1251,7 +1242,8 @@
     int label,disp;
     char *rrn = register_name(r);
     disp = search_const(GVAR,(int)nptr,&label);
-    printf("\tldr %s, .L%d+%d\n",rrn,label,disp);
+    inc_inst(1);
+    printf("\tldr\t%s, .L%d+%d\n",rrn,label,disp);
 }
 
 #define mask8(d,bit)   (d & (255 << bit))
@@ -1324,6 +1316,7 @@
 
     use_int(reg);
     crn = register_name(reg);
+    inc_inst(3);
     if ((s=make_const(e2,&p1,&p2,&p3,0))) {
 	add = s>0?"add":"sub";
 	mov = s>0?"mov":"mvn";
@@ -1349,6 +1342,7 @@
     int s,p1,p2,p3;
     char *add;
     int label,disp;
+    inc_inst(3);
     if (offset==0) {
         if(r!=reg)
             printf("\tmov %s,%s\n",crn,rrn);
@@ -1371,6 +1365,7 @@
 {
     char *crn = register_name(reg);
     char *rrn = register_name(r);
+    inc_inst(1);
     if (-1024<offset&&offset<1024) {
 	printf("\t%s\t%s, [%s, #%d]%s\n",ld,crn,rrn,offset,cext);
     } else {
@@ -1385,6 +1380,7 @@
     char *rrn = register_name(r);
     char *orn;
     int reg;
+    inc_inst(1);
     if (-1024<offset&&offset<1024) {
 	printf("\t%s\t%s, [%s, #%d]%s\n",ld,crn,rrn,offset,cext);
     } else {
@@ -1434,14 +1430,17 @@
 void
 code_register(int e2,int reg) {
     use_int(reg);
-    if (reg!=e2)
-	printf("\tmov %s,%s\n",register_name(reg),register_name(e2));
+    if (reg!=e2) {
+	inc_inst(1);
+	printf("\tmov\t%s, %s\n",register_name(reg),register_name(e2));
+    }
 }
 
 
 void
 code_rlvar(int e2,int reg) {
     use_int(reg);
+    inc_inst(1);
     lvar_intro(e2);
     printf("\tldr\t%s, ",register_name(reg));
     lvar(e2,"");
@@ -1461,6 +1460,7 @@
 code_u2uc(int reg)
 {   
     use_int(reg);
+    inc_inst(1);
     printf("and\t%s, %s, #255\n",register_name(reg),register_name(reg));
 }
 
@@ -1468,6 +1468,7 @@
 code_u2us(int reg)
 {   
     use_int(reg);
+    inc_inst(2);
     printf("bic %s, %s, #16711680\n",register_name(reg),register_name(reg));
     printf("bic %s, %s, #-16777216\n",register_name(reg),register_name(reg));
 }
@@ -1475,8 +1476,9 @@
 void
 code_crlvar(int e2,int reg,int sign,int sz) {
     use_int(reg);
+    inc_inst(1);
     lvar_intro(e2);
-    printf("\t%s %s,",cload(sz,sign),register_name(reg));
+    printf("\t%s\t%s,",cload(sz,sign),register_name(reg));
     lvar(e2,sz==1?"  @ zero_extendqisi2":"");
     cext(sign,sz,reg);
 }
@@ -1486,8 +1488,10 @@
     int r;
     use_int(reg);
     r = get_ptr_cache(n);
-    if(r!=reg)
-	printf("\tmov %s,%s\n",register_name(reg),register_name(r));
+    inc_inst(2);
+    if(r!=reg) {
+	printf("\tmov\t%s, %s\n",register_name(reg),register_name(r));
+    }
     return;
 }
 
@@ -1496,6 +1500,7 @@
     int lb,disp;
     use_int(reg);
     disp = search_const(LABEL,label,&lb);
+    inc_inst(1);
     printf("\tldr\t%s, .L%d+%d\n",register_name(reg),lb,disp);
     return;
 }
@@ -1503,6 +1508,7 @@
 void
 code_neg(int creg) {
     use_int(creg);
+    inc_inst(1);
     printf("\trsb\t%s, %s, #0\n", register_name(creg), register_name(creg));
 }
 
@@ -1510,6 +1516,7 @@
 void
 code_not(int creg) {
     use_int(creg);
+    inc_inst(1);
     printf("\tmvn\t%s, %s, %s\n", 
 	register_name(creg), register_name(creg),register_name(creg));
 }
@@ -1519,6 +1526,7 @@
 code_lnot(int creg) {
     use_int(creg);
 
+    inc_inst(3);
     printf("\tcmp\t%s, #0\n", register_name(creg));
     printf("\tmovne\t%s, #0\n", register_name(creg));
     printf("\tmoveq\t%s, #1\n", register_name(creg));
@@ -1597,6 +1605,7 @@
 void
 code_environment(int creg) {
     /* save frame pointer */
+    inc_inst(1);
 #if R1SAVE
     use_int(creg);
     printf("\tldr\t%s,[fp, #0]\n",register_name(creg));
@@ -1613,25 +1622,11 @@
 
 
     if (rexpr_bool(e1, reg)) return;
-#if 0
-    b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
-    if (use) {
-	use_int(reg);
-	xrn = register_name(reg);
-	printf("\tli %s,0\n",xrn);
-	jmp(e3=fwdlabel());
-	fwddef(e2);
-	printf("\tli %s,1\n",xrn);
-	fwddef(e3);
-    } else {
-	fwddef(e2);
-    }
-#else
     b_expr(e1,1,0,1);  /* including > < ... */
     use_int(reg);
+    inc_inst(2);
     printf("\tmovne\t%s, #0\n", register_name(reg));
     printf("\tmoveq\t%s, #1\n", register_name(reg));
-#endif
 }
 
 char *
@@ -1666,6 +1661,7 @@
     code_ld(cload(sz,0),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1)),
 	sz==1?"  @ zero_extendqisi2":"");
     cext(0,sz,r);
+    inc_inst(1);
     printf("\tcmp\t%s, #0\n",register_name(reg));
     jcond(label,cond);
 }
@@ -1677,7 +1673,8 @@
     use_int(reg);
     crn = register_name(reg);
     lvar_intro(e2);
-    printf("\t%s %s,",cload(sz,0),crn);
+    inc_inst(1);
+    printf("\t%s\t%s,",cload(sz,0),crn);
     lvar(e2,sz==1?"  @ zero_extendqisi2":"");
     cext(0,sz,reg);
     code_cmp_register(reg,label,cond);
@@ -1697,6 +1694,7 @@
     char *crn;
     use_int(reg);
     crn = register_name(reg);
+    inc_inst(1);
     lvar_intro(e2);
     printf("\tldr\t%s,",crn);
     lvar(e2,"");
@@ -1707,6 +1705,7 @@
 void
 code_cmp_register(int e2,int label,int cond) {
     use_int(e2);
+    inc_inst(1);
     printf("\tcmp\t%s, #0\n",register_name(e2));
     jcond(label,cond);
 }
@@ -1728,6 +1727,7 @@
 
     disp = search_const(LABEL,lb,&label);
     printf("\tldr\t%s, .L%d+%d\n",crn,label,disp);
+    inc_inst(1);
 }
 
 #define MAX_COPY_LEN 20
@@ -1752,14 +1752,17 @@
     switch (length) {
     case 0:	break;
     case 1: case -1:
+	inc_inst(2);
 	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:
+	inc_inst(2);
 	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:
+	inc_inst(2);
 	printf("\tldr\t%s, [%s,#%d]\n",drn,frn,offset);
 	printf("\tstr\t%s, [%s,#%d]\n",drn,frn,offset);
 	break;
@@ -1789,6 +1792,7 @@
 	code_register(to,1);
 	code_const(length,2);
         /* overrap must be allowed */
+	inc_inst(1);
 	printf("\tbl %s\n",memmove);
 	extern_define(memmove,0,FUNCTION,1);
         fix=0;
@@ -1829,6 +1833,7 @@
         srn = register_name(sreg);
         code_lvar(cadr(arg),dreg);
         for(count=0;count<length;count+=SIZE_OF_INT) {
+	    inc_inst(2);
             printf("\tldr\t%s, [%s, #%d]\n",srn,crn,count);
             printf("\tstr\t%s, [%s, #%d]\n",srn,crn,count);
         }
@@ -1853,7 +1858,8 @@
 	if (ireg && reg!=ireg ) {
 	    free_register(ireg);
 	    if (mode) {
-		printf("\tmov\t%s,%s\n",register_name(reg),register_name(ireg));
+		inc_inst(1);
+		printf("\tmov\t%s, %s\n",register_name(reg),register_name(ireg));
 	    }
 	}
 	free_register(creg);
@@ -1870,7 +1876,8 @@
 	if (freg && reg!=freg) {
 	    free_register(freg);
 	    if (mode) {
-		printf("\t%s %s,%s\n",
+		inc_inst(1);
+		printf("\t%s\t%s, %s\n",
 		    (arch_mode&UseFPP)?"mvfs":"mov",
 		    fregister_name(reg),fregister_name(freg));
 	    }
@@ -1887,9 +1894,10 @@
     if (reg!=creg) {
 	if (lreg && reg!=lreg) {
 	    if (mode) {
-		printf("\tmov %s,%s\n",
+		inc_inst(2);
+		printf("\tmov\t%s, %s\n",
 		    lregister_name_low(reg),lregister_name_low(lreg));
-		printf("\tmov %s,%s\n",
+		printf("\tmov\t%s, %s\n",
 		    lregister_name_high(reg),lregister_name_high(lreg));
 	    }
 	    free_register(lreg);
@@ -2200,8 +2208,10 @@
 code_call(int e2,NMTBL *fn,int jmp)
 {
     if (car(e2) == FNAME) {
+	inc_inst(1);
 	printf("\tbl\t%s\n",fn->nm);
     } else {
+	inc_inst(3);
 	printf("\tmov\tlr, pc\n");
 	printf("\tmov\tpc, %s\n",register_name(jmp));
 	printf("\tldmea\tfp, {fp, sp, pc}\n");
@@ -2411,6 +2421,7 @@
     g = get_register();
     crn = register_name(reg);
     grn = register_name(g);
+    inc_inst(2);
     printf("\trsb\tsp, %s, sp, %s\n",crn, grn);
     printf("\tmov\t%s, sp\n",crn);
     free_register(g);
@@ -2419,10 +2430,11 @@
 void
 code_frame_pointer(int e3) {
     use_int(e3);
+    inc_inst(1);
 #if R1SAVE
-    printf("\tmov fp, %s\n",register_name(e3));
+    printf("\tmov\tfp, %s\n",register_name(e3));
 #else
-    printf("\tmov fp, %s\n",register_name(e3));
+    printf("\tmov\tfp, %s\n",register_name(e3));
 #endif
 }
 
@@ -2436,6 +2448,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;
+    inc_inst(1);
     printf("\tb\t%s\n",s);
     control=0;
 }
@@ -2446,6 +2459,7 @@
     max_reg_var = REG_VAR_BASE-REG_VAR_MIN;
     max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN;
     use_int(e2);
+    inc_inst(1);
     printf("\tmov\tpc, %s @ indirect jump\n",register_name(e2)); // ?!
     control=0;
 }
@@ -2491,6 +2505,7 @@
 lload(int creg,int reg,int offset) 
 {
     char *crn=register_name(creg);
+    inc_inst(2);
 #if ENDIAN==0
     if (creg!=regv_l(reg)) {
 	printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset);
@@ -2540,6 +2555,7 @@
     char *crn_l;
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
+    inc_inst(2);
 #if ENDIAN==0
     printf("\tstr\t%s, [%s, #0]\n",crn_l,drn);
     printf("\tstr\t%s, [%s, #%d]\n",crn_h,drn,SIZE_OF_INT);
@@ -2585,6 +2601,7 @@
     char *crn;
     use_int(creg);
     crn=register_name(creg);
+    inc_inst(1);
     lvar_intro(e2);
     printf("\t%s\t%s,",cstore(byte),crn);
     lvar(e2,"");
@@ -2593,8 +2610,10 @@
 void
 code_assign_register(int e2,int byte,int creg) {
     use_int(creg);
-    if (e2!=creg)
-	printf("\tmov %s,%s\n",register_name(e2),register_name(creg));
+    if (e2!=creg) {
+	inc_inst(1);
+	printf("\tmov\t%s, %s\n",register_name(e2),register_name(creg));
+    }
 }
 
 void
@@ -2606,6 +2625,7 @@
     use_int(creg);
     crn=register_name(creg);
 
+    inc_inst(1);
     printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn);
 }
 
@@ -2626,7 +2646,6 @@
 
     use_int(creg);
     xrn = register_name(xreg = emit_pop(0));       /* pop e3 value */
-#if 1
     set_ireg(edx,0);
     ld_indexx(byte,0,creg,ireg,sign);
     tosop(op,ireg,xreg);
@@ -2635,16 +2654,7 @@
     printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn);
     free_register(edx);
     emit_pop_free(xreg);
-#else
-    printf("# assop\n\tmove %s,%s\n",register_name(edx),register_name(creg));
-    ld_indexx(byte,0,edx,creg,sign);
-    tosop(op,creg,xreg);
-    crn = register_name(creg);
-    drn = register_name(edx);
-    printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn);
-    free_register(edx);
-    emit_pop_free(xreg);
-#endif
+    inc_inst(1);
 }
 
 
@@ -2684,25 +2694,32 @@
     crn = register_name(creg);
     switch(op) {
     case ADD:
+	inc_inst(1);
 	printf("\tadd %s,%s,%s\n",crn,crn,orn);
 	break;
     case SUB:
+	inc_inst(1);
 	printf("\tsub %s,%s,%s\n",crn,crn,orn);
 	break;
     case CMP:
+	inc_inst(1);
         printf("\tcmp %s,%s\n",crn,orn);
 	break;
     case BAND: 
+	inc_inst(1);
 	printf("\tand %s,%s,%s\n",crn,crn,orn);
 	break;
     case EOR: 
+	inc_inst(1);
 	printf("\teor %s,%s,%s\n",crn,crn,orn);
 	break;
     case BOR:
+	inc_inst(1);
 	printf("\torr %s,%s,%s\n",crn,crn,orn);
 	break;
     case MUL:
     case UMUL:
+	inc_inst(1);
 	printf("\tmul %s,%s,%s\n",crn,crn,orn);
 	break;
     case DIV:
@@ -2755,17 +2772,17 @@
     case LSHIFT:
     case ULSHIFT:
 	printf("\tmov\t%s, %s, asl #%d\n",crn,crn,v);
-	return;
+	break;
     case DIV:
 	v=ilog(v);
     case RSHIFT:
 	printf("\tmov\t%s, %s, asr #%d\n",crn,crn,v);
-	return;
+	break;
     case UDIV:
 	v=ilog(v);
     case URSHIFT:
 	printf("\tmov\t%s, %s, lsr #%d\n",crn,crn,v);
-	return;
+	break;
     case ADD:
 	code_add(creg,v,creg);
 	break;
@@ -2779,6 +2796,7 @@
     default:
 	error(-1);
     }
+    inc_inst(1);
 }
 
 void
@@ -2788,7 +2806,8 @@
     char *rrn = register_name(reg);
     use_int(creg);
     crn = register_name(creg);
-    printf("\tmov %s, %s, %s %s\n",crn,crn,op,rrn);
+    inc_inst(1);
+    printf("\tmov\t%s, %s, %s %s\n",crn,crn,op,rrn);
 }
 
 void
@@ -2813,6 +2832,7 @@
     if(chk) return;
     crn = register_name(csreg);
 
+    inc_inst(2);
     if (!(sign=is_stage1_const(e,CMP))) {
 	rn = register_name(reg= get_register());
 	code_const(list2(CONST,e),reg);
@@ -2878,10 +2898,12 @@
 
     if (mode==COND_BRANCH) {
 	printf("\tb%s\t.L%d\n",cc,l1);
+	inc_inst(1);
     } else if (mode==COND_VALUE) {
 	rn0 =		register_name(r0);
-	printf("\tmov%s\t%s, #0\n",rn2,ncc);
-	printf("\tmov%s\t%s, #1\n",rn2,cc);
+	printf("\tmov%s\t%s, #0\n",ncc,rn2);
+	printf("\tmov%s\t%s, #1\n",cc,rn2);
+	inc_inst(2);
     } else error(-1);
 }
 
@@ -2926,6 +2948,7 @@
 jcond(int l, int cond)
 {       
     if (chk) return;
+    inc_inst(1);
     printf("\tb%s\t.L%d\n",cond?"ne":"eq",l);
 }
 
@@ -2934,6 +2957,7 @@
 {       
     control=0;
     if (chk) return;
+    inc_inst(1);
     printf("\tb\t.L%d\n",l);
 }
 
@@ -2948,13 +2972,15 @@
 code_register_save(int reg_save,int freg_save,int disp)
 {
     int i;
+    inc_inst(1);
     printf("\tstmfd\tsp!, {");
     for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) {
-	    printf(", %s",register_name(i));
+	    printf("%s, ",register_name(i));
 	disp -= SIZE_OF_INT;
     }
     printf("fp, ip, lr, pc}\n");
     if (freg_save>0) {
+	inc_inst(1);
 	printf("\tsfmfd\tf4, %d, [sp]!\n",freg_save);
 	disp -= SIZE_OF_DOUBLE*freg_save;
     }
@@ -2968,7 +2994,9 @@
     if (freg_save>0) {  i=reg_save*SIZE_OF_INT+freg_save*SIZE_OF_DOUBLE;
 	printf("\tlfm\tf4, %d, [fp, #%d]!\n",freg_save,i);
 	disp -= SIZE_OF_DOUBLE*freg_save;
-    }
+	inc_inst(1);
+    }
+    inc_inst(1);
     printf("\tldmea\tfp, {");
     for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) {
 	    printf("%s, ",register_name(i));
@@ -2988,21 +3016,8 @@
 	printf("\t.align 3\n");
     if (stmode!=STATIC)
     printf("\t.globl\t%s\n",name);
-#ifdef DOT_SIZE
-    printf("\t.type\t%s,@function\n",name);
-#endif
-    printf("%s:\n",name);
-    printf("\t.frame $fp,$L_%d,$31\n",r1_offset_label=fwdlabel());
-    printf("\t.mask  $L_%d,$L_%d\n",mask_label=fwdlabel(),
-	mask_offset_label=fwdlabel());
-    printf("\t.fmask  $L_%d,$L_%d\n",fmask_label=fwdlabel(),
-	fmask_offset_label=fwdlabel());
-    printf("\t.set noreorder\n");
-    printf("\t.cpload $25\n");
-    printf("\t.set reorder\n");
-    printf("\tsubu $sp,$fp,$L_%d\n",r1_offset_label);
-    printf("\t.cprestore $L_%d\n",cprestore_label=fwdlabel());
-    // printf("\tmove  $fp,$sp\n");
+    printf("\t.type\t%s,function\n",name);
+    code_size_label = backdef();
     lvar_offset_label = fwdlabel();
     max_func_args = 0;
 }
@@ -3020,40 +3035,30 @@
 code_leave(char *name)
 {
     code_offset_set(fnptr);
+    printf("%s:\n",name);
+    code_add(REG_sp,disp,REG_fp);
+    jmp(code_size_label);
     local_table();
-    printf("\t.end    %s\n",name);
+    printf("\t.size\t%s,.L%d-.L%d\n",name, code_size_label,backdef());
 }
 
 void
 enter(char *name)
 {
     if (output_mode!=TEXT_EMIT_MODE) 
-	text_mode(3);
+	text_mode(2);
     else
-	printf("\t.align 3\n");
+	printf("\t.align 2\n");
     
     max_func_args = 0;
 
     lvar_offset_label = fwdlabel();
-
+    code_size_label = fwdlabel();
+    printf("\t.type\t%s,function\n",name);
     if (stmode!=STATIC)
 	printf("\t.globl\t%s\n",name);
-    printf("%s:\n",name);
-    printf("\t.frame $fp,$L_%d,$31\n",r1_offset_label=fwdlabel());
-    printf("\t.mask  $L_%d,$L_%d\n",mask_label=fwdlabel(),
-	mask_offset_label=fwdlabel());
-    printf("\t.fmask  $L_%d,$L_%d\n",fmask_label=fwdlabel(),
-	fmask_offset_label=fwdlabel());
-    printf("\t.set noreorder\n");
-    printf("\t.cpload $25\n");
-    printf("\t.set reorder\n");
-    printf("\tsubu $sp,$sp,$L_%d\n",r1_offset_label);
-    printf("\t.cprestore $L_%d\n",cprestore_label=fwdlabel());
-    printf("\tsw      $31,$L_%d-%d($sp)\n",r1_offset_label,arg_offset);
-    printf("\tsw      $fp,$L_%d-%d($sp)\n",r1_offset_label,arg_offset+SIZE_OF_INT);
-    printf("\tj $L_%d\n",register_save_label=fwdlabel());
     register_save_return_label = backdef();
-    printf("\tmove  $fp,$sp\n");
+
 }
 
 void
@@ -3091,9 +3096,10 @@
 	    car(cadr(fnptr->ty))==STRUCT ||
 	    car(cadr(fnptr->ty))==UNION)) {
 	    sz = size(cadr(fnptr->ty));
-	    printf("\tli $4,%d\n",sz);
-	    printf("\tsubl $5,$4,$fp\n");
-	    printf("\tlw $3,(%d)($fp)\n",(my_func_args-1)*SIZE_OF_INT);
+	    inc_inst(3);
+	    code_const(sz,REGISTER_OPERAND);
+	    printf("\tsubl\tr1, r2, fp\n");
+	    printf("\tldr\tr0, [fp, #%d]\n",(my_func_args-1)*SIZE_OF_INT);
 	    emit_copy(6,3,sz,0,1,1);
 	} else if (cadr(fnptr->ty)!=VOID) {
 	    creg = ireg = cadr(get_input_register_var(0,0,1));
@@ -3102,41 +3108,31 @@
 	}
 #if R1SAVE
 #else
-	printf("\tsubu $fp,");
-	printf("$fp,%d+$L_%d\n",FUNC_LVAR(0),lvar_offset_label);
-	// printf("\tj $L_%d\n",retcont1);
+	inc_inst(1);
+	printf("\tsub\tfp, ");
+	printf("fp, #%d+.L%d\n",FUNC_LVAR(0),lvar_offset_label);
 #endif
     }
     fwddef(retlabel);
-    // if (retcont) {
-// 	fwddef(retcont1);
-    // }
 
     r1_offsetv = code_offset_set(fnptr);
-
-    printf("\tmove    $sp,$fp\n");
-    printf("\tlw      $31,$L_%d-%d($sp)\n",r1_offset_label,arg_offset);
-    printf("\tlw      $fp,$L_%d-%d($sp)\n",r1_offset_label,arg_offset+SIZE_OF_INT);
-    if (max_reg_var+max_freg_var)
-	code_register_restore(max_reg_var,max_freg_var,-arg_offset-SIZE_OF_INT*2);
-    printf("\taddu    $sp,$sp,%d\n",r1_offsetv);
-    printf("\tj       $31\n");
+    code_register_restore(max_reg_var,max_freg_var,-arg_offset-SIZE_OF_INT*2);
 
 //  leave part end
 
 //  entry part  (save register)
 
-    if (max_reg_var+max_freg_var==0) {
-    } else {
-	code_label(register_save_label);
-	code_register_save(max_reg_var,max_freg_var,-arg_offset-SIZE_OF_INT*2);
-	jmp(register_save_return_label);
-    }
-
+    printf("%s:\n",name);
+    printf("\tmov\tip, sp\n");
+    code_register_save(max_reg_var,max_freg_var,-arg_offset-SIZE_OF_INT*2);
+
+    code_add(REG_fp,-4,REG_ip);
+    code_add(REG_sp,disp,REG_sp);
+    jmp(register_save_return_label);
     local_table();
-    printf("\t.end    %s\n",name);
-
-    labelno++;
+
+    printf("\t.size\t%s,.L%d-.L%d\n",name, code_size_label,backdef());
+
     free_all_register();
 }
 
@@ -3221,7 +3217,7 @@
     lb=fwdlabel();
     // should put on different segement
     printf("\t.rdata\n\t.align 2\n");
-    printf("$L_%d:\n",lb);
+    printf(".L%d:\n",lb);
     output_mode = RODATA_EMIT_MODE;
     return lb;
 }
@@ -3316,7 +3312,7 @@
 emit_label(int labelno)
 {
     data_mode(0);
-    printf("\t.long $L_%d\n",labelno);
+    printf("\t.long .L%d\n",labelno);
 }
 
 extern void
@@ -3330,8 +3326,8 @@
 	data_mode(0);
 #ifdef DOT_SIZE
 	lb=fwdlabel();
-	printf("$L_%d:\n",lb);
-	printf("\t.size\t%s,$L_%d-%s\n",n->nm,lb,n->nm);
+	printf(".L%d:\n",lb);
+	printf("\t.size\t%s,.L%d-%s\n",n->nm,lb,n->nm);
 #endif
     }
 }
@@ -3424,7 +3420,8 @@
      code_save_stacks();
      clear_ptr_cache();
      extern_define(conv,0,FUNCTION,1);
-     printf("\tjal %s\n",conv);
+     inc_inst(1);
+     printf("\tbl\t%s\n",conv);
      lib_args(16);
 }
 
@@ -3458,6 +3455,7 @@
     int greg;
     use_float(d,e2);
 
+     inc_inst(2);
     if (!(arch_mode&UseFPP)) {
         code_save_stacks();
 	clear_ptr_cache();
@@ -3508,6 +3506,7 @@
     } else {
 	if (freg!=e2) {
 	    if (is_int_reg(e2)) error(-1);
+	    inc_inst(1);
 	    printf("\t%s\t%s,%s\n",movef(d),
 		fregister_name(freg),fregister_name(e2));
 	}
@@ -3542,6 +3541,7 @@
     } else {
 	use_float(d,freg);
 	lvar_intro(e2);
+	inc_inst(1);
 	printf("\t%s\t%s,",fstore(d),fregister_name(freg));
 	lvar(e2,"@ float");
     }
@@ -3558,6 +3558,7 @@
 	}
     }
     use_float(d,freg);
+    inc_inst(1);
     printf("\t%s\t%s,0(%s) @ float\n",fstore(d),
 	fregister_name(freg),register_name(e2));
 }
@@ -3573,7 +3574,8 @@
     }
     use_float(d,freg);
     if (e2!=freg) {
-	printf("\t%s\t%s,%s\n",movef(d),
+	inc_inst(1);
+	printf("\t%s\t%s, %s\n",movef(d),
 		fregister_name(e2),fregister_name(freg));
     }
 }
@@ -3638,6 +3640,7 @@
 	}
     } else {
 	frn = register_name(freg);
+	inc_inst(1);
 	if (value==0 || value==1 || value==10) {
 	    printf("\t%s\t%s, #%d\n",movef(d),frn,(int)value);
 	} else if (value==-1 || value==-10) {
@@ -3682,6 +3685,7 @@
 	}
     } else {
 	frn = fregister_name(freg);
+	inc_inst(1);
 	printf("\t%s\t%s, %s\n",d?"mnfd":"mnfs",frn,frn);
     }
 }
@@ -3700,6 +3704,7 @@
     } else {
 	use_float(d,reg);
 	lreg = get_register();
+	inc_inst(1);
 	printf("\tfixz\t%s, %s\n",register_name(lreg),register_name(reg));
 	set_ireg(lreg,0);
     }
@@ -3720,6 +3725,7 @@
     } else {
 	use_int(reg);
 	lreg = get_dregister(1);
+	inc_inst(1);
 	printf("\tflt%c\t%s, %s\n",dsuffix(d),
 		register_name(lreg),register_name(reg));
 	set_dreg(lreg,0);
@@ -3741,6 +3747,7 @@
 	set_ireg(RET_REGISTER,0);
     } else {
 	//   u = (d>2.1e9)?((int)(d-2.1e9)^2147483648):(int)d
+	inc_inst(7);
         if (!d) printf("\tmvfd    %s, %s\n",frn,frn);
 	emit_dpush(1);
 	code_dconst(dlist2(DCONST,2.147483648e9),USE_CREG,1);
@@ -3776,6 +3783,7 @@
 	clear_ptr_cache();
 	extern_conv(d?"__floatsidf":"__floatsisf");
 	code_rlvar(tmp,REGISTER_OPERAND);
+	inc_inst(2);
 	printf("\tcmp\t%s, #0\n",register_name(REGISTER_OPERAND));
 	printf("\tbge\t1f\n");
 	if (d)
@@ -3802,6 +3810,7 @@
 	crn = register_name(reg);
 	set_dreg(reg=get_dregister(1),0);
 	frn = register_name(reg);
+	inc_inst(5);
 	printf("\tfltd\t%s, %s\n",frn,crn);
 	printf("\tcmp\t%s, #0\n",crn);
         printf("\tbge\t1f\n");
@@ -3829,6 +3838,7 @@
 	use_float(0,reg);
     } else {
 	frn = register_name(freg);
+	inc_inst(1);
 	printf("\tmvfs\t%s,%s\n",frn,frn);
     }
     return;
@@ -3846,6 +3856,7 @@
 	use_float(1,reg);
     } else {
 	frn = register_name(freg);
+	inc_inst(1);
 	printf("\tmvfd\t%s,%s\n",frn,frn);
     }
     return;
@@ -3928,6 +3939,7 @@
     } else {
 	use_float(d,freg);
 	lvar_intro(e2);
+	inc_inst(1);
 	printf("\t%s\t%s,",fload(d),fregister_name(freg)); 
 	lvar(e2,d?"@ double":"@ float");
     }
@@ -4069,6 +4081,7 @@
     }
     grn = fregister_name(e1);
     frn = fregister_name(reg);
+    inc_inst(1);
     if (cmp) {
       printf("\t%s\t%s, %s\n",opn,frn,grn);
     } else {
@@ -4103,7 +4116,8 @@
     if (d) {
 	if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
 	    edx0 = get_register(); if(!edx0) error(-1);
-	    printf("# dassop\n\tmov %s,%s\n",
+	    inc_inst(1);
+	    printf("# dassop\n\tmov\t%s, %s\n",
 		register_name(edx0),register_name(edx));
 	    edx = edx0;
 	}
@@ -4123,7 +4137,8 @@
     } else {
 	if (freg==edx) {
 	    edx0 = get_register(); if(!edx0) error(-1);
-	    printf("# dassop\n\tmov %s,%s\n",
+	    inc_inst(1);
+	    printf("# dassop\n\tmov\t%s, %s\n",
 		register_name(edx0),register_name(edx));
 	    edx = edx0;
 	}
@@ -4200,6 +4215,7 @@
     if (!(arch_mode&UseFPP)) {
 	error(-1);
     }
+    inc_inst(1);
     printf("\tmvf%c\t%s,#1\n",dsuffix(d),fregister_name(g));
     return g;
 }
@@ -4366,11 +4382,14 @@
 	    if (d) set_dreg(reg,0); else set_freg(reg,0);
 	}
 	frn=fregister_name(reg);
+	inc_inst(1);
 	printf("\t%s%c\t%s, %s, %s\n",
 	    dir>0?"adf":"suf",dsuffix(d),
 	    crn,crn,grn);
-	if (use && reg!=cadr(e2))
+	if (use && reg!=cadr(e2)) {
+	    inc_inst(1);
 	    printf("\tmvf%c\t%s, %s\n",dsuffix(d),frn,crn);
+	}
     } else {
 	g_expr(e2);
 	if (!is_int_reg(creg)) error(-1);
@@ -4382,6 +4401,7 @@
 	grn = fregister_name(g = code_dload_1(d));
 	frn=fregister_name(reg);
 	code_ldf(fload(d),frn,0,reg0,"");
+	inc_inst(1);
 	printf("\t%s%c\t%s, %s, %s\n",
 	    dir>0?"adf":"suf",dsuffix(d),
 	    frn,frn,grn);
@@ -4406,8 +4426,11 @@
 	    set_freg(reg,0);
 	}
 	frn=fregister_name(reg);
-	if (use && reg!=cadr(e2))
+	if (use && reg!=cadr(e2)) {
+	    inc_inst(1);
 	    printf("\tmvf%c\t%s, %s\n",dsuffix(d),frn,crn);
+	}
+	inc_inst(1);
 	printf("\t%s%c\t%s,%s,%s\n",dir>0?"adf":"suf",
 	    dsuffix(d),crn,crn,grn);
     } else {
@@ -4421,6 +4444,7 @@
 	frn=fregister_name(reg);
 	grn = fregister_name(g = code_dload_1(d));
 	code_ldf(fload(d),frn,0,reg0,"");
+	inc_inst(1);
 	printf("\t%s%c\t%s, %s, %s\n",
 	    dir>0?"adf":"suf",dsuffix(d),
 	    grn,frn,grn);
@@ -4483,6 +4507,7 @@
     default: error(-1);
     }
     g_expr(list3(op1,e2,e1));
+    inc_inst(1);
     printf("\t%s\t.L%d\n",opn,l1);
 }
 
@@ -4597,6 +4622,7 @@
 code_cmp_lregister(int reg,int label,int cond)
 {
     use_longlong(reg);
+    inc_inst(1);
     printf("\torr\t%s, %s, %s\n",
 		lregister_name_low(reg),
 		lregister_name_low(reg),
@@ -4652,6 +4678,7 @@
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
     lvar_intro(e2);
+    inc_inst(2);
 #if ENDIAN==0
     printf("\tstr\t%s, ",crn_l);lvar(e2,"");
     printf("\tstr\t%s, ",crn_h);lvar(e2+SIZE_OF_INT,"");
@@ -4707,6 +4734,7 @@
     use_longlong(creg);
     rl=lregister_name_low(creg);
     rh=lregister_name_high(creg);
+    inc_inst(2);
     printf("\trsbs\t%s, %s, #0\n",rl,rl);
     printf("\trsc\t%s, %s, #0\n",rh,rh);
 }
@@ -4738,6 +4766,7 @@
     use_longlong(creg);
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
+    inc_inst(2);
     lvar_intro(e1);
     printf("\tldr\t%s, ",crn_l); lvar(e1,"");
     printf("\tldr\t%s, ",crn_h); lvar(e1+SIZE_OF_INT,"");
@@ -4799,10 +4828,12 @@
     crn_l = lregister_name_low(reg);
     switch(op) {
     case LADD:
+	inc_inst(2);
         printf("\tadds\t%s, %s, %s\n",crn_l,crn_l,orn_l);
         printf("\tadc\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
     case LSUB:
+	inc_inst(2);
         printf("\tsubs\t%s, %s, %s\n",crn_l,crn_l,orn_l);
         printf("\tsbc\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
@@ -4810,14 +4841,17 @@
 	error(-1);
 	break;
     case LBAND: 
+	inc_inst(2);
 	printf("\tand\t%s, %s, %s\n",crn_l,crn_l,orn_l);
 	printf("\tand\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
     case LEOR: 
+	inc_inst(2);
 	printf("\teor\t%s, %s, %s\n",crn_l,crn_l,orn_l);
 	printf("\teor\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
     case LBOR:
+	inc_inst(2);
 	printf("\torr\t%s, %s, %s\n",crn_l,crn_l,orn_l);
 	printf("\torr\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
@@ -4899,6 +4933,7 @@
     case LULSHIFT:
 	greg = get_register();
 	grn = register_name(greg);
+	inc_inst(4);
 	printf("\tmov\t%s, %s lsl #%d\n",crn_h,crn_h,v);
 	printf("\tmov\t%s, %s lsr #%d\n",grn,crn_l,32-v);
 	printf("\torr\t%s, %s,%s\n",crn_h,crn_h,grn);
@@ -4910,6 +4945,7 @@
     case LRSHIFT:
 	greg = get_register();
 	grn = register_name(greg);
+	inc_inst(4);
 	printf("\tmov\t%s, %s lsr #%d\n",crn_l,crn_l,v);
 	printf("\tmov\t%s, %s lsl #%d\n",grn,crn_h,32-v);
 	printf("\torr\t%s, %s,%s\n",crn_l,crn_l,grn);
@@ -4921,6 +4957,7 @@
     case LURSHIFT:
 	greg = get_register();
 	grn = register_name(greg);
+	inc_inst(4);
 	printf("\tmov\t%s, %s lsl #%d\n",grn,crn_h,32-v);
 	printf("\tmov\t%s, %s lsr #%d\n",crn_l,crn_l,v);
 	printf("\torr\t%s, %s,%s\n",crn_l,grn,crn_l);
@@ -4928,22 +4965,27 @@
 	free_register(greg);
 	return;
     case LADD:
+	inc_inst(2);
         printf("\tadds\t%s, %s, #%d\n",crn_l,crn_l,v);
         printf("\tadc\t%s, %s, #%d\n",crn_h,crn_h,vh);
 	break;
     case LSUB:
+	inc_inst(2);
         printf("\tsubs\t%s, %s, #%d\n",crn_l,crn_l,v);
         printf("\tsbc\t%s, %s, #%d\n",crn_h,crn_h,vh);
 	break;
     case LBAND: 
+	inc_inst(2);
 	printf("\tand\t%s, %s, #%d\n",crn_l,crn_l,v);
 	printf("\tand\t%s, %s, #%d\n",crn_h,crn_h,vh);
 	break;
     case LEOR: 
+	inc_inst(2);
 	printf("\teor\t%s, %s, #%d\n",crn_l,crn_l,v);
 	printf("\teor\t%s, %s, #%d\n",crn_h,crn_h,vh);
 	break;
     case LBOR:
+	inc_inst(2);
 	printf("\torr\t%s, %s, #%d\n",crn_l,crn_l,v);
 	printf("\torr\t%s, %s, #%d\n",crn_h,crn_h,vh);
 	break;
@@ -4981,9 +5023,10 @@
     use_longlong(reg);
     crn_h = lregister_name_high(lreg);
     crn_l = lregister_name_low(lreg);
+    inc_inst(2);
     if (reg0!=regv_l(lreg))
 	printf("\tmov\t%s, %s\n",crn_l,crn);
-    printf("\tmov %s,%s asr #31\n",crn_h,crn_l);
+    printf("\tmov\t%s, %s asr #31\n",crn_h,crn_l);
 }
 
 void
@@ -5001,6 +5044,7 @@
     use_longlong(reg);
     crn_h = lregister_name_high(lreg);
     crn_l = lregister_name_low(lreg);
+    inc_inst(2);
     if (reg0!=regv_l(lreg))
 	printf("\tmov\t%s, %s\n",crn_l,crn);
     printf("\tmov\t%s, #0\n",crn_h);
@@ -5019,8 +5063,10 @@
     int reg0;
     crn_l = lregister_name_low(reg0=lreg);
     use_int(reg);
-    if (ireg!=regv_l(reg0))
+    if (ireg!=regv_l(reg0)) {
+	inc_inst(1);
 	printf("\tmov\t%s, %s\n",register_name(ireg),crn_l);
+    }
 }
 
 void
@@ -5124,6 +5170,7 @@
 ladd(int dreg,int rreg,int v)   //   rreg = dreg + v
 {
     // v should be 8bit const with 2's shift
+    inc_inst(2);
     if (v>0) {
 	printf("\tadds\t%s, %s, #%d\n", 
 		lregister_name_low(rreg),lregister_name_low(dreg), v);
@@ -5210,6 +5257,7 @@
     use_longlong(reg);
     if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
 	edx0 = get_register(); if(!edx0) error(-1);
+	inc_inst(1);
 	printf("# lassop\n\tmov\t%s, %s\n",register_name(edx0),
 	       register_name(edx));
 	edx = edx0;
@@ -5301,21 +5349,26 @@
     code_add(t,csvalue,-min);
     code_cmpdimm(max-min+1,t,dlabel,GT);
     switch(delta) {
-    case 1: printf("\tldrls\tpc, [pc, %s, asl #2]\n",trn); break;
+    case 1: printf("\tldrls\tpc, [pc, %s, asl #2]\n",trn);
+	inc_inst(1);
+	break;
     case 2:
 	printf("\ttst\t%s, #1\n",trn);
 	printf("\tbne\t.L%d\n",dlabel);
 	printf("\tldrls\tpc, [pc, %s, asl #1]\n",trn); break;
+	inc_inst(3);
 	break;
     case 4:
 	printf("\ttst\t%s, #3\n",trn);
 	printf("\tbne\t.L%d\n",dlabel);
 	printf("\tbne\t.L%d\n",dlabel);
 	printf("\tldrls\tpc, [pc, %s]\n",trn); break;
+	inc_inst(4);
 	break;
     default:
 	error(-1);
     }
+    inc_inst(1);
     printf("\tb\t.L%d\n",dlabel);
 
     free_register(t);
@@ -5602,6 +5655,7 @@
 make_mask_and_or(int mask,int tmp,char *trn,char *crn,char *lrn)
 {
 // printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
+	inc_inst(4);
 	code_const(~mask,tmp);
 	printf("\torr %s,%s,%s\n",trn,crn,trn);
 	/* do conjunction  */
@@ -5667,6 +5721,7 @@
     int m;
 // printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
     if ((m=(~mask|c))!=-1) {
+	inc_inst(1);
 	if (is_stage1_const(m,0)) {
 	    printf("\tand\t%s, %s, #%d\n",crn,trn,m);
 	} else {
@@ -5679,6 +5734,7 @@
     /* make or-mask  */
     c = mask&c;
     if (c!=0) {
+	inc_inst(1);
 	/* do disjunction  */
 	if (is_stage1_const(c,0)) {
 	    printf("\torr\t%s, %s, #%d\n",crn,trn,m);