)]}'
{
  "commit": "358cf414137077ed37b889cd99b3836e8b805792",
  "tree": "60c43876fbd598dbb1d46641c5e099c29b5e028f",
  "parents": [
    "11a3b27b91388bad2fa1ac68f346f440ad6819df"
  ],
  "author": {
    "name": "Brad Fitzpatrick",
    "email": "bradfitz@golang.org",
    "time": "Wed May 06 23:26:42 2026 +0000"
  },
  "committer": {
    "name": "Brad Fitzpatrick",
    "email": "bradfitz@golang.org",
    "time": "Mon May 11 10:45:00 2026 -0700"
  },
  "message": "cmd/internal/obj/arm: use single BIC for AND with negative-rotated immediate\n\nWhen AND $imm, Rn, Rd is given a constant whose bitwise complement\nfits in a rotated 8-bit ARM immediate (i.e. classified as C_NCON),\nthe assembler synthesized the operation as MVN $~imm, R11 followed\nby AND R11, Rn, Rd. This silently clobbered REGTMP (R11) for an\noperation that has a one-instruction encoding: BIC $~imm, Rn, Rd.\n\nWithin Go\u0027s internal ABI this synthesis is technically legal: R11\nis documented REGTMP, reserved for assembler and linker scratch,\nand Go-compiled callers do not assume its value is preserved across\narbitrary instructions. So this is a quality-of-implementation\nimprovement, not a correctness bug fix for first-party Go code.\n\nThe rewrite is unconditional within the C_NCON path: the class is\nonly assigned when immrot(^imm) succeeds, which is exactly the\ncondition for BIC to encode the immediate directly. AND.S maps to\nBIC.S; both set N from bit 31 and Z from result\u003d\u003d0, leave V\nunchanged, and the C flag from a rotated immediate is the same in\neither form. Constants that fall through to C_LCON (literal pool)\nare unaffected.\n\nIt also stops surprising hand-written assembly ported in from other\ntoolchains. Outside Go\u0027s ABI, on the standard ARM ABI used by\nGAS/GCC/clang/etc., R11 is fp -- an ordinary callee-saved register\nthat hand-written code routinely keeps live across instructions.\nCode ported from those toolchains (e.g. CryptoGAMS, OpenSSL) reads\nas plain AND but, with the old synthesis, silently expands to two\ninstructions and trashes R11 in between. After this change a single\nAND in Plan 9 syntax encodes as a single ARM instruction, matching\nwhat GAS produces for the same source.\n\nThe Go compiler does not currently emit AND with a C_NCON immediate\non ARM, so this only affects hand-written .s files. Building cmd/go\nfor GOARCH\u003darm hits exactly three call sites:\n\n  internal/bytealg/compare_arm.s:52  AND $0xfffffffc, R6, R8  -\u003e BIC $3, R6, R8\n  internal/bytealg/equal_arm.s:61    AND $0xfffffffc, R1, R6  -\u003e BIC $3, R1, R6\n  runtime/asm_arm.s:105              AND $~7, R13             -\u003e BIC $7, R13\n\nChange-Id: I0194961917c8a5b3fb5075f787bf8d1e4020ab40\nReviewed-on: https://go-review.googlesource.com/c/go/+/774862\nTryBot-Bypass: Brad Fitzpatrick \u003cbradfitz@golang.org\u003e\nLUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com \u003cgolang-scoped@luci-project-accounts.iam.gserviceaccount.com\u003e\nReviewed-by: Nicholas Husin \u003chusin@google.com\u003e\nReviewed-by: Cherry Mui \u003ccherryyz@google.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "93edc8854ead472df0dc790c2d57c97f390c30ea",
      "old_mode": 33188,
      "old_path": "src/cmd/asm/internal/asm/testdata/arm.s",
      "new_id": "fcc6ac32df4d0d2cf1d50590c558a4827af9c58f",
      "new_mode": 33188,
      "new_path": "src/cmd/asm/internal/asm/testdata/arm.s"
    },
    {
      "type": "modify",
      "old_id": "1e2891de0a7ddc5a277e010c26c038ffdf540a17",
      "old_mode": 33188,
      "old_path": "src/cmd/internal/obj/arm/asm5.go",
      "new_id": "9f59e0a287e25d52d35e719390aa64c15ba7c8bd",
      "new_mode": 33188,
      "new_path": "src/cmd/internal/obj/arm/asm5.go"
    }
  ]
}
