Skip to content

Commit

Permalink
cmd/compile, cmd/link: enable Duff's device on darwin/arm64
Browse files Browse the repository at this point in the history
Duff's device was disabled on darwin/arm64 because the darwin
linker couldn't handle a branch relocation with non-zero addend.
This is no longer the case now. The darwin linker can handle it
just fine. So enable it.

Fixes golang#54189.

Change-Id: Ida7ebafe6eb01db1af5bb8ae60a62491da5eabdf
Reviewed-on: https://go-review.googlesource.com/c/go/+/420894
Reviewed-by: Eric Fang <eric.fang@arm.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
cherrymui authored and jproberts committed Aug 10, 2022
1 parent 4e0f8d5 commit 0a9efc8
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 25 deletions.
5 changes: 1 addition & 4 deletions src/cmd/compile/internal/arm64/ggen.go
Expand Up @@ -10,11 +10,8 @@ import (
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/obj/arm64"
"internal/buildcfg"
)

var darwin = buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios"

func padframe(frame int64) int64 {
// arm64 requires that the frame size (not counting saved FP&LR)
// be 16 bytes aligned. If not, pad it.
Expand All @@ -32,7 +29,7 @@ func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog
for i := int64(0); i < cnt; i += int64(types.PtrSize) {
p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
}
} else if cnt <= int64(128*types.PtrSize) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend
} else if cnt <= int64(128*types.PtrSize) {
if cnt%(2*int64(types.PtrSize)) != 0 {
p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off)
off += int64(types.PtrSize)
Expand Down
1 change: 0 additions & 1 deletion src/cmd/compile/internal/ssa/config.go
Expand Up @@ -230,7 +230,6 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo
c.FPReg = framepointerRegARM64
c.LinkReg = linkRegARM64
c.hasGReg = true
c.noDuffDevice = buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios" // darwin linker cannot handle BR26 reloc with non-zero addend
case "ppc64":
c.BigEndian = true
fallthrough
Expand Down
34 changes: 14 additions & 20 deletions src/cmd/link/internal/arm64/asm.go
Expand Up @@ -539,7 +539,8 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
v |= ld.MACHO_ARM64_RELOC_UNSIGNED << 28
case objabi.R_CALLARM64:
if xadd != 0 {
ldr.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", ldr.SymName(rs), xadd)
out.Write32(uint32(sectoff))
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
}

v |= 1 << 24 // pc-relative bit
Expand Down Expand Up @@ -719,15 +720,22 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
}

return val, nExtReloc, isOk
case objabi.R_CALLARM64,
objabi.R_ARM64_TLS_LE,
objabi.R_ARM64_TLS_IE:

case objabi.R_CALLARM64:
nExtReloc = 1
if rt == objabi.R_ARM64_TLS_IE {
nExtReloc = 2 // need two ELF relocations. see elfreloc1
if target.IsDarwin() && r.Add() != 0 {
nExtReloc = 2 // need another relocation for addend
}
return val, nExtReloc, isOk

case objabi.R_ARM64_TLS_LE:
nExtReloc = 1
return val, nExtReloc, isOk

case objabi.R_ARM64_TLS_IE:
nExtReloc = 2 // need two ELF relocations. see elfreloc1
return val, nExtReloc, isOk

case objabi.R_ADDR:
if target.IsWindows() && r.Add() != 0 {
if r.Siz() == 8 {
Expand Down Expand Up @@ -946,20 +954,6 @@ func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sy
case objabi.R_ARM64_GOTPCREL,
objabi.R_ADDRARM64:
rr := ld.ExtrelocViaOuterSym(ldr, r, s)

// Note: ld64 currently has a bug that any non-zero addend for BR26 relocation
// will make the linking fail because it thinks the code is not PIC even though
// the BR26 relocation should be fully resolved at link time.
// That is the reason why the next if block is disabled. When the bug in ld64
// is fixed, we can enable this block and also enable duff's device in cmd/7g.
if false && target.IsDarwin() {
// Mach-O wants the addend to be encoded in the instruction
// Note that although Mach-O supports ARM64_RELOC_ADDEND, it
// can only encode 24-bit of signed addend, but the instructions
// supports 33-bit of signed addend, so we always encode the
// addend in place.
rr.Xadd = 0
}
return rr, true
case objabi.R_CALLARM64,
objabi.R_ARM64_TLS_LE,
Expand Down

0 comments on commit 0a9efc8

Please sign in to comment.