Skip to content

Commit 7e07e63

Browse files
committed
cmd/compile: implement non-constant rotates
Makes math/bits.Rotate{Left,Right} fast on amd64. name old time/op new time/op delta RotateLeft-12 7.42ns ± 6% 5.45ns ± 6% -26.54% (p=0.000 n=9+10) RotateLeft8-12 4.77ns ± 5% 3.42ns ± 7% -28.25% (p=0.000 n=8+10) RotateLeft16-12 4.82ns ± 8% 3.40ns ± 7% -29.36% (p=0.000 n=10+10) RotateLeft32-12 4.87ns ± 7% 3.48ns ± 7% -28.51% (p=0.000 n=8+9) RotateLeft64-12 5.23ns ±10% 3.35ns ± 6% -35.97% (p=0.000 n=9+10) RotateRight-12 7.59ns ± 8% 5.71ns ± 1% -24.72% (p=0.000 n=10+8) RotateRight8-12 4.98ns ± 7% 3.36ns ± 9% -32.55% (p=0.000 n=10+10) RotateRight16-12 5.12ns ± 2% 3.45ns ± 5% -32.62% (p=0.000 n=10+10) RotateRight32-12 4.80ns ± 6% 3.42ns ±16% -28.68% (p=0.000 n=10+10) RotateRight64-12 4.78ns ± 6% 3.42ns ± 6% -28.50% (p=0.000 n=10+10) Update #18940 Change-Id: Ie79fb5581c489ed4d3b859314c5e669a134c119b Reviewed-on: https://go-review.googlesource.com/39711 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Josh Bleecher Snyder <[email protected]>
1 parent 3852100 commit 7e07e63

File tree

6 files changed

+13619
-7823
lines changed

6 files changed

+13619
-7823
lines changed

src/cmd/compile/internal/amd64/ssa.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
189189
ssa.OpAMD64SHLQ, ssa.OpAMD64SHLL,
190190
ssa.OpAMD64SHRQ, ssa.OpAMD64SHRL, ssa.OpAMD64SHRW, ssa.OpAMD64SHRB,
191191
ssa.OpAMD64SARQ, ssa.OpAMD64SARL, ssa.OpAMD64SARW, ssa.OpAMD64SARB,
192+
ssa.OpAMD64ROLQ, ssa.OpAMD64ROLL, ssa.OpAMD64ROLW, ssa.OpAMD64ROLB,
193+
ssa.OpAMD64RORQ, ssa.OpAMD64RORL, ssa.OpAMD64RORW, ssa.OpAMD64RORB,
192194
ssa.OpAMD64ADDSS, ssa.OpAMD64ADDSD, ssa.OpAMD64SUBSS, ssa.OpAMD64SUBSD,
193195
ssa.OpAMD64MULSS, ssa.OpAMD64MULSD, ssa.OpAMD64DIVSS, ssa.OpAMD64DIVSD,
194196
ssa.OpAMD64PXOR:

src/cmd/compile/internal/gc/asm_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,63 @@ var linuxAMD64Tests = []*asmTest{
800800
}`,
801801
[]string{"\tCMPQ\t[A-Z]"},
802802
},
803+
// Non-constant rotate
804+
{
805+
`func rot64l(x uint64, y int) uint64 {
806+
z := uint(y & 63)
807+
return x << z | x >> (64-z)
808+
}`,
809+
[]string{"\tROLQ\t"},
810+
},
811+
{
812+
`func rot64r(x uint64, y int) uint64 {
813+
z := uint(y & 63)
814+
return x >> z | x << (64-z)
815+
}`,
816+
[]string{"\tRORQ\t"},
817+
},
818+
{
819+
`func rot32l(x uint32, y int) uint32 {
820+
z := uint(y & 31)
821+
return x << z | x >> (32-z)
822+
}`,
823+
[]string{"\tROLL\t"},
824+
},
825+
{
826+
`func rot32r(x uint32, y int) uint32 {
827+
z := uint(y & 31)
828+
return x >> z | x << (32-z)
829+
}`,
830+
[]string{"\tRORL\t"},
831+
},
832+
{
833+
`func rot16l(x uint16, y int) uint16 {
834+
z := uint(y & 15)
835+
return x << z | x >> (16-z)
836+
}`,
837+
[]string{"\tROLW\t"},
838+
},
839+
{
840+
`func rot16r(x uint16, y int) uint16 {
841+
z := uint(y & 15)
842+
return x >> z | x << (16-z)
843+
}`,
844+
[]string{"\tRORW\t"},
845+
},
846+
{
847+
`func rot8l(x uint8, y int) uint8 {
848+
z := uint(y & 7)
849+
return x << z | x >> (8-z)
850+
}`,
851+
[]string{"\tROLB\t"},
852+
},
853+
{
854+
`func rot8r(x uint8, y int) uint8 {
855+
z := uint(y & 7)
856+
return x >> z | x << (8-z)
857+
}`,
858+
[]string{"\tRORB\t"},
859+
},
803860
}
804861

805862
var linux386Tests = []*asmTest{

src/cmd/compile/internal/ssa/gen/AMD64.rules

Lines changed: 156 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -621,19 +621,60 @@
621621
(SARB x (MOVQconst [c])) -> (SARBconst [min(c&31,7)] x)
622622
(SARB x (MOVLconst [c])) -> (SARBconst [min(c&31,7)] x)
623623

624-
(SARL x (ANDLconst [31] y)) -> (SARL x y)
625-
(SARQ x (ANDQconst [63] y)) -> (SARQ x y)
626-
627-
(SHLL x (ANDLconst [31] y)) -> (SHLL x y)
628-
(SHLQ x (ANDQconst [63] y)) -> (SHLQ x y)
629-
(SHLQ x (ANDLconst [63] y)) -> (SHLQ x y)
630-
631-
(SHRL x (ANDLconst [31] y)) -> (SHRL x y)
632-
(SHRQ x (ANDQconst [63] y)) -> (SHRQ x y)
633-
(SHRQ x (ANDLconst [63] y)) -> (SHRQ x y)
634-
635-
// Rotate instructions
636-
624+
// Operations which don't affect the low 6/5 bits of the shift amount are NOPs.
625+
(SHLQ x (ADDQconst [c] y)) && c & 63 == 0 -> (SHLQ x y)
626+
(SHRQ x (ADDQconst [c] y)) && c & 63 == 0 -> (SHRQ x y)
627+
(SARQ x (ADDQconst [c] y)) && c & 63 == 0 -> (SARQ x y)
628+
(SHLQ x (NEGQ <t> (ADDQconst [c] y))) && c & 63 == 0 -> (SHLQ x (NEGQ <t> y))
629+
(SHRQ x (NEGQ <t> (ADDQconst [c] y))) && c & 63 == 0 -> (SHRQ x (NEGQ <t> y))
630+
(SARQ x (NEGQ <t> (ADDQconst [c] y))) && c & 63 == 0 -> (SARQ x (NEGQ <t> y))
631+
(SHLQ x (ANDQconst [c] y)) && c & 63 == 63 -> (SHLQ x y)
632+
(SHRQ x (ANDQconst [c] y)) && c & 63 == 63 -> (SHRQ x y)
633+
(SARQ x (ANDQconst [c] y)) && c & 63 == 63 -> (SARQ x y)
634+
(SHLQ x (NEGQ <t> (ANDQconst [c] y))) && c & 63 == 63 -> (SHLQ x (NEGQ <t> y))
635+
(SHRQ x (NEGQ <t> (ANDQconst [c] y))) && c & 63 == 63 -> (SHRQ x (NEGQ <t> y))
636+
(SARQ x (NEGQ <t> (ANDQconst [c] y))) && c & 63 == 63 -> (SARQ x (NEGQ <t> y))
637+
638+
(SHLL x (ADDQconst [c] y)) && c & 31 == 0 -> (SHLL x y)
639+
(SHRL x (ADDQconst [c] y)) && c & 31 == 0 -> (SHRL x y)
640+
(SARL x (ADDQconst [c] y)) && c & 31 == 0 -> (SARL x y)
641+
(SHLL x (NEGQ <t> (ADDQconst [c] y))) && c & 31 == 0 -> (SHLL x (NEGQ <t> y))
642+
(SHRL x (NEGQ <t> (ADDQconst [c] y))) && c & 31 == 0 -> (SHRL x (NEGQ <t> y))
643+
(SARL x (NEGQ <t> (ADDQconst [c] y))) && c & 31 == 0 -> (SARL x (NEGQ <t> y))
644+
(SHLL x (ANDQconst [c] y)) && c & 31 == 31 -> (SHLL x y)
645+
(SHRL x (ANDQconst [c] y)) && c & 31 == 31 -> (SHRL x y)
646+
(SARL x (ANDQconst [c] y)) && c & 31 == 31 -> (SARL x y)
647+
(SHLL x (NEGQ <t> (ANDQconst [c] y))) && c & 31 == 31 -> (SHLL x (NEGQ <t> y))
648+
(SHRL x (NEGQ <t> (ANDQconst [c] y))) && c & 31 == 31 -> (SHRL x (NEGQ <t> y))
649+
(SARL x (NEGQ <t> (ANDQconst [c] y))) && c & 31 == 31 -> (SARL x (NEGQ <t> y))
650+
651+
(SHLQ x (ADDLconst [c] y)) && c & 63 == 0 -> (SHLQ x y)
652+
(SHRQ x (ADDLconst [c] y)) && c & 63 == 0 -> (SHRQ x y)
653+
(SARQ x (ADDLconst [c] y)) && c & 63 == 0 -> (SARQ x y)
654+
(SHLQ x (NEGL <t> (ADDLconst [c] y))) && c & 63 == 0 -> (SHLQ x (NEGL <t> y))
655+
(SHRQ x (NEGL <t> (ADDLconst [c] y))) && c & 63 == 0 -> (SHRQ x (NEGL <t> y))
656+
(SARQ x (NEGL <t> (ADDLconst [c] y))) && c & 63 == 0 -> (SARQ x (NEGL <t> y))
657+
(SHLQ x (ANDLconst [c] y)) && c & 63 == 63 -> (SHLQ x y)
658+
(SHRQ x (ANDLconst [c] y)) && c & 63 == 63 -> (SHRQ x y)
659+
(SARQ x (ANDLconst [c] y)) && c & 63 == 63 -> (SARQ x y)
660+
(SHLQ x (NEGL <t> (ANDLconst [c] y))) && c & 63 == 63 -> (SHLQ x (NEGL <t> y))
661+
(SHRQ x (NEGL <t> (ANDLconst [c] y))) && c & 63 == 63 -> (SHRQ x (NEGL <t> y))
662+
(SARQ x (NEGL <t> (ANDLconst [c] y))) && c & 63 == 63 -> (SARQ x (NEGL <t> y))
663+
664+
(SHLL x (ADDLconst [c] y)) && c & 31 == 0 -> (SHLL x y)
665+
(SHRL x (ADDLconst [c] y)) && c & 31 == 0 -> (SHRL x y)
666+
(SARL x (ADDLconst [c] y)) && c & 31 == 0 -> (SARL x y)
667+
(SHLL x (NEGL <t> (ADDLconst [c] y))) && c & 31 == 0 -> (SHLL x (NEGL <t> y))
668+
(SHRL x (NEGL <t> (ADDLconst [c] y))) && c & 31 == 0 -> (SHRL x (NEGL <t> y))
669+
(SARL x (NEGL <t> (ADDLconst [c] y))) && c & 31 == 0 -> (SARL x (NEGL <t> y))
670+
(SHLL x (ANDLconst [c] y)) && c & 31 == 31 -> (SHLL x y)
671+
(SHRL x (ANDLconst [c] y)) && c & 31 == 31 -> (SHRL x y)
672+
(SARL x (ANDLconst [c] y)) && c & 31 == 31 -> (SARL x y)
673+
(SHLL x (NEGL <t> (ANDLconst [c] y))) && c & 31 == 31 -> (SHLL x (NEGL <t> y))
674+
(SHRL x (NEGL <t> (ANDLconst [c] y))) && c & 31 == 31 -> (SHRL x (NEGL <t> y))
675+
(SARL x (NEGL <t> (ANDLconst [c] y))) && c & 31 == 31 -> (SARL x (NEGL <t> y))
676+
677+
// Constant rotate instructions
637678
(ADDQ (SHLQconst x [c]) (SHRQconst x [d])) && d==64-c -> (ROLQconst x [c])
638679
( ORQ (SHLQconst x [c]) (SHRQconst x [d])) && d==64-c -> (ROLQconst x [c])
639680
(XORQ (SHLQconst x [c]) (SHRQconst x [d])) && d==64-c -> (ROLQconst x [c])
@@ -655,10 +696,109 @@
655696
(ROLWconst [c] (ROLWconst [d] x)) -> (ROLWconst [(c+d)&15] x)
656697
(ROLBconst [c] (ROLBconst [d] x)) -> (ROLBconst [(c+d)& 7] x)
657698

658-
// TODO: non-constant rotates if shift amount is known to be bounded (shift & 63 or something).
699+
// Non-constant rotates.
700+
// We want to issue a rotate when the Go source contains code like
701+
// y &= 63
702+
// x << y | x >> (64-y)
703+
// The shift rules above convert << to SHLx and >> to SHRx.
704+
// SHRx converts its shift argument from 64-y to -y.
705+
// A tricky situation occurs when y==0. Then the original code would be:
706+
// x << 0 | x >> 64
707+
// But x >> 64 is 0, not x. So there's an additional mask that is ANDed in
708+
// to force the second term to 0. We don't need that mask, but we must match
709+
// it in order to strip it out.
710+
(ORQ (SHLQ x y) (ANDQ (SHRQ x (NEGQ y)) (SBBQcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [63]) [-64])) [64])))) -> (ROLQ x y)
711+
(ORQ (SHLQ x y) (ANDQ (SHRQ x (NEGL y)) (SBBQcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [63]) [-64])) [64])))) -> (ROLQ x y)
712+
(ORQ (SHRQ x y) (ANDQ (SHLQ x (NEGQ y)) (SBBQcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [63]) [-64])) [64])))) -> (RORQ x y)
713+
(ORQ (SHRQ x y) (ANDQ (SHLQ x (NEGL y)) (SBBQcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [63]) [-64])) [64])))) -> (RORQ x y)
714+
715+
(ORL (SHLL x y) (ANDL (SHRL x (NEGQ y)) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [31]) [-32])) [32])))) -> (ROLL x y)
716+
(ORL (SHLL x y) (ANDL (SHRL x (NEGL y)) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [31]) [-32])) [32])))) -> (ROLL x y)
717+
(ORL (SHRL x y) (ANDL (SHLL x (NEGQ y)) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [31]) [-32])) [32])))) -> (RORL x y)
718+
(ORL (SHRL x y) (ANDL (SHLL x (NEGL y)) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [31]) [-32])) [32])))) -> (RORL x y)
719+
720+
// Help with rotate detection
721+
(CMPQconst (NEGQ (ADDQconst [-16] (ANDQconst [15] _))) [32]) -> (FlagLT_ULT)
722+
(CMPQconst (NEGQ (ADDQconst [ -8] (ANDQconst [7] _))) [32]) -> (FlagLT_ULT)
723+
724+
(ORL (SHLL x (ANDQconst y [15]))
725+
(ANDL (SHRW x (NEGQ (ADDQconst (ANDQconst y [15]) [-16])))
726+
(SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [15]) [-16])) [16]))))
727+
&& v.Type.Size() == 2
728+
-> (ROLW x y)
729+
(ORL (SHLL x (ANDLconst y [15]))
730+
(ANDL (SHRW x (NEGL (ADDLconst (ANDLconst y [15]) [-16])))
731+
(SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [15]) [-16])) [16]))))
732+
&& v.Type.Size() == 2
733+
-> (ROLW x y)
734+
(ORL (SHRW x (ANDQconst y [15]))
735+
(SHLL x (NEGQ (ADDQconst (ANDQconst y [15]) [-16]))))
736+
&& v.Type.Size() == 2
737+
-> (RORW x y)
738+
(ORL (SHRW x (ANDLconst y [15]))
739+
(SHLL x (NEGL (ADDLconst (ANDLconst y [15]) [-16]))))
740+
&& v.Type.Size() == 2
741+
-> (RORW x y)
742+
743+
(ORL (SHLL x (ANDQconst y [ 7]))
744+
(ANDL (SHRB x (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8])))
745+
(SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8])) [ 8]))))
746+
&& v.Type.Size() == 1
747+
-> (ROLB x y)
748+
(ORL (SHLL x (ANDLconst y [ 7]))
749+
(ANDL (SHRB x (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8])))
750+
(SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8])) [ 8]))))
751+
&& v.Type.Size() == 1
752+
-> (ROLB x y)
753+
(ORL (SHRB x (ANDQconst y [ 7]))
754+
(SHLL x (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8]))))
755+
&& v.Type.Size() == 1
756+
-> (RORB x y)
757+
(ORL (SHRB x (ANDLconst y [ 7]))
758+
(SHLL x (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8]))))
759+
&& v.Type.Size() == 1
760+
-> (RORB x y)
761+
762+
// rotate left negative = rotate right
763+
(ROLQ x (NEGQ y)) -> (RORQ x y)
764+
(ROLQ x (NEGL y)) -> (RORQ x y)
765+
(ROLL x (NEGQ y)) -> (RORL x y)
766+
(ROLL x (NEGL y)) -> (RORL x y)
767+
(ROLW x (NEGQ y)) -> (RORW x y)
768+
(ROLW x (NEGL y)) -> (RORW x y)
769+
(ROLB x (NEGQ y)) -> (RORB x y)
770+
(ROLB x (NEGL y)) -> (RORB x y)
771+
772+
// rotate right negative = rotate left
773+
(RORQ x (NEGQ y)) -> (ROLQ x y)
774+
(RORQ x (NEGL y)) -> (ROLQ x y)
775+
(RORL x (NEGQ y)) -> (ROLL x y)
776+
(RORL x (NEGL y)) -> (ROLL x y)
777+
(RORW x (NEGQ y)) -> (ROLW x y)
778+
(RORW x (NEGL y)) -> (ROLW x y)
779+
(RORB x (NEGQ y)) -> (ROLB x y)
780+
(RORB x (NEGL y)) -> (ROLB x y)
781+
782+
// rotate by constants
783+
(ROLQ x (MOVQconst [c])) -> (ROLQconst [c&63] x)
784+
(ROLQ x (MOVLconst [c])) -> (ROLQconst [c&63] x)
785+
(ROLL x (MOVQconst [c])) -> (ROLLconst [c&31] x)
786+
(ROLL x (MOVLconst [c])) -> (ROLLconst [c&31] x)
787+
(ROLW x (MOVQconst [c])) -> (ROLWconst [c&15] x)
788+
(ROLW x (MOVLconst [c])) -> (ROLWconst [c&15] x)
789+
(ROLB x (MOVQconst [c])) -> (ROLBconst [c&7 ] x)
790+
(ROLB x (MOVLconst [c])) -> (ROLBconst [c&7 ] x)
791+
792+
(RORQ x (MOVQconst [c])) -> (ROLQconst [(-c)&63] x)
793+
(RORQ x (MOVLconst [c])) -> (ROLQconst [(-c)&63] x)
794+
(RORL x (MOVQconst [c])) -> (ROLLconst [(-c)&31] x)
795+
(RORL x (MOVLconst [c])) -> (ROLLconst [(-c)&31] x)
796+
(RORW x (MOVQconst [c])) -> (ROLWconst [(-c)&15] x)
797+
(RORW x (MOVLconst [c])) -> (ROLWconst [(-c)&15] x)
798+
(RORB x (MOVQconst [c])) -> (ROLBconst [(-c)&7 ] x)
799+
(RORB x (MOVLconst [c])) -> (ROLBconst [(-c)&7 ] x)
659800

660801
// Constant shift simplifications
661-
662802
(SHLQconst x [0]) -> x
663803
(SHRQconst x [0]) -> x
664804
(SARQconst x [0]) -> x
@@ -1171,6 +1311,7 @@
11711311
(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= int32(m) && int32(m) < int32(n) -> (FlagLT_ULT)
11721312
(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < int16(n) -> (FlagLT_ULT)
11731313
(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < int8(n) -> (FlagLT_ULT)
1314+
11741315
// TODO: DIVxU also.
11751316

11761317
// Absorb flag constants into SBB ops.

src/cmd/compile/internal/ssa/gen/AMD64Ops.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,14 @@ func init() {
284284
{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-15
285285
{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-7
286286

287+
{name: "ROLQ", argLength: 2, reg: gp21shift, asm: "ROLQ", resultInArg0: true, clobberFlags: true}, // arg0 rotate left arg1 bits.
288+
{name: "ROLL", argLength: 2, reg: gp21shift, asm: "ROLL", resultInArg0: true, clobberFlags: true}, // arg0 rotate left arg1 bits.
289+
{name: "ROLW", argLength: 2, reg: gp21shift, asm: "ROLW", resultInArg0: true, clobberFlags: true}, // arg0 rotate left arg1 bits.
290+
{name: "ROLB", argLength: 2, reg: gp21shift, asm: "ROLB", resultInArg0: true, clobberFlags: true}, // arg0 rotate left arg1 bits.
291+
{name: "RORQ", argLength: 2, reg: gp21shift, asm: "RORQ", resultInArg0: true, clobberFlags: true}, // arg0 rotate right arg1 bits.
292+
{name: "RORL", argLength: 2, reg: gp21shift, asm: "RORL", resultInArg0: true, clobberFlags: true}, // arg0 rotate right arg1 bits.
293+
{name: "RORW", argLength: 2, reg: gp21shift, asm: "RORW", resultInArg0: true, clobberFlags: true}, // arg0 rotate right arg1 bits.
294+
{name: "RORB", argLength: 2, reg: gp21shift, asm: "RORB", resultInArg0: true, clobberFlags: true}, // arg0 rotate right arg1 bits.
287295
{name: "ROLQconst", argLength: 1, reg: gp11, asm: "ROLQ", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-63
288296
{name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-31
289297
{name: "ROLWconst", argLength: 1, reg: gp11, asm: "ROLW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-15

0 commit comments

Comments
 (0)