mirror of
https://github.com/golang/go.git
synced 2026-01-29 07:02:05 +03:00
Compare commits
8 Commits
a0796d8af6
...
83b232b0af
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83b232b0af | ||
|
|
6aef900af4 | ||
|
|
026fa9dc59 | ||
|
|
133b339ca5 | ||
|
|
4f9c3439a3 | ||
|
|
134035855c | ||
|
|
f65fe3216e | ||
|
|
514790c2b9 |
@@ -529,6 +529,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
ssa.OpLOONG64BITREV4B,
|
||||
ssa.OpLOONG64BITREVW,
|
||||
ssa.OpLOONG64BITREVV,
|
||||
ssa.OpLOONG64ABSF,
|
||||
ssa.OpLOONG64ABSD:
|
||||
p := s.Prog(v.Op.Asm())
|
||||
p.From.Type = obj.TYPE_REG
|
||||
|
||||
@@ -197,7 +197,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
ssa.OpMIPSANDconst,
|
||||
ssa.OpMIPSORconst,
|
||||
ssa.OpMIPSXORconst,
|
||||
ssa.OpMIPSNORconst,
|
||||
ssa.OpMIPSSLLconst,
|
||||
ssa.OpMIPSSRLconst,
|
||||
ssa.OpMIPSSRAconst,
|
||||
|
||||
@@ -191,7 +191,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
ssa.OpMIPS64ANDconst,
|
||||
ssa.OpMIPS64ORconst,
|
||||
ssa.OpMIPS64XORconst,
|
||||
ssa.OpMIPS64NORconst,
|
||||
ssa.OpMIPS64SLLVconst,
|
||||
ssa.OpMIPS64SRLVconst,
|
||||
ssa.OpMIPS64SRAVconst,
|
||||
|
||||
@@ -773,6 +773,9 @@
|
||||
(SUBF (NEGF (MULF x y)) z) && z.Block.Func.useFMA(v) => (FNMADDF x y z)
|
||||
(SUBD (NEGD (MULD x y)) z) && z.Block.Func.useFMA(v) => (FNMADDD x y z)
|
||||
|
||||
// Absorb conversion between 32 bit and 64 bit if both src and dst are 32 bit.
|
||||
(MOVDF ((ABS|SQRT)D (MOVFD x))) => ((ABS|SQRT)F x)
|
||||
|
||||
// generic simplifications
|
||||
(ADDV x (NEGV y)) => (SUBV x y)
|
||||
(SUBV x (NEGV y)) => (ADDV x y)
|
||||
|
||||
@@ -169,6 +169,7 @@ func init() {
|
||||
{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
|
||||
{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
|
||||
|
||||
{name: "ABSF", argLength: 1, reg: fp11, asm: "ABSF"}, // abs(arg0), float32
|
||||
{name: "ABSD", argLength: 1, reg: fp11, asm: "ABSD"}, // abs(arg0), float64
|
||||
|
||||
{name: "CLZW", argLength: 1, reg: gp11, asm: "CLZW"}, // Count leading (high order) zeroes (returns 0-32)
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
(Neg(32|16|8) ...) => (NEG ...)
|
||||
(Neg(32|64)F ...) => (NEG(F|D) ...)
|
||||
|
||||
(Com(32|16|8) x) => (NORconst [0] x)
|
||||
(Com(32|16|8) x) => (NOR (MOVWconst [0]) x)
|
||||
|
||||
(Sqrt ...) => (SQRTD ...)
|
||||
(Sqrt32 ...) => (SQRTF ...)
|
||||
@@ -382,7 +382,7 @@
|
||||
(OR <typ.UInt32> (SLL <typ.UInt32> (ZeroExt8to32 val)
|
||||
(SLLconst <typ.UInt32> [3]
|
||||
(ANDconst <typ.UInt32> [3] ptr)))
|
||||
(NORconst [0] <typ.UInt32> (SLL <typ.UInt32>
|
||||
(NOR (MOVWconst [0]) <typ.UInt32> (SLL <typ.UInt32>
|
||||
(MOVWconst [0xff]) (SLLconst <typ.UInt32> [3]
|
||||
(ANDconst <typ.UInt32> [3] ptr))))) mem)
|
||||
|
||||
@@ -401,7 +401,7 @@
|
||||
(SLLconst <typ.UInt32> [3]
|
||||
(ANDconst <typ.UInt32> [3]
|
||||
(XORconst <typ.UInt32> [3] ptr))))
|
||||
(NORconst [0] <typ.UInt32> (SLL <typ.UInt32>
|
||||
(NOR (MOVWconst [0]) <typ.UInt32> (SLL <typ.UInt32>
|
||||
(MOVWconst [0xff]) (SLLconst <typ.UInt32> [3]
|
||||
(ANDconst <typ.UInt32> [3]
|
||||
(XORconst <typ.UInt32> [3] ptr)))))) mem)
|
||||
@@ -599,7 +599,6 @@
|
||||
(AND x (MOVWconst [c])) => (ANDconst [c] x)
|
||||
(OR x (MOVWconst [c])) => (ORconst [c] x)
|
||||
(XOR x (MOVWconst [c])) => (XORconst [c] x)
|
||||
(NOR x (MOVWconst [c])) => (NORconst [c] x)
|
||||
|
||||
(SLL x (MOVWconst [c])) => (SLLconst x [c&31])
|
||||
(SRL x (MOVWconst [c])) => (SRLconst x [c&31])
|
||||
@@ -648,7 +647,6 @@
|
||||
(ORconst [0] x) => x
|
||||
(ORconst [-1] _) => (MOVWconst [-1])
|
||||
(XORconst [0] x) => x
|
||||
(XORconst [-1] x) => (NORconst [0] x)
|
||||
|
||||
// generic constant folding
|
||||
(ADDconst [c] (MOVWconst [d])) => (MOVWconst [int32(c+d)])
|
||||
@@ -673,7 +671,6 @@
|
||||
(ORconst [c] (ORconst [d] x)) => (ORconst [c|d] x)
|
||||
(XORconst [c] (MOVWconst [d])) => (MOVWconst [c^d])
|
||||
(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x)
|
||||
(NORconst [c] (MOVWconst [d])) => (MOVWconst [^(c|d)])
|
||||
(NEG (MOVWconst [c])) => (MOVWconst [-c])
|
||||
(MOVBreg (MOVWconst [c])) => (MOVWconst [int32(int8(c))])
|
||||
(MOVBUreg (MOVWconst [c])) => (MOVWconst [int32(uint8(c))])
|
||||
|
||||
@@ -433,7 +433,7 @@
|
||||
(OR <typ.UInt64> (SLLV <typ.UInt32> (ZeroExt8to32 val)
|
||||
(SLLVconst <typ.UInt64> [3]
|
||||
(ANDconst <typ.UInt64> [3] ptr)))
|
||||
(NORconst [0] <typ.UInt64> (SLLV <typ.UInt64>
|
||||
(NOR (MOVVconst [0]) <typ.UInt64> (SLLV <typ.UInt64>
|
||||
(MOVVconst [0xff]) (SLLVconst <typ.UInt64> [3]
|
||||
(ANDconst <typ.UInt64> [3] ptr))))) mem)
|
||||
|
||||
@@ -452,7 +452,7 @@
|
||||
(SLLVconst <typ.UInt64> [3]
|
||||
(ANDconst <typ.UInt64> [3]
|
||||
(XORconst <typ.UInt64> [3] ptr))))
|
||||
(NORconst [0] <typ.UInt64> (SLLV <typ.UInt64>
|
||||
(NOR (MOVVconst [0]) <typ.UInt64> (SLLV <typ.UInt64>
|
||||
(MOVVconst [0xff]) (SLLVconst <typ.UInt64> [3]
|
||||
(ANDconst <typ.UInt64> [3]
|
||||
(XORconst <typ.UInt64> [3] ptr)))))) mem)
|
||||
@@ -668,7 +668,6 @@
|
||||
(AND x (MOVVconst [c])) && is32Bit(c) => (ANDconst [c] x)
|
||||
(OR x (MOVVconst [c])) && is32Bit(c) => (ORconst [c] x)
|
||||
(XOR x (MOVVconst [c])) && is32Bit(c) => (XORconst [c] x)
|
||||
(NOR x (MOVVconst [c])) && is32Bit(c) => (NORconst [c] x)
|
||||
|
||||
(SLLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
|
||||
(SRLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
|
||||
@@ -711,7 +710,6 @@
|
||||
(ORconst [0] x) => x
|
||||
(ORconst [-1] _) => (MOVVconst [-1])
|
||||
(XORconst [0] x) => x
|
||||
(XORconst [-1] x) => (NORconst [0] x)
|
||||
|
||||
// generic constant folding
|
||||
(ADDVconst [c] (MOVVconst [d])) => (MOVVconst [c+d])
|
||||
@@ -734,7 +732,6 @@
|
||||
(ORconst [c] (ORconst [d] x)) && is32Bit(c|d) => (ORconst [c|d] x)
|
||||
(XORconst [c] (MOVVconst [d])) => (MOVVconst [c^d])
|
||||
(XORconst [c] (XORconst [d] x)) && is32Bit(c^d) => (XORconst [c^d] x)
|
||||
(NORconst [c] (MOVVconst [d])) => (MOVVconst [^(c|d)])
|
||||
(NEGV (MOVVconst [c])) => (MOVVconst [-c])
|
||||
(MOVBreg (MOVVconst [c])) => (MOVVconst [int64(int8(c))])
|
||||
(MOVBUreg (MOVVconst [c])) => (MOVVconst [int64(uint8(c))])
|
||||
|
||||
@@ -189,7 +189,6 @@ func init() {
|
||||
{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, typ: "UInt64"}, // arg0 ^ arg1
|
||||
{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", typ: "UInt64"}, // arg0 ^ auxInt
|
||||
{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true}, // ^(arg0 | arg1)
|
||||
{name: "NORconst", argLength: 1, reg: gp11, asm: "NOR", aux: "Int64"}, // ^(arg0 | auxInt)
|
||||
|
||||
{name: "NEGV", argLength: 1, reg: gp11}, // -arg0
|
||||
{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"}, // -arg0, float32
|
||||
|
||||
@@ -173,7 +173,6 @@ func init() {
|
||||
{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, typ: "UInt32"}, // arg0 ^ arg1
|
||||
{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int32", typ: "UInt32"}, // arg0 ^ auxInt
|
||||
{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true}, // ^(arg0 | arg1)
|
||||
{name: "NORconst", argLength: 1, reg: gp11, asm: "NOR", aux: "Int32"}, // ^(arg0 | auxInt)
|
||||
|
||||
{name: "NEG", argLength: 1, reg: gp11}, // -arg0
|
||||
{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"}, // -arg0, float32
|
||||
|
||||
@@ -28,16 +28,16 @@ func simdAMD64Ops(v11, v21, v2k, vkv, v2kv, v2kk, v31, v3kv, vgpv, vgp, vfpv, vf
|
||||
{name: "VADDSUBPS128", argLength: 2, reg: v21, asm: "VADDSUBPS", commutative: false, typ: "Vec128", resultInArg0: false},
|
||||
{name: "VADDSUBPS256", argLength: 2, reg: v21, asm: "VADDSUBPS", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESDEC128", argLength: 2, reg: v21, asm: "VAESDEC", commutative: false, typ: "Vec128", resultInArg0: false},
|
||||
{name: "VAESDEC256", argLength: 2, reg: w21, asm: "VAESDEC", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESDEC256", argLength: 2, reg: v21, asm: "VAESDEC", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESDEC512", argLength: 2, reg: w21, asm: "VAESDEC", commutative: false, typ: "Vec512", resultInArg0: false},
|
||||
{name: "VAESDECLAST128", argLength: 2, reg: v21, asm: "VAESDECLAST", commutative: false, typ: "Vec128", resultInArg0: false},
|
||||
{name: "VAESDECLAST256", argLength: 2, reg: w21, asm: "VAESDECLAST", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESDECLAST256", argLength: 2, reg: v21, asm: "VAESDECLAST", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESDECLAST512", argLength: 2, reg: w21, asm: "VAESDECLAST", commutative: false, typ: "Vec512", resultInArg0: false},
|
||||
{name: "VAESENC128", argLength: 2, reg: v21, asm: "VAESENC", commutative: false, typ: "Vec128", resultInArg0: false},
|
||||
{name: "VAESENC256", argLength: 2, reg: w21, asm: "VAESENC", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESENC256", argLength: 2, reg: v21, asm: "VAESENC", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESENC512", argLength: 2, reg: w21, asm: "VAESENC", commutative: false, typ: "Vec512", resultInArg0: false},
|
||||
{name: "VAESENCLAST128", argLength: 2, reg: v21, asm: "VAESENCLAST", commutative: false, typ: "Vec128", resultInArg0: false},
|
||||
{name: "VAESENCLAST256", argLength: 2, reg: w21, asm: "VAESENCLAST", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESENCLAST256", argLength: 2, reg: v21, asm: "VAESENCLAST", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
{name: "VAESENCLAST512", argLength: 2, reg: w21, asm: "VAESENCLAST", commutative: false, typ: "Vec512", resultInArg0: false},
|
||||
{name: "VAESIMC128", argLength: 1, reg: v11, asm: "VAESIMC", commutative: false, typ: "Vec128", resultInArg0: false},
|
||||
{name: "VBROADCASTSD256", argLength: 1, reg: v11, asm: "VBROADCASTSD", commutative: false, typ: "Vec256", resultInArg0: false},
|
||||
|
||||
@@ -4486,6 +4486,7 @@ const (
|
||||
OpLOONG64NEGD
|
||||
OpLOONG64SQRTD
|
||||
OpLOONG64SQRTF
|
||||
OpLOONG64ABSF
|
||||
OpLOONG64ABSD
|
||||
OpLOONG64CLZW
|
||||
OpLOONG64CLZV
|
||||
@@ -4709,7 +4710,6 @@ const (
|
||||
OpMIPSXOR
|
||||
OpMIPSXORconst
|
||||
OpMIPSNOR
|
||||
OpMIPSNORconst
|
||||
OpMIPSNEG
|
||||
OpMIPSNEGF
|
||||
OpMIPSNEGD
|
||||
@@ -4825,7 +4825,6 @@ const (
|
||||
OpMIPS64XOR
|
||||
OpMIPS64XORconst
|
||||
OpMIPS64NOR
|
||||
OpMIPS64NORconst
|
||||
OpMIPS64NEGV
|
||||
OpMIPS64NEGF
|
||||
OpMIPS64NEGD
|
||||
@@ -21199,11 +21198,11 @@ var opcodeTable = [...]opInfo{
|
||||
asm: x86.AVAESDEC,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{1, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
|
||||
{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 281472829161472}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -21241,11 +21240,11 @@ var opcodeTable = [...]opInfo{
|
||||
asm: x86.AVAESDECLAST,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{1, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
|
||||
{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 281472829161472}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -21283,11 +21282,11 @@ var opcodeTable = [...]opInfo{
|
||||
asm: x86.AVAESENC,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{1, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
|
||||
{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 281472829161472}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -21325,11 +21324,11 @@ var opcodeTable = [...]opInfo{
|
||||
asm: x86.AVAESENCLAST,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{1, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
|
||||
{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 281472829161472}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
|
||||
{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -69672,6 +69671,19 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ABSF",
|
||||
argLen: 1,
|
||||
asm: loong64.AABSF,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ABSD",
|
||||
argLen: 1,
|
||||
@@ -72738,20 +72750,6 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NORconst",
|
||||
auxType: auxInt32,
|
||||
argLen: 1,
|
||||
asm: mips.ANOR,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 335544318}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NEG",
|
||||
argLen: 1,
|
||||
@@ -74276,20 +74274,6 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NORconst",
|
||||
auxType: auxInt64,
|
||||
argLen: 1,
|
||||
asm: mips.ANOR,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NEGV",
|
||||
argLen: 1,
|
||||
|
||||
@@ -360,6 +360,8 @@ func rewriteValueLOONG64(v *Value) bool {
|
||||
return rewriteValueLOONG64_OpLOONG64MOVBstore(v)
|
||||
case OpLOONG64MOVBstoreidx:
|
||||
return rewriteValueLOONG64_OpLOONG64MOVBstoreidx(v)
|
||||
case OpLOONG64MOVDF:
|
||||
return rewriteValueLOONG64_OpLOONG64MOVDF(v)
|
||||
case OpLOONG64MOVDload:
|
||||
return rewriteValueLOONG64_OpLOONG64MOVDload(v)
|
||||
case OpLOONG64MOVDloadidx:
|
||||
@@ -3182,6 +3184,40 @@ func rewriteValueLOONG64_OpLOONG64MOVBstoreidx(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueLOONG64_OpLOONG64MOVDF(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (MOVDF (ABSD (MOVFD x)))
|
||||
// result: (ABSF x)
|
||||
for {
|
||||
if v_0.Op != OpLOONG64ABSD {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64MOVFD {
|
||||
break
|
||||
}
|
||||
x := v_0_0.Args[0]
|
||||
v.reset(OpLOONG64ABSF)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDF (SQRTD (MOVFD x)))
|
||||
// result: (SQRTF x)
|
||||
for {
|
||||
if v_0.Op != OpLOONG64SQRTD {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64MOVFD {
|
||||
break
|
||||
}
|
||||
x := v_0_0.Args[0]
|
||||
v.reset(OpLOONG64SQRTF)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
|
||||
@@ -333,10 +333,6 @@ func rewriteValueMIPS(v *Value) bool {
|
||||
return rewriteValueMIPS_OpMIPSMUL(v)
|
||||
case OpMIPSNEG:
|
||||
return rewriteValueMIPS_OpMIPSNEG(v)
|
||||
case OpMIPSNOR:
|
||||
return rewriteValueMIPS_OpMIPSNOR(v)
|
||||
case OpMIPSNORconst:
|
||||
return rewriteValueMIPS_OpMIPSNORconst(v)
|
||||
case OpMIPSOR:
|
||||
return rewriteValueMIPS_OpMIPSOR(v)
|
||||
case OpMIPSORconst:
|
||||
@@ -654,7 +650,7 @@ func rewriteValueMIPS_OpAtomicAnd8(v *Value) bool {
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (AtomicAnd8 ptr val mem)
|
||||
// cond: !config.BigEndian
|
||||
// result: (LoweredAtomicAnd (AND <typ.UInt32Ptr> (MOVWconst [^3]) ptr) (OR <typ.UInt32> (SLL <typ.UInt32> (ZeroExt8to32 val) (SLLconst <typ.UInt32> [3] (ANDconst <typ.UInt32> [3] ptr))) (NORconst [0] <typ.UInt32> (SLL <typ.UInt32> (MOVWconst [0xff]) (SLLconst <typ.UInt32> [3] (ANDconst <typ.UInt32> [3] ptr))))) mem)
|
||||
// result: (LoweredAtomicAnd (AND <typ.UInt32Ptr> (MOVWconst [^3]) ptr) (OR <typ.UInt32> (SLL <typ.UInt32> (ZeroExt8to32 val) (SLLconst <typ.UInt32> [3] (ANDconst <typ.UInt32> [3] ptr))) (NOR (MOVWconst [0]) <typ.UInt32> (SLL <typ.UInt32> (MOVWconst [0xff]) (SLLconst <typ.UInt32> [3] (ANDconst <typ.UInt32> [3] ptr))))) mem)
|
||||
for {
|
||||
ptr := v_0
|
||||
val := v_1
|
||||
@@ -678,20 +674,21 @@ func rewriteValueMIPS_OpAtomicAnd8(v *Value) bool {
|
||||
v6.AddArg(ptr)
|
||||
v5.AddArg(v6)
|
||||
v3.AddArg2(v4, v5)
|
||||
v7 := b.NewValue0(v.Pos, OpMIPSNORconst, typ.UInt32)
|
||||
v7.AuxInt = int32ToAuxInt(0)
|
||||
v8 := b.NewValue0(v.Pos, OpMIPSSLL, typ.UInt32)
|
||||
v9 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v9.AuxInt = int32ToAuxInt(0xff)
|
||||
v8.AddArg2(v9, v5)
|
||||
v7.AddArg(v8)
|
||||
v7 := b.NewValue0(v.Pos, OpMIPSNOR, typ.UInt32)
|
||||
v8 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v8.AuxInt = int32ToAuxInt(0)
|
||||
v9 := b.NewValue0(v.Pos, OpMIPSSLL, typ.UInt32)
|
||||
v10 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v10.AuxInt = int32ToAuxInt(0xff)
|
||||
v9.AddArg2(v10, v5)
|
||||
v7.AddArg2(v8, v9)
|
||||
v2.AddArg2(v3, v7)
|
||||
v.AddArg3(v0, v2, mem)
|
||||
return true
|
||||
}
|
||||
// match: (AtomicAnd8 ptr val mem)
|
||||
// cond: config.BigEndian
|
||||
// result: (LoweredAtomicAnd (AND <typ.UInt32Ptr> (MOVWconst [^3]) ptr) (OR <typ.UInt32> (SLL <typ.UInt32> (ZeroExt8to32 val) (SLLconst <typ.UInt32> [3] (ANDconst <typ.UInt32> [3] (XORconst <typ.UInt32> [3] ptr)))) (NORconst [0] <typ.UInt32> (SLL <typ.UInt32> (MOVWconst [0xff]) (SLLconst <typ.UInt32> [3] (ANDconst <typ.UInt32> [3] (XORconst <typ.UInt32> [3] ptr)))))) mem)
|
||||
// result: (LoweredAtomicAnd (AND <typ.UInt32Ptr> (MOVWconst [^3]) ptr) (OR <typ.UInt32> (SLL <typ.UInt32> (ZeroExt8to32 val) (SLLconst <typ.UInt32> [3] (ANDconst <typ.UInt32> [3] (XORconst <typ.UInt32> [3] ptr)))) (NOR (MOVWconst [0]) <typ.UInt32> (SLL <typ.UInt32> (MOVWconst [0xff]) (SLLconst <typ.UInt32> [3] (ANDconst <typ.UInt32> [3] (XORconst <typ.UInt32> [3] ptr)))))) mem)
|
||||
for {
|
||||
ptr := v_0
|
||||
val := v_1
|
||||
@@ -718,13 +715,14 @@ func rewriteValueMIPS_OpAtomicAnd8(v *Value) bool {
|
||||
v6.AddArg(v7)
|
||||
v5.AddArg(v6)
|
||||
v3.AddArg2(v4, v5)
|
||||
v8 := b.NewValue0(v.Pos, OpMIPSNORconst, typ.UInt32)
|
||||
v8.AuxInt = int32ToAuxInt(0)
|
||||
v9 := b.NewValue0(v.Pos, OpMIPSSLL, typ.UInt32)
|
||||
v10 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v10.AuxInt = int32ToAuxInt(0xff)
|
||||
v9.AddArg2(v10, v5)
|
||||
v8.AddArg(v9)
|
||||
v8 := b.NewValue0(v.Pos, OpMIPSNOR, typ.UInt32)
|
||||
v9 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v9.AuxInt = int32ToAuxInt(0)
|
||||
v10 := b.NewValue0(v.Pos, OpMIPSSLL, typ.UInt32)
|
||||
v11 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v11.AuxInt = int32ToAuxInt(0xff)
|
||||
v10.AddArg2(v11, v5)
|
||||
v8.AddArg2(v9, v10)
|
||||
v2.AddArg2(v3, v8)
|
||||
v.AddArg3(v0, v2, mem)
|
||||
return true
|
||||
@@ -869,37 +867,46 @@ func rewriteValueMIPS_OpBitLen8(v *Value) bool {
|
||||
}
|
||||
func rewriteValueMIPS_OpCom16(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Com16 x)
|
||||
// result: (NORconst [0] x)
|
||||
// result: (NOR (MOVWconst [0]) x)
|
||||
for {
|
||||
x := v_0
|
||||
v.reset(OpMIPSNORconst)
|
||||
v.AuxInt = int32ToAuxInt(0)
|
||||
v.AddArg(x)
|
||||
v.reset(OpMIPSNOR)
|
||||
v0 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v0.AuxInt = int32ToAuxInt(0)
|
||||
v.AddArg2(v0, x)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueMIPS_OpCom32(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Com32 x)
|
||||
// result: (NORconst [0] x)
|
||||
// result: (NOR (MOVWconst [0]) x)
|
||||
for {
|
||||
x := v_0
|
||||
v.reset(OpMIPSNORconst)
|
||||
v.AuxInt = int32ToAuxInt(0)
|
||||
v.AddArg(x)
|
||||
v.reset(OpMIPSNOR)
|
||||
v0 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v0.AuxInt = int32ToAuxInt(0)
|
||||
v.AddArg2(v0, x)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueMIPS_OpCom8(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Com8 x)
|
||||
// result: (NORconst [0] x)
|
||||
// result: (NOR (MOVWconst [0]) x)
|
||||
for {
|
||||
x := v_0
|
||||
v.reset(OpMIPSNORconst)
|
||||
v.AuxInt = int32ToAuxInt(0)
|
||||
v.AddArg(x)
|
||||
v.reset(OpMIPSNOR)
|
||||
v0 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32)
|
||||
v0.AuxInt = int32ToAuxInt(0)
|
||||
v.AddArg2(v0, x)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -4273,43 +4280,6 @@ func rewriteValueMIPS_OpMIPSNEG(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueMIPS_OpMIPSNOR(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (NOR x (MOVWconst [c]))
|
||||
// result: (NORconst [c] x)
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
x := v_0
|
||||
if v_1.Op != OpMIPSMOVWconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt32(v_1.AuxInt)
|
||||
v.reset(OpMIPSNORconst)
|
||||
v.AuxInt = int32ToAuxInt(c)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueMIPS_OpMIPSNORconst(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (NORconst [c] (MOVWconst [d]))
|
||||
// result: (MOVWconst [^(c|d)])
|
||||
for {
|
||||
c := auxIntToInt32(v.AuxInt)
|
||||
if v_0.Op != OpMIPSMOVWconst {
|
||||
break
|
||||
}
|
||||
d := auxIntToInt32(v_0.AuxInt)
|
||||
v.reset(OpMIPSMOVWconst)
|
||||
v.AuxInt = int32ToAuxInt(^(c | d))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueMIPS_OpMIPSOR(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
@@ -5046,18 +5016,6 @@ func rewriteValueMIPS_OpMIPSXORconst(v *Value) bool {
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
// match: (XORconst [-1] x)
|
||||
// result: (NORconst [0] x)
|
||||
for {
|
||||
if auxIntToInt32(v.AuxInt) != -1 {
|
||||
break
|
||||
}
|
||||
x := v_0
|
||||
v.reset(OpMIPSNORconst)
|
||||
v.AuxInt = int32ToAuxInt(0)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (XORconst [c] (MOVWconst [d]))
|
||||
// result: (MOVWconst [c^d])
|
||||
for {
|
||||
|
||||
@@ -370,10 +370,6 @@ func rewriteValueMIPS64(v *Value) bool {
|
||||
return rewriteValueMIPS64_OpMIPS64MOVWstore(v)
|
||||
case OpMIPS64NEGV:
|
||||
return rewriteValueMIPS64_OpMIPS64NEGV(v)
|
||||
case OpMIPS64NOR:
|
||||
return rewriteValueMIPS64_OpMIPS64NOR(v)
|
||||
case OpMIPS64NORconst:
|
||||
return rewriteValueMIPS64_OpMIPS64NORconst(v)
|
||||
case OpMIPS64OR:
|
||||
return rewriteValueMIPS64_OpMIPS64OR(v)
|
||||
case OpMIPS64ORconst:
|
||||
@@ -719,7 +715,7 @@ func rewriteValueMIPS64_OpAtomicAnd8(v *Value) bool {
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (AtomicAnd8 ptr val mem)
|
||||
// cond: !config.BigEndian
|
||||
// result: (LoweredAtomicAnd32 (AND <typ.UInt32Ptr> (MOVVconst [^3]) ptr) (OR <typ.UInt64> (SLLV <typ.UInt32> (ZeroExt8to32 val) (SLLVconst <typ.UInt64> [3] (ANDconst <typ.UInt64> [3] ptr))) (NORconst [0] <typ.UInt64> (SLLV <typ.UInt64> (MOVVconst [0xff]) (SLLVconst <typ.UInt64> [3] (ANDconst <typ.UInt64> [3] ptr))))) mem)
|
||||
// result: (LoweredAtomicAnd32 (AND <typ.UInt32Ptr> (MOVVconst [^3]) ptr) (OR <typ.UInt64> (SLLV <typ.UInt32> (ZeroExt8to32 val) (SLLVconst <typ.UInt64> [3] (ANDconst <typ.UInt64> [3] ptr))) (NOR (MOVVconst [0]) <typ.UInt64> (SLLV <typ.UInt64> (MOVVconst [0xff]) (SLLVconst <typ.UInt64> [3] (ANDconst <typ.UInt64> [3] ptr))))) mem)
|
||||
for {
|
||||
ptr := v_0
|
||||
val := v_1
|
||||
@@ -743,20 +739,21 @@ func rewriteValueMIPS64_OpAtomicAnd8(v *Value) bool {
|
||||
v6.AddArg(ptr)
|
||||
v5.AddArg(v6)
|
||||
v3.AddArg2(v4, v5)
|
||||
v7 := b.NewValue0(v.Pos, OpMIPS64NORconst, typ.UInt64)
|
||||
v7.AuxInt = int64ToAuxInt(0)
|
||||
v8 := b.NewValue0(v.Pos, OpMIPS64SLLV, typ.UInt64)
|
||||
v9 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
|
||||
v9.AuxInt = int64ToAuxInt(0xff)
|
||||
v8.AddArg2(v9, v5)
|
||||
v7.AddArg(v8)
|
||||
v7 := b.NewValue0(v.Pos, OpMIPS64NOR, typ.UInt64)
|
||||
v8 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
|
||||
v8.AuxInt = int64ToAuxInt(0)
|
||||
v9 := b.NewValue0(v.Pos, OpMIPS64SLLV, typ.UInt64)
|
||||
v10 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
|
||||
v10.AuxInt = int64ToAuxInt(0xff)
|
||||
v9.AddArg2(v10, v5)
|
||||
v7.AddArg2(v8, v9)
|
||||
v2.AddArg2(v3, v7)
|
||||
v.AddArg3(v0, v2, mem)
|
||||
return true
|
||||
}
|
||||
// match: (AtomicAnd8 ptr val mem)
|
||||
// cond: config.BigEndian
|
||||
// result: (LoweredAtomicAnd32 (AND <typ.UInt32Ptr> (MOVVconst [^3]) ptr) (OR <typ.UInt64> (SLLV <typ.UInt32> (ZeroExt8to32 val) (SLLVconst <typ.UInt64> [3] (ANDconst <typ.UInt64> [3] (XORconst <typ.UInt64> [3] ptr)))) (NORconst [0] <typ.UInt64> (SLLV <typ.UInt64> (MOVVconst [0xff]) (SLLVconst <typ.UInt64> [3] (ANDconst <typ.UInt64> [3] (XORconst <typ.UInt64> [3] ptr)))))) mem)
|
||||
// result: (LoweredAtomicAnd32 (AND <typ.UInt32Ptr> (MOVVconst [^3]) ptr) (OR <typ.UInt64> (SLLV <typ.UInt32> (ZeroExt8to32 val) (SLLVconst <typ.UInt64> [3] (ANDconst <typ.UInt64> [3] (XORconst <typ.UInt64> [3] ptr)))) (NOR (MOVVconst [0]) <typ.UInt64> (SLLV <typ.UInt64> (MOVVconst [0xff]) (SLLVconst <typ.UInt64> [3] (ANDconst <typ.UInt64> [3] (XORconst <typ.UInt64> [3] ptr)))))) mem)
|
||||
for {
|
||||
ptr := v_0
|
||||
val := v_1
|
||||
@@ -783,13 +780,14 @@ func rewriteValueMIPS64_OpAtomicAnd8(v *Value) bool {
|
||||
v6.AddArg(v7)
|
||||
v5.AddArg(v6)
|
||||
v3.AddArg2(v4, v5)
|
||||
v8 := b.NewValue0(v.Pos, OpMIPS64NORconst, typ.UInt64)
|
||||
v8.AuxInt = int64ToAuxInt(0)
|
||||
v9 := b.NewValue0(v.Pos, OpMIPS64SLLV, typ.UInt64)
|
||||
v10 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
|
||||
v10.AuxInt = int64ToAuxInt(0xff)
|
||||
v9.AddArg2(v10, v5)
|
||||
v8.AddArg(v9)
|
||||
v8 := b.NewValue0(v.Pos, OpMIPS64NOR, typ.UInt64)
|
||||
v9 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
|
||||
v9.AuxInt = int64ToAuxInt(0)
|
||||
v10 := b.NewValue0(v.Pos, OpMIPS64SLLV, typ.UInt64)
|
||||
v11 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64)
|
||||
v11.AuxInt = int64ToAuxInt(0xff)
|
||||
v10.AddArg2(v11, v5)
|
||||
v8.AddArg2(v9, v10)
|
||||
v2.AddArg2(v3, v8)
|
||||
v.AddArg3(v0, v2, mem)
|
||||
return true
|
||||
@@ -4526,47 +4524,6 @@ func rewriteValueMIPS64_OpMIPS64NEGV(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueMIPS64_OpMIPS64NOR(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (NOR x (MOVVconst [c]))
|
||||
// cond: is32Bit(c)
|
||||
// result: (NORconst [c] x)
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
x := v_0
|
||||
if v_1.Op != OpMIPS64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
if !(is32Bit(c)) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpMIPS64NORconst)
|
||||
v.AuxInt = int64ToAuxInt(c)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueMIPS64_OpMIPS64NORconst(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (NORconst [c] (MOVVconst [d]))
|
||||
// result: (MOVVconst [^(c|d)])
|
||||
for {
|
||||
c := auxIntToInt64(v.AuxInt)
|
||||
if v_0.Op != OpMIPS64MOVVconst {
|
||||
break
|
||||
}
|
||||
d := auxIntToInt64(v_0.AuxInt)
|
||||
v.reset(OpMIPS64MOVVconst)
|
||||
v.AuxInt = int64ToAuxInt(^(c | d))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueMIPS64_OpMIPS64OR(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
@@ -5305,18 +5262,6 @@ func rewriteValueMIPS64_OpMIPS64XORconst(v *Value) bool {
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
// match: (XORconst [-1] x)
|
||||
// result: (NORconst [0] x)
|
||||
for {
|
||||
if auxIntToInt64(v.AuxInt) != -1 {
|
||||
break
|
||||
}
|
||||
x := v_0
|
||||
v.reset(OpMIPS64NORconst)
|
||||
v.AuxInt = int64ToAuxInt(0)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (XORconst [c] (MOVVconst [d]))
|
||||
// result: (MOVVconst [c^d])
|
||||
for {
|
||||
|
||||
@@ -23,7 +23,7 @@ func cheapComputableIndex(width int64) bool {
|
||||
// MIPS does not have R+R addressing
|
||||
// Arm64 may lack ability to generate this code in our assembler,
|
||||
// but the architecture supports it.
|
||||
case sys.PPC64, sys.S390X:
|
||||
case sys.Loong64, sys.PPC64, sys.S390X:
|
||||
return width == 1
|
||||
case sys.AMD64, sys.I386, sys.ARM64, sys.ARM:
|
||||
switch width {
|
||||
|
||||
@@ -980,10 +980,6 @@ const maxSessionTicketLifetime = 7 * 24 * time.Hour
|
||||
|
||||
// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a [Config] that is
|
||||
// being used concurrently by a TLS client or server.
|
||||
//
|
||||
// If Config.SessionTicketKey is unpopulated, and Config.SetSessionTicketKeys has not been
|
||||
// called, the clone will not share the same auto-rotated session ticket keys as the original
|
||||
// Config in order to prevent sessions from being resumed across Configs.
|
||||
func (c *Config) Clone() *Config {
|
||||
if c == nil {
|
||||
return nil
|
||||
@@ -1024,8 +1020,7 @@ func (c *Config) Clone() *Config {
|
||||
EncryptedClientHelloRejectionVerify: c.EncryptedClientHelloRejectionVerify,
|
||||
EncryptedClientHelloKeys: c.EncryptedClientHelloKeys,
|
||||
sessionTicketKeys: c.sessionTicketKeys,
|
||||
// We explicitly do not copy autoSessionTicketKeys, so that Configs do
|
||||
// not share the same auto-rotated keys.
|
||||
autoSessionTicketKeys: c.autoSessionTicketKeys,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1851,3 +1846,31 @@ func fipsAllowChain(chain []*x509.Certificate) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// anyValidVerifiedChain reports if at least one of the chains in verifiedChains
|
||||
// is valid, as indicated by none of the certificates being expired and the root
|
||||
// being in opts.Roots (or in the system root pool if opts.Roots is nil). If
|
||||
// verifiedChains is empty, it returns false.
|
||||
func anyValidVerifiedChain(verifiedChains [][]*x509.Certificate, opts x509.VerifyOptions) bool {
|
||||
for _, chain := range verifiedChains {
|
||||
if len(chain) == 0 {
|
||||
continue
|
||||
}
|
||||
if slices.ContainsFunc(chain, func(cert *x509.Certificate) bool {
|
||||
return opts.CurrentTime.Before(cert.NotBefore) || opts.CurrentTime.After(cert.NotAfter)
|
||||
}) {
|
||||
continue
|
||||
}
|
||||
// Since we already validated the chain, we only care that it is
|
||||
// rooted in a CA in CAs, or in the system pool. On platforms where
|
||||
// we control chain validation (e.g. not Windows or macOS) this is a
|
||||
// simple lookup in the CertPool internal hash map. On other
|
||||
// platforms, this may be more expensive, depending on how they
|
||||
// implement verification of just root certificates.
|
||||
root := chain[len(chain)-1]
|
||||
if _, err := root.Verify(opts); err == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -397,9 +397,6 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
|
||||
// Check that the cached server certificate is not expired, and that it's
|
||||
// valid for the ServerName. This should be ensured by the cache key, but
|
||||
// protect the application from a faulty ClientSessionCache implementation.
|
||||
if c.config.time().After(session.peerCertificates[0].NotAfter) {
|
||||
// Expired certificate, delete the entry.
|
||||
c.config.ClientSessionCache.Put(cacheKey, nil)
|
||||
@@ -411,6 +408,18 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
if err := session.peerCertificates[0].VerifyHostname(c.config.ServerName); err != nil {
|
||||
// This should be ensured by the cache key, but protect the
|
||||
// application from a faulty ClientSessionCache implementation.
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
opts := x509.VerifyOptions{
|
||||
CurrentTime: c.config.time(),
|
||||
Roots: c.config.RootCAs,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
if !anyValidVerifiedChain(session.verifiedChains, opts) {
|
||||
// No valid chains, delete the entry.
|
||||
c.config.ClientSessionCache.Put(cacheKey, nil)
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,16 +520,16 @@ func (hs *serverHandshakeState) checkForResumption() error {
|
||||
if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
|
||||
return nil
|
||||
}
|
||||
if sessionHasClientCerts {
|
||||
now := c.config.time()
|
||||
for _, c := range sessionState.peerCertificates {
|
||||
if now.After(c.NotAfter) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
|
||||
return nil
|
||||
}
|
||||
opts := x509.VerifyOptions{
|
||||
CurrentTime: c.config.time(),
|
||||
Roots: c.config.ClientCAs,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
|
||||
len(sessionState.verifiedChains) == 0 {
|
||||
!anyValidVerifiedChain(sessionState.verifiedChains, opts) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -2155,7 +2155,7 @@ func TestHandshakeContextHierarchy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandshakeChainExpiryResumptionTLS12(t *testing.T) {
|
||||
func TestHandshakeChainExpiryResumption(t *testing.T) {
|
||||
t.Run("TLS1.2", func(t *testing.T) {
|
||||
testHandshakeChainExpiryResumption(t, VersionTLS12)
|
||||
})
|
||||
@@ -2166,7 +2166,8 @@ func TestHandshakeChainExpiryResumptionTLS12(t *testing.T) {
|
||||
|
||||
func testHandshakeChainExpiryResumption(t *testing.T, version uint16) {
|
||||
now := time.Now()
|
||||
createChain := func(leafNotAfter, rootNotAfter time.Time) (certDER []byte, root *x509.Certificate) {
|
||||
|
||||
createChain := func(leafNotAfter, rootNotAfter time.Time) (leafDER, expiredLeafDER []byte, root *x509.Certificate) {
|
||||
tmpl := &x509.Certificate{
|
||||
Subject: pkix.Name{CommonName: "root"},
|
||||
NotBefore: rootNotAfter.Add(-time.Hour * 24),
|
||||
@@ -2190,39 +2191,177 @@ func testHandshakeChainExpiryResumption(t *testing.T, version uint16) {
|
||||
NotAfter: leafNotAfter,
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
certDER, err = x509.CreateCertificate(rand.Reader, tmpl, root, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
leafCertDER, err := x509.CreateCertificate(rand.Reader, tmpl, root, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
tmpl.NotBefore, tmpl.NotAfter = leafNotAfter.Add(-time.Hour*24*365), leafNotAfter.Add(-time.Hour*24*364)
|
||||
expiredLeafDERCertDER, err := x509.CreateCertificate(rand.Reader, tmpl, root, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
|
||||
return certDER, root
|
||||
return leafCertDER, expiredLeafDERCertDER, root
|
||||
}
|
||||
testExpiration := func(name string, leafNotAfter, rootNotAfter time.Time) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
initialLeafDER, expiredLeafDER, initialRoot := createChain(leafNotAfter, rootNotAfter)
|
||||
|
||||
serverConfig := testConfig.Clone()
|
||||
serverConfig.MaxVersion = version
|
||||
serverConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{initialLeafDER, expiredLeafDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(initialRoot)
|
||||
serverConfig.ClientAuth = RequireAndVerifyClientCert
|
||||
serverConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
serverConfig.InsecureSkipVerify = false
|
||||
serverConfig.ServerName = "expired-resume.example.com"
|
||||
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.MaxVersion = version
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{initialLeafDER, expiredLeafDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(initialRoot)
|
||||
clientConfig.ServerName = "expired-resume.example.com"
|
||||
clientConfig.ClientSessionCache = NewLRUClientSessionCache(32)
|
||||
clientConfig.InsecureSkipVerify = false
|
||||
clientConfig.ServerName = "expired-resume.example.com"
|
||||
clientConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
|
||||
testResume := func(t *testing.T, sc, cc *Config, expectResume bool) {
|
||||
t.Helper()
|
||||
ss, cs, err := testHandshake(t, cc, sc)
|
||||
if err != nil {
|
||||
t.Fatalf("handshake: %v", err)
|
||||
}
|
||||
if cs.DidResume != expectResume {
|
||||
t.Fatalf("DidResume = %v; want %v", cs.DidResume, expectResume)
|
||||
}
|
||||
if ss.DidResume != expectResume {
|
||||
t.Fatalf("DidResume = %v; want %v", cs.DidResume, expectResume)
|
||||
}
|
||||
}
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
|
||||
expiredNow := time.Unix(0, min(leafNotAfter.UnixNano(), rootNotAfter.UnixNano())).Add(time.Minute)
|
||||
|
||||
freshLeafDER, expiredLeafDER, freshRoot := createChain(expiredNow.Add(time.Hour), expiredNow.Add(time.Hour))
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{freshLeafDER, expiredLeafDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
serverConfig.Time = func() time.Time {
|
||||
return expiredNow
|
||||
}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(freshRoot)
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
})
|
||||
}
|
||||
|
||||
initialLeafDER, initialRoot := createChain(now.Add(time.Hour), now.Add(2*time.Hour))
|
||||
testExpiration("LeafExpiresBeforeRoot", now.Add(2*time.Hour), now.Add(3*time.Hour))
|
||||
testExpiration("LeafExpiresAfterRoot", now.Add(2*time.Hour), now.Add(time.Hour))
|
||||
}
|
||||
|
||||
func TestHandshakeGetConfigForClientDifferentClientCAs(t *testing.T) {
|
||||
t.Run("TLS1.2", func(t *testing.T) {
|
||||
testHandshakeGetConfigForClientDifferentClientCAs(t, VersionTLS12)
|
||||
})
|
||||
t.Run("TLS1.3", func(t *testing.T) {
|
||||
testHandshakeGetConfigForClientDifferentClientCAs(t, VersionTLS13)
|
||||
})
|
||||
}
|
||||
|
||||
func testHandshakeGetConfigForClientDifferentClientCAs(t *testing.T, version uint16) {
|
||||
now := time.Now()
|
||||
tmpl := &x509.Certificate{
|
||||
Subject: pkix.Name{CommonName: "root"},
|
||||
NotBefore: now.Add(-time.Hour * 24),
|
||||
NotAfter: now.Add(time.Hour * 24),
|
||||
IsCA: true,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
rootDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
rootA, err := x509.ParseCertificate(rootDER)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificate: %v", err)
|
||||
}
|
||||
rootDER, err = x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
rootB, err := x509.ParseCertificate(rootDER)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificate: %v", err)
|
||||
}
|
||||
|
||||
tmpl = &x509.Certificate{
|
||||
Subject: pkix.Name{},
|
||||
DNSNames: []string{"example.com"},
|
||||
NotBefore: now.Add(-time.Hour * 24),
|
||||
NotAfter: now.Add(time.Hour * 24),
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, rootA, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
|
||||
serverConfig := testConfig.Clone()
|
||||
serverConfig.MaxVersion = version
|
||||
serverConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{initialLeafDER},
|
||||
Certificate: [][]byte{certDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(initialRoot)
|
||||
serverConfig.ClientAuth = RequireAndVerifyClientCert
|
||||
serverConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(rootA)
|
||||
serverConfig.ClientAuth = RequireAndVerifyClientCert
|
||||
switchConfig := false
|
||||
serverConfig.GetConfigForClient = func(clientHello *ClientHelloInfo) (*Config, error) {
|
||||
if !switchConfig {
|
||||
return nil, nil
|
||||
}
|
||||
cfg := serverConfig.Clone()
|
||||
cfg.ClientCAs = x509.NewCertPool()
|
||||
cfg.ClientCAs.AddCert(rootB)
|
||||
return cfg, nil
|
||||
}
|
||||
serverConfig.InsecureSkipVerify = false
|
||||
serverConfig.ServerName = "example.com"
|
||||
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.MaxVersion = version
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{initialLeafDER},
|
||||
Certificate: [][]byte{certDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(initialRoot)
|
||||
clientConfig.ServerName = "expired-resume.example.com"
|
||||
clientConfig.ClientSessionCache = NewLRUClientSessionCache(32)
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(rootA)
|
||||
clientConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
clientConfig.InsecureSkipVerify = false
|
||||
clientConfig.ServerName = "example.com"
|
||||
|
||||
testResume := func(t *testing.T, sc, cc *Config, expectResume bool) {
|
||||
t.Helper()
|
||||
@@ -2241,16 +2380,112 @@ func testHandshakeChainExpiryResumption(t *testing.T, version uint16) {
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
|
||||
freshLeafDER, freshRoot := createChain(now.Add(2*time.Hour), now.Add(3*time.Hour))
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{freshLeafDER},
|
||||
// Cause GetConfigForClient to return a config cloned from the base config,
|
||||
// but with a different ClientCAs pool. This should cause resumption to fail.
|
||||
switchConfig = true
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
}
|
||||
|
||||
func TestHandshakeChangeRootCAsResumption(t *testing.T) {
|
||||
t.Run("TLS1.2", func(t *testing.T) {
|
||||
testHandshakeChangeRootCAsResumption(t, VersionTLS12)
|
||||
})
|
||||
t.Run("TLS1.3", func(t *testing.T) {
|
||||
testHandshakeChangeRootCAsResumption(t, VersionTLS13)
|
||||
})
|
||||
}
|
||||
|
||||
func testHandshakeChangeRootCAsResumption(t *testing.T, version uint16) {
|
||||
now := time.Now()
|
||||
tmpl := &x509.Certificate{
|
||||
Subject: pkix.Name{CommonName: "root"},
|
||||
NotBefore: now.Add(-time.Hour * 24),
|
||||
NotAfter: now.Add(time.Hour * 24),
|
||||
IsCA: true,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
rootDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
rootA, err := x509.ParseCertificate(rootDER)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificate: %v", err)
|
||||
}
|
||||
rootDER, err = x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
rootB, err := x509.ParseCertificate(rootDER)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificate: %v", err)
|
||||
}
|
||||
|
||||
tmpl = &x509.Certificate{
|
||||
Subject: pkix.Name{},
|
||||
DNSNames: []string{"example.com"},
|
||||
NotBefore: now.Add(-time.Hour * 24),
|
||||
NotAfter: now.Add(time.Hour * 24),
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, rootA, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
|
||||
serverConfig := testConfig.Clone()
|
||||
serverConfig.MaxVersion = version
|
||||
serverConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{certDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
serverConfig.Time = func() time.Time {
|
||||
return now.Add(1*time.Hour + 30*time.Minute)
|
||||
return now
|
||||
}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(freshRoot)
|
||||
serverConfig.ClientCAs.AddCert(rootA)
|
||||
serverConfig.ClientAuth = RequireAndVerifyClientCert
|
||||
serverConfig.InsecureSkipVerify = false
|
||||
serverConfig.ServerName = "example.com"
|
||||
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.MaxVersion = version
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{certDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
clientConfig.ClientSessionCache = NewLRUClientSessionCache(32)
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(rootA)
|
||||
clientConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
clientConfig.InsecureSkipVerify = false
|
||||
clientConfig.ServerName = "example.com"
|
||||
|
||||
testResume := func(t *testing.T, sc, cc *Config, expectResume bool) {
|
||||
t.Helper()
|
||||
ss, cs, err := testHandshake(t, cc, sc)
|
||||
if err != nil {
|
||||
t.Fatalf("handshake: %v", err)
|
||||
}
|
||||
if cs.DidResume != expectResume {
|
||||
t.Fatalf("DidResume = %v; want %v", cs.DidResume, expectResume)
|
||||
}
|
||||
if ss.DidResume != expectResume {
|
||||
t.Fatalf("DidResume = %v; want %v", cs.DidResume, expectResume)
|
||||
}
|
||||
}
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
|
||||
clientConfig = clientConfig.Clone()
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(rootB)
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"crypto/internal/fips140/tls13"
|
||||
"crypto/rsa"
|
||||
"crypto/tls/internal/fips140tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
@@ -314,7 +315,6 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
pskIdentityLoop:
|
||||
for i, identity := range hs.clientHello.pskIdentities {
|
||||
if i >= maxClientPSKIdentities {
|
||||
break
|
||||
@@ -367,16 +367,16 @@ pskIdentityLoop:
|
||||
if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
|
||||
continue
|
||||
}
|
||||
if sessionHasClientCerts {
|
||||
now := c.config.time()
|
||||
for _, c := range sessionState.peerCertificates {
|
||||
if now.After(c.NotAfter) {
|
||||
continue pskIdentityLoop
|
||||
}
|
||||
}
|
||||
if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
|
||||
continue
|
||||
}
|
||||
opts := x509.VerifyOptions{
|
||||
CurrentTime: c.config.time(),
|
||||
Roots: c.config.ClientCAs,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
|
||||
len(sessionState.verifiedChains) == 0 {
|
||||
!anyValidVerifiedChain(sessionState.verifiedChains, opts) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -935,8 +935,8 @@ func TestCloneNonFuncFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// Set the unexported fields related to session ticket keys, which are copied with Clone().
|
||||
c1.autoSessionTicketKeys = []ticketKey{c1.ticketKeyFromBytes(c1.SessionTicketKey)}
|
||||
c1.sessionTicketKeys = []ticketKey{c1.ticketKeyFromBytes(c1.SessionTicketKey)}
|
||||
// We explicitly don't copy autoSessionTicketKeys in Clone, so don't set it.
|
||||
|
||||
c2 := c1.Clone()
|
||||
if !reflect.DeepEqual(&c1, c2) {
|
||||
@@ -2461,12 +2461,3 @@ func (s messageOnlySigner) SignMessage(rand io.Reader, msg []byte, opts crypto.S
|
||||
digest := h.Sum(nil)
|
||||
return s.Signer.Sign(rand, digest, opts)
|
||||
}
|
||||
|
||||
func TestConfigCloneAutoSessionTicketKeys(t *testing.T) {
|
||||
orig := &Config{}
|
||||
orig.ticketKeys(nil)
|
||||
clone := orig.Clone()
|
||||
if slices.Equal(orig.autoSessionTicketKeys, clone.autoSessionTicketKeys) {
|
||||
t.Fatal("autoSessionTicketKeys slice copied in Clone")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ var X86 struct {
|
||||
HasSSSE3 bool
|
||||
HasSSE41 bool
|
||||
HasSSE42 bool
|
||||
HasVAES bool
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ const (
|
||||
cpuid_AVX512VBMI2 = 1 << 6
|
||||
cpuid_SSSE3 = 1 << 9
|
||||
cpuid_AVX512GFNI = 1 << 8
|
||||
cpuid_AVX512VAES = 1 << 9
|
||||
cpuid_VAES = 1 << 9
|
||||
cpuid_AVX512VNNI = 1 << 11
|
||||
cpuid_AVX512BITALG = 1 << 12
|
||||
cpuid_FMA = 1 << 12
|
||||
@@ -173,6 +173,7 @@ func doinit() {
|
||||
X86.HasERMS = isSet(ebx7, cpuid_ERMS)
|
||||
X86.HasADX = isSet(ebx7, cpuid_ADX)
|
||||
X86.HasSHA = isSet(ebx7, cpuid_SHA)
|
||||
X86.HasVAES = isSet(ecx7, cpuid_VAES) && X86.HasAVX
|
||||
|
||||
X86.HasAVX512F = isSet(ebx7, cpuid_AVX512F) && osSupportsAVX512
|
||||
if X86.HasAVX512F {
|
||||
@@ -185,7 +186,7 @@ func doinit() {
|
||||
X86.HasAVX512VPOPCNTDQ = isSet(ecx7, cpuid_AVX512VPOPCNTDQ)
|
||||
X86.HasAVX512VBMI = isSet(ecx7, cpuid_AVX512VBMI)
|
||||
X86.HasAVX512VBMI2 = isSet(ecx7, cpuid_AVX512VBMI2)
|
||||
X86.HasAVX512VAES = isSet(ecx7, cpuid_AVX512VAES)
|
||||
X86.HasAVX512VAES = isSet(ecx7, cpuid_VAES) && X86.HasAES && isSet(ebx7, cpuid_AVX512VL)
|
||||
X86.HasAVX512VNNI = isSet(ecx7, cpuid_AVX512VNNI)
|
||||
X86.HasAVX512VPCLMULQDQ = isSet(ecx7, cpuid_AVX512VPCLMULQDQ)
|
||||
X86.HasAVX512VBMI = isSet(ecx7, cpuid_AVX512_VBMI)
|
||||
|
||||
@@ -156,3 +156,10 @@ func TestDocs(t *testing.T) {
|
||||
fmt.Fprintf(os.Stderr, "go test -generate: doc.go already up-to-date\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadEmptySlice(t *testing.T) {
|
||||
// Test that Read does not panic when given an empty slice.
|
||||
// This should be a no-op.
|
||||
metrics.Read(nil)
|
||||
metrics.Read([]metrics.Sample{})
|
||||
}
|
||||
|
||||
@@ -43,5 +43,8 @@ func runtime_readMetrics(unsafe.Pointer, int, int)
|
||||
// Sample values with names not appearing in [All] will have their Value populated
|
||||
// as KindBad to indicate that the name is unknown.
|
||||
func Read(m []Sample) {
|
||||
if len(m) == 0 {
|
||||
return
|
||||
}
|
||||
runtime_readMetrics(unsafe.Pointer(&m[0]), len(m), cap(m))
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@ func loadXED(xedPath string) []*unify.Value {
|
||||
switch {
|
||||
case inst.RealOpcode == "N":
|
||||
return // Skip unstable instructions
|
||||
case !(strings.HasPrefix(inst.Extension, "AVX") || strings.HasPrefix(inst.Extension, "SHA") || inst.Extension == "FMA"):
|
||||
case !(strings.HasPrefix(inst.Extension, "AVX") || strings.HasPrefix(inst.Extension, "SHA") ||
|
||||
inst.Extension == "FMA" || inst.Extension == "VAES"):
|
||||
// We're only interested in AVX and SHA instructions.
|
||||
return
|
||||
}
|
||||
@@ -796,6 +797,7 @@ var cpuFeatureMap = map[string]string{
|
||||
"AVXAES": "AVXAES",
|
||||
"SHA": "SHA",
|
||||
"FMA": "FMA",
|
||||
"VAES": "VAES",
|
||||
|
||||
// AVX-512 foundational features. We combine all of these into one "AVX512" feature.
|
||||
"AVX512F": "AVX512",
|
||||
@@ -829,6 +831,7 @@ func init() {
|
||||
|
||||
"AVXAES": {Virtual: true, Implies: []string{"AVX", "AES"}},
|
||||
"FMA": {Implies: []string{"AVX"}},
|
||||
"VAES": {Implies: []string{"AVX"}},
|
||||
|
||||
// AVX-512 subfeatures.
|
||||
"AVX512BITALG": {Implies: []string{"AVX512"}},
|
||||
|
||||
@@ -158,3 +158,13 @@ func (X86Features) FMA() bool {
|
||||
func (X86Features) SHA() bool {
|
||||
return cpu.X86.HasSHA
|
||||
}
|
||||
|
||||
// VAES returns whether the CPU supports the VAES feature.
|
||||
//
|
||||
// If it returns true, then the CPU also supports AVX.
|
||||
//
|
||||
// VAES is defined on all GOARCHes, but will only return true on
|
||||
// GOARCH amd64.
|
||||
func (X86Features) VAES() bool {
|
||||
return cpu.X86.HasVAES
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func (x Uint8x16) AESDecryptLastRound(y Uint32x4) Uint8x16
|
||||
// y is the chunk of dw array in use.
|
||||
// result = AddRoundKey(InvShiftRows(InvSubBytes(x)), y)
|
||||
//
|
||||
// Asm: VAESDECLAST, CPU Feature: AVX512VAES
|
||||
// Asm: VAESDECLAST, CPU Feature: VAES
|
||||
func (x Uint8x32) AESDecryptLastRound(y Uint32x8) Uint8x32
|
||||
|
||||
// AESDecryptLastRound performs a series of operations in AES cipher algorithm defined in FIPS 197.
|
||||
@@ -45,7 +45,7 @@ func (x Uint8x16) AESDecryptOneRound(y Uint32x4) Uint8x16
|
||||
// y is the chunk of dw array in use.
|
||||
// result = AddRoundKey(InvMixColumns(InvShiftRows(InvSubBytes(x))), y)
|
||||
//
|
||||
// Asm: VAESDEC, CPU Feature: AVX512VAES
|
||||
// Asm: VAESDEC, CPU Feature: VAES
|
||||
func (x Uint8x32) AESDecryptOneRound(y Uint32x8) Uint8x32
|
||||
|
||||
// AESDecryptOneRound performs a series of operations in AES cipher algorithm defined in FIPS 197.
|
||||
@@ -71,7 +71,7 @@ func (x Uint8x16) AESEncryptLastRound(y Uint32x4) Uint8x16
|
||||
// y is the chunk of w array in use.
|
||||
// result = AddRoundKey((ShiftRows(SubBytes(x))), y)
|
||||
//
|
||||
// Asm: VAESENCLAST, CPU Feature: AVX512VAES
|
||||
// Asm: VAESENCLAST, CPU Feature: VAES
|
||||
func (x Uint8x32) AESEncryptLastRound(y Uint32x8) Uint8x32
|
||||
|
||||
// AESEncryptLastRound performs a series of operations in AES cipher algorithm defined in FIPS 197.
|
||||
@@ -97,7 +97,7 @@ func (x Uint8x16) AESEncryptOneRound(y Uint32x4) Uint8x16
|
||||
// y is the chunk of w array in use.
|
||||
// result = AddRoundKey(MixColumns(ShiftRows(SubBytes(x))), y)
|
||||
//
|
||||
// Asm: VAESENC, CPU Feature: AVX512VAES
|
||||
// Asm: VAESENC, CPU Feature: VAES
|
||||
func (x Uint8x32) AESEncryptOneRound(y Uint32x8) Uint8x32
|
||||
|
||||
// AESEncryptOneRound performs a series of operations in AES cipher algorithm defined in FIPS 197.
|
||||
|
||||
Reference in New Issue
Block a user