cmd/compile: convert rest ARM64.rules lines to typed aux mode

This patch adds the ARM6464Bitfield auxInt to auxIntType() and
returns its Go type as "arm64Bitfield" type, which is defined
as int16 type.

And the Go type of SymOff auxInt is int32, but some functions
(such as min(), areAdjacentOffsets() and read16/32/64(),etc.)
use SymOff as an input parameter and treat its type as int64,
this patch adds the type conversion for these rules.

Passes toolstash-check -all.

Change-Id: Ib234b48d0a97ef244dd37878e06b5825316dd782
Reviewed-on: https://go-review.googlesource.com/c/go/+/234378
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
fanzha02 2020-05-14 17:01:11 +08:00 committed by Keith Randall
parent 0e03167628
commit 85902b6786
8 changed files with 1745 additions and 1728 deletions

View File

@ -1138,7 +1138,7 @@
// ((x>>8) | (x<<8)) -> (REV16 x), the type of x is uint16, "|" can also be "^" or "+".
// UBFX instruction is supported by ARMv6T2, ARMv7 and above versions, REV16 is supported by
// ARMv6 and above versions. So for ARMv6, we need to match SLLconst, SRLconst and ORshiftLL.
((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (BFXU <typ.UInt16> [armBFAuxInt(8, 8)] x) x) -> (REV16 x)
((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x) => (REV16 x)
((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && objabi.GOARM>=6 -> (REV16 x)
// use indexed loads and stores

File diff suppressed because it is too large Load Diff

View File

@ -1820,6 +1820,8 @@ func (op opData) auxIntType() string {
return "Op"
case "FlagConstant":
return "flagConstant"
case "ARM64BitField":
return "arm64BitField"
default:
return "invalid"
}

View File

@ -277,3 +277,9 @@ func boundsABI(b int64) int {
panic("bad BoundsKind")
}
}
// arm64BitFileld is the GO type of ARM64BitField auxInt.
// if x is an ARM64BitField, then width=x&0xff, lsb=(x>>8)&0xff, and
// width+lsb<64 for 64-bit variant, width+lsb<32 for 32-bit variant.
// the meaning of width and lsb are instruction-dependent.
type arm64BitField int16

View File

@ -618,6 +618,9 @@ func auxIntToFloat64(i int64) float64 {
func auxIntToValAndOff(i int64) ValAndOff {
return ValAndOff(i)
}
func auxIntToArm64BitField(i int64) arm64BitField {
return arm64BitField(i)
}
func auxIntToInt128(x int64) int128 {
if x != 0 {
panic("nonzero int128 not allowed")
@ -658,6 +661,9 @@ func float64ToAuxInt(f float64) int64 {
func valAndOffToAuxInt(v ValAndOff) int64 {
return int64(v)
}
func arm64BitFieldToAuxInt(v arm64BitField) int64 {
return int64(v)
}
func int128ToAuxInt(x int128) int64 {
if x != 0 {
panic("nonzero int128 not allowed")
@ -1295,24 +1301,24 @@ func hasSmallRotate(c *Config) bool {
}
// encodes the lsb and width for arm(64) bitfield ops into the expected auxInt format.
func armBFAuxInt(lsb, width int64) int64 {
func armBFAuxInt(lsb, width int64) arm64BitField {
if lsb < 0 || lsb > 63 {
panic("ARM(64) bit field lsb constant out of range")
}
if width < 1 || width > 64 {
panic("ARM(64) bit field width constant out of range")
}
return width | lsb<<8
return arm64BitField(width | lsb<<8)
}
// returns the lsb part of the auxInt field of arm64 bitfield ops.
func getARM64BFlsb(bfc int64) int64 {
func (bfc arm64BitField) getARM64BFlsb() int64 {
return int64(uint64(bfc) >> 8)
}
// returns the width part of the auxInt field of arm64 bitfield ops.
func getARM64BFwidth(bfc int64) int64 {
return bfc & 0xff
func (bfc arm64BitField) getARM64BFwidth() int64 {
return int64(bfc) & 0xff
}
// checks if mask >> rshift applied at lsb is a valid arm64 bitfield op mask.

View File

@ -2069,10 +2069,10 @@ func rewriteValueARM_OpARMADDshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ADDshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
// match: (ADDshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x)
// result: (REV16 x)
for {
if v.Type != typ.UInt16 || v.AuxInt != 8 || v_0.Op != OpARMBFXU || v_0.Type != typ.UInt16 || v_0.AuxInt != armBFAuxInt(8, 8) {
if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMBFXU || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != int32(armBFAuxInt(8, 8)) {
break
}
x := v_0.Args[0]
@ -8537,10 +8537,10 @@ func rewriteValueARM_OpARMORshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
// match: (ORshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x)
// result: (REV16 x)
for {
if v.Type != typ.UInt16 || v.AuxInt != 8 || v_0.Op != OpARMBFXU || v_0.Type != typ.UInt16 || v_0.AuxInt != armBFAuxInt(8, 8) {
if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMBFXU || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != int32(armBFAuxInt(8, 8)) {
break
}
x := v_0.Args[0]
@ -12576,10 +12576,10 @@ func rewriteValueARM_OpARMXORshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (XORshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
// match: (XORshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x)
// result: (REV16 x)
for {
if v.Type != typ.UInt16 || v.AuxInt != 8 || v_0.Op != OpARMBFXU || v_0.Type != typ.UInt16 || v_0.AuxInt != armBFAuxInt(8, 8) {
if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMBFXU || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != int32(armBFAuxInt(8, 8)) {
break
}
x := v_0.Args[0]

File diff suppressed because it is too large Load Diff

View File

@ -126,6 +126,13 @@ func (v *Value) AuxValAndOff() ValAndOff {
return ValAndOff(v.AuxInt)
}
func (v *Value) AuxArm64BitField() arm64BitField {
if opcodeTable[v.Op].auxType != auxARM64BitField {
v.Fatalf("op %s doesn't have a ValAndOff aux field", v.Op)
}
return arm64BitField(v.AuxInt)
}
// long form print. v# = opcode <type> [aux] args [: reg] (names)
func (v *Value) LongString() string {
s := fmt.Sprintf("v%d = %s", v.ID, v.Op)
@ -176,8 +183,8 @@ func (v *Value) auxString() string {
case auxInt64, auxInt128:
return fmt.Sprintf(" [%d]", v.AuxInt)
case auxARM64BitField:
lsb := getARM64BFlsb(v.AuxInt)
width := getARM64BFwidth(v.AuxInt)
lsb := v.AuxArm64BitField().getARM64BFlsb()
width := v.AuxArm64BitField().getARM64BFwidth()
return fmt.Sprintf(" [lsb=%d,width=%d]", lsb, width)
case auxFloat32, auxFloat64:
return fmt.Sprintf(" [%g]", v.AuxFloat())