From 45eee553e29770a264c378bccbb80c44807609f4 Mon Sep 17 00:00:00 2001 From: Vasily Leonenko Date: Sat, 6 Sep 2025 23:03:16 +0300 Subject: [PATCH] cmd/internal/obj: move ARM64RegisterExtension from cmd/asm/internal/arch Change-Id: Iab41674953655efa7be3d306dfb3f5be486be501 Reviewed-on: https://go-review.googlesource.com/c/go/+/701455 Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall --- src/cmd/asm/internal/arch/arm64.go | 143 ---------------------------- src/cmd/asm/internal/asm/parse.go | 2 +- src/cmd/internal/obj/arm64/asm7.go | 144 +++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 144 deletions(-) diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go index 87ccb8c0409..d562e5907d6 100644 --- a/src/cmd/asm/internal/arch/arm64.go +++ b/src/cmd/asm/internal/arch/arm64.go @@ -195,149 +195,6 @@ func ARM64RegisterShift(reg, op, count int16) (int64, error) { return int64(reg&31)<<16 | int64(op)<<22 | int64(uint16(count)), nil } -// ARM64RegisterExtension constructs an ARM64 register with extension or arrangement. -func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error { - Rnum := (reg & 31) + int16(num<<5) - if isAmount { - if num < 0 || num > 7 { - return errors.New("index shift amount is out of range") - } - } - if reg <= arm64.REG_R31 && reg >= arm64.REG_R0 { - if !isAmount { - return errors.New("invalid register extension") - } - switch ext { - case "UXTB": - if a.Type == obj.TYPE_MEM { - return errors.New("invalid shift for the register offset addressing mode") - } - a.Reg = arm64.REG_UXTB + Rnum - case "UXTH": - if a.Type == obj.TYPE_MEM { - return errors.New("invalid shift for the register offset addressing mode") - } - a.Reg = arm64.REG_UXTH + Rnum - case "UXTW": - // effective address of memory is a base register value and an offset register value. - if a.Type == obj.TYPE_MEM { - a.Index = arm64.REG_UXTW + Rnum - } else { - a.Reg = arm64.REG_UXTW + Rnum - } - case "UXTX": - if a.Type == obj.TYPE_MEM { - return errors.New("invalid shift for the register offset addressing mode") - } - a.Reg = arm64.REG_UXTX + Rnum - case "SXTB": - if a.Type == obj.TYPE_MEM { - return errors.New("invalid shift for the register offset addressing mode") - } - a.Reg = arm64.REG_SXTB + Rnum - case "SXTH": - if a.Type == obj.TYPE_MEM { - return errors.New("invalid shift for the register offset addressing mode") - } - a.Reg = arm64.REG_SXTH + Rnum - case "SXTW": - if a.Type == obj.TYPE_MEM { - a.Index = arm64.REG_SXTW + Rnum - } else { - a.Reg = arm64.REG_SXTW + Rnum - } - case "SXTX": - if a.Type == obj.TYPE_MEM { - a.Index = arm64.REG_SXTX + Rnum - } else { - a.Reg = arm64.REG_SXTX + Rnum - } - case "LSL": - a.Index = arm64.REG_LSL + Rnum - default: - return errors.New("unsupported general register extension type: " + ext) - - } - } else if reg <= arm64.REG_V31 && reg >= arm64.REG_V0 { - switch ext { - case "B8": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8B & 15) << 5) - case "B16": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_16B & 15) << 5) - case "H4": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4H & 15) << 5) - case "H8": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8H & 15) << 5) - case "S2": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2S & 15) << 5) - case "S4": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4S & 15) << 5) - case "D1": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1D & 15) << 5) - case "D2": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2D & 15) << 5) - case "Q1": - if isIndex { - return errors.New("invalid register extension") - } - a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1Q & 15) << 5) - case "B": - if !isIndex { - return nil - } - a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_B & 15) << 5) - a.Index = num - case "H": - if !isIndex { - return nil - } - a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_H & 15) << 5) - a.Index = num - case "S": - if !isIndex { - return nil - } - a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_S & 15) << 5) - a.Index = num - case "D": - if !isIndex { - return nil - } - a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_D & 15) << 5) - a.Index = num - default: - return errors.New("unsupported simd register extension type: " + ext) - } - } else { - return errors.New("invalid register and extension combination") - } - return nil -} - // ARM64RegisterArrangement constructs an ARM64 vector register arrangement. func ARM64RegisterArrangement(reg int16, name, arng string) (int64, error) { var curQ, curSize uint16 diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go index 8f8f6dcc346..545f6c75533 100644 --- a/src/cmd/asm/internal/asm/parse.go +++ b/src/cmd/asm/internal/asm/parse.go @@ -775,7 +775,7 @@ func (p *Parser) registerExtension(a *obj.Addr, name string, prefix rune) { switch p.arch.Family { case sys.ARM64: - err := arch.ARM64RegisterExtension(a, ext, reg, num, isAmount, isIndex) + err := arm64.ARM64RegisterExtension(a, ext, reg, num, isAmount, isIndex) if err != nil { p.errorf("%v", err) } diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index cfb70cf08a3..3cb4be436b9 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -34,6 +34,7 @@ import ( "cmd/internal/obj" "cmd/internal/objabi" "encoding/binary" + "errors" "fmt" "log" "math" @@ -7855,3 +7856,146 @@ func (c *ctxt7) encRegShiftOrExt(p *obj.Prog, a *obj.Addr, r int16) uint32 { func pack(q uint32, arngA, arngB uint8) uint32 { return uint32(q)<<16 | uint32(arngA)<<8 | uint32(arngB) } + +// ARM64RegisterExtension constructs an ARM64 register with extension or arrangement. +func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error { + Rnum := (reg & 31) + int16(num<<5) + if isAmount { + if num < 0 || num > 7 { + return errors.New("index shift amount is out of range") + } + } + if reg <= REG_R31 && reg >= REG_R0 { + if !isAmount { + return errors.New("invalid register extension") + } + switch ext { + case "UXTB": + if a.Type == obj.TYPE_MEM { + return errors.New("invalid shift for the register offset addressing mode") + } + a.Reg = REG_UXTB + Rnum + case "UXTH": + if a.Type == obj.TYPE_MEM { + return errors.New("invalid shift for the register offset addressing mode") + } + a.Reg = REG_UXTH + Rnum + case "UXTW": + // effective address of memory is a base register value and an offset register value. + if a.Type == obj.TYPE_MEM { + a.Index = REG_UXTW + Rnum + } else { + a.Reg = REG_UXTW + Rnum + } + case "UXTX": + if a.Type == obj.TYPE_MEM { + return errors.New("invalid shift for the register offset addressing mode") + } + a.Reg = REG_UXTX + Rnum + case "SXTB": + if a.Type == obj.TYPE_MEM { + return errors.New("invalid shift for the register offset addressing mode") + } + a.Reg = REG_SXTB + Rnum + case "SXTH": + if a.Type == obj.TYPE_MEM { + return errors.New("invalid shift for the register offset addressing mode") + } + a.Reg = REG_SXTH + Rnum + case "SXTW": + if a.Type == obj.TYPE_MEM { + a.Index = REG_SXTW + Rnum + } else { + a.Reg = REG_SXTW + Rnum + } + case "SXTX": + if a.Type == obj.TYPE_MEM { + a.Index = REG_SXTX + Rnum + } else { + a.Reg = REG_SXTX + Rnum + } + case "LSL": + a.Index = REG_LSL + Rnum + default: + return errors.New("unsupported general register extension type: " + ext) + + } + } else if reg <= REG_V31 && reg >= REG_V0 { + switch ext { + case "B8": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_8B & 15) << 5) + case "B16": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_16B & 15) << 5) + case "H4": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_4H & 15) << 5) + case "H8": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_8H & 15) << 5) + case "S2": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_2S & 15) << 5) + case "S4": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_4S & 15) << 5) + case "D1": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_1D & 15) << 5) + case "D2": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_2D & 15) << 5) + case "Q1": + if isIndex { + return errors.New("invalid register extension") + } + a.Reg = REG_ARNG + (reg & 31) + ((ARNG_1Q & 15) << 5) + case "B": + if !isIndex { + return nil + } + a.Reg = REG_ELEM + (reg & 31) + ((ARNG_B & 15) << 5) + a.Index = num + case "H": + if !isIndex { + return nil + } + a.Reg = REG_ELEM + (reg & 31) + ((ARNG_H & 15) << 5) + a.Index = num + case "S": + if !isIndex { + return nil + } + a.Reg = REG_ELEM + (reg & 31) + ((ARNG_S & 15) << 5) + a.Index = num + case "D": + if !isIndex { + return nil + } + a.Reg = REG_ELEM + (reg & 31) + ((ARNG_D & 15) << 5) + a.Index = num + default: + return errors.New("unsupported simd register extension type: " + ext) + } + } else { + return errors.New("invalid register and extension combination") + } + return nil +}