changeset 90:07e3113c3c13

*** empty log message ***
author kono
date Fri, 07 Mar 2003 03:09:02 +0900
parents 917947ffeb7c
children 9b1aeb62e0b9
files Changes mc-code-powerpc.c test/float.c
diffstat 3 files changed, 194 insertions(+), 172 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Thu Mar 06 23:47:42 2003 +0900
+++ b/Changes	Fri Mar 07 03:09:02 2003 +0900
@@ -2008,3 +2008,5 @@
 全部、stub にしておいて、.set で書き換えるという手もあるけど。
 
 (さすがに一日ではできないか...)
+
+なんか整数から浮動小数点への変換はじぶんでやらないとだめなのね。
--- a/mc-code-powerpc.c	Thu Mar 06 23:47:42 2003 +0900
+++ b/mc-code-powerpc.c	Fri Mar 07 03:09:02 2003 +0900
@@ -92,6 +92,7 @@
 void local_table(void);
 void text_mode(void);
 void data_mode(char *name);
+int    init_ptr_cache();
 
 char *register_name(int i,int byte);
 int register_var(int r);
@@ -264,6 +265,7 @@
     int i;
     for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;}
     free_all_register();
+    init_ptr_cache();
     reg_sp = 0;
     text_mode();
 }
@@ -329,6 +331,15 @@
 int ptr_cache=0;
 
 int
+init_ptr_cache()
+{
+    int i;
+    for(i=0;i<MAX_PTR_CACHE;i++) {
+	ptr_cache=glist3(0,ptr_cache,0);
+    }
+}
+
+int
 clear_ptr_cache()
 {
     int ptcptr=ptr_cache;
@@ -341,15 +352,6 @@
     }
 }
 
-int
-init_ptr_cache()
-{
-    int i;
-    for(i=0;i<MAX_PTR_CACHE;i++) {
-	ptr_cache=glist3(0,ptr_cache,0);
-    }
-}
-
 
 int
 get_ptr_cache(char *name)
@@ -407,25 +409,26 @@
 
 void
 code_lvar(int e2) {
-    printf("\tla %d(r1),%s\n",e2,register_name(creg));
+    printf("\tla %s,%d(r1),%s\n",register_name(creg),e2);
 }
 
 
 void
 code_register(int e2) {
-    printf("\tmr %s,%s\n",register_name(creg),register_name(e2));
+    if (creg!=e2)
+	printf("\tmr %s,%s\n",register_name(creg),register_name(e2));
 }
 
 
 void
 code_rlvar(int e2) {
-    printf("\tlwz %d(r1),%s\n",e2,register_name(creg));
+    printf("\tlwz %s,%d(r1),%s\n",register_name(creg),e2);
 }
 
 
 void
 code_crlvar(int e2) {
-    printf("\tlbz %d(r1),%s\n",e2,register_name(creg));
+    printf("\tlbz %s,%d(r1),%s\n",register_name(creg),e2);
     printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
 }
 
@@ -940,6 +943,7 @@
 	free_register(jmp);
     }
     regv[creg]=1;
+    clear_ptr_cache();
 }
 
 void
@@ -969,41 +973,65 @@
 void
 rindirect(int e1)   /* *(p +5 ) */
 {
-    char *op;
+    char *op,*crn;
     int e2,e3,byte;
     e3 = cadr(e2 = cadr(e1));
     g_expr(e2);
+    crn=register_name(creg);
     switch (car(e1)) {
     case FRINDIRECT: case DRINDIRECT:
-    printf("\t%s (%s)\n",fload(car(e1)==DRINDIRECT),register_name(creg));
-    break;
-    case CRINDIRECT: case RINDIRECT:
-    op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl");
-    printf("\t%s (%s),%s\n",op,register_name(creg),register_name(creg));
+	printf("\t%s %s,(%s)\n",fload(car(e1)==DRINDIRECT),
+	    register_name(freg),crn);
+	regv[creg]=0; regv[freg]=1;
+	break;
+    case CRINDIRECT: 
+	printf("\tlbz %s,(%s)\n",crn,crn);
+	printf("\textsb %s,%s\n",crn,crn);
+	break;
+    case RINDIRECT:
+	printf("\tlwz %s,(%s)\n",crn,crn);
+	break;
     }
 }
 
-
 void
 code_assign_gvar(int e2,int byte) {
-    if (byte) use_data_reg(creg,1);
-    printf("\t%s %s,%s\n",move(byte),register_name(creg,byte),(char *)caddr(e2));
+    int r;
+    char *crn,*rrn;
+    r = get_ptr_cache((char*)caddr(e2));
+    rrn=register_name(r);
+    crn=register_name(creg);
+    if (byte) {
+	printf("\tstb %s,(%s)\n",crn,rrn);
+    } else {
+	printf("\tstw %s,(%s)\n",crn,rrn);
+    }
 }
 
 void
 code_assign_lvar(int e2,int byte) {
-    if (byte) use_data_reg(creg,1);
-    printf("\t%s %s,%d(%%ebp)\n",move(byte),register_name(creg,byte),e2);
+    char *crn;
+    crn=register_name(creg);
+    if (byte) {
+	printf("\tstb %s,%d(r1)\n",crn,e2);
+    } else {
+	printf("\tstw %s,%d(r1)\n",crn,e2);
+    }
 }
 
 void
 code_assign_register(int e2,int byte) {
-    printf("\tmovl %s,%s\n",register_name(creg),register_name(e2,0));
+    printf("\tmr %s,%s\n",register_name(e2),register_name(creg));
 }
 
 void
 code_assign(int e2,int byte) {
-    printf("\t%s %s,(%s)\n",move(byte),register_name(creg,byte),register_name(e2,0));
+    char *drn=register_name(dreg);
+    if (byte) {
+	printf("\tstb %s,(%s)\n",crn,drn);
+    } else {
+	printf("\tstw %s,(%s)\n",crn,drn);
+    }
 }
 
 
@@ -1014,23 +1042,29 @@
     creg = reg = e2;
     tosop(op,xreg);
     creg = xreg;
-    printf("\tmovl %s,%s\n",register_name(reg,0),register_name(creg));
+    printf("\tmr %s,%s\n",register_name(creg),register_name(reg));
 }
 
 
 void
 code_assop(int op,int byte) {
-    char *xrn;
+    char *xrn,*crn,*drn;
     int xreg;
-    int edx = edx_setup();
+    int edx = get_register(); if(!edx) error(-1);
     xrn = register_name(xreg = emit_pop(0),0);       /* pop e3 value */
     regv[xreg]=regs[xreg]=1;
     printf("\tmovl %s,%s  # assop \n",register_name(creg),register_name(edx,0));
     regv[edx]=1;
     ld_indexx(byte,0,edx);
     tosop(op,xreg);
-    printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",register_name(creg,byte),register_name(edx,0));
-    edx_cleanup();
+    crn = register_name(creg);
+    drn = register_name(edx);
+    if (byte) {
+	printf("\tstb %s,(%s)\n",crn,drn);
+    } else {
+	printf("\tstw %s,(%s)\n",crn,drn);
+    }
+    free_register(edx);
     emit_pop_free(xreg);
 }
 
@@ -1044,116 +1078,72 @@
     switch(op) {
     case LSHIFT:
     case ULSHIFT:
-	shift("sall",oreg);
+	shift("slw",oreg);
 	return;
     case RSHIFT:
-	shift("sarl",oreg);
+	shift("srw",oreg);
 	return;
     case URSHIFT:
-	shift("shrl",oreg);
+	shift("sraw",oreg);
 	return;
     }
-    if(oreg==-1) {
-        printf("\tpopl %s\n",register_name(dreg,0));
-	oreg = dreg;
-	regv[dreg]=1;
-    }
-    regv[oreg]=1; regs[oreg]=1;
     orn = register_name(oreg,0);
     crn = register_name(creg);
     switch(op) {
     case ADD:
-	printf("\taddl %s,%s\n",orn,crn);
+	printf("\tadd %s,%s,%s\n",crn,orn,crn);
 	break;
     case SUB:
-	printf("\tsubl %s,%s\n",orn,crn);
+	printf("\tsub %s,%s,%s\n",crn,orn,crn);
 	break;
     case BAND: 
-	printf("\tandl %s,%s\n",orn,crn);
+	printf("\tand %s,%s,%s\n",crn,orn,crn);
 	break;
     case EOR: 
-	printf("\txorl %s,%s\n",orn,crn);
+	printf("\txor %s,%s,%s\n",crn,orn,crn);
 	break;
     case BOR:
-	printf("\torl %s,%s\n",orn,crn);
+	printf("\torl %s,%s,%s\n",crn,orn,crn);
 	break;
     case MUL:
     case UMUL:
-	printf("\t%s %s,%s\n","imull",orn,crn);
+	printf("\t%mullw %s,%s,%s\n",crn,orn,crn);
 	break;
     case DIV:
+	printf("\t%divw %s,%s,%s\n",crn,orn,crn);
+	break;
     case UDIV:
-	use_register(creg,REG_EAX,1);
-	edx_setup();
-	orn = register_name(oreg,0);
-	if (op==DIV)
-	    printf("\tcltd\n\tdivl %s\n",orn);
-	else 
-	    printf("\txor %%edx,%%edx\n\tidivl %s\n",orn);
-	edx_cleanup();
+	printf("\t%divwu %s,%s,%s\n",crn,orn,crn);
 	break;
     case MOD:
+	dx=get_register();
+	drn = register_name(drn);
+	printf("\t%divwu %s,%s,%s\n",drn,orn,crn);
+	printf("\t%mullw %s,%s,%s\n",drn,drn,crn);
+	printf("\t%subf %s,%s,%s\n",drn,drn,orn);
+	free_register(creg);
+	creg=dx;
+	break;
     case UMOD:
-	use_register(creg,REG_EAX,1);
-	edx_setup();
-	orn = register_name(oreg,0);
-	if (op==DIV)
-	    printf("\tcltd\n\tdivl %s\n",orn);
-	else 
-	    printf("\txor %%edx,%%edx\n\tidivl %s\n",orn);
-        dx = virtual(REG_EDX);	
-	if (dx!=creg) {
-	    rname[dx]=rname[creg];
-	    rname[creg]=REG_EDX;
-	}
-	edx_cleanup();
+	dx=get_register();
+	drn = register_name(drn);
+	printf("\t%divwu %s,%s,%s\n",drn,orn,crn);
+	printf("\t%mullw %s,%s,%s\n",drn,drn,crn);
+	printf("\t%subf %s,%s,%s\n",drn,drn,orn);
+	free_register(creg);
+	creg=dx;
 	break;
     }
-    if (oreg!=dreg&&oreg>=0)
-	free_register(oreg);
-}
-
-static int edx_stack=0;
-
-int
-edx_setup()
-{
-    int edx_save;
-    /* make real EDX register empty */
-    if (free_register_count()<1) {
-        for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++);
-	printf("\tpushl %s\n",register_name(edx_save,0));
-        edx_stack = list3(edx_save,edx_stack,0);
-    } else {
-        edx_save = get_register();
-        edx_stack = list3(edx_save,edx_stack,1);
-    }
-    regv[edx_save]=0;
-    use_register(edx_save,REG_EDX,0);
-    return edx_save;
+    if(oreg!=cre) free_register(oreg);
 }
 
 
 void
-edx_cleanup()
-{
-    if (caddr(edx_stack)==0) {
-	printf("\tpopl %s\n",register_name(car(edx_stack),0));
-    } else
-	free_register(car(edx_stack));
-    edx_stack = cadr(edx_stack);
-}
-
-void
 shift(char *op, int reg)
 {
-    if (reg>=0) {
-	use_register(reg,REG_ECX,1);
-    } else {
-	use_register(dreg,REG_ECX,0);
-	printf("\tpopl %%ecx\n");
-    }
-    printf("\t%s %%cl,%s\n",op,register_name(creg));
+    char *crn = register_name(creg));
+    char *rrn = register_name(reg));
+    printf("\t%s %s,%s,%s\n",op,crn,rrn,crn);
 }
 
 void
@@ -1161,11 +1151,13 @@
 {	
     char *op;
 
-    op = byte ? "movsbl" : "movl";
-    if (n) 
-	    printf("\t%s %d(%s),%s\n",op,n,register_name(xreg,0),register_name(creg,byte));
-    else
-	    printf("\t%s (%s),%s\n",op,register_name(xreg,0),register_name(creg,byte));
+    if (byte) {
+	printf("\tlbz %s,%d(%s),%s\n",register_name(creg),n,
+	    register_name(xreg));
+	printf("\textsb %s,%s\n",crn,crn);
+    } else 
+	printf("\tlwz %s,%d(%s),%s\n",register_name(creg),n,
+	    register_name(xreg));
 }
 
 void
@@ -1173,8 +1165,7 @@
 {
     /* used in dosiwtch() */
     if(chk) return;
-    use_register(creg,csreg,0);
-    printf("\tcmpl $%d,%s\n",e,register_name(creg));
+    printf("\tcmpw cr0,%s,%d\n",register_name(csreg),e);
 }
 
 void
@@ -1196,8 +1187,8 @@
 void
 rexpr(int e1, int l1, char *s)
 {       
-    g_expr(list3(SUB,cadr(e1),caddr(e1)));
-    printf("\tj%s\t_%d\n",s,l1);
+    g_expr(list3(CMP,cadr(e1),caddr(e1)));
+    printf("\tb%s cr0,_%d\n",s,l1);
 }
 
 
@@ -1205,7 +1196,7 @@
 jcond(int l, char cond)
 {       
     if (chk) return;
-    printf("\tj%s\t_%d\n",cond?"ne":"e",l);
+    printf("\tb%s cr0,_%d\n",cond?"ne":"eq",l);
 }
 
 void
@@ -1213,14 +1204,7 @@
 {       
     control=0;
     if (chk) return;
-    printf("\tjmp\t_%d\n",l);
-    /* align? */
-    /*
-      this is not allowed because of ? operator
-    regv[creg]=regv[dreg]=0; 
-    use_register(creg,REG_EAX,0);
-    use_register(dreg,REG_EBX,0);
-     */
+    printf("\tb\t_%d\n",l);
 }
 
 void
@@ -1321,7 +1305,7 @@
 
 void
 code_set_fixed_creg(int mode) {
-    use_register(creg,REG_EAX,mode);
+    creg=11;
 }
 
 void
@@ -1491,38 +1475,30 @@
 char *
 fstore(int d)
 {
-    return use?
-	(d?"fstl":"fsts"):
-	(d?"fstpl":"fstps")
-    ;
-}
-
-char *
-fstore_u(int d)
-{
-    return d?"fstpl":"fstps";
+    return (d?"stfd":"stfs");
 }
 
 char *
 fload(int d)
 {
-    return d?"fldl":"flds";
+    return d?"lfd":"lfs";
 }
 
-
 void code_dassign_gvar(int e2,int d)
 { 
-    printf("\t%s %s\n",fstore(d),(char *)caddr(e2)) ;
+    int r;
+    r = get_ptr_cache((char*)caddr(e1));
+    printf("\t%s %s,(%s)\n",fstore(d),register_name(freg),register_name(r));
 }
 
 void code_dassign_lvar(int e2,int d)
 { 
-    printf("\t%s %d(%%ebp)\n",fstore(d),e2);
+    printf("\t%s %s,%d(r1)\n",fstore(d),register_name(creg),e2);
 }
 
 void code_dassign(int e2,int d)
 { 
-    printf("\t%s (%s)\n",fstore(d),register_name(e2,0));
+    printf("\t%s %s,(%s)\n",fstore(d),register_name(creg),register_name(e2));
 }
 
 static double d0 = 1.0;
@@ -1545,6 +1521,9 @@
 { 
     int lb;
     double d = dcadr(e2);
+    int r;
+    char *rrn;
+    rrn = register_name((r=get_register()));
 
     if (d==0.0) {
 	printf("\tfldz\n"); return;
@@ -1561,58 +1540,90 @@
     } else {
 	text_mode();
     }
-    printf("\tfldl _%d\n",lb);
+    printf("\taddis %s,r31,ha16(_%d-%s)\n",rrn,lb,code_base);
+    printf("\tla %s,lo16(_%d-%s)(%s)\n",rrn,lb,code_base,rrn);
+    printf("\tlfd %s,%(s)\n",register_name(freg),rrn);
+    free_register(r);
 }
 
 void code_dneg()
 { 
-    printf("\tfchs\n");
+    char *frn = register_name(freg);
+    printf("\tfneg %s,%s\n",freg);
 }
 
 void code_d2i()
 { 
-    /* fuck you! */
-    printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2);
-    printf("\tfnstcw  (%%esp)\n");
-    printf("\tmovl    (%%esp), %s\n",register_name(creg));
-    printf("\tmovb    $12, 1(%%esp)\n");
-    printf("\tfldcw   (%%esp)\n");
-    printf("\tmovl    %s, (%%ebp)\n",register_name(creg));
-    printf("\tfistpl  %d(%%esp)\n",size_of_int);
-    printf("\tfldcw   (%%esp)\n");
-    printf("\tpopl    %s\n",register_name(creg));
-    printf("\tpopl    %s\n",register_name(creg));
+    char *frn = register_name(freg);
+    disp-=size_of_double;
+    printf("\tfctiwz  %s,%s\n",);
+    printf("\tstfd  %s,%d(r1)\n",disp);
+    printf("\tlwz  %s,%d(r1)\n",crn,disp+size_of_double-size_of_int);
+    fregs[freg]=0;
+    regs[creg]=1;
 }
 
 void code_i2d()
 { 
-    printf("\tpushl %s\n",register_name(creg));
-    printf("\tfildl (%%esp)\n");
-    printf("\tlea %d(%%esp),%%esp\n",size_of_int);
+    char *frn = register_name(freg);
+    char *crn = register_name(creg);
+    int  dreg = get_register();
+    char *drn = register_name(dreg);
+    disp-=size_of_double;
+
+    printf("\tlis %s,0x4330\n",drn);
+    printf("\txoris %s,%s,0x8000\n",crn,crn);
+    printf("\tstw %s,%d(r1)\n",crn,disp+size_of_int);
+    printf("\tstw %s,%d(r1)\n",drn,disp);
+    printf("\tlfd %s,%d(r1)\n",frn,disp);
+    free_register(dreg);
+    fregs[freg]=1;
+    regs[creg]=0;
 }
 
 void code_d2u()
 { 
-    /* fuck you! */
-    printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3);
-    printf("\tfnstcw  (%%esp)\n");
-    printf("\tmovl    (%%esp), %s\n",register_name(creg));
-    printf("\tmovb    $12, 1(%%esp)\n");
-    printf("\tfldcw   (%%esp)\n");
-    printf("\tmovl    %s, (%%ebp)\n",register_name(creg));
-    printf("\tfistpll %d(%%esp)\n",size_of_int);
-    printf("\tfldcw   (%%esp)\n");
-    printf("\tmovl    %d(%%esp),%s\n",size_of_int,register_name(creg));
-    printf("\tlea %d(%%esp),%%esp\n",size_of_int*3);
+        bl _u2w
+        addis r9,r31,ha16(_d-L1$pb)
+        la r9,lo16(_d-L1$pb)(r9)
+        lfd f13,0(r9)
+        addis r11,r31,ha16(LC1-L1$pb)
+        lfd f0,lo16(LC1-L1$pb)(r11)
+        fcmpu cr0,f13,f0
+        cror 2,1,2
+        beq- cr0,L2
+        fctiwz f0,f13
+        stfd f0,72(r1)
+        lwz r0,76(r1)
+        b L3
+L2:
+        lfd f0,0(r9)
+        addis r9,r31,ha16(LC1-L1$pb)
+        lfd f13,lo16(LC1-L1$pb)(r9)
+        fsub f0,f0,f13
+        fctiwz f0,f0
+        stfd f0,80(r1)
+        lwz r0,84(r1)
+        xoris r0,r0,0x8000
+L3:
+        stw r0,0(r29)
+
+    code_d2i();
 }
 
 void code_u2d()
 { 
-    printf("\tpushl  %s\n",register_name(creg));
-    printf("\tpushl  %s\n",register_name(creg));
-    printf("\tmovl   $0, %d(%%esp)\n",size_of_int);
-    printf("\tfildll (%%esp)\n");
-    printf("\tlea %d(%%esp),%%esp\n",size_of_int*2);
+    code_i2d();
+    lwz r0,0(r29)
+        stw r0,68(r1)
+        lis r0,0x4330
+        stw r0,64(r1)
+        lfd f13,64(r1)
+        addis r9,r31,ha16(LC0-L1$pb)
+        lfd f0,lo16(LC0-L1$pb)(r9)
+        fsub f13,f13,f0
+        addis r9,r31,ha16(_d1-L1$pb)
+        stfd f13,lo16(_d1-L1$pb)(r9)
 }
 
 void code_drgvar(int e2,int d)
--- a/test/float.c	Thu Mar 06 23:47:42 2003 +0900
+++ b/test/float.c	Fri Mar 07 03:09:02 2003 +0900
@@ -13,6 +13,15 @@
 double d1 = 0.3;
 double d2 = -0.2;
 
+unsigned u;
+
+int
+u2w() {
+   d1=u;
+   u2w();
+   u=d;
+}
+
 int
 main(int ac,char *av[]) {
    double g;