1
0
mirror of https://github.com/golang/go synced 2024-11-11 19:41:36 -07:00

cmd/compile: fix incorrect shift count type with s390x rules

The type of the shift count must be an unsigned integer. Some s390x
rules for shift have their auxint type being int8. This results in a
compilation failure on s390x with an invalid operation when running
make.bash using older versions of go (e.g: go1.10.4).

This CL adds an auxint type of uint8 and changes the ops for shift and
rotate to use auxint with type uint8. The related rules are also
modified to address this change.

Fixes #43090

Change-Id: I594274b6e3d9b23092fc9e9f4b354870164f2f19
Reviewed-on: https://go-review.googlesource.com/c/go/+/277078
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Dmitri Shuralyov <dmitshur@golang.org>
This commit is contained in:
Ruixin Bao 2020-12-09 13:55:37 -08:00 committed by Keith Randall
parent 64d8846aae
commit a58be734ea
9 changed files with 196 additions and 188 deletions

View File

@ -147,6 +147,11 @@ func checkFunc(f *Func) {
canHaveAuxInt = true
case auxInt128:
// AuxInt must be zero, so leave canHaveAuxInt set to false.
case auxUInt8:
if v.AuxInt != int64(uint8(v.AuxInt)) {
f.Fatalf("bad uint8 AuxInt value for %v", v)
}
canHaveAuxInt = true
case auxFloat32:
canHaveAuxInt = true
if math.IsNaN(v.AuxFloat()) {

View File

@ -663,8 +663,8 @@
((OR|XOR)W x (MOVDconst [c])) => ((OR|XOR)Wconst [int32(c)] x)
// Constant shifts.
(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [int8(c&63)])
(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [int8(c&31)])
(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [uint8(c&63)])
(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [uint8(c&31)])
(S(LW|RW) _ (MOVDconst [c])) && c&32 != 0 => (MOVDconst [0])
(SRAW x (MOVDconst [c])) && c&32 != 0 => (SRAWconst x [31])
@ -685,8 +685,8 @@
(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAW x y)
// Match rotate by constant.
(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, int8(c&63))})
(RLL x (MOVDconst [c])) => (RLLconst x [int8(c&31)])
(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, uint8(c&63))})
(RLL x (MOVDconst [c])) => (RLLconst x [uint8(c&31)])
// Match rotate by constant pattern.
((ADD|OR|XOR) (SLDconst x [c]) (SRDconst x [64-c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, c)})
@ -705,10 +705,10 @@
(CMP(W|WU) (MOVDconst [c]) x) => (InvertFlags (CMP(W|WU)const x [int32(c)]))
// Match (x >> c) << d to 'rotate then insert selected bits [into zero]'.
(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(max8(0, c-d), 63-d, (d-c)&63)})
(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(uint8(max8(0, int8(c-d))), 63-d, uint8(int8(d-c)&63))})
// Match (x << c) >> d to 'rotate then insert selected bits [into zero]'.
(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, min8(63, 63-c+d), (c-d)&63)})
(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, uint8(min8(63, int8(63-c+d))), uint8(int8(c-d)&63))})
// Absorb input zero extension into 'rotate then insert selected bits [into zero]'.
(RISBGZ (MOVWZreg x) {r}) && r.InMerge(0xffffffff) != nil => (RISBGZ x {*r.InMerge(0xffffffff)})
@ -818,18 +818,18 @@
// c = 2ˣ + 2ʸ => c - 2ˣ = 2ʸ
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c&(c-1))
=> ((ADD|ADDW) (SL(D|W)const <t> x [int8(log32(c&(c-1)))])
(SL(D|W)const <t> x [int8(log32(c&^(c-1)))]))
=> ((ADD|ADDW) (SL(D|W)const <t> x [uint8(log32(c&(c-1)))])
(SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
// c = 2ʸ - 2ˣ => c + 2ˣ = 2ʸ
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c+(c&^(c-1)))
=> ((SUB|SUBW) (SL(D|W)const <t> x [int8(log32(c+(c&^(c-1))))])
(SL(D|W)const <t> x [int8(log32(c&^(c-1)))]))
=> ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(c+(c&^(c-1))))])
(SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
// c = 2ˣ - 2ʸ => -c + 2ˣ = 2ʸ
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(-c+(-c&^(-c-1)))
=> ((SUB|SUBW) (SL(D|W)const <t> x [int8(log32(-c&^(-c-1)))])
(SL(D|W)const <t> x [int8(log32(-c+(-c&^(-c-1))))]))
=> ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(-c&^(-c-1)))])
(SL(D|W)const <t> x [uint8(log32(-c+(-c&^(-c-1))))]))
// Fold ADD into MOVDaddr. Odd offsets from SB shouldn't be folded (LARL can't handle them).
(ADDconst [c] (MOVDaddr [d] {s} x:(SB))) && ((c+d)&1 == 0) && is32Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)

View File

@ -330,27 +330,27 @@ func init() {
{name: "LTDBR", argLength: 1, reg: fp1flags, asm: "LTDBR", typ: "Flags"}, // arg0 compare to 0, f64
{name: "LTEBR", argLength: 1, reg: fp1flags, asm: "LTEBR", typ: "Flags"}, // arg0 compare to 0, f32
{name: "SLD", argLength: 2, reg: sh21, asm: "SLD"}, // arg0 << arg1, shift amount is mod 64
{name: "SLW", argLength: 2, reg: sh21, asm: "SLW"}, // arg0 << arg1, shift amount is mod 64
{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int8"}, // arg0 << auxint, shift amount 0-63
{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int8"}, // arg0 << auxint, shift amount 0-31
{name: "SLD", argLength: 2, reg: sh21, asm: "SLD"}, // arg0 << arg1, shift amount is mod 64
{name: "SLW", argLength: 2, reg: sh21, asm: "SLW"}, // arg0 << arg1, shift amount is mod 64
{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "UInt8"}, // arg0 << auxint, shift amount 0-63
{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "UInt8"}, // arg0 << auxint, shift amount 0-31
{name: "SRD", argLength: 2, reg: sh21, asm: "SRD"}, // unsigned arg0 >> arg1, shift amount is mod 64
{name: "SRW", argLength: 2, reg: sh21, asm: "SRW"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 64
{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int8"}, // unsigned arg0 >> auxint, shift amount 0-63
{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
{name: "SRD", argLength: 2, reg: sh21, asm: "SRD"}, // unsigned arg0 >> arg1, shift amount is mod 64
{name: "SRW", argLength: 2, reg: sh21, asm: "SRW"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 64
{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "UInt8"}, // unsigned arg0 >> auxint, shift amount 0-63
{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "UInt8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
// Arithmetic shifts clobber flags.
{name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64
{name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true}, // signed int32(arg0) >> arg1, shift amount is mod 64
{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
{name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64
{name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true}, // signed int32(arg0) >> arg1, shift amount is mod 64
{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "UInt8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "UInt8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
// Rotate instructions.
// Note: no RLLGconst - use RISBGZ instead.
{name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63
{name: "RLL", argLength: 2, reg: sh21, asm: "RLL"}, // arg0 rotate left arg1, rotate amount 0-31
{name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "Int8"}, // arg0 rotate left auxint, rotate amount 0-31
{name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63
{name: "RLL", argLength: 2, reg: sh21, asm: "RLL"}, // arg0 rotate left arg1, rotate amount 0-31
{name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "UInt8"}, // arg0 rotate left auxint, rotate amount 0-31
// Rotate then (and|or|xor|insert) selected bits instructions.
//

View File

@ -1395,7 +1395,7 @@ func parseValue(val string, arch arch, loc string) (op opData, oparch, typ, auxi
func opHasAuxInt(op opData) bool {
switch op.aux {
case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64",
case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "UInt8", "Float32", "Float64",
"SymOff", "CallOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop":
return true
}
@ -1780,6 +1780,8 @@ func (op opData) auxIntType() string {
return "int64"
case "Int128":
return "int128"
case "UInt8":
return "uint8"
case "Float32":
return "float32"
case "Float64":

View File

@ -205,6 +205,7 @@ const (
auxInt32 // auxInt is a 32-bit integer
auxInt64 // auxInt is a 64-bit integer
auxInt128 // auxInt represents a 128-bit integer. Always 0.
auxUInt8 // auxInt is an 8-bit unsigned integer
auxFloat32 // auxInt is a float32 (encoded with math.Float64bits)
auxFloat64 // auxInt is a float64 (encoded with math.Float64bits)
auxFlagConstant // auxInt is a flagConstant

View File

@ -30569,7 +30569,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SLDconst",
auxType: auxInt8,
auxType: auxUInt8,
argLen: 1,
asm: s390x.ASLD,
reg: regInfo{
@ -30583,7 +30583,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SLWconst",
auxType: auxInt8,
auxType: auxUInt8,
argLen: 1,
asm: s390x.ASLW,
reg: regInfo{
@ -30625,7 +30625,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SRDconst",
auxType: auxInt8,
auxType: auxUInt8,
argLen: 1,
asm: s390x.ASRD,
reg: regInfo{
@ -30639,7 +30639,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SRWconst",
auxType: auxInt8,
auxType: auxUInt8,
argLen: 1,
asm: s390x.ASRW,
reg: regInfo{
@ -30683,7 +30683,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SRADconst",
auxType: auxInt8,
auxType: auxUInt8,
argLen: 1,
clobberFlags: true,
asm: s390x.ASRAD,
@ -30698,7 +30698,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SRAWconst",
auxType: auxInt8,
auxType: auxUInt8,
argLen: 1,
clobberFlags: true,
asm: s390x.ASRAW,
@ -30741,7 +30741,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "RLLconst",
auxType: auxInt8,
auxType: auxUInt8,
argLen: 1,
asm: s390x.ARLL,
reg: regInfo{

File diff suppressed because it is too large Load Diff

View File

@ -28,9 +28,9 @@ import (
// input left by. Note that this rotation is performed
// before the masked region is used.
type RotateParams struct {
Start int8 // big-endian start bit index [0..63]
End int8 // big-endian end bit index [0..63]
Amount int8 // amount to rotate left
Start uint8 // big-endian start bit index [0..63]
End uint8 // big-endian end bit index [0..63]
Amount uint8 // amount to rotate left
}
// NewRotateParams creates a set of parameters representing a
@ -39,7 +39,7 @@ type RotateParams struct {
//
// The start and end indexes and the rotation amount must all
// be in the range 0-63 inclusive or this function will panic.
func NewRotateParams(start, end, amount int8) RotateParams {
func NewRotateParams(start, end, amount uint8) RotateParams {
if start&^63 != 0 {
panic("start out of bounds")
}
@ -58,7 +58,7 @@ func NewRotateParams(start, end, amount int8) RotateParams {
// RotateLeft generates a new set of parameters with the rotation amount
// increased by the given value. The selected bits are left unchanged.
func (r RotateParams) RotateLeft(amount int8) RotateParams {
func (r RotateParams) RotateLeft(amount uint8) RotateParams {
r.Amount += amount
r.Amount &= 63
return r
@ -100,8 +100,8 @@ func (r RotateParams) OutMerge(mask uint64) *RotateParams {
}
// update start and end positions (rotation amount remains the same)
r.Start = int8(o+z) & 63
r.End = (r.Start + int8(l) - 1) & 63
r.Start = uint8(o+z) & 63
r.End = (r.Start + uint8(l) - 1) & 63
return &r
}

View File

@ -10,7 +10,7 @@ import (
func TestRotateParamsMask(t *testing.T) {
tests := []struct {
start, end, amount int8
start, end, amount uint8
inMask, outMask uint64
}{
// start before end, no rotation