From b54547c08d41eb0b2de7ceb25b210a5f9fb6098f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Balv=C3=ADn?= Date: Wed, 7 Oct 2026 12:48:52 +0200 Subject: [PATCH] fix(asm): reject the shifted-register compositions on loong64 Assisted-by: GLM 5.3 --- asm/loong64_assemble.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/asm/loong64_assemble.go b/asm/loong64_assemble.go index e16070e..fbd1a75 100644 --- a/asm/loong64_assemble.go +++ b/asm/loong64_assemble.go @@ -487,6 +487,21 @@ func encodeLOONG64Instr(instr *ast.Instr, pc int, offsets map[string]int, fi loo } // Pseudo-instructions and the branches first. + // Before any of them: the toolchain's loong64 operand grammar has no + // shifted-register composition (R0<<2, R0>>R1, R0->3, R0@>3 are parse + // errors under GOARCH=loong64 go tool asm), and the shift suffix the + // shared parser records is arm64's. Encoding on would silently drop + // the composition and emit the bare register, so every operand whose + // verbatim suffix is not the element-selector index (V1.B[3] records + // the name as V1.B and the suffix "[3]", which is a real loong64 + // form) is rejected outright. + for _, op := range ops { + sfx := strings.Join(strings.Fields(op.Addr.Shift), "") + if sfx != "" && !strings.HasPrefix(sfx, "[") { + return nil, fmt.Errorf("%s: shifted register operand %s%s is not a loong64 form", + mnem, operandRegName(op), sfx) + } + } switch mnem { case "RET": return loong64Return(fi), nil