]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile, cmd/link: enable Duff's device on darwin/arm64
authorCherry Mui <cherryyz@google.com>
Tue, 2 Aug 2022 21:39:11 +0000 (17:39 -0400)
committerCherry Mui <cherryyz@google.com>
Mon, 8 Aug 2022 17:54:10 +0000 (17:54 +0000)
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 #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>

src/cmd/compile/internal/arm64/ggen.go
src/cmd/compile/internal/ssa/config.go
src/cmd/link/internal/arm64/asm.go

index 89be4964619c16a30f469de696451a0aec5bab51..a681adcb7fe28fb71797688981c90cf7e0077c1e 100644 (file)
@@ -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.
@@ -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)
index 79b6849e4ed2b429b1acbfa3fed63899073609e6..d7a413268b6eb007946c8317eb0eac64305099c7 100644 (file)
@@ -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
index 9937683a133190fdb8a4a6d03449a12408b93b81..42f0e77865c861e8a653add87c0b1595d7c36f5a 100644 (file)
@@ -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
@@ -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 {
@@ -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,