mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
27f9a6705c
commit
45eee553e2
3 changed files with 145 additions and 144 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue