]> Cypherpunks repositories - gostls13.git/commitdiff
changed 5c 64 bit word ordering to little endian so it matches
authorKai Backman <kaib@golang.org>
Mon, 12 Oct 2009 20:35:28 +0000 (13:35 -0700)
committerKai Backman <kaib@golang.org>
Mon, 12 Oct 2009 20:35:28 +0000 (13:35 -0700)
5g. fixes to 64 bit code gen. added (finally) function to do
shifts properly.

go/test: passes 83% (287/342)

R=rsc
APPROVED=rsc
DELTA=156  (50 added, 53 deleted, 53 changed)
OCL=35589
CL=35616

src/cmd/5c/cgen.c
src/cmd/5c/gc.h
src/cmd/5c/swt.c
src/cmd/5g/cgen64.c
src/cmd/5g/gg.h
src/cmd/5g/gsubr.c
src/pkg/runtime/arm/vlrt.c
test/arm-pass.txt

index bbad8a17919d5aa0bf6239e2cb7ae5aa905d2d3d..9e74f515b040e9dc9617d3ea257103aa6e9a0471 100644 (file)
@@ -916,12 +916,12 @@ sugen(Node *n, Node *nn, int32 w)
                        reglcgen(&nod1, nn, Z);
                        nn->type = t;
 
-                       if(1 || align(0, types[TCHAR], Aarg1))  /* isbigendian */
+                       if(isbigendian)
                                gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
                        else
                                gopcode(OAS, nod32const(n->vconst), Z, &nod1);
                        nod1.xoffset += SZ_LONG;
-                       if(1 || align(0, types[TCHAR], Aarg1))  /* isbigendian */
+                       if(isbigendian)
                                gopcode(OAS, nod32const(n->vconst), Z, &nod1);
                        else
                                gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
index 9aa7681b2e974aacd064b43df7f70ea77762c042..9e9d1bd7d5a25597bdca16edb91c42ddf415dc44 100644 (file)
@@ -175,6 +175,7 @@ EXTERN      int32   continpc;
 EXTERN int32   curarg;
 EXTERN int32   cursafe;
 EXTERN Prog*   firstp;
+EXTERN int32   isbigendian;
 EXTERN Prog*   lastp;
 EXTERN int32   maxargsafe;
 EXTERN int     mnstring;
index 5f50e483c547fbab9552a77255c7241cd2c3d2a4..4c2a81cbfff778c888d2f9ec1eb62ddea1efd8f6 100644 (file)
@@ -311,13 +311,13 @@ gextern(Sym *s, Node *a, int32 o, int32 w)
 {
 
        if(a->op == OCONST && typev[a->type->etype]) {
-               if(1 || align(0, types[TCHAR], Aarg1))  /* isbigendian */
+               if(isbigendian)
                        gpseudo(ADATA, s, nod32const(a->vconst>>32));
                else
                        gpseudo(ADATA, s, nod32const(a->vconst));
                p->from.offset += o;
                p->reg = 4;
-               if(1 || align(0, types[TCHAR], Aarg1))  /* isbigendian */
+               if(isbigendian)
                        gpseudo(ADATA, s, nod32const(a->vconst));
                else
                        gpseudo(ADATA, s, nod32const(a->vconst>>32));
index 8e768198db51b13886f73dfd2f3fac72eb6d0fe0..a732991db40cea81f9b229e46bbcb31285fa3af8 100644 (file)
@@ -49,7 +49,8 @@ cgen64(Node *n, Node *res)
 
                gmove(ncon(0), &t1);
 
-               gins(ASUB, &t1, &al);
+               p1 = gins(ASUB, &t1, &al);
+               p1->scond |= C_SBIT;
                gins(ASBC, &t1, &ah);
 
                gins(AMOVW, &al, &lo2);
@@ -104,6 +105,7 @@ cgen64(Node *n, Node *res)
 
        regalloc(&al, lo1.type, N);
        regalloc(&ah, hi1.type, N);
+
        // Do op.  Leave result in ah:al.
        switch(n->op) {
        default:
@@ -117,7 +119,8 @@ cgen64(Node *n, Node *res)
                gins(AMOVW, &lo1, &al);
                gins(AMOVW, &hi2, &bh);
                gins(AMOVW, &lo2, &bl);
-               gins(AADD, &bl, &al);
+               p1 = gins(AADD, &bl, &al);
+               p1->scond |= C_SBIT;
                gins(AADC, &bh, &ah);
                regfree(&bl);
                regfree(&bh);
@@ -131,7 +134,8 @@ cgen64(Node *n, Node *res)
                gins(AMOVW, &hi1, &ah);
                gins(AMOVW, &lo2, &bl);
                gins(AMOVW, &hi2, &bh);
-               gins(ASUB, &bl, &al);
+               p1 = gins(ASUB, &bl, &al);
+               p1->scond |= C_SBIT;
                gins(ASBC, &bh, &ah);
                regfree(&bl);
                regfree(&bh);
@@ -139,10 +143,10 @@ cgen64(Node *n, Node *res)
 
        case OMUL:
                // TODO(kaib): this can be done with 4 regs and does not need 6
-               regalloc(&bh, types[TPTR32], N);
                regalloc(&bl, types[TPTR32], N);
-               regalloc(&ch, types[TPTR32], N);
+               regalloc(&bh, types[TPTR32], N);
                regalloc(&cl, types[TPTR32], N);
+               regalloc(&ch, types[TPTR32], N);
 
                // load args into bh:bl and bh:bl.
                gins(AMOVW, &hi1, &bh);
@@ -156,27 +160,27 @@ cgen64(Node *n, Node *res)
                p1->from.reg = bl.val.u.reg;
                p1->reg = cl.val.u.reg;
                p1->to.type = D_REGREG;
-               p1->to.reg = al.val.u.reg;
-               p1->to.offset = ah.val.u.reg;
+               p1->to.reg = ah.val.u.reg;
+               p1->to.offset = al.val.u.reg;
 //print("%P\n", p1);
 
                // bl * ch
-               p1 = gins(AMULALU, N, N);
+               p1 = gins(AMULA, N, N);
                p1->from.type = D_REG;
-               p1->from.reg = ah.val.u.reg;
-               p1->reg = bl.val.u.reg;
+               p1->from.reg = bl.val.u.reg;
+               p1->reg = ch.val.u.reg;
                p1->to.type = D_REGREG;
-               p1->to.reg = ch.val.u.reg;
+               p1->to.reg = ah.val.u.reg;
                p1->to.offset = ah.val.u.reg;
 //print("%P\n", p1);
 
                // bh * cl
-               p1 = gins(AMULALU, N, N);
+               p1 = gins(AMULA, N, N);
                p1->from.type = D_REG;
-               p1->from.reg = ah.val.u.reg;
-               p1->reg = bh.val.u.reg;
+               p1->from.reg = bh.val.u.reg;
+               p1->reg = cl.val.u.reg;
                p1->to.type = D_REGREG;
-               p1->to.reg = cl.val.u.reg;
+               p1->to.reg = ah.val.u.reg;
                p1->to.offset = ah.val.u.reg;
 //print("%P\n", p1);
 
@@ -188,8 +192,8 @@ cgen64(Node *n, Node *res)
                break;
 
        case OLSH:
-               regalloc(&bh, hi1.type, N);
                regalloc(&bl, lo1.type, N);
+               regalloc(&bh, hi1.type, N);
                gins(AMOVW, &hi1, &bh);
                gins(AMOVW, &lo1, &bl);
 
@@ -205,32 +209,21 @@ cgen64(Node *n, Node *res)
                        if(v >= 32) {
                                gins(AEOR, &al, &al);
                                //      MOVW    bl<<(v-32), ah
-                               p1 = gins(AMOVW, &bl, &ah);
-                               p1->from.type = D_SHIFT;
-                               p1->from.offset = SHIFT_LL | (v-32)<<7 | bl.val.u.reg;
-                               p1->from.reg = NREG;
+                               gshift(AMOVW, &bl, SHIFT_LL, v-32, &ah);
                                goto olsh_break;
                        }
 
                        // general literal left shift
 
                        //      MOVW    bl<<v, al
-                       p1 = gins(AMOVW, &bl, &al);
-                       p1->from.type = D_SHIFT;
-                       p1->from.offset = SHIFT_LL | v<<7 | bl.val.u.reg;
-                       p1->from.reg = NREG;
+                       gshift(AMOVW, &bl, SHIFT_LL, v, &al);
 
                        //      MOVW    bh<<v, ah
-                       p1 = gins(AMOVW, &bh, &ah);
-                       p1->from.type = D_SHIFT;
-                       p1->from.offset = SHIFT_LL | v<<7 | bh.val.u.reg;
-                       p1->from.reg = NREG;
+                       gshift(AMOVW, &bh, SHIFT_LL, v, &ah);
 
                        //      OR              bl>>(32-v), ah
-                       p1 = gins(AORR, &bl, &ah);
-                       p1->from.type = D_SHIFT;
-                       p1->from.offset = SHIFT_LR | (32-v)<<7 | bl.val.u.reg;
-                       p1->from.reg = NREG;
+                       gshift(AORR, &bl, SHIFT_LR, 32-v, &ah);
+
                        goto olsh_break;
                }
 
@@ -244,25 +237,19 @@ cgen64(Node *n, Node *res)
                gcmp(ACMP, &s, &creg);
 
                //      MOVW.LT         bl<<s, al
-               p1 = gins(AMOVW, N, &al);
-               p1->from.type = D_SHIFT;
-               p1->from.offset = SHIFT_LL | s.val.u.reg << 8 | 1<<4 | bl.val.u.reg;
+               p1 = gregshift(AMOVW, &bl, SHIFT_LL, &s, &al);
                p1->scond = C_SCOND_LT;
 
-               //      MOVW.LT         bh<<s, al
-               p1 = gins(AMOVW, N, &al);
-               p1->from.type = D_SHIFT;
-               p1->from.offset = SHIFT_LL | s.val.u.reg << 8 | 1<<4 | bh.val.u.reg;
+               //      MOVW.LT         bh<<s, ah
+               p1 = gregshift(AMOVW, &bh, SHIFT_LL, &s, &ah);
                p1->scond = C_SCOND_LT;
 
                //      SUB.LT          creg, s
                p1 = gins(ASUB, &creg, &s);
                p1->scond = C_SCOND_LT;
 
-               //      OR.LT           bl>>(32-s), ah
-               p1 = gins(AMOVW, N, &ah);
-               p1->from.type = D_SHIFT;
-               p1->from.offset = SHIFT_LR | t1.val.u.reg<<8| 1<<4 | bl.val.u.reg;
+               //      OR.LT           bl>>creg, ah
+               p1 = gregshift(AORR, &bl, SHIFT_LR, &creg, &ah);
                p1->scond = C_SCOND_LT;
 
                //      BLT     end
@@ -278,19 +265,15 @@ cgen64(Node *n, Node *res)
                p1->scond = C_SCOND_LT;
 
                //      MOVW.LT         creg>>1, creg
-               p1 = gins(AMOVW, N, &creg);
-               p1->from.type = D_SHIFT;
-               p1->from.offset = SHIFT_LR | 1<<7 | creg.val.u.reg;
+               p1 = gshift(AMOVW, &creg, SHIFT_LR, 1, &creg);
                p1->scond = C_SCOND_LT;
 
                //      SUB.LT          creg, s
                p1 = gins(ASUB, &s, &creg);
                p1->scond = C_SCOND_LT;
 
-               //      MOVW    bl<<(s-32), ah
-               p1 = gins(AMOVW, N, &ah);
-               p1->from.type = D_SHIFT;
-               p1->from.offset = SHIFT_LL | s.val.u.reg<<8 | 1<<4 | bl.val.u.reg;
+               //      MOVW    bl<<s, ah
+               p1 = gregshift(AMOVW, &bl, SHIFT_LL, &s, &ah);
                p1->scond = C_SCOND_LT;
 
                p3 = gbranch(ABLT, T);
@@ -310,8 +293,8 @@ olsh_break:
 
 
        case ORSH:
-               regalloc(&bh, hi1.type, N);
                regalloc(&bl, lo1.type, N);
+               regalloc(&bh, hi1.type, N);
                gins(AMOVW, &hi1, &bh);
                gins(AMOVW, &lo1, &bl);
 
@@ -320,14 +303,10 @@ olsh_break:
                        if(v >= 64) {
                                if(bh.type->etype == TINT32) {
                                        //      MOVW    bh->31, al
-                                       p1 = gins(AMOVW, N, &al);
-                                       p1->from.type = D_SHIFT;
-                                       p1->from.offset = SHIFT_AR | 31 << 7 | bh.val.u.reg;
+                                       gshift(AMOVW, &bh, SHIFT_AR, 31, &al);
 
                                        //      MOVW    bh->31, ah
-                                       p1 = gins(AMOVW, N, &ah);
-                                       p1->from.type = D_SHIFT;
-                                       p1->from.offset = SHIFT_AR | 31 << 7 | bh.val.u.reg;
+                                       gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
                                } else {
                                        gins(AEOR, &al, &al);
                                        gins(AEOR, &ah, &ah);
@@ -337,19 +316,13 @@ olsh_break:
                        if(v >= 32) {
                                if(bh.type->etype == TINT32) {
                                        //      MOVW    bh->(v-32), al
-                                       p1 = gins(AMOVW, N, &al);
-                                       p1->from.type = D_SHIFT;
-                                       p1->from.offset = SHIFT_AR | (v-32)<<7 | bh.val.u.reg;
+                                       gshift(AMOVW, &bh, SHIFT_AR, v-32, &al);
 
                                        //      MOVW    bh->31, ah
-                                       p1 = gins(AMOVW, N, &ah);
-                                       p1->from.type = D_SHIFT;
-                                       p1->from.offset = SHIFT_AR | 31<<7 | bh.val.u.reg;
+                                       gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
                                } else {
                                        //      MOVW    bh>>(v-32), al
-                                       p1 = gins(AMOVW, N, &al);
-                                       p1->from.type = D_SHIFT;
-                                       p1->from.offset = SHIFT_LR | (v-32)<<7 | bh.val.u.reg;
+                                       gshift(AMOVW, &bh, SHIFT_LR, v-32, &al);
                                        gins(AEOR, &ah, &ah);
                                }
                                goto orsh_break;
@@ -358,26 +331,17 @@ olsh_break:
                        // general literal right shift
 
                        //      MOVW    bl>>v, al
-                       p1 = gins(AMOVW, N, &al);
-                       p1->from.type = D_SHIFT;
-                       p1->from.offset = SHIFT_LR | v<<7 | bl.val.u.reg;
+                       gshift(AMOVW, &bl, SHIFT_LR, v, &al);
 
-                       //      OR              bh<<(32-v), al, al
-                       p1 = gins(AORR, N, &al);
-                       p1->from.type = D_SHIFT;
-                       p1->from.offset = SHIFT_LL | (32-v)<<7 | bh.val.u.reg;
-                       p1->reg = al.val.u.reg;
+                       //      OR              bh<<(32-v), al
+                       gshift(AORR, &bh, SHIFT_LL, 32-v, &al);
 
                        if(bh.type->etype == TINT32) {
                                //      MOVW    bh->v, ah
-                               p1 = gins(AMOVW, N, &ah);
-                               p1->from.type = D_SHIFT;
-                               p1->from.offset = SHIFT_AR | v<<7 | bh.val.u.reg;
+                               gshift(AMOVW, &bh, SHIFT_AR, v, &ah);
                        } else {
                                //      MOVW    bh>>v, ah
-                               p1 = gins(AMOVW, N, &ah);
-                               p1->from.type = D_SHIFT;
-                               p1->from.offset = SHIFT_LR | v<<7 | bh.val.u.reg;
+                               gshift(AMOVW, &bh, SHIFT_LR, v, &ah);
                        }
                        goto orsh_break;
                }
index c681b59dd1c1d766d64bbb534e72b792533f81db..867c34139ccfa07e38f55ec66a9aa4b5b565a944 100644 (file)
@@ -97,6 +97,8 @@ Prog* gins(int, Node*, Node*);
 int    samaddr(Node*, Node*);
 void   raddr(Node *n, Prog *p);
 Prog*  gcmp(int, Node*, Node*);
+Prog*  gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs);
+Prog * gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs);
 void   naddr(Node*, Addr*);
 void   cgen_aret(Node*, Node*);
 
index df175349fe7b987e12f979703cade9a8f3f42e39..e9131b43683dc07d9cc9c316a6699becf35c38b9 100644 (file)
@@ -964,6 +964,34 @@ gcmp(int as, Node *lhs, Node *rhs)
        return p;
 }
 
+/* generate a constant shift
+*/
+Prog*
+gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs)
+{
+       Prog *p;
+
+       if (sval < 0 || sval > 31)
+               fatal("bad shift value: %d", sval);
+
+       p = gins(as, N, rhs);
+       p->from.type = D_SHIFT;
+       p->from.offset = stype | sval<<7 | lhs->val.u.reg;
+       return p;
+}
+
+/* generate a register shift
+*/
+Prog *
+gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
+{
+       Prog *p;
+       p = gins(as, N, rhs);
+       p->from.type = D_SHIFT;
+       p->from.offset = stype | reg->val.u.reg << 8 | 1<<4 | lhs->val.u.reg;
+       return p;
+}
+
 
 /*
  * generate code to compute n;
index a012b3e14efa9e05eee4c99a0fd4f5f6cf25da45..276a91f2041c35825bf4c31b4b4a5f58198cd45b 100755 (executable)
@@ -34,19 +34,19 @@ typedef signed char     schar;
 typedef struct  Vlong   Vlong;
 struct  Vlong
 {
-        union
-        {
-                struct
-                {
-                        ulong   hi;
-                        ulong   lo;
-                };
-                struct
-                {
-                        ushort  hims;
-                        ushort  hils;
-                        ushort  loms;
-                        ushort  lols;
+       union
+       {
+               struct
+               {
+                       ulong   lo;
+                       ulong   hi;
+               };
+               struct
+               {
+                       ushort lols;
+                       ushort loms;
+                       ushort hils;
+                       ushort hims;
                 };
         };
 };
index d16071006d69aef266a574e13acb258abef79e9b..15c7be6e41ee1cbd866639da83c44395c9f79b19 100644 (file)
@@ -243,6 +243,7 @@ interface/returntype.go
 interface/struct.go
 iota.go
 ken/complit.go
+ken/divmod.go
 ken/embed.go
 ken/for.go
 ken/interbasic.go
@@ -262,6 +263,7 @@ ken/simpfun.go
 ken/simpprint.go
 ken/simpswitch.go
 ken/simpvar.go
+ken/string.go
 ken/strvar.go
 method.go
 method1.go