mirror of
https://github.com/golang/go
synced 2024-11-23 08:00:05 -07:00
liblink: generate correct code for MOVD $-n(Rm), x on ppc64
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>
This commit is contained in:
parent
e0e1cee8e9
commit
b21e936f3e
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user