]> Cypherpunks repositories - gostls13.git/commitdiff
liblink: generate correct code for MOVD $-n(Rm), x on ppc64
authorAustin Clements <austin@google.com>
Thu, 18 Dec 2014 06:08:09 +0000 (01:08 -0500)
committerAustin Clements <austin@google.com>
Thu, 18 Dec 2014 15:31:47 +0000 (15:31 +0000)
On ppc64, liblink rewrites MOVD's of >32-bit constants by putting the
constant in memory and rewriting the MOVD to load from that memory
address.  However, there were two bugs in the condition:

a) owing to an incorrect sign extension, it triggered for all negative
   constants, and

b) it could trigger for constant offsets from registers (addresses of
   the form $n(Rm) in assembly)

Together, these meant instructions of the form MOVD $-n(Rm), x were
compiled by putting -n in memory and rewriting the MOVD to load this
constant from memory (completely dropping Rm).

Change-Id: I1f6cc980efa3e3d6f164b46c985b2c3b55971cca
Reviewed-on: https://go-review.googlesource.com/1752
Reviewed-by: Minux Ma <minux@golang.org>
src/cmd/9l/9.out.h
src/liblink/obj9.c

index 87917f88ac6ac7e6676aa6ba83b892fad5ed0b1b..016163b6fa575a570330e3a66686e2f76d94ff36 100644 (file)
@@ -106,9 +106,9 @@ enum
        C_ANDCON,       /* 0 < v <= 0xFFFF */
        C_LCON,         /* other 32 */
        C_DCON,         /* other 64 (could subdivide further) */
-       C_SACON,
+       C_SACON,        /* $n(REG) where n is small */
        C_SECON,
-       C_LACON,
+       C_LACON,        /* $n(REG) where n is large */
        C_LECON,
        C_SBRA,
        C_LBRA,
index 533dbc271b5093dfc30f184b081c12192dcdc61d..a1ead3a0f39d74446115e34a8e310541915f0ed8 100644 (file)
@@ -145,7 +145,8 @@ progedit(Link *ctxt, Prog *p)
                }
                break;
        case AMOVD:
-               if(p->from.type == D_CONST && p->from.name == D_NONE && (int64)(uint32)p->from.offset != p->from.offset) {
+               // Put >32-bit constants in memory and load them
+               if(p->from.type == D_CONST && p->from.name == D_NONE && p->from.reg == NREG && (int32)p->from.offset != p->from.offset) {
                        sprint(literal, "$i64.%016llux", (uvlong)p->from.offset);
                        s = linklookup(ctxt, literal, 0);
                        s->size = 8;