changeset 374:9bc42f69f653 lvar-offset-before

arm continue...
author kono
date Sun, 11 Jul 2004 20:59:52 +0900
parents a9bc85fe6702
children 91849fdeea60
files Changes mc-code-arm.c mc-code-mips.c
diffstat 3 files changed, 147 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sun Jul 11 13:31:52 2004 +0900
+++ b/Changes	Sun Jul 11 20:59:52 2004 +0900
@@ -5708,9 +5708,56 @@
 で1000命令毎には出力する必要がある。しかも、既に出力されてい
 るものは、前のを使う必要がある。なるほどね。っていうことは、
 テーブルにそういうフラグをつけないとだめか。(それぐらい
-アセンブラでやってよ〜)
+アセンブラでやってよ〜) 
+
+すべてのprintfにcounter をつければ良いわけだけど、いくつかは
+問題があるだろうな。ちょっと量多いしね。
 
 ARMには short ってないのか。short を多用しているプログラムは
 だめなのね。
 
 (でも、どっちかって言うとテスト環境を作る方が難しそう)
+
+slとかipとか思い入れがありそうなレジスタの名前も大した意味がある
+わけではないらしい。
+
+ARMって、なんかsigned char とunsinged char の区別がないな。
+
+lvar offset が、ちょっとめんどくさいかな。
+constant が決まってないから、せっかく作ったcode_add
+が使えない。いや、決まるのかな?
+
+Sun Jul 11 20:37:20 JST 2004
+
+やっぱり、local variable のオフセットがその場で定数でないのは
+まずい。
+
+                     負の値
+         fp          <-------|
+   +------+------------------+
+          <----lvar_offset--->
+
+なのがまずいんだよね。
+
+          負の値
+         fp------->          |
+   +------+------------------+
+          <----lvar_offset--->
+
+にすれば良いだけだよね。なんけど、def で pre decrement しているが
+まずい。が、<0 でないとまずいので、単純な post decrement でもだめ。
+
+でも、これ修正量が多いよね。
+
+          負の値               
+         fp------->          sp----->
+   +------+------------------+
+ callee   <----lvar_offset--->  caller
+   arg                            arg
+   <------> pre known offset
+   ---->
+
+と、直せば良い。
+
+ん、だが....
+
--- a/mc-code-arm.c	Sun Jul 11 13:31:52 2004 +0900
+++ b/mc-code-arm.c	Sun Jul 11 20:59:52 2004 +0900
@@ -83,12 +83,12 @@
 static int  lreg_sp;  /* longlong  REGister Stack-Pointer */
 static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
 
-#define REG_fp   11
-#define REG_sp   15
-#define REG_VAR_BASE 10
-#define REG_VAR_MIN  8
-#define MIN_TMP_REG 0
-#define MAX_TMP_REG 7
+#define REG_fp   13
+#define REG_sp   14
+#define REG_VAR_BASE 11
+#define REG_VAR_MIN  4
+#define MIN_TMP_REG 12          /* only one tmp register? */
+#define MAX_TMP_REG 12
 
 #define PTRC_REG 3              /* mark for pointer cache */
 
@@ -107,7 +107,7 @@
 #define LREG_OFFSET (REAL_MAX_REGISTER+REAL_MAX_FREGISTER)
 
 int MAX_INPUT_REGISTER_VAR = 4;
-int MAX_CODE_INPUT_REGISTER_VAR = 7-MIN_TMP_REG;
+int MAX_CODE_INPUT_REGISTER_VAR = 9-MIN_TMP_REG;
 int MAX_INPUT_DREGISTER_VAR = 0;
 int MAX_INPUT_FREGISTER_VAR = 0;
 int MAX_CODE_INPUT_DREGISTER_VAR = 3-MIN_TMP_FREG;
@@ -162,7 +162,7 @@
 
 static char *reg_name[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 
-    "r8", "r9", "sl", "fp", "ip", "lr", "pc", "sp",
+    "r8", "r9", "sl", "lr", "ip", "fp", "sp", "pc",
     "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7";
 }; 
 
@@ -418,16 +418,14 @@
 {
     if (fnptr->sc==CODE) {
         if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-            printf("\tadd\t%s, sp, #%d\n",
-		register_name(creg),CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
+	    code_add(creg,CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp);
         } else
-            printf("\tadd\t%s, fp,#%d\n",register_name(creg),CODE_LVAR(l));
+	    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),
 		FUNC_LVAR(l),lvar_offset_label);
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-        printf("\tadd\t%s, $sp, #%d\n",
-		register_name(creg),CALLER_ARG(l-ARG_LVAR_OFFSET));
+	code_add(creg,CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp);
     } else { /* callee's arguments */
         printf("\tsub\t%s, fp, #%d+$L_%d\n",
 		register_name(creg),CALLEE_ARG(l),r1_offset_label);
@@ -1032,6 +1030,7 @@
 void
 gexpr_init(void)
 {
+    gvar_ref_list();
     while(reg_sp > 0) {
 	error(-1);
 	free_register(reg_stack[--reg_sp]);
@@ -1189,8 +1188,8 @@
 
 #define mask8(d,bit)   (d & (255 << bit))
 
-static void
-make_const(int c)
+static int
+make_const(int c,int *p1,int *p2,int *p3)
 {
     int sign,im,jm,km;
     int min_stage = 4;
@@ -1233,8 +1232,10 @@
             }
         }
     }
-    if (min_stage<=3) { emit(sign,im,jm,km); }
-    else { print "emit const c\n"; }
+    if (min_stage<=3) {
+	*p1 = im; *p2= jm; *p3 = km; 
+	return sign;
+    } else return 0;
 }
 
 static void 
@@ -1242,51 +1243,64 @@
 {
     char *crn = register_name(reg);
     char *rrn = register_name(r);
+    int s,p1,p2,p3;
     if (offset==0) {
         if(r!=reg)
             printf("\tmov %s,%s\n",crn,rrn);
-    } else if (offset > 0) {
-	if (offset>
-        printf("\tadd %s, %s, #%d\n",crn,rrn,offset);
+    if ((s=make_const(offset,&p1,&p2,&p3))) {
+	add = s>0?"add":"sub";
+	if (p1) printf("\t%s\t%s, %s, #%d\n",add,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,offset));
+	printf("\tadd\t%s, %s, %s\n",add,crn,crn,rrn);
     }
 }
 
 
 static void 
-code_ld(char *ld,int reg,int offset,int r)
+code_ld(char *ld,int reg,int offset,int r,char *cext)
 {
     char *crn = register_name(reg);
     char *rrn = register_name(r);
-    printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn);
+    if (-1024<offset&&offset<1024) {
+	printf("\t%s\t%s, [%s, #%d]%s\n",ld,crn,rrn,offset,cext);
+    } else {
+	code_add(reg,offset,r);
+	printf("\t%s\t%s, [%s, #0]%s\n",ldcrn,crn,cext);
+    }
 }
 
 static void 
-code_ldf(char *ld,char *crn,int offset,int r)
+code_ldf(char *ld,char *crn,int offset,int r,char *cext)
 {
     char *rrn = register_name(r);
-    printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn);
-}
-
-
-static char *cload(int sz,int sign) { 
-    if (sign) {
-        return sz==1?"lb":sz==SIZE_OF_SHORT?"lh":"lw"; 
+    char *orn;
+    int reg;
+    if (-1024<offset&&offset<1024) {
+	printf("\t%s\t%s, [%s, #%d]%s\n",ld,crn,rrn,offset,cext);
     } else {
-        return sz==1?"lbu":sz==SIZE_OF_SHORT?"lhu":"lw"; 
-    }
-}
-
-static char *cstore(int sz) { return sz==1?"sb":sz==SIZE_OF_SHORT?"sh":"sw"; }
-
-#define cext(sign,sz,reg)  /* do nothing */
-
+	orn = register_name(reg=get_register());
+	code_add(reg,offset,r);
+	printf("\t%s\t%s, [%s, #%d]%s\n",ld,crn,orn,offset,cext);
+	free_register(reg);
+    }
+}
+
+
+#define cload(sz,sign) \
+    (sz==1?"ldrb":sz==SIZE_OF_SHORT?(sign?"ldrsh":"ldrh"):"ldr")
+
+#define cstore(sz) (sz==1?"strb":sz==SIZE_OF_SHORT?"strh":"str")
+
+#define cext(sign,sz,reg)
 
 void
 code_label(int labelno)
 {
     clear_ptr_cache();
-    printf("$L_%d:\n",labelno);
+    printf(".L%d:\n",labelno);
 }
 
 void
@@ -1299,13 +1313,14 @@
 void
 code_rgvar(int e1,int reg) {
     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)),"");
 }
 
 void
 code_crgvar(int e1,int reg,int sign,int sz){
     use_int(reg);
-    code_ld(cload(sz,sign),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1)));
+    code_ld(cload(sz,sign),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1))
+	sz==1?"  @ zero_extendqisi2":"");
     cext(sign,sz,reg);
 }
 
@@ -1314,7 +1329,7 @@
 code_register(int e2,int reg) {
     use_int(reg);
     if (reg!=e2)
-	printf("\tmove %s,%s\n",register_name(reg),register_name(e2));
+	printf("\tmov %s,%s\n",register_name(reg),register_name(e2));
 }
 
 
@@ -1322,7 +1337,7 @@
 code_rlvar(int e2,int reg) {
     use_int(reg);
     lvar_intro(e2);
-    printf("\tlw %s,",register_name(reg));
+    printf("\tldr\t%s, ",register_name(reg));
     lvar(e2);
 }
 
@@ -1384,59 +1399,65 @@
 void
 code_label_value(int label,int reg) {
     use_int(reg);
-    printf("\tla %s,$L_%d\n",register_name(reg),label);
+    printf("\tldr %s,.L%d\n",register_name(reg),
+	make_const_ptr(label));
     return;
 }
 
 void
 code_const(int e2,int reg) {
-    char *crn;
+    char *crn,*add;
+    int p1,p2,p3;
     use_int(reg);
     crn = register_name(reg);
-    printf("\tli %s,%d\n",crn,e2);
+    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("\tsubu %s,$0,%s\n", register_name(creg), register_name(creg));
+    printf("\trsb\t%s, %s, #0\n", register_name(creg), register_name(creg));
 }
 
 
 void
 code_not(int creg) {
     use_int(creg);
-    printf("\tnor %s,%s,%s\n", 
+    printf("\tmvn\t%s, %s, %s\n", 
 	register_name(creg), register_name(creg),register_name(creg));
 }
 
 
 void
 code_lnot(int creg) {
-    int dreg = get_register();
     use_int(creg);
 
-    printf("\txori %s,%s,0x0\n", 
-        register_name(dreg),register_name(creg));
-    printf("\tsltu %s,%s,1\n", 
-        register_name(creg),register_name(dreg));
-    free_register(dreg);
+    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));
 }
 
 void
 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) {
     char *xrn,*drn;
+    int xreg;
     if (car(e2)==REGISTER) {
 	use_int(reg);
-	printf("\taddu %s,%s,%d\n", 
-		register_name(cadr(e2)),register_name(cadr(e2)), dir);
+	code_add(dir,cadr(e2));
 	if (cadr(reg)!=e2)
-	    printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2)));
+	    code_register(cadr(e2),reg);
 	return;
     } 
     g_expr(e2);
     if (!is_int_reg(creg)) error(-1);
-    xrn = register_name(creg);
+    xrn = register_name(xreg = creg);
     if (reg==USE_CREG) {
 	reg=get_register(); if (!reg) error(-1);
 	drn = register_name(reg);
@@ -1444,27 +1465,25 @@
     } else {
 	drn = register_name(reg);
     }
-    printf("\t%s %s,0(%s)\n",cload(sz,sign),drn,xrn);
-    if (use) cext(sign,sz,reg);
-    printf("\taddi %s,%s,%d\n",drn,drn,dir);
-    printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn);
+    code_ld(cload(sz,sign),reg,0,xreg,sz==1?"  @ zero_extendqisi2":"");
+    code_add(reg,dir,reg);
+    code_ldf(cstore(sz),reg,0,xreg,sz==SIZE_OF_SHORT?"  @ movhi":"");
 }
 
 
 void
 code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) {
     char *xrn,*crn,*nrn;
-    int nreg;
+    int nreg,xreg;
     if (car(e2)==REGISTER) {
 	use_int(reg);
-	printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2)));
-	printf("\taddu %s,%s,%d\n", 
-	    register_name(cadr(e2)),register_name(cadr(e2)),dir);
+	code_register(cadr(e2),reg);
+	code_add(dir,reg);
 	return;
     } 
     g_expr(e2);
     if (!is_int_reg(creg)) error(-1);
-    crn = register_name(creg);
+    crn = register_name(xreg=creg);
     nreg=get_register(); if (!nreg) error(-1);
     nrn = register_name(nreg);
     if (reg==USE_CREG) {
@@ -1474,10 +1493,10 @@
     } else {
 	xrn = register_name(reg);
     }
-    printf("\t%s %s,0(%s)\n",cload(sz,sign),xrn,crn);
-    if (use) cext(sign,sz,reg);
-    printf("\taddi %s,%s,%d\n",nrn,xrn,dir);
-    printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn);
+    code_ld(cload(sz,sign),reg,0,xreg,sz==1?"  @ zero_extendqisi2":"");
+    code_add(nreg,dir,reg);
+    code_ldf(cstore(sz),nreg,0,xreg,sz==SIZE_OF_SHORT?"  @ movhi":"");
+
     free_register(nreg);
 }
 
@@ -1497,7 +1516,7 @@
     /* save frame pointer */
 #if R1SAVE
     use_int(creg);
-    printf("\tlw %s,0($fp)\n",register_name(creg));
+    printf("\tldr\t%s,[fp, #0]\n",register_name(creg));
 #else
     use_int(creg);
     printf("\taddu %s,",register_name(creg));
@@ -1512,6 +1531,7 @@
     char *xrn;
     int e2,e3;
     if (rexpr_bool(e1, reg)) return;
+#if 0
     b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
     if (use) {
 	use_int(reg);
@@ -1524,6 +1544,12 @@
     } else {
 	fwddef(e2);
     }
+#else
+    b_expr(e1,1,0,1);  /* including > < ... */
+    use_int(reg);
+    printf("\tmovne\t%s, #0\n", register_name(reg));
+    printf("\tmoveq\t%s, #1\n", register_name(reg));
+#endif
 }
 
 char *
@@ -2384,9 +2410,6 @@
     printf("%d+$L_%d($sp)\n",FUNC_LVAR(0),lvar_offset_label);
 }
 
-//  MIPS $25 (=$jp) contains calling function address.
-//  It is used in cpload $25 to get global address table $gp.
-
 void
 code_jmp(char *s) {
     // jump to continuation means use all register variable
--- a/mc-code-mips.c	Sun Jul 11 13:31:52 2004 +0900
+++ b/mc-code-mips.c	Sun Jul 11 20:59:52 2004 +0900
@@ -1332,7 +1332,7 @@
 	use_int(reg);
 	printf("\taddu %s,%s,%d\n", 
 		register_name(cadr(e2)),register_name(cadr(e2)), dir);
-	if (cadr(reg)!=e2)
+	if (cadr(e2)!=reg)
 	    printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2)));
 	return;
     }