{"record":{"id":"1cd241ad637a638c","repo":"golang/go","slug":"invalid-register-for-shift-operation","errorCode":null,"errorMessage":"invalid register for shift operation","messagePattern":"invalid register for shift operation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/asm/internal/arch/arm64.go","lineNumber":208,"sourceCode":"\t\t\treturn arm64.REG_Z0 + n, true\n\t\t}\n\tcase \"P\":\n\t\tif 0 <= n && n <= 15 {\n\t\t\treturn arm64.REG_P0 + n, true\n\t\t}\n\tcase \"PN\":\n\t\tif 0 <= n && n <= 15 {\n\t\t\treturn arm64.REG_PN0 + n, true\n\t\t}\n\t}\n\treturn 0, false\n}\n\n// ARM64RegisterShift constructs an ARM64 register with shift operation.\nfunc ARM64RegisterShift(reg, op, count int16) (int64, error) {\n\t// the base register of shift operations must be general register.\n\tif reg > arm64.REG_R31 || reg < arm64.REG_R0 {\n\t\treturn 0, errors.New(\"invalid register for shift operation\")\n\t}\n\treturn int64(reg&31)<<16 | int64(op)<<22 | int64(uint16(count)), nil\n}\n\n// ARM64RegisterArrangement constructs an ARM64 vector register arrangement.\nfunc ARM64RegisterArrangement(reg int16, name, arng string) (int64, error) {\n\tvar curQ, curSize, prefix uint16\n\tif name[0] != 'V' && name[0] != 'Z' && name[0] != 'P' {\n\t\treturn 0, errors.New(\"expect V0-V31, Z0-Z31, or P0-P15; found: \" + name)\n\t}\n\tswitch name[0] {\n\tcase 'V':\n\t\tprefix = 0\n\tcase 'Z':\n\t\tprefix = 1\n\tcase 'P':\n\t\tprefix = 2\n\t}","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/asm/internal/arch/arm64.go#L190-L226","documentation":"The Go assembler's ARM64 arch helper ARM64RegisterShift returns this error when the base register of a shift operation is outside the general-purpose register range [REG_R0, REG_R31] (arm64.go:207-209). Only general-purpose registers (R0-R31, where R31 is NZR/SP) are valid as the base of a shifted operand; vector/SVE/predicate registers are not allowed, so the assembler rejects them with this message at assembly time.","triggerScenarios":"Triggered by writing an ARM64 assembly instruction with a shift applied to a non-GPR operand, e.g., `ADD V0.LSL#1, V1, V2` or `ADD Z0.LSL#2, ...`. The check `reg > arm64.REG_R31 || reg < arm64.REG_R0` catches vector (V), SVE (Z), and predicate (P) registers, as well as any out-of-range encoding.","commonSituations":"Hand-written ARM64 assembly (`.s` files assembled by `go tool asm`) using shift modifiers (LSL, LSR, ASR, ROR) on vector or SVE registers. Migrating AArch64 code that used a shift on an operand the Go assembler classifies as non-GPR. Typos in register names that decode to a non-R register.","solutions":["Use a general-purpose register (R0-R30, or R31 where valid) as the base of the shifted operand.","If the operation genuinely targets a vector register, use the correct vector instruction form without a GPR-style shift (e.g., SVE shift instructions).","Double-check register name spelling in the .s file — a typo can cause a non-R decode.","Consult the ARM Architecture Reference Manual for the instruction's permitted operand types."],"exampleFix":"; before — shift on a vector register (invalid)\nTEXT foo(SB), $0\n  ADD V0.LSL#1, V1, V2\n\n; after — use a general-purpose register\nTEXT foo(SB), $0\n  ADD R0.LSL#1, R1, R2","handlingStrategy":"validation","validationCode":"// Validate register class before constructing a shift operand (assembler tooling).\nfunc validShiftBase(reg int16) bool {\n    return reg >= arm64.REG_R0 && reg <= arm64.REG_R31\n}\nif !validShiftBase(reg) { return fmt.Errorf(\"shift base must be R0-R31\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only general-purpose registers (R0-R30/R31) as the base of ARM64 shift operands.","Reserve vector/SVE shift operations for their dedicated instruction forms.","Double-check register prefix spelling in .s files."],"tags":["go","asm","arm64","register","assembler"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}