Compare commits

...

8 Commits

Author SHA1 Message Date
Junyang Shao
83b232b0af cmd/compile, simd: capture VAES instructions and fix AVX512VAES feature
The code previously filters out VAES-only instructions, this CL added
them back.

This CL added the VAES feature check following the Intel xed data:

  XED_ISA_SET_VAES:              vaes.7.0.ecx.9 # avx.1.0.ecx.28

This CL also found out that the old AVX512VAES feature check is not
checking the correct bits, it also fixes it:

  XED_ISA_SET_AVX512_VAES_128:    vaes.7.0.ecx.9  aes.1.0.ecx.25  avx512f.7.0.ebx.16 avx512vl.7.0.ebx.31
  XED_ISA_SET_AVX512_VAES_256:    vaes.7.0.ecx.9  aes.1.0.ecx.25  avx512f.7.0.ebx.16 avx512vl.7.0.ebx.31
  XED_ISA_SET_AVX512_VAES_512:    vaes.7.0.ecx.9  aes.1.0.ecx.25  avx512f.7.0.ebx.16

It restricts to the most strict common set - includes avx512vl for even
512-bits although it doesn't requires it.

Change-Id: I4e2f72b312fd2411589fbc12f9ee5c63c09c2e9a
Reviewed-on: https://go-review.googlesource.com/c/go/+/738500
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2026-01-28 11:06:13 -08:00
Amol Yadav
6aef900af4 runtime/metrics: fix panic in Read with empty slice
Calling Read with a nil or empty slice previously caused a panic with
"index out of range" because the function unconditionally accessed the
first element of the slice (via &m[0]) to pass the pointer to the
runtime.

This change adds a check for len(m) == 0 to return early, preventing
the panic when no samples are provided.

Fixes #77231

Change-Id: I442635f5c61de432883c8d0efae9cc6aa1363cc9
GitHub-Last-Rev: 6f24f67b18
GitHub-Pull-Request: golang/go#77233
Reviewed-on: https://go-review.googlesource.com/c/go/+/737380
Reviewed-by: Amol Yadav <amolyadav6125@gmail.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Commit-Queue: Michael Pratt <mpratt@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2026-01-28 08:44:36 -08:00
Roland Shoemaker
026fa9dc59 crypto/tls: check verifiedChains roots when resuming sessions
When resuming TLS sessions, on the server and client verify that the
chains stored in the session state (verifiedChains) are still acceptable
with regards to the Config by checking for the inclusion of the root in
either ClientCAs (server) or RootCAs (client). This prevents resuming
a session with a certificate chain that would be rejected during a full
handshake due to an untrusted root.

Updates #77113
Updates #77217
Updates CVE-2025-68121

Change-Id: I11fe00909ef1961c24ecf80bf5b97f7b1121d359
Reviewed-on: https://go-review.googlesource.com/c/go/+/737700
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Coia Prant <coiaprant@gmail.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2026-01-28 08:15:14 -08:00
Roland Shoemaker
133b339ca5 crypto/tls: add verifiedChains expiration checking during resumption
When resuming a session, check that the verifiedChains contain at least
one chain that is still valid at the time of resumption. If not, trigger
a new handshake.

Updates #77113
Updates #77217
Updates CVE-2025-68121

Change-Id: I14f585c43da17802513cbdd5b10c552d7a38b34e
Reviewed-on: https://go-review.googlesource.com/c/go/+/739321
Reviewed-by: Coia Prant <coiaprant@gmail.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2026-01-28 08:13:28 -08:00
Roland Shoemaker
4f9c3439a3 Revert "crypto/tls: don't copy auto-rotated session ticket keys in Config.Clone"
This reverts CL 736709 (commit bba24719a4).

Updates #77113
Updates CVE-2025-68121

Change-Id: I0261cb75e9adf9d0ac9890dc91ae8476b8988ba0
Reviewed-on: https://go-review.googlesource.com/c/go/+/739320
Reviewed-by: Coia Prant <coiaprant@gmail.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2026-01-28 08:12:11 -08:00
Guoqi Chen
134035855c cmd/compile: simplify slice/array range loops on loong64
loong64 supports R+R addressing ({st,ld}x.{b,h,w,d} instructions)
and has implemented the relevant lowering rules (only width is 1).

Removes 1616 instructions from the go binary on loong64.

file         before    after      Δ         %
asm          575366    575314    -52     -0.0090%
cgo          489972    489884    -88     -0.0180%
compile     2920418   2920110    -308    -0.0105%
cover        540458    540290    -168    -0.0311%
fix          865840    865668    -172    -0.0199%
link         732858    732662    -196    -0.0267%
preprofile   246022    245978    -44     -0.0179%
vet          839268    839124    -144    -0.0172%
go          1666470   1666114    -356    -0.0214%
gofmt        326526    326438    -88     -0.0270%
total       9203198   9201582    -1616   -0.0176%

Change-Id: If3518547c785764877a6cf987781d43d8b572990
Reviewed-on: https://go-review.googlesource.com/c/go/+/738240
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2026-01-28 06:42:05 -08:00
Xiaolin Zhao
f65fe3216e cmd/compile: (loong64) optimize float32(abs|sqrt64(float64(x)))
Ref: #733621
Updates #75463

Change-Id: Idd8821d1713754097a2fe83a050c25d9ec5b17eb
Reviewed-on: https://go-review.googlesource.com/c/go/+/735540
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2026-01-28 06:19:53 -08:00
Xiaolin Zhao
514790c2b9 cmd/compile: remove the NORconst op on mips{,64}
In the mips{,64} instruction sets and their extensions, there is no
NORI instruction.

Change-Id: If008442c792297d011b3d0c1e8501e62e32ab175
Reviewed-on: https://go-review.googlesource.com/c/go/+/735900
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2026-01-28 06:17:40 -08:00
28 changed files with 478 additions and 277 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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)

View File

@@ -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)

View File

@@ -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))])

View File

@@ -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))])

View File

@@ -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

View File

@@ -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

View File

@@ -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},

View File

@@ -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,

View File

@@ -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]

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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")
}
}

View File

@@ -56,6 +56,7 @@ var X86 struct {
HasSSSE3 bool
HasSSE41 bool
HasSSE42 bool
HasVAES bool
_ CacheLinePad
}

View File

@@ -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)

View File

@@ -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{})
}

View File

@@ -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))
}

View File

@@ -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"}},

View File

@@ -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
}

View File

@@ -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.