cmd/compile: restrict ppc64 constant shifts to amount 0-63

... and 0-31 for 32-bit shifts.

Generally update the docs for ppc64 shift instructions to be
clearer about what they actually do.

This issue is causing problems for the subsequent CL. The shift
amount was <0 and caused the assembler to report an invalid instruction.

Change-Id: I8c708a15e7f71931835e6e543d8db3c716186e52
Reviewed-on: https://go-review.googlesource.com/c/go/+/232858
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
This commit is contained in:
Keith Randall 2020-05-07 15:16:25 -07:00
parent d40b0a1494
commit daf39d06ee
3 changed files with 62 additions and 61 deletions

View File

@ -153,18 +153,18 @@
(Rsh8x64 x (MOVDconst [c])) && uint64(c) < 8 => (SRAWconst (SignExt8to32 x) [c])
(Rsh8Ux64 x (MOVDconst [c])) && uint64(c) < 8 => (SRWconst (ZeroExt8to32 x) [c])
(Lsh64x32 x (MOVDconst [c])) && uint32(c) < 64 => (SLDconst x [c])
(Rsh64x32 x (MOVDconst [c])) && uint32(c) < 64 => (SRADconst x [c])
(Rsh64Ux32 x (MOVDconst [c])) && uint32(c) < 64 => (SRDconst x [c])
(Lsh32x32 x (MOVDconst [c])) && uint32(c) < 32 => (SLWconst x [c])
(Rsh32x32 x (MOVDconst [c])) && uint32(c) < 32 => (SRAWconst x [c])
(Rsh32Ux32 x (MOVDconst [c])) && uint32(c) < 32 => (SRWconst x [c])
(Lsh16x32 x (MOVDconst [c])) && uint32(c) < 16 => (SLWconst x [c])
(Rsh16x32 x (MOVDconst [c])) && uint32(c) < 16 => (SRAWconst (SignExt16to32 x) [c])
(Rsh16Ux32 x (MOVDconst [c])) && uint32(c) < 16 => (SRWconst (ZeroExt16to32 x) [c])
(Lsh8x32 x (MOVDconst [c])) && uint32(c) < 8 => (SLWconst x [c])
(Rsh8x32 x (MOVDconst [c])) && uint32(c) < 8 => (SRAWconst (SignExt8to32 x) [c])
(Rsh8Ux32 x (MOVDconst [c])) && uint32(c) < 8 => (SRWconst (ZeroExt8to32 x) [c])
(Lsh64x32 x (MOVDconst [c])) && uint32(c) < 64 => (SLDconst x [c&63])
(Rsh64x32 x (MOVDconst [c])) && uint32(c) < 64 => (SRADconst x [c&63])
(Rsh64Ux32 x (MOVDconst [c])) && uint32(c) < 64 => (SRDconst x [c&63])
(Lsh32x32 x (MOVDconst [c])) && uint32(c) < 32 => (SLWconst x [c&31])
(Rsh32x32 x (MOVDconst [c])) && uint32(c) < 32 => (SRAWconst x [c&31])
(Rsh32Ux32 x (MOVDconst [c])) && uint32(c) < 32 => (SRWconst x [c&31])
(Lsh16x32 x (MOVDconst [c])) && uint32(c) < 16 => (SLWconst x [c&31])
(Rsh16x32 x (MOVDconst [c])) && uint32(c) < 16 => (SRAWconst (SignExt16to32 x) [c&15])
(Rsh16Ux32 x (MOVDconst [c])) && uint32(c) < 16 => (SRWconst (ZeroExt16to32 x) [c&15])
(Lsh8x32 x (MOVDconst [c])) && uint32(c) < 8 => (SLWconst x [c&7])
(Rsh8x32 x (MOVDconst [c])) && uint32(c) < 8 => (SRAWconst (SignExt8to32 x) [c&7])
(Rsh8Ux32 x (MOVDconst [c])) && uint32(c) < 8 => (SRWconst (ZeroExt8to32 x) [c&7])
// Lower bounded shifts first. No need to check shift value.
(Lsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SLD x y)
@ -285,7 +285,8 @@
(MaskIfNotCarry (FlagCarrySet)) => (MOVDconst [0])
(MaskIfNotCarry (FlagCarryClear)) => (MOVDconst [-1])
(S(RAD|RAW|RD|RW|LD|LW) x (MOVDconst [c])) => (S(RAD|RAW|RD|RW|LD|LW)const [c] x)
(S(RAD|RD|LD) x (MOVDconst [c])) => (S(RAD|RD|LD)const [c&63 | (c>>6&1*63)] x)
(S(RAW|RW|LW) x (MOVDconst [c])) => (S(RAW|RW|LW)const [c&31 | (c>>5&1*31)] x)
(Addr {sym} base) => (MOVDaddr {sym} [0] base)
(LocalAddr {sym} base _) => (MOVDaddr {sym} base)

View File

@ -194,12 +194,12 @@ func init() {
{name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB"}, // arg0*arg1 - arg2
{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS"}, // arg0*arg1 - arg2
{name: "SRAD", argLength: 2, reg: gp21, asm: "SRAD"}, // arg0 >>a arg1, 64 bits (all sign if arg1 & 64 != 0)
{name: "SRAW", argLength: 2, reg: gp21, asm: "SRAW"}, // arg0 >>a arg1, 32 bits (all sign if arg1 & 32 != 0)
{name: "SRD", argLength: 2, reg: gp21, asm: "SRD"}, // arg0 >> arg1, 64 bits (0 if arg1 & 64 != 0)
{name: "SRW", argLength: 2, reg: gp21, asm: "SRW"}, // arg0 >> arg1, 32 bits (0 if arg1 & 32 != 0)
{name: "SLD", argLength: 2, reg: gp21, asm: "SLD"}, // arg0 << arg1, 64 bits (0 if arg1 & 64 != 0)
{name: "SLW", argLength: 2, reg: gp21, asm: "SLW"}, // arg0 << arg1, 32 bits (0 if arg1 & 32 != 0)
{name: "SRAD", argLength: 2, reg: gp21, asm: "SRAD"}, // signed arg0 >> (arg1&127), 64 bit width (note: 127, not 63!)
{name: "SRAW", argLength: 2, reg: gp21, asm: "SRAW"}, // signed arg0 >> (arg1&63), 32 bit width
{name: "SRD", argLength: 2, reg: gp21, asm: "SRD"}, // unsigned arg0 >> (arg1&127), 64 bit width
{name: "SRW", argLength: 2, reg: gp21, asm: "SRW"}, // unsigned arg0 >> (arg1&63), 32 bit width
{name: "SLD", argLength: 2, reg: gp21, asm: "SLD"}, // arg0 << (arg1&127), 64 bit width
{name: "SLW", argLength: 2, reg: gp21, asm: "SLW"}, // arg0 << (arg1&63), 32 bit width
{name: "ROTL", argLength: 2, reg: gp21, asm: "ROTL"}, // arg0 rotate left by arg1 mod 64
{name: "ROTLW", argLength: 2, reg: gp21, asm: "ROTLW"}, // uint32(arg0) rotate left by arg1 mod 32
@ -208,12 +208,12 @@ func init() {
{name: "ADDconstForCarry", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, aux: "Int16", asm: "ADDC", typ: "Flags"}, // _, carry := arg0 + auxint
{name: "MaskIfNotCarry", argLength: 1, reg: crgp, asm: "ADDME", typ: "Int64"}, // carry - 1 (if carry then 0 else -1)
{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int64"}, // arg0 >>a aux, 64 bits
{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int64"}, // arg0 >>a aux, 32 bits
{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int64"}, // arg0 >> aux, 64 bits
{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int64"}, // arg0 >> aux, 32 bits
{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int64"}, // arg0 << aux, 64 bits
{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int64"}, // arg0 << aux, 32 bits
{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int64"}, // unsigned arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int64"}, // unsigned arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int64"}, // arg0 << auxInt, 0 <= auxInt < 64, 64 bit width
{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int64"}, // arg0 << auxInt, 0 <= auxInt < 32, 32 bit width
{name: "ROTLconst", argLength: 1, reg: gp11, asm: "ROTL", aux: "Int64"}, // arg0 rotate left by auxInt bits
{name: "ROTLWconst", argLength: 1, reg: gp11, asm: "ROTLW", aux: "Int64"}, // uint32(arg0) rotate left by auxInt bits

View File

@ -2351,7 +2351,7 @@ func rewriteValuePPC64_OpLsh16x32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Lsh16x32 x (MOVDconst [c]))
// cond: uint32(c) < 16
// result: (SLWconst x [c])
// result: (SLWconst x [c&31])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -2362,7 +2362,7 @@ func rewriteValuePPC64_OpLsh16x32(v *Value) bool {
break
}
v.reset(OpPPC64SLWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 31)
v.AddArg(x)
return true
}
@ -2552,7 +2552,7 @@ func rewriteValuePPC64_OpLsh32x32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Lsh32x32 x (MOVDconst [c]))
// cond: uint32(c) < 32
// result: (SLWconst x [c])
// result: (SLWconst x [c&31])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -2563,7 +2563,7 @@ func rewriteValuePPC64_OpLsh32x32(v *Value) bool {
break
}
v.reset(OpPPC64SLWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 31)
v.AddArg(x)
return true
}
@ -2792,7 +2792,7 @@ func rewriteValuePPC64_OpLsh64x32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Lsh64x32 x (MOVDconst [c]))
// cond: uint32(c) < 64
// result: (SLDconst x [c])
// result: (SLDconst x [c&63])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -2803,7 +2803,7 @@ func rewriteValuePPC64_OpLsh64x32(v *Value) bool {
break
}
v.reset(OpPPC64SLDconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 63)
v.AddArg(x)
return true
}
@ -3032,7 +3032,7 @@ func rewriteValuePPC64_OpLsh8x32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Lsh8x32 x (MOVDconst [c]))
// cond: uint32(c) < 8
// result: (SLWconst x [c])
// result: (SLWconst x [c&7])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -3043,7 +3043,7 @@ func rewriteValuePPC64_OpLsh8x32(v *Value) bool {
break
}
v.reset(OpPPC64SLWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 7)
v.AddArg(x)
return true
}
@ -12046,7 +12046,7 @@ func rewriteValuePPC64_OpPPC64SLD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SLD x (MOVDconst [c]))
// result: (SLDconst [c] x)
// result: (SLDconst [c&63 | (c>>6&1*63)] x)
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -12054,7 +12054,7 @@ func rewriteValuePPC64_OpPPC64SLD(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpPPC64SLDconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c&63 | (c >> 6 & 1 * 63))
v.AddArg(x)
return true
}
@ -12064,7 +12064,7 @@ func rewriteValuePPC64_OpPPC64SLW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SLW x (MOVDconst [c]))
// result: (SLWconst [c] x)
// result: (SLWconst [c&31 | (c>>5&1*31)] x)
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -12072,7 +12072,7 @@ func rewriteValuePPC64_OpPPC64SLW(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpPPC64SLWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c&31 | (c >> 5 & 1 * 31))
v.AddArg(x)
return true
}
@ -12082,7 +12082,7 @@ func rewriteValuePPC64_OpPPC64SRAD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SRAD x (MOVDconst [c]))
// result: (SRADconst [c] x)
// result: (SRADconst [c&63 | (c>>6&1*63)] x)
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -12090,7 +12090,7 @@ func rewriteValuePPC64_OpPPC64SRAD(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpPPC64SRADconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c&63 | (c >> 6 & 1 * 63))
v.AddArg(x)
return true
}
@ -12100,7 +12100,7 @@ func rewriteValuePPC64_OpPPC64SRAW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SRAW x (MOVDconst [c]))
// result: (SRAWconst [c] x)
// result: (SRAWconst [c&31 | (c>>5&1*31)] x)
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -12108,7 +12108,7 @@ func rewriteValuePPC64_OpPPC64SRAW(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpPPC64SRAWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c&31 | (c >> 5 & 1 * 31))
v.AddArg(x)
return true
}
@ -12118,7 +12118,7 @@ func rewriteValuePPC64_OpPPC64SRD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SRD x (MOVDconst [c]))
// result: (SRDconst [c] x)
// result: (SRDconst [c&63 | (c>>6&1*63)] x)
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -12126,7 +12126,7 @@ func rewriteValuePPC64_OpPPC64SRD(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpPPC64SRDconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c&63 | (c >> 6 & 1 * 63))
v.AddArg(x)
return true
}
@ -12136,7 +12136,7 @@ func rewriteValuePPC64_OpPPC64SRW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SRW x (MOVDconst [c]))
// result: (SRWconst [c] x)
// result: (SRWconst [c&31 | (c>>5&1*31)] x)
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -12144,7 +12144,7 @@ func rewriteValuePPC64_OpPPC64SRW(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpPPC64SRWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c&31 | (c >> 5 & 1 * 31))
v.AddArg(x)
return true
}
@ -12630,7 +12630,7 @@ func rewriteValuePPC64_OpRsh16Ux32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Rsh16Ux32 x (MOVDconst [c]))
// cond: uint32(c) < 16
// result: (SRWconst (ZeroExt16to32 x) [c])
// result: (SRWconst (ZeroExt16to32 x) [c&15])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -12641,7 +12641,7 @@ func rewriteValuePPC64_OpRsh16Ux32(v *Value) bool {
break
}
v.reset(OpPPC64SRWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 15)
v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
v0.AddArg(x)
v.AddArg(v0)
@ -12851,7 +12851,7 @@ func rewriteValuePPC64_OpRsh16x32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Rsh16x32 x (MOVDconst [c]))
// cond: uint32(c) < 16
// result: (SRAWconst (SignExt16to32 x) [c])
// result: (SRAWconst (SignExt16to32 x) [c&15])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -12862,7 +12862,7 @@ func rewriteValuePPC64_OpRsh16x32(v *Value) bool {
break
}
v.reset(OpPPC64SRAWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 15)
v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
v0.AddArg(x)
v.AddArg(v0)
@ -13072,7 +13072,7 @@ func rewriteValuePPC64_OpRsh32Ux32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Rsh32Ux32 x (MOVDconst [c]))
// cond: uint32(c) < 32
// result: (SRWconst x [c])
// result: (SRWconst x [c&31])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -13083,7 +13083,7 @@ func rewriteValuePPC64_OpRsh32Ux32(v *Value) bool {
break
}
v.reset(OpPPC64SRWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 31)
v.AddArg(x)
return true
}
@ -13377,7 +13377,7 @@ func rewriteValuePPC64_OpRsh32x32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Rsh32x32 x (MOVDconst [c]))
// cond: uint32(c) < 32
// result: (SRAWconst x [c])
// result: (SRAWconst x [c&31])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -13388,7 +13388,7 @@ func rewriteValuePPC64_OpRsh32x32(v *Value) bool {
break
}
v.reset(OpPPC64SRAWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 31)
v.AddArg(x)
return true
}
@ -13684,7 +13684,7 @@ func rewriteValuePPC64_OpRsh64Ux32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Rsh64Ux32 x (MOVDconst [c]))
// cond: uint32(c) < 64
// result: (SRDconst x [c])
// result: (SRDconst x [c&63])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -13695,7 +13695,7 @@ func rewriteValuePPC64_OpRsh64Ux32(v *Value) bool {
break
}
v.reset(OpPPC64SRDconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 63)
v.AddArg(x)
return true
}
@ -13989,7 +13989,7 @@ func rewriteValuePPC64_OpRsh64x32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Rsh64x32 x (MOVDconst [c]))
// cond: uint32(c) < 64
// result: (SRADconst x [c])
// result: (SRADconst x [c&63])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -14000,7 +14000,7 @@ func rewriteValuePPC64_OpRsh64x32(v *Value) bool {
break
}
v.reset(OpPPC64SRADconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 63)
v.AddArg(x)
return true
}
@ -14300,7 +14300,7 @@ func rewriteValuePPC64_OpRsh8Ux32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Rsh8Ux32 x (MOVDconst [c]))
// cond: uint32(c) < 8
// result: (SRWconst (ZeroExt8to32 x) [c])
// result: (SRWconst (ZeroExt8to32 x) [c&7])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -14311,7 +14311,7 @@ func rewriteValuePPC64_OpRsh8Ux32(v *Value) bool {
break
}
v.reset(OpPPC64SRWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 7)
v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
v0.AddArg(x)
v.AddArg(v0)
@ -14521,7 +14521,7 @@ func rewriteValuePPC64_OpRsh8x32(v *Value) bool {
typ := &b.Func.Config.Types
// match: (Rsh8x32 x (MOVDconst [c]))
// cond: uint32(c) < 8
// result: (SRAWconst (SignExt8to32 x) [c])
// result: (SRAWconst (SignExt8to32 x) [c&7])
for {
x := v_0
if v_1.Op != OpPPC64MOVDconst {
@ -14532,7 +14532,7 @@ func rewriteValuePPC64_OpRsh8x32(v *Value) bool {
break
}
v.reset(OpPPC64SRAWconst)
v.AuxInt = int64ToAuxInt(c)
v.AuxInt = int64ToAuxInt(c & 7)
v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
v0.AddArg(x)
v.AddArg(v0)