]> Cypherpunks repositories - gostls13.git/commitdiff
64bit literal RSH
authorKai Backman <kaib@golang.org>
Mon, 24 Aug 2009 20:57:04 +0000 (13:57 -0700)
committerKai Backman <kaib@golang.org>
Mon, 24 Aug 2009 20:57:04 +0000 (13:57 -0700)
R=rsc
APPROVED=rsc
DELTA=85  (35 added, 0 deleted, 50 changed)
OCL=33761
CL=33767

src/cmd/5g/cgen64.c
src/cmd/5g/gsubr.c
src/cmd/5l/5.out.h

index 9499742d373248daeb6ae10d38256beb47d71942..9c42a4958b79c0dc7493210e2d232c3d38ad26fe 100644 (file)
@@ -17,7 +17,7 @@ cgen64(Node *n, Node *res)
        Node al, ah, bl, bh, cl, ch; //, s1, s2;
        Prog *p1;
  //, *p2;
-//     uint64 v;
+       uint64 v;
 //     uint32 lv, hv;
 
        if(res->op != OINDREG && res->op != ONAME) {
@@ -191,54 +191,83 @@ cgen64(Node *n, Node *res)
 //             regfree(&s2);
 //             break;
 
-//     case ORSH:
-//             if(r->op == OLITERAL) {
-//                     fatal("cgen64 ORSH, OLITERAL not implemented");
-//                     v = mpgetfix(r->val.u.xval);
-//                     if(v >= 64) {
-//                             if(is64(r->type))
-//                                     splitclean();
-//                             splitclean();
-//                             split64(res, &lo2, &hi2);
-//                             if(hi1.type->etype == TINT32) {
-//                                     gmove(&hi1, &lo2);
-//                                     gins(ASARL, ncon(31), &lo2);
-//                                     gmove(&hi1, &hi2);
-//                                     gins(ASARL, ncon(31), &hi2);
-//                             } else {
-//                                     gins(AMOVL, ncon(0), &lo2);
-//                                     gins(AMOVL, ncon(0), &hi2);
-//                             }
-//                             splitclean();
-//                             goto out;
-//                     }
-//                     if(v >= 32) {
-//                             if(is64(r->type))
-//                                     splitclean();
-//                             split64(res, &lo2, &hi2);
-//                             gmove(&hi1, &lo2);
-//                             if(v > 32)
-//                                     gins(optoas(ORSH, hi1.type), ncon(v-32), &lo2);
-//                             if(hi1.type->etype == TINT32) {
-//                                     gmove(&hi1, &hi2);
-//                                     gins(ASARL, ncon(31), &hi2);
-//                             } else
-//                                     gins(AMOVL, ncon(0), &hi2);
-//                             splitclean();
-//                             splitclean();
-//                             goto out;
-//                     }
-
-//                     // general shift
-//                     gins(AMOVL, &lo1, &ax);
-//                     gins(AMOVL, &hi1, &dx);
-//                     p1 = gins(ASHRL, ncon(v), &ax);
-//                     p1->from.index = D_DX;  // double-width shift
-//                     p1->from.scale = 0;
-//                     gins(optoas(ORSH, hi1.type), ncon(v), &dx);
-//                     break;
-//             }
-//             fatal("cgen64 ORSH, !OLITERAL not implemented");
+       case ORSH:
+               if(r->op == OLITERAL) {
+                       v = mpgetfix(r->val.u.xval);
+                       if(v >= 64) {
+                               if(hi1.type->etype == TINT32) {
+                                       //      MOVW    hi1->31, al
+                                       p1 = gins(AMOVW, &hi1, &al);
+                                       p1->from.type = D_SHIFT;
+                                       p1->from.offset = SHIFT_AR | 31 << 7 | hi1.val.u.reg;
+                                       p1->from.reg = NREG;
+
+                                       //      MOVW    hi1->31, ah
+                                       p1 = gins(AMOVW, &hi1, &ah);
+                                       p1->from.type = D_SHIFT;
+                                       p1->from.offset = SHIFT_AR | 31 << 7 | hi1.val.u.reg;
+                                       p1->from.reg = NREG;
+                               } else {
+                                       gins(AEOR, &al, &al);
+                                       gins(AEOR, &ah, &ah);
+                               }
+                               break;
+                       }
+                       if(v >= 32) {
+                               if(hi1.type->etype == TINT32) {
+                                       //      MOVW    hi1->(v-32), al
+                                       p1 = gins(AMOVW, &hi1, &al);
+                                       p1->from.type = D_SHIFT;
+                                       p1->from.offset = SHIFT_AR | (v-32)<<7 | hi1.val.u.reg;
+                                       p1->from.reg = NREG;
+
+                                       //      MOVW    hi1->31, ah
+                                       p1 = gins(AMOVW, &hi1, &ah);
+                                       p1->from.type = D_SHIFT;
+                                       p1->from.offset = SHIFT_AR | 31<<7 | hi1.val.u.reg;
+                                       p1->from.reg = NREG;
+                               } else {
+                                       //      MOVW    hi1>>(v-32), al
+                                       p1 = gins(AMOVW, &hi1, &al);
+                                       p1->from.type = D_SHIFT;
+                                       p1->from.offset = SHIFT_LR | (v-32)<<7 | hi1.val.u.reg;
+                                       p1->from.reg = NREG;
+                                       gins(AEOR, &ah, &ah);
+                               }
+                               break;
+                       }
+
+                       // general shift
+
+                       //      MOVW    lo1>>v, al
+                       p1 = gins(AMOVW, &lo1, &al);
+                       p1->from.type = D_SHIFT;
+                       p1->from.offset = SHIFT_LR | v<<7 | lo1.val.u.reg;
+                       p1->from.reg = NREG;
+
+                       //      OR              hi1<<(32-v), al, al
+                       p1 = gins(AORR, &hi1, &al);
+                       p1->from.type = D_SHIFT;
+                       p1->from.offset = SHIFT_LL | (32-v)<<7 | hi1.val.u.reg;
+                       p1->from.reg = NREG;
+                       p1->reg = al.val.u.reg;
+
+                       if(hi1.type->etype == TINT32) {
+                               //      MOVW    hi1->v, ah
+                               p1 = gins(AMOVW, &hi1, &ah);
+                               p1->from.type = D_SHIFT;
+                               p1->from.offset = SHIFT_AR | v<<7 | hi1.val.u.reg;
+                               p1->from.reg = NREG;
+                       } else {
+                               //      MOVW    hi1>>v, ah
+                               p1 = gins(AMOVW, &hi1, &ah);
+                               p1->from.type = D_SHIFT;
+                               p1->from.offset = SHIFT_LR | v<<7 | hi1.val.u.reg;
+                               p1->from.reg = NREG;
+                       }
+                       break;
+               }
+               fatal("cgen64 ORSH, !OLITERAL not implemented");
 
 //             // load value into DX:AX.
 //             gins(AMOVL, &lo1, &ax);
index 49997640d0f3b5769ef33149471af50d23b94c81..cfd21fcc9d6aa638c0f8106ea643d5cd8bda3914 100644 (file)
@@ -811,7 +811,7 @@ rdst:
 
 hard:
        // requires register intermediate
-       regalloc(&r1, cvt, T);
+       regalloc(&r1, cvt, N);
        gmove(f, &r1);
        gmove(&r1, t);
        regfree(&r1);
index 29dd4d367965c03ff2107a683536dc84107b3571..39018030029b7a07217f915d3a55f57b60b4d2d7 100644 (file)
@@ -203,6 +203,12 @@ enum       as
 #define C_SCOND_NONE   14
 #define C_SCOND_NV     15
 
+/* D_SHIFT type */
+#define SHIFT_LL               0<<5
+#define SHIFT_LR               1<<5
+#define SHIFT_AR               2<<5
+#define SHIFT_RR               3<<5
+
 /* type/name */
 #define        D_GOK   0
 #define        D_NONE  1