mirror of
https://github.com/golang/go
synced 2024-11-11 20:50:23 -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:
parent
64d8846aae
commit
a58be734ea
@ -147,6 +147,11 @@ func checkFunc(f *Func) {
|
|||||||
canHaveAuxInt = true
|
canHaveAuxInt = true
|
||||||
case auxInt128:
|
case auxInt128:
|
||||||
// AuxInt must be zero, so leave canHaveAuxInt set to false.
|
// 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:
|
case auxFloat32:
|
||||||
canHaveAuxInt = true
|
canHaveAuxInt = true
|
||||||
if math.IsNaN(v.AuxFloat()) {
|
if math.IsNaN(v.AuxFloat()) {
|
||||||
|
@ -663,8 +663,8 @@
|
|||||||
((OR|XOR)W x (MOVDconst [c])) => ((OR|XOR)Wconst [int32(c)] x)
|
((OR|XOR)W x (MOVDconst [c])) => ((OR|XOR)Wconst [int32(c)] x)
|
||||||
|
|
||||||
// Constant shifts.
|
// Constant shifts.
|
||||||
(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [int8(c&63)])
|
(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 [int8(c&31)])
|
(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])
|
(S(LW|RW) _ (MOVDconst [c])) && c&32 != 0 => (MOVDconst [0])
|
||||||
(SRAW x (MOVDconst [c])) && c&32 != 0 => (SRAWconst x [31])
|
(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)
|
(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAW x y)
|
||||||
|
|
||||||
// Match rotate by constant.
|
// Match rotate by constant.
|
||||||
(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, int8(c&63))})
|
(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, uint8(c&63))})
|
||||||
(RLL x (MOVDconst [c])) => (RLLconst x [int8(c&31)])
|
(RLL x (MOVDconst [c])) => (RLLconst x [uint8(c&31)])
|
||||||
|
|
||||||
// Match rotate by constant pattern.
|
// Match rotate by constant pattern.
|
||||||
((ADD|OR|XOR) (SLDconst x [c]) (SRDconst x [64-c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, c)})
|
((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)]))
|
(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]'.
|
// 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]'.
|
// 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]'.
|
// 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)})
|
(RISBGZ (MOVWZreg x) {r}) && r.InMerge(0xffffffff) != nil => (RISBGZ x {*r.InMerge(0xffffffff)})
|
||||||
@ -818,18 +818,18 @@
|
|||||||
|
|
||||||
// c = 2ˣ + 2ʸ => c - 2ˣ = 2ʸ
|
// c = 2ˣ + 2ʸ => c - 2ˣ = 2ʸ
|
||||||
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c&(c-1))
|
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c&(c-1))
|
||||||
=> ((ADD|ADDW) (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 [int8(log32(c&^(c-1)))]))
|
(SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
|
||||||
|
|
||||||
// c = 2ʸ - 2ˣ => c + 2ˣ = 2ʸ
|
// c = 2ʸ - 2ˣ => c + 2ˣ = 2ʸ
|
||||||
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c+(c&^(c-1)))
|
(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))))])
|
=> ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(c+(c&^(c-1))))])
|
||||||
(SL(D|W)const <t> x [int8(log32(c&^(c-1)))]))
|
(SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
|
||||||
|
|
||||||
// c = 2ˣ - 2ʸ => -c + 2ˣ = 2ʸ
|
// c = 2ˣ - 2ʸ => -c + 2ˣ = 2ʸ
|
||||||
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(-c+(-c&^(-c-1)))
|
(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)))])
|
=> ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(-c&^(-c-1)))])
|
||||||
(SL(D|W)const <t> x [int8(log32(-c+(-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).
|
// 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)
|
(ADDconst [c] (MOVDaddr [d] {s} x:(SB))) && ((c+d)&1 == 0) && is32Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
|
||||||
|
@ -332,25 +332,25 @@ func init() {
|
|||||||
|
|
||||||
{name: "SLD", argLength: 2, reg: sh21, asm: "SLD"}, // arg0 << arg1, shift amount is mod 64
|
{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: "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: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "UInt8"}, // arg0 << auxint, shift amount 0-63
|
||||||
{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int8"}, // arg0 << auxint, shift amount 0-31
|
{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: "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: "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: "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: "Int8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
|
{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "UInt8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
|
||||||
|
|
||||||
// Arithmetic shifts clobber flags.
|
// Arithmetic shifts clobber flags.
|
||||||
{name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64
|
{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: "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: "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: "Int8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
|
{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "UInt8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
|
||||||
|
|
||||||
// Rotate instructions.
|
// Rotate instructions.
|
||||||
// Note: no RLLGconst - use RISBGZ instead.
|
// Note: no RLLGconst - use RISBGZ instead.
|
||||||
{name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63
|
{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: "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: "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.
|
// Rotate then (and|or|xor|insert) selected bits instructions.
|
||||||
//
|
//
|
||||||
|
@ -1395,7 +1395,7 @@ func parseValue(val string, arch arch, loc string) (op opData, oparch, typ, auxi
|
|||||||
|
|
||||||
func opHasAuxInt(op opData) bool {
|
func opHasAuxInt(op opData) bool {
|
||||||
switch op.aux {
|
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":
|
"SymOff", "CallOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop":
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -1780,6 +1780,8 @@ func (op opData) auxIntType() string {
|
|||||||
return "int64"
|
return "int64"
|
||||||
case "Int128":
|
case "Int128":
|
||||||
return "int128"
|
return "int128"
|
||||||
|
case "UInt8":
|
||||||
|
return "uint8"
|
||||||
case "Float32":
|
case "Float32":
|
||||||
return "float32"
|
return "float32"
|
||||||
case "Float64":
|
case "Float64":
|
||||||
|
@ -205,6 +205,7 @@ const (
|
|||||||
auxInt32 // auxInt is a 32-bit integer
|
auxInt32 // auxInt is a 32-bit integer
|
||||||
auxInt64 // auxInt is a 64-bit integer
|
auxInt64 // auxInt is a 64-bit integer
|
||||||
auxInt128 // auxInt represents a 128-bit integer. Always 0.
|
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)
|
auxFloat32 // auxInt is a float32 (encoded with math.Float64bits)
|
||||||
auxFloat64 // auxInt is a float64 (encoded with math.Float64bits)
|
auxFloat64 // auxInt is a float64 (encoded with math.Float64bits)
|
||||||
auxFlagConstant // auxInt is a flagConstant
|
auxFlagConstant // auxInt is a flagConstant
|
||||||
|
@ -30569,7 +30569,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "SLDconst",
|
name: "SLDconst",
|
||||||
auxType: auxInt8,
|
auxType: auxUInt8,
|
||||||
argLen: 1,
|
argLen: 1,
|
||||||
asm: s390x.ASLD,
|
asm: s390x.ASLD,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
@ -30583,7 +30583,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "SLWconst",
|
name: "SLWconst",
|
||||||
auxType: auxInt8,
|
auxType: auxUInt8,
|
||||||
argLen: 1,
|
argLen: 1,
|
||||||
asm: s390x.ASLW,
|
asm: s390x.ASLW,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
@ -30625,7 +30625,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "SRDconst",
|
name: "SRDconst",
|
||||||
auxType: auxInt8,
|
auxType: auxUInt8,
|
||||||
argLen: 1,
|
argLen: 1,
|
||||||
asm: s390x.ASRD,
|
asm: s390x.ASRD,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
@ -30639,7 +30639,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "SRWconst",
|
name: "SRWconst",
|
||||||
auxType: auxInt8,
|
auxType: auxUInt8,
|
||||||
argLen: 1,
|
argLen: 1,
|
||||||
asm: s390x.ASRW,
|
asm: s390x.ASRW,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
@ -30683,7 +30683,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "SRADconst",
|
name: "SRADconst",
|
||||||
auxType: auxInt8,
|
auxType: auxUInt8,
|
||||||
argLen: 1,
|
argLen: 1,
|
||||||
clobberFlags: true,
|
clobberFlags: true,
|
||||||
asm: s390x.ASRAD,
|
asm: s390x.ASRAD,
|
||||||
@ -30698,7 +30698,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "SRAWconst",
|
name: "SRAWconst",
|
||||||
auxType: auxInt8,
|
auxType: auxUInt8,
|
||||||
argLen: 1,
|
argLen: 1,
|
||||||
clobberFlags: true,
|
clobberFlags: true,
|
||||||
asm: s390x.ASRAW,
|
asm: s390x.ASRAW,
|
||||||
@ -30741,7 +30741,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "RLLconst",
|
name: "RLLconst",
|
||||||
auxType: auxInt8,
|
auxType: auxUInt8,
|
||||||
argLen: 1,
|
argLen: 1,
|
||||||
asm: s390x.ARLL,
|
asm: s390x.ARLL,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -28,9 +28,9 @@ import (
|
|||||||
// input left by. Note that this rotation is performed
|
// input left by. Note that this rotation is performed
|
||||||
// before the masked region is used.
|
// before the masked region is used.
|
||||||
type RotateParams struct {
|
type RotateParams struct {
|
||||||
Start int8 // big-endian start bit index [0..63]
|
Start uint8 // big-endian start bit index [0..63]
|
||||||
End int8 // big-endian end bit index [0..63]
|
End uint8 // big-endian end bit index [0..63]
|
||||||
Amount int8 // amount to rotate left
|
Amount uint8 // amount to rotate left
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRotateParams creates a set of parameters representing a
|
// 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
|
// The start and end indexes and the rotation amount must all
|
||||||
// be in the range 0-63 inclusive or this function will panic.
|
// 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 {
|
if start&^63 != 0 {
|
||||||
panic("start out of bounds")
|
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
|
// RotateLeft generates a new set of parameters with the rotation amount
|
||||||
// increased by the given value. The selected bits are left unchanged.
|
// 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 += amount
|
||||||
r.Amount &= 63
|
r.Amount &= 63
|
||||||
return r
|
return r
|
||||||
@ -100,8 +100,8 @@ func (r RotateParams) OutMerge(mask uint64) *RotateParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update start and end positions (rotation amount remains the same)
|
// update start and end positions (rotation amount remains the same)
|
||||||
r.Start = int8(o+z) & 63
|
r.Start = uint8(o+z) & 63
|
||||||
r.End = (r.Start + int8(l) - 1) & 63
|
r.End = (r.Start + uint8(l) - 1) & 63
|
||||||
return &r
|
return &r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
func TestRotateParamsMask(t *testing.T) {
|
func TestRotateParamsMask(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
start, end, amount int8
|
start, end, amount uint8
|
||||||
inMask, outMask uint64
|
inMask, outMask uint64
|
||||||
}{
|
}{
|
||||||
// start before end, no rotation
|
// start before end, no rotation
|
||||||
|
Loading…
Reference in New Issue
Block a user