mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: optimize some patterns into revb2h/revb4h instruction on loong64
Pattern1: (the type of c is uint16)
c>>8 | c<<8
To:
revb2h c
Pattern2: (the type of c is uint32)
(c & 0xff00ff00)>>8 | (c & 0x00ff00ff)<<8
To:
revb2h c
Pattern3: (the type of c is uint64)
(c & 0xff00ff00ff00ff00)>>8 | (c & 0x00ff00ff00ff00ff)<<8
To:
revb4h c
Change-Id: Ic6231a3f476cbacbea4bd00e31193d107cb86cda
Reviewed-on: https://go-review.googlesource.com/c/go/+/696335
Reviewed-by: Meidan Li <limeidan@loongson.cn>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
8dcab6f450
commit
9632ba8160
6 changed files with 469 additions and 0 deletions
|
|
@ -543,6 +543,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
|||
ssa.OpLOONG64SQRTF,
|
||||
ssa.OpLOONG64REVB2H,
|
||||
ssa.OpLOONG64REVB2W,
|
||||
ssa.OpLOONG64REVB4H,
|
||||
ssa.OpLOONG64REVBV,
|
||||
ssa.OpLOONG64BITREV4B,
|
||||
ssa.OpLOONG64BITREVW,
|
||||
|
|
|
|||
|
|
@ -136,6 +136,27 @@
|
|||
(Rsh8x16 <t> x y) && !shiftIsBounded(v) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
|
||||
(Rsh8x8 <t> x y) && !shiftIsBounded(v) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64 y)))
|
||||
|
||||
|
||||
// revb2h
|
||||
// ((x>>8) | (x<<8)) => (REVB2H x), the type of x is uint16
|
||||
((OR|XOR|ADDV) <typ.UInt16> (SRLVconst [8] <typ.UInt16> x) (SLLVconst [8] <typ.UInt16> x)) => (REVB2H x)
|
||||
|
||||
// ((x & 0xff00ff00)>>8) | ((x & 0x00ff00ff)<<8), the type of x is uint32
|
||||
((OR|XOR|ADDV) (SRLconst [8] (ANDconst [c1] x)) (SLLconst [8] (ANDconst [c2] x)))
|
||||
&& uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
|
||||
=> (REVB2H x)
|
||||
|
||||
// revb4h
|
||||
// ((x & 0xff00ff00ff00ff00)>>8) | ((x & 0x00ff00ff00ff00ff)<<8), the type of x is uint64
|
||||
((OR|XOR|ADDV) (SRLVconst [8] (AND (MOVVconst [c1]) x)) (SLLVconst [8] (AND (MOVVconst [c2]) x)))
|
||||
&& uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff
|
||||
=> (REVB4H x)
|
||||
|
||||
// ((x & 0xff00ff00)>>8) | ((x & 0x00ff00ff)<<8), the type of x is uint64
|
||||
((OR|XOR|ADDV) (SRLVconst [8] (AND (MOVVconst [c1]) x)) (SLLVconst [8] (ANDconst [c2] x)))
|
||||
&& uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff
|
||||
=> (REVB4H (ANDconst <x.Type> [0xffffffff] x))
|
||||
|
||||
// bitfield ops
|
||||
|
||||
// bstrpickv
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ func init() {
|
|||
|
||||
{name: "REVB2H", argLength: 1, reg: gp11, asm: "REVB2H"}, // Swap bytes: 0x11223344 -> 0x22114433 (sign extends to 64 bits)
|
||||
{name: "REVB2W", argLength: 1, reg: gp11, asm: "REVB2W"}, // Swap bytes: 0x1122334455667788 -> 0x4433221188776655
|
||||
{name: "REVB4H", argLength: 1, reg: gp11, asm: "REVB4H"}, // Swap bytes: 0x1122334455667788 -> 0x2211443366558877
|
||||
{name: "REVBV", argLength: 1, reg: gp11, asm: "REVBV"}, // Swap bytes: 0x1122334455667788 -> 0x8877665544332211
|
||||
|
||||
{name: "BITREV4B", argLength: 1, reg: gp11, asm: "BITREV4B"}, // Reverse the bits of each byte inside a 32-bit arg[0]
|
||||
|
|
|
|||
|
|
@ -1780,6 +1780,7 @@ const (
|
|||
OpLOONG64CTZV
|
||||
OpLOONG64REVB2H
|
||||
OpLOONG64REVB2W
|
||||
OpLOONG64REVB4H
|
||||
OpLOONG64REVBV
|
||||
OpLOONG64BITREV4B
|
||||
OpLOONG64BITREVW
|
||||
|
|
@ -23938,6 +23939,19 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "REVB4H",
|
||||
argLen: 1,
|
||||
asm: loong64.AREVB4H,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "REVBV",
|
||||
argLen: 1,
|
||||
|
|
|
|||
|
|
@ -1784,6 +1784,148 @@ func rewriteValueLOONG64_OpLOONG64ADDF(v *Value) bool {
|
|||
func rewriteValueLOONG64_OpLOONG64ADDV(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (ADDV <typ.UInt16> (SRLVconst [8] <typ.UInt16> x) (SLLVconst [8] <typ.UInt16> x))
|
||||
// result: (REVB2H x)
|
||||
for {
|
||||
if v.Type != typ.UInt16 {
|
||||
break
|
||||
}
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || v_0.Type != typ.UInt16 || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
if v_1.Op != OpLOONG64SLLVconst || v_1.Type != typ.UInt16 || auxIntToInt64(v_1.AuxInt) != 8 || x != v_1.Args[0] {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB2H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (ADDV (SRLconst [8] (ANDconst [c1] x)) (SLLconst [8] (ANDconst [c2] x)))
|
||||
// cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
|
||||
// result: (REVB2H x)
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0.AuxInt)
|
||||
x := v_0_0.Args[0]
|
||||
if v_1.Op != OpLOONG64SLLconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0.AuxInt)
|
||||
if x != v_1_0.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB2H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (ADDV (SRLVconst [8] (AND (MOVVconst [c1]) x)) (SLLVconst [8] (AND (MOVVconst [c2]) x)))
|
||||
// cond: uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff
|
||||
// result: (REVB4H x)
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_0_0_0 := v_0_0.Args[0]
|
||||
v_0_0_1 := v_0_0.Args[1]
|
||||
for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 {
|
||||
if v_0_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0_0.AuxInt)
|
||||
x := v_0_0_1
|
||||
if v_1.Op != OpLOONG64SLLVconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_1_0.Args[1]
|
||||
v_1_0_0 := v_1_0.Args[0]
|
||||
v_1_0_1 := v_1_0.Args[1]
|
||||
for _i2 := 0; _i2 <= 1; _i2, v_1_0_0, v_1_0_1 = _i2+1, v_1_0_1, v_1_0_0 {
|
||||
if v_1_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0_0.AuxInt)
|
||||
if x != v_1_0_1 || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB4H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (ADDV (SRLVconst [8] (AND (MOVVconst [c1]) x)) (SLLVconst [8] (ANDconst [c2] x)))
|
||||
// cond: uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff
|
||||
// result: (REVB4H (ANDconst <x.Type> [0xffffffff] x))
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_0_0_0 := v_0_0.Args[0]
|
||||
v_0_0_1 := v_0_0.Args[1]
|
||||
for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 {
|
||||
if v_0_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0_0.AuxInt)
|
||||
x := v_0_0_1
|
||||
if v_1.Op != OpLOONG64SLLVconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0.AuxInt)
|
||||
if x != v_1_0.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB4H)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64ANDconst, x.Type)
|
||||
v0.AuxInt = int64ToAuxInt(0xffffffff)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (ADDV x (MOVVconst <t> [c]))
|
||||
// cond: is32Bit(c) && !t.IsPtr()
|
||||
// result: (ADDVconst [c] x)
|
||||
|
|
@ -5774,6 +5916,148 @@ func rewriteValueLOONG64_OpLOONG64NORconst(v *Value) bool {
|
|||
func rewriteValueLOONG64_OpLOONG64OR(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (OR <typ.UInt16> (SRLVconst [8] <typ.UInt16> x) (SLLVconst [8] <typ.UInt16> x))
|
||||
// result: (REVB2H x)
|
||||
for {
|
||||
if v.Type != typ.UInt16 {
|
||||
break
|
||||
}
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || v_0.Type != typ.UInt16 || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
if v_1.Op != OpLOONG64SLLVconst || v_1.Type != typ.UInt16 || auxIntToInt64(v_1.AuxInt) != 8 || x != v_1.Args[0] {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB2H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (OR (SRLconst [8] (ANDconst [c1] x)) (SLLconst [8] (ANDconst [c2] x)))
|
||||
// cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
|
||||
// result: (REVB2H x)
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0.AuxInt)
|
||||
x := v_0_0.Args[0]
|
||||
if v_1.Op != OpLOONG64SLLconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0.AuxInt)
|
||||
if x != v_1_0.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB2H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (OR (SRLVconst [8] (AND (MOVVconst [c1]) x)) (SLLVconst [8] (AND (MOVVconst [c2]) x)))
|
||||
// cond: uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff
|
||||
// result: (REVB4H x)
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_0_0_0 := v_0_0.Args[0]
|
||||
v_0_0_1 := v_0_0.Args[1]
|
||||
for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 {
|
||||
if v_0_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0_0.AuxInt)
|
||||
x := v_0_0_1
|
||||
if v_1.Op != OpLOONG64SLLVconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_1_0.Args[1]
|
||||
v_1_0_0 := v_1_0.Args[0]
|
||||
v_1_0_1 := v_1_0.Args[1]
|
||||
for _i2 := 0; _i2 <= 1; _i2, v_1_0_0, v_1_0_1 = _i2+1, v_1_0_1, v_1_0_0 {
|
||||
if v_1_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0_0.AuxInt)
|
||||
if x != v_1_0_1 || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB4H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (OR (SRLVconst [8] (AND (MOVVconst [c1]) x)) (SLLVconst [8] (ANDconst [c2] x)))
|
||||
// cond: uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff
|
||||
// result: (REVB4H (ANDconst <x.Type> [0xffffffff] x))
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_0_0_0 := v_0_0.Args[0]
|
||||
v_0_0_1 := v_0_0.Args[1]
|
||||
for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 {
|
||||
if v_0_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0_0.AuxInt)
|
||||
x := v_0_0_1
|
||||
if v_1.Op != OpLOONG64SLLVconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0.AuxInt)
|
||||
if x != v_1_0.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB4H)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64ANDconst, x.Type)
|
||||
v0.AuxInt = int64ToAuxInt(0xffffffff)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (OR x (MOVVconst [c]))
|
||||
// cond: is32Bit(c)
|
||||
// result: (ORconst [c] x)
|
||||
|
|
@ -7245,6 +7529,148 @@ func rewriteValueLOONG64_OpLOONG64SUBVconst(v *Value) bool {
|
|||
func rewriteValueLOONG64_OpLOONG64XOR(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (XOR <typ.UInt16> (SRLVconst [8] <typ.UInt16> x) (SLLVconst [8] <typ.UInt16> x))
|
||||
// result: (REVB2H x)
|
||||
for {
|
||||
if v.Type != typ.UInt16 {
|
||||
break
|
||||
}
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || v_0.Type != typ.UInt16 || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
if v_1.Op != OpLOONG64SLLVconst || v_1.Type != typ.UInt16 || auxIntToInt64(v_1.AuxInt) != 8 || x != v_1.Args[0] {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB2H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (XOR (SRLconst [8] (ANDconst [c1] x)) (SLLconst [8] (ANDconst [c2] x)))
|
||||
// cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
|
||||
// result: (REVB2H x)
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0.AuxInt)
|
||||
x := v_0_0.Args[0]
|
||||
if v_1.Op != OpLOONG64SLLconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0.AuxInt)
|
||||
if x != v_1_0.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB2H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (XOR (SRLVconst [8] (AND (MOVVconst [c1]) x)) (SLLVconst [8] (AND (MOVVconst [c2]) x)))
|
||||
// cond: uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff
|
||||
// result: (REVB4H x)
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_0_0_0 := v_0_0.Args[0]
|
||||
v_0_0_1 := v_0_0.Args[1]
|
||||
for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 {
|
||||
if v_0_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0_0.AuxInt)
|
||||
x := v_0_0_1
|
||||
if v_1.Op != OpLOONG64SLLVconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_1_0.Args[1]
|
||||
v_1_0_0 := v_1_0.Args[0]
|
||||
v_1_0_1 := v_1_0.Args[1]
|
||||
for _i2 := 0; _i2 <= 1; _i2, v_1_0_0, v_1_0_1 = _i2+1, v_1_0_1, v_1_0_0 {
|
||||
if v_1_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0_0.AuxInt)
|
||||
if x != v_1_0_1 || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB4H)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (XOR (SRLVconst [8] (AND (MOVVconst [c1]) x)) (SLLVconst [8] (ANDconst [c2] x)))
|
||||
// cond: uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff
|
||||
// result: (REVB4H (ANDconst <x.Type> [0xffffffff] x))
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64SRLVconst || auxIntToInt64(v_0.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLOONG64AND {
|
||||
continue
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_0_0_0 := v_0_0.Args[0]
|
||||
v_0_0_1 := v_0_0.Args[1]
|
||||
for _i1 := 0; _i1 <= 1; _i1, v_0_0_0, v_0_0_1 = _i1+1, v_0_0_1, v_0_0_0 {
|
||||
if v_0_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c1 := auxIntToInt64(v_0_0_0.AuxInt)
|
||||
x := v_0_0_1
|
||||
if v_1.Op != OpLOONG64SLLVconst || auxIntToInt64(v_1.AuxInt) != 8 {
|
||||
continue
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLOONG64ANDconst {
|
||||
continue
|
||||
}
|
||||
c2 := auxIntToInt64(v_1_0.AuxInt)
|
||||
if x != v_1_0.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64REVB4H)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64ANDconst, x.Type)
|
||||
v0.AuxInt = int64ToAuxInt(0xffffffff)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (XOR x (MOVVconst [c]))
|
||||
// cond: is32Bit(c)
|
||||
// result: (XORconst [c] x)
|
||||
|
|
|
|||
|
|
@ -338,20 +338,26 @@ func shift_no_cmp(x int) int {
|
|||
|
||||
func rev16(c uint64) (uint64, uint64, uint64) {
|
||||
// arm64:`REV16`,-`AND`,-`LSR`,-`AND`,-`ORR\tR[0-9]+<<8`
|
||||
// loong64:`REVB4H`,-`MOVV`,-`AND`,-`SRLV`,-`AND`,-`SLLV`,-`OR`
|
||||
b1 := ((c & 0xff00ff00ff00ff00) >> 8) | ((c & 0x00ff00ff00ff00ff) << 8)
|
||||
// arm64:-`ADD\tR[0-9]+<<8`
|
||||
// loong64:-`ADDV`
|
||||
b2 := ((c & 0xff00ff00ff00ff00) >> 8) + ((c & 0x00ff00ff00ff00ff) << 8)
|
||||
// arm64:-`EOR\tR[0-9]+<<8`
|
||||
// loong64:-`XOR`
|
||||
b3 := ((c & 0xff00ff00ff00ff00) >> 8) ^ ((c & 0x00ff00ff00ff00ff) << 8)
|
||||
return b1, b2, b3
|
||||
}
|
||||
|
||||
func rev16w(c uint32) (uint32, uint32, uint32) {
|
||||
// arm64:`REV16W`,-`AND`,-`UBFX`,-`AND`,-`ORR\tR[0-9]+<<8`
|
||||
// loong64:`REVB2H`,-`AND`,-`SRL`,-`AND`,-`SLL`,-`OR`
|
||||
b1 := ((c & 0xff00ff00) >> 8) | ((c & 0x00ff00ff) << 8)
|
||||
// arm64:-`ADD\tR[0-9]+<<8`
|
||||
// loong64:-`ADDV`
|
||||
b2 := ((c & 0xff00ff00) >> 8) + ((c & 0x00ff00ff) << 8)
|
||||
// arm64:-`EOR\tR[0-9]+<<8`
|
||||
// loong64:-`XOR`
|
||||
b3 := ((c & 0xff00ff00) >> 8) ^ ((c & 0x00ff00ff) << 8)
|
||||
return b1, b2, b3
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue