]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.power64] liblink: power64 fixes and ports of changes
authorAustin Clements <austin@google.com>
Mon, 27 Oct 2014 19:25:40 +0000 (15:25 -0400)
committerAustin Clements <austin@google.com>
Mon, 27 Oct 2014 19:25:40 +0000 (15:25 -0400)
Ports of platform-specific changes that happened on default
after dev.power64 forked (fixes for c2go, wrapper math fixes,
moved stackguard field, stackguard1 support, precise stacks).
Bug fixes (missing AMOVW in instruction table, correct
unsigned 32-bit remainder).

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/164920044

src/liblink/asm9.c
src/liblink/obj9.c

index 47d515e0544bf15f4e22ca375be637dfc2eca75c..c5a78e53ca99e64f9ddf89f28be97228877c55a7 100644 (file)
@@ -232,6 +232,7 @@ static Optab        optab[] = {
        { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_LAUTO,        35, 8, REGSP },
        { AMOVB,        C_REG,  C_NONE, C_NONE,         C_LAUTO,        35, 8, REGSP },
        { AMOVD,        C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
        { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
        { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
        { AMOVB,        C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
@@ -349,8 +350,12 @@ static Optab       optab[] = {
 
        { AREM,         C_REG,  C_NONE, C_NONE,         C_REG,          50, 12, 0 },
        { AREM,         C_REG,  C_REG, C_NONE,  C_REG,          50, 12, 0 },
+       { AREMU,                C_REG,  C_NONE, C_NONE,         C_REG,          50, 16, 0 },
+       { AREMU,                C_REG,  C_REG, C_NONE,  C_REG,          50, 16, 0 },
        { AREMD,                C_REG,  C_NONE, C_NONE,         C_REG,          51, 12, 0 },
        { AREMD,                C_REG,  C_REG, C_NONE,  C_REG,          51, 12, 0 },
+       { AREMDU,               C_REG,  C_NONE, C_NONE,         C_REG,          51, 12, 0 },
+       { AREMDU,               C_REG,  C_REG, C_NONE,  C_REG,          51, 12, 0 },
 
        { AMTFSB0,      C_SCON, C_NONE, C_NONE,         C_NONE,         52, 4, 0 },
        { AMOVFL, C_FPSCR, C_NONE, C_NONE,      C_FREG,         53, 4, 0 },
@@ -433,12 +438,11 @@ static Optab      optab[] = {
        { AUSEFIELD,    C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0 },
        { APCDATA,      C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0 },
        { AFUNCDATA,    C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0 },
+       { ANOP,         C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0 },
 
        { ADUFFZERO,    C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0 },  // same as ABR/ABL
        { ADUFFCOPY,    C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0 },  // same as ABR/ABL
 
-       { ANOP,         C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0 },
-
        { AXXX,         C_NONE, C_NONE, C_NONE,         C_NONE,          0, 4, 0 },
 };
 
@@ -472,7 +476,7 @@ static struct
        Optab*  stop;
 } oprange[ALAST];
 
-static char    xcmp[C_NCLASS][C_NCLASS];
+static uchar   xcmp[C_NCLASS][C_NCLASS];
 
 
 void
@@ -747,7 +751,7 @@ static Optab*
 oplook(Link *ctxt, Prog *p)
 {
        int a1, a2, a3, a4, r;
-       char *c1, *c3, *c4;
+       uchar *c1, *c3, *c4;
        Optab *o, *e;
 
        a1 = p->optab;
@@ -931,6 +935,8 @@ buildop(Link *ctxt)
                        oprange[AREMCC] = oprange[r];
                        oprange[AREMV] = oprange[r];
                        oprange[AREMVCC] = oprange[r];
+                       break;
+               case AREMU:
                        oprange[AREMU] = oprange[r];
                        oprange[AREMUCC] = oprange[r];
                        oprange[AREMUV] = oprange[r];
@@ -940,6 +946,8 @@ buildop(Link *ctxt)
                        oprange[AREMDCC] = oprange[r];
                        oprange[AREMDV] = oprange[r];
                        oprange[AREMDVCC] = oprange[r];
+                       break;
+               case AREMDU:
                        oprange[AREMDU] = oprange[r];
                        oprange[AREMDUCC] = oprange[r];
                        oprange[AREMDUV] = oprange[r];
@@ -2005,6 +2013,11 @@ asmout(Link *ctxt, Prog *p, Optab *o, int32 *out)
                o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
                o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, p->from.reg);
                o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
+               if(p->as == AREMU) {
+                       o4 = o3;
+                       /* Clear top 32 bits */
+                       o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | (1<<5);
+               }
                break;
 
        case 51:        /* remd[u] r1[,r2],r3 */
@@ -2264,54 +2277,6 @@ asmout(Link *ctxt, Prog *p, Optab *o, int32 *out)
        out[3] = o4;
        out[4] = o5;
        return;
-
-#if NOTDEF
-       v = p->pc;
-       switch(o->size) {
-       default:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
-               break;
-       case 4:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
-               lput(o1);
-               break;
-       case 8:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
-               lput(o1);
-               lput(o2);
-               break;
-       case 12:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
-               lput(o1);
-               lput(o2);
-               lput(o3);
-               break;
-       case 16:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
-                               v, o1, o2, o3, o4, p);
-               lput(o1);
-               lput(o2);
-               lput(o3);
-               lput(o4);
-               break;
-       case 20:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
-                               v, o1, o2, o3, o4, o5, p);
-               lput(o1);
-               lput(o2);
-               lput(o3);
-               lput(o4);
-               lput(o5);
-               break;
-       }
-       return 0;
-#endif
 }
 
 static vlong
index 3906181a31dba5a4e749f2a078855c49c15a1c59..fa8af5f839d33f6397131b3ce2717d490a0a9f9d 100644 (file)
@@ -199,7 +199,7 @@ parsetextconst(vlong arg, vlong *textstksiz, vlong *textarg)
 static void
 addstacksplit(Link *ctxt, LSym *cursym)
 {
-       Prog *p, *q, *q1;
+       Prog *p, *q, *p1, *p2, *q1;
        int o, mov, aoffset;
        vlong textstksiz, textarg;
        int32 autoffset, autosize;
@@ -472,32 +472,92 @@ addstacksplit(Link *ctxt, LSym *cursym)
                                q->spadj = -aoffset;
 
                        if(cursym->text->reg & WRAPPER) {
-                               // g->panicwrap += autosize;
-                               // MOVWZ panicwrap_offset(g), R3
-                               // ADD $autosize, R3
-                               // MOVWZ R3, panicwrap_offset(g)
-                               p = appendp(ctxt, q);
-                               p->as = AMOVWZ;
+                               // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
+                               //
+                               //      MOVD g_panic(g), R3
+                               //      CMP R0, R3
+                               //      BEQ end
+                               //      MOVD panic_argp(R3), R4
+                               //      ADD $(autosize+8), R1, R5
+                               //      CMP R4, R5
+                               //      BNE end
+                               //      ADD $8, R1, R6
+                               //      MOVD R6, panic_argp(R3)
+                               // end:
+                               //      NOP
+                               //
+                               // The NOP is needed to give the jumps somewhere to land.
+                               // It is a liblink NOP, not a Power64 NOP: it encodes to 0 instruction bytes.
+
+
+                               p = appendp(ctxt, p);
+                               p->as = AMOVD;
                                p->from.type = D_OREG;
                                p->from.reg = REGG;
-                               p->from.offset = 2*ctxt->arch->ptrsize;
+                               p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
                                p->to.type = D_REG;
                                p->to.reg = 3;
 
+                               p = appendp(ctxt, p);
+                               p->as = ACMP;
+                               p->from.type = D_REG;
+                               p->from.reg = 0;
+                               p->to.type = D_REG;
+                               p->to.reg = 3;
+
+                               p = appendp(ctxt, p);
+                               p->as = ABEQ;
+                               p->to.type = D_BRANCH;
+                               p1 = p;
+
+                               p = appendp(ctxt, p);
+                               p->as = AMOVD;
+                               p->from.type = D_OREG;
+                               p->from.reg = 3;
+                               p->from.offset = 0; // Panic.argp
+                               p->to.type = D_REG;
+                               p->to.reg = 4;
+
                                p = appendp(ctxt, p);
                                p->as = AADD;
                                p->from.type = D_CONST;
-                               p->from.offset = autosize;
+                               p->from.offset = autosize+8;
+                               p->reg = REGSP;
                                p->to.type = D_REG;
-                               p->to.reg = 3;
+                               p->to.reg = 5;
 
                                p = appendp(ctxt, p);
-                               p->as = AMOVWZ;
+                               p->as = ACMP;
                                p->from.type = D_REG;
-                               p->from.reg = 3;
+                               p->from.reg = 4;
+                               p->to.type = D_REG;
+                               p->to.reg = 5;
+
+                               p = appendp(ctxt, p);
+                               p->as = ABNE;
+                               p->to.type = D_BRANCH;
+                               p2 = p;
+
+                               p = appendp(ctxt, p);
+                               p->as = AADD;
+                               p->from.type = D_CONST;
+                               p->from.offset = 8;
+                               p->reg = REGSP;
+                               p->to.type = D_REG;
+                               p->to.reg = 6;
+
+                               p = appendp(ctxt, p);
+                               p->as = AMOVD;
+                               p->from.type = D_REG;
+                               p->from.reg = 6;
                                p->to.type = D_OREG;
-                               p->to.reg = REGG;
-                               p->to.offset = 2*ctxt->arch->ptrsize;
+                               p->to.reg = 3;
+                               p->to.offset = 0; // Panic.argp
+
+                               p = appendp(ctxt, p);
+                               p->as = ANOP;
+                               p1->pcond = p;
+                               p2->pcond = p;
                        }
 
                        break;
@@ -512,36 +572,6 @@ addstacksplit(Link *ctxt, LSym *cursym)
                                p->to.type = D_BRANCH;
                                break;
                        }
-                       if(cursym->text->reg & WRAPPER) {
-                               // g->panicwrap -= autosize;
-                               // MOVWZ panicwrap_offset(g), R3
-                               // ADD $-autosize, R3
-                               // MOVWZ R3, panicwrap_offset(g)
-                               p->as = AMOVWZ;
-                               p->from.type = D_OREG;
-                               p->from.reg = REGG;
-                               p->from.offset = 2*ctxt->arch->ptrsize;
-                               p->to.type = D_REG;
-                               p->to.reg = 3;
-                               p = appendp(ctxt, p);
-
-                               p->as = AADD;
-                               p->from.type = D_CONST;
-                               p->from.offset = -autosize;
-                               p->to.type = D_REG;
-                               p->to.reg = 3;
-                               p = appendp(ctxt, p);
-
-                               p->as = AMOVWZ;
-                               p->from.type = D_REG;
-                               p->from.reg = 3;
-                               p->to.type = D_OREG;
-                               p->to.reg = REGG;
-                               p->to.offset = 2*ctxt->arch->ptrsize;
-                               p = appendp(ctxt, p);
-
-                               p->as = ARETURN;
-                       }
                        if(cursym->text->mark & LEAF) {
                                if(!autosize) {
                                        p->as = ABR;
@@ -673,18 +703,19 @@ addstacksplit(Link *ctxt, LSym *cursym)
 static Prog*
 stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
 {
-       int32 arg;
-       Prog *q, *q1;
+       Prog *q1;
 
        // MOVD g_stackguard(g), R3
        p = appendp(ctxt, p);
        p->as = AMOVD;
        p->from.type = D_OREG;
        p->from.reg = REGG;
+       p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0
+       if(ctxt->cursym->cfunc)
+               p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1
        p->to.type = D_REG;
        p->to.reg = 3;
 
-       q = nil;
        if(framesize <= StackSmall) {
                // small stack: SP < stackguard
                //      CMP     stackguard, SP
@@ -735,7 +766,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
                p->to.type = D_CONST;
                p->to.offset = StackPreempt;
 
-               q = p = appendp(ctxt, p);
+               p = appendp(ctxt, p);
                p->as = ABEQ;
                p->to.type = D_BRANCH;
 
@@ -774,31 +805,6 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
        p->as = ABLT;
        p->to.type = D_BRANCH;
 
-       // MOVD $framesize, R3
-       p = appendp(ctxt, p);
-       p->as = AMOVD;
-       p->from.type = D_CONST;
-       p->from.offset = framesize;
-       p->to.type = D_REG;
-       p->to.reg = 3;
-       if(q)
-               q->pcond = p;
-
-       // MOVD $args, R4
-       p = appendp(ctxt, p);
-       p->as = AMOVD;
-       p->from.type = D_CONST;
-       arg = (ctxt->cursym->text->to.offset >> 32) & 0xffffffffull;
-       if(arg == 1) // special marker for known 0
-               arg = 0;
-       else if(arg == ArgsSizeUnknown)
-               ctxt->diag("%s: arg size unknown, but split stack", ctxt->cursym->name);
-       if(arg&7)
-               ctxt->diag("misaligned argument size in stack split: %d", arg);
-       p->from.offset = arg;
-       p->to.type = D_REG;
-       p->to.reg = 4;
-
        // MOVD LR, R5
        p = appendp(ctxt, p);
        p->as = AMOVD;
@@ -811,7 +817,10 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
        p = appendp(ctxt, p);
        p->as = ABL;
        p->to.type = D_BRANCH;
-       p->to.sym = ctxt->symmorestack[noctxt];
+       if(ctxt->cursym->cfunc)
+               p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
+       else
+               p->to.sym = ctxt->symmorestack[noctxt];
 
        // BR   start
        p = appendp(ctxt, p);
@@ -1010,6 +1019,7 @@ LinkArch linkpower64 = {
        .D_PARAM = D_PARAM,
        .D_SCONST = D_SCONST,
        .D_STATIC = D_STATIC,
+       .D_OREG = D_OREG,
 
        .ACALL = ABL,
        .ADATA = ADATA,
@@ -1056,6 +1066,7 @@ LinkArch linkpower64le = {
        .D_PARAM = D_PARAM,
        .D_SCONST = D_SCONST,
        .D_STATIC = D_STATIC,
+       .D_OREG = D_OREG,
 
        .ACALL = ABL,
        .ADATA = ADATA,