mirror of
https://github.com/golang/go
synced 2024-11-23 18:40:03 -07:00
cmd/compile: optimize multiplication on loong64
Previously, multiplication on loong64 architecture was performed using MULV and MULHVU instructions to calculate the low 64-bit and high 64-bit of a multiplication respectively. However, in most cases, only the low 64-bits are needed. This commit enalbes only computating the low 64-bit result with the MULV instruction. Reduce the binary size slightly. file before after Δ % addr2line 2833777 2833849 +72 +0.003% asm 5267499 5266963 -536 -0.010% buildid 2579706 2579402 -304 -0.012% cgo 4798260 4797444 -816 -0.017% compile 25247419 25175030 -72389 -0.287% cover 4973091 4972027 -1064 -0.021% dist 3631013 3565653 -65360 -1.800% doc 4076036 4074004 -2032 -0.050% fix 3496378 3496066 -312 -0.009% link 6984102 6983214 -888 -0.013% nm 2743820 2743516 -304 -0.011% objdump 4277171 4277035 -136 -0.003% pack 2379248 2378872 -376 -0.016% pprof 14419090 14419874 +784 +0.005% test2json 2684386 2684018 -368 -0.014% trace 13640018 13631034 -8984 -0.066% vet 7748918 7752630 +3712 +0.048% go 15643850 15638098 -5752 -0.037% total 127423782 127268729 -155053 -0.122% Change-Id: Ifce4a9a3ed1d03c170681e39cb6f3541db9882dc Reviewed-on: https://go-review.googlesource.com/c/go/+/472775 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
0487ba08a6
commit
14015be5bb
@ -140,7 +140,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
ssa.OpLOONG64MULF,
|
||||
ssa.OpLOONG64MULD,
|
||||
ssa.OpLOONG64DIVF,
|
||||
ssa.OpLOONG64DIVD:
|
||||
ssa.OpLOONG64DIVD,
|
||||
ssa.OpLOONG64MULV, ssa.OpLOONG64MULHV, ssa.OpLOONG64MULHVU:
|
||||
p := s.Prog(v.Op.Asm())
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = v.Args[1].Reg()
|
||||
@ -174,32 +175,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
p.Reg = v.Args[0].Reg()
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = v.Reg()
|
||||
case ssa.OpLOONG64MULV:
|
||||
p := s.Prog(loong64.AMULV)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = v.Args[1].Reg()
|
||||
p.Reg = v.Args[0].Reg()
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = v.Reg1()
|
||||
p1 := s.Prog(loong64.AMULHV)
|
||||
p1.From.Type = obj.TYPE_REG
|
||||
p1.From.Reg = v.Args[1].Reg()
|
||||
p1.Reg = v.Args[0].Reg()
|
||||
p1.To.Type = obj.TYPE_REG
|
||||
p1.To.Reg = v.Reg0()
|
||||
case ssa.OpLOONG64MULVU:
|
||||
p := s.Prog(loong64.AMULV)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = v.Args[1].Reg()
|
||||
p.Reg = v.Args[0].Reg()
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = v.Reg1()
|
||||
p1 := s.Prog(loong64.AMULHVU)
|
||||
p1.From.Type = obj.TYPE_REG
|
||||
p1.From.Reg = v.Args[1].Reg()
|
||||
p1.Reg = v.Args[0].Reg()
|
||||
p1.To.Type = obj.TYPE_REG
|
||||
p1.To.Reg = v.Reg0()
|
||||
case ssa.OpLOONG64DIVV:
|
||||
p := s.Prog(loong64.ADIVV)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
|
@ -8,16 +8,17 @@
|
||||
(Sub(Ptr|64|32|16|8) ...) => (SUBV ...)
|
||||
(Sub(32|64)F ...) => (SUB(F|D) ...)
|
||||
|
||||
(Mul(64|32|16|8) x y) => (Select1 (MULVU x y))
|
||||
(Mul(64|32|16|8) ...) => (MULV ...)
|
||||
(Mul(32|64)F ...) => (MUL(F|D) ...)
|
||||
(Mul64uhilo ...) => (MULVU ...)
|
||||
(Select0 (Mul64uover x y)) => (Select1 <typ.UInt64> (MULVU x y))
|
||||
(Select1 (Mul64uover x y)) => (SGTU <typ.Bool> (Select0 <typ.UInt64> (MULVU x y)) (MOVVconst <typ.UInt64> [0]))
|
||||
(Select0 (Mul64uhilo x y)) => (MULHVU x y)
|
||||
(Select1 (Mul64uhilo x y)) => (MULV x y)
|
||||
(Select0 (Mul64uover x y)) => (MULV x y)
|
||||
(Select1 (Mul64uover x y)) => (SGTU <typ.Bool> (MULHVU x y) (MOVVconst <typ.UInt64> [0]))
|
||||
|
||||
(Hmul64 x y) => (Select0 (MULV x y))
|
||||
(Hmul64u x y) => (Select0 (MULVU x y))
|
||||
(Hmul32 x y) => (SRAVconst (Select1 <typ.Int64> (MULV (SignExt32to64 x) (SignExt32to64 y))) [32])
|
||||
(Hmul32u x y) => (SRLVconst (Select1 <typ.UInt64> (MULVU (ZeroExt32to64 x) (ZeroExt32to64 y))) [32])
|
||||
(Hmul64 ...) => (MULHV ...)
|
||||
(Hmul64u ...) => (MULHVU ...)
|
||||
(Hmul32 x y) => (SRAVconst (MULV (SignExt32to64 x) (SignExt32to64 y)) [32])
|
||||
(Hmul32u x y) => (SRLVconst (MULV (ZeroExt32to64 x) (ZeroExt32to64 y)) [32])
|
||||
|
||||
(Div64 x y) => (Select1 (DIVV x y))
|
||||
(Div64u x y) => (Select1 (DIVVU x y))
|
||||
@ -591,10 +592,10 @@
|
||||
(SGTU (MOVVconst [c]) x) && is32Bit(c) => (SGTUconst [c] x)
|
||||
|
||||
// mul by constant
|
||||
(Select1 (MULVU x (MOVVconst [-1]))) => (NEGV x)
|
||||
(Select1 (MULVU _ (MOVVconst [0]))) => (MOVVconst [0])
|
||||
(Select1 (MULVU x (MOVVconst [1]))) => x
|
||||
(Select1 (MULVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x)
|
||||
(MULV x (MOVVconst [-1])) => (NEGV x)
|
||||
(MULV _ (MOVVconst [0])) => (MOVVconst [0])
|
||||
(MULV x (MOVVconst [1])) => x
|
||||
(MULV x (MOVVconst [c])) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x)
|
||||
|
||||
// div by constant
|
||||
(Select1 (DIVVU x (MOVVconst [1]))) => x
|
||||
@ -634,7 +635,7 @@
|
||||
(SLLVconst [c] (MOVVconst [d])) => (MOVVconst [d<<uint64(c)])
|
||||
(SRLVconst [c] (MOVVconst [d])) => (MOVVconst [int64(uint64(d)>>uint64(c))])
|
||||
(SRAVconst [c] (MOVVconst [d])) => (MOVVconst [d>>uint64(c)])
|
||||
(Select1 (MULVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c*d])
|
||||
(MULV (MOVVconst [c]) (MOVVconst [d])) => (MOVVconst [c*d])
|
||||
(Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c/d])
|
||||
(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))])
|
||||
(Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c%d]) // mod
|
||||
|
@ -163,10 +163,11 @@ func init() {
|
||||
{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"}, // arg0 - arg1
|
||||
{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"}, // arg0 - auxInt
|
||||
|
||||
{name: "MULV", argLength: 2, reg: gp22, resultNotInArgs: true, commutative: true, typ: "(Int64,Int64)"}, // arg0 * arg1, signed
|
||||
{name: "MULVU", argLength: 2, reg: gp22, resultNotInArgs: true, commutative: true, typ: "(UInt64,UInt64)"}, // arg0 * arg1, unsigned
|
||||
{name: "DIVV", argLength: 2, reg: gp22, resultNotInArgs: true, typ: "(Int64,Int64)"}, // arg0 / arg1, signed
|
||||
{name: "DIVVU", argLength: 2, reg: gp22, resultNotInArgs: true, typ: "(UInt64,UInt64)"}, // arg0 / arg1, unsigned
|
||||
{name: "MULV", argLength: 2, reg: gp21, asm: "MULV", commutative: true, typ: "Int64"}, // arg0 * arg1
|
||||
{name: "MULHV", argLength: 2, reg: gp21, asm: "MULHV", commutative: true, typ: "Int64"}, // (arg0 * arg1) >> 64, signed
|
||||
{name: "MULHVU", argLength: 2, reg: gp21, asm: "MULHVU", commutative: true, typ: "UInt64"}, // (arg0 * arg1) >> 64, unsigned
|
||||
{name: "DIVV", argLength: 2, reg: gp22, resultNotInArgs: true, typ: "(Int64,Int64)"}, // arg0 / arg1, signed
|
||||
{name: "DIVVU", argLength: 2, reg: gp22, resultNotInArgs: true, typ: "(UInt64,UInt64)"}, // arg0 / arg1, unsigned
|
||||
|
||||
{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
|
||||
{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
|
||||
|
@ -1716,7 +1716,8 @@ const (
|
||||
OpLOONG64SUBV
|
||||
OpLOONG64SUBVconst
|
||||
OpLOONG64MULV
|
||||
OpLOONG64MULVU
|
||||
OpLOONG64MULHV
|
||||
OpLOONG64MULHVU
|
||||
OpLOONG64DIVV
|
||||
OpLOONG64DIVVU
|
||||
OpLOONG64ADDF
|
||||
@ -22912,34 +22913,47 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MULV",
|
||||
argLen: 2,
|
||||
commutative: true,
|
||||
resultNotInArgs: true,
|
||||
name: "MULV",
|
||||
argLen: 2,
|
||||
commutative: true,
|
||||
asm: loong64.AMULV,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{1, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MULVU",
|
||||
argLen: 2,
|
||||
commutative: true,
|
||||
resultNotInArgs: true,
|
||||
name: "MULHV",
|
||||
argLen: 2,
|
||||
commutative: true,
|
||||
asm: loong64.AMULHV,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{1, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MULHVU",
|
||||
argLen: 2,
|
||||
commutative: true,
|
||||
asm: loong64.AMULHVU,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
|
||||
{1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -201,9 +201,11 @@ func rewriteValueLOONG64(v *Value) bool {
|
||||
case OpHmul32u:
|
||||
return rewriteValueLOONG64_OpHmul32u(v)
|
||||
case OpHmul64:
|
||||
return rewriteValueLOONG64_OpHmul64(v)
|
||||
v.Op = OpLOONG64MULHV
|
||||
return true
|
||||
case OpHmul64u:
|
||||
return rewriteValueLOONG64_OpHmul64u(v)
|
||||
v.Op = OpLOONG64MULHVU
|
||||
return true
|
||||
case OpInterCall:
|
||||
v.Op = OpLOONG64CALLinter
|
||||
return true
|
||||
@ -285,6 +287,8 @@ func rewriteValueLOONG64(v *Value) bool {
|
||||
return rewriteValueLOONG64_OpLOONG64MOVWstore(v)
|
||||
case OpLOONG64MOVWstorezero:
|
||||
return rewriteValueLOONG64_OpLOONG64MOVWstorezero(v)
|
||||
case OpLOONG64MULV:
|
||||
return rewriteValueLOONG64_OpLOONG64MULV(v)
|
||||
case OpLOONG64NEGV:
|
||||
return rewriteValueLOONG64_OpLOONG64NEGV(v)
|
||||
case OpLOONG64NOR:
|
||||
@ -422,22 +426,23 @@ func rewriteValueLOONG64(v *Value) bool {
|
||||
case OpMove:
|
||||
return rewriteValueLOONG64_OpMove(v)
|
||||
case OpMul16:
|
||||
return rewriteValueLOONG64_OpMul16(v)
|
||||
v.Op = OpLOONG64MULV
|
||||
return true
|
||||
case OpMul32:
|
||||
return rewriteValueLOONG64_OpMul32(v)
|
||||
v.Op = OpLOONG64MULV
|
||||
return true
|
||||
case OpMul32F:
|
||||
v.Op = OpLOONG64MULF
|
||||
return true
|
||||
case OpMul64:
|
||||
return rewriteValueLOONG64_OpMul64(v)
|
||||
v.Op = OpLOONG64MULV
|
||||
return true
|
||||
case OpMul64F:
|
||||
v.Op = OpLOONG64MULD
|
||||
return true
|
||||
case OpMul64uhilo:
|
||||
v.Op = OpLOONG64MULVU
|
||||
return true
|
||||
case OpMul8:
|
||||
return rewriteValueLOONG64_OpMul8(v)
|
||||
v.Op = OpLOONG64MULV
|
||||
return true
|
||||
case OpNeg16:
|
||||
v.Op = OpLOONG64NEGV
|
||||
return true
|
||||
@ -1228,20 +1233,18 @@ func rewriteValueLOONG64_OpHmul32(v *Value) bool {
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Hmul32 x y)
|
||||
// result: (SRAVconst (Select1 <typ.Int64> (MULV (SignExt32to64 x) (SignExt32to64 y))) [32])
|
||||
// result: (SRAVconst (MULV (SignExt32to64 x) (SignExt32to64 y)) [32])
|
||||
for {
|
||||
x := v_0
|
||||
y := v_1
|
||||
v.reset(OpLOONG64SRAVconst)
|
||||
v.AuxInt = int64ToAuxInt(32)
|
||||
v0 := b.NewValue0(v.Pos, OpSelect1, typ.Int64)
|
||||
v1 := b.NewValue0(v.Pos, OpLOONG64MULV, types.NewTuple(typ.Int64, typ.Int64))
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULV, typ.Int64)
|
||||
v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
|
||||
v1.AddArg(x)
|
||||
v2 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
|
||||
v2.AddArg(x)
|
||||
v3 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
|
||||
v3.AddArg(y)
|
||||
v1.AddArg2(v2, v3)
|
||||
v0.AddArg(v1)
|
||||
v2.AddArg(y)
|
||||
v0.AddArg2(v1, v2)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
@ -1252,54 +1255,18 @@ func rewriteValueLOONG64_OpHmul32u(v *Value) bool {
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Hmul32u x y)
|
||||
// result: (SRLVconst (Select1 <typ.UInt64> (MULVU (ZeroExt32to64 x) (ZeroExt32to64 y))) [32])
|
||||
// result: (SRLVconst (MULV (ZeroExt32to64 x) (ZeroExt32to64 y)) [32])
|
||||
for {
|
||||
x := v_0
|
||||
y := v_1
|
||||
v.reset(OpLOONG64SRLVconst)
|
||||
v.AuxInt = int64ToAuxInt(32)
|
||||
v0 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
|
||||
v1 := b.NewValue0(v.Pos, OpLOONG64MULVU, types.NewTuple(typ.UInt64, typ.UInt64))
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULV, typ.Int64)
|
||||
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
|
||||
v1.AddArg(x)
|
||||
v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
|
||||
v2.AddArg(x)
|
||||
v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
|
||||
v3.AddArg(y)
|
||||
v1.AddArg2(v2, v3)
|
||||
v0.AddArg(v1)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueLOONG64_OpHmul64(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Hmul64 x y)
|
||||
// result: (Select0 (MULV x y))
|
||||
for {
|
||||
x := v_0
|
||||
y := v_1
|
||||
v.reset(OpSelect0)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULV, types.NewTuple(typ.Int64, typ.Int64))
|
||||
v0.AddArg2(x, y)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueLOONG64_OpHmul64u(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Hmul64u x y)
|
||||
// result: (Select0 (MULVU x y))
|
||||
for {
|
||||
x := v_0
|
||||
y := v_1
|
||||
v.reset(OpSelect0)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULVU, types.NewTuple(typ.UInt64, typ.UInt64))
|
||||
v0.AddArg2(x, y)
|
||||
v2.AddArg(y)
|
||||
v0.AddArg2(v1, v2)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
@ -3272,6 +3239,89 @@ func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueLOONG64_OpLOONG64MULV(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (MULV x (MOVVconst [-1]))
|
||||
// result: (NEGV 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 != OpLOONG64MOVVconst || auxIntToInt64(v_1.AuxInt) != -1 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64NEGV)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (MULV _ (MOVVconst [0]))
|
||||
// result: (MOVVconst [0])
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64MOVVconst)
|
||||
v.AuxInt = int64ToAuxInt(0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (MULV x (MOVVconst [1]))
|
||||
// result: 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 != OpLOONG64MOVVconst || auxIntToInt64(v_1.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (MULV x (MOVVconst [c]))
|
||||
// cond: isPowerOfTwo64(c)
|
||||
// result: (SLLVconst [log64(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 != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(v_1.AuxInt)
|
||||
if !(isPowerOfTwo64(c)) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64SLLVconst)
|
||||
v.AuxInt = int64ToAuxInt(log64(c))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (MULV (MOVVconst [c]) (MOVVconst [d]))
|
||||
// result: (MOVVconst [c*d])
|
||||
for {
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(v_0.AuxInt)
|
||||
if v_1.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
d := auxIntToInt64(v_1.AuxInt)
|
||||
v.reset(OpLOONG64MOVVconst)
|
||||
v.AuxInt = int64ToAuxInt(c * d)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueLOONG64_OpLOONG64NEGV(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (NEGV (MOVVconst [c]))
|
||||
@ -5659,74 +5709,6 @@ func rewriteValueLOONG64_OpMove(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueLOONG64_OpMul16(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Mul16 x y)
|
||||
// result: (Select1 (MULVU x y))
|
||||
for {
|
||||
x := v_0
|
||||
y := v_1
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULVU, types.NewTuple(typ.UInt64, typ.UInt64))
|
||||
v0.AddArg2(x, y)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueLOONG64_OpMul32(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Mul32 x y)
|
||||
// result: (Select1 (MULVU x y))
|
||||
for {
|
||||
x := v_0
|
||||
y := v_1
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULVU, types.NewTuple(typ.UInt64, typ.UInt64))
|
||||
v0.AddArg2(x, y)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueLOONG64_OpMul64(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Mul64 x y)
|
||||
// result: (Select1 (MULVU x y))
|
||||
for {
|
||||
x := v_0
|
||||
y := v_1
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULVU, types.NewTuple(typ.UInt64, typ.UInt64))
|
||||
v0.AddArg2(x, y)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueLOONG64_OpMul8(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Mul8 x y)
|
||||
// result: (Select1 (MULVU x y))
|
||||
for {
|
||||
x := v_0
|
||||
y := v_1
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULVU, types.NewTuple(typ.UInt64, typ.UInt64))
|
||||
v0.AddArg2(x, y)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueLOONG64_OpNeq16(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
@ -6881,20 +6863,28 @@ func rewriteValueLOONG64_OpRsh8x8(v *Value) bool {
|
||||
func rewriteValueLOONG64_OpSelect0(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Select0 (Mul64uhilo x y))
|
||||
// result: (MULHVU x y)
|
||||
for {
|
||||
if v_0.Op != OpMul64uhilo {
|
||||
break
|
||||
}
|
||||
y := v_0.Args[1]
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpLOONG64MULHVU)
|
||||
v.AddArg2(x, y)
|
||||
return true
|
||||
}
|
||||
// match: (Select0 (Mul64uover x y))
|
||||
// result: (Select1 <typ.UInt64> (MULVU x y))
|
||||
// result: (MULV x y)
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
y := v_0.Args[1]
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpSelect1)
|
||||
v.Type = typ.UInt64
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULVU, types.NewTuple(typ.UInt64, typ.UInt64))
|
||||
v0.AddArg2(x, y)
|
||||
v.AddArg(v0)
|
||||
v.reset(OpLOONG64MULV)
|
||||
v.AddArg2(x, y)
|
||||
return true
|
||||
}
|
||||
// match: (Select0 <t> (Add64carry x y c))
|
||||
@ -7022,8 +7012,20 @@ func rewriteValueLOONG64_OpSelect1(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Select1 (Mul64uhilo x y))
|
||||
// result: (MULV x y)
|
||||
for {
|
||||
if v_0.Op != OpMul64uhilo {
|
||||
break
|
||||
}
|
||||
y := v_0.Args[1]
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpLOONG64MULV)
|
||||
v.AddArg2(x, y)
|
||||
return true
|
||||
}
|
||||
// match: (Select1 (Mul64uover x y))
|
||||
// result: (SGTU <typ.Bool> (Select0 <typ.UInt64> (MULVU x y)) (MOVVconst <typ.UInt64> [0]))
|
||||
// result: (SGTU <typ.Bool> (MULHVU x y) (MOVVconst <typ.UInt64> [0]))
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
@ -7032,13 +7034,11 @@ func rewriteValueLOONG64_OpSelect1(v *Value) bool {
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpLOONG64SGTU)
|
||||
v.Type = typ.Bool
|
||||
v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
|
||||
v1 := b.NewValue0(v.Pos, OpLOONG64MULVU, types.NewTuple(typ.UInt64, typ.UInt64))
|
||||
v1.AddArg2(x, y)
|
||||
v0.AddArg(v1)
|
||||
v2 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64)
|
||||
v2.AuxInt = int64ToAuxInt(0)
|
||||
v.AddArg2(v0, v2)
|
||||
v0 := b.NewValue0(v.Pos, OpLOONG64MULHVU, typ.UInt64)
|
||||
v0.AddArg2(x, y)
|
||||
v1 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64)
|
||||
v1.AuxInt = int64ToAuxInt(0)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
// match: (Select1 <t> (Add64carry x y c))
|
||||
@ -7085,90 +7085,6 @@ func rewriteValueLOONG64_OpSelect1(v *Value) bool {
|
||||
v.AddArg2(v0, v2)
|
||||
return true
|
||||
}
|
||||
// match: (Select1 (MULVU x (MOVVconst [-1])))
|
||||
// result: (NEGV x)
|
||||
for {
|
||||
if v_0.Op != OpLOONG64MULVU {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != -1 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64NEGV)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (MULVU _ (MOVVconst [0])))
|
||||
// result: (MOVVconst [0])
|
||||
for {
|
||||
if v_0.Op != OpLOONG64MULVU {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64MOVVconst)
|
||||
v.AuxInt = int64ToAuxInt(0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (MULVU x (MOVVconst [1])))
|
||||
// result: x
|
||||
for {
|
||||
if v_0.Op != OpLOONG64MULVU {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (MULVU x (MOVVconst [c])))
|
||||
// cond: isPowerOfTwo64(c)
|
||||
// result: (SLLVconst [log64(c)] x)
|
||||
for {
|
||||
if v_0.Op != OpLOONG64MULVU {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
x := v_0_0
|
||||
if v_0_1.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(v_0_1.AuxInt)
|
||||
if !(isPowerOfTwo64(c)) {
|
||||
continue
|
||||
}
|
||||
v.reset(OpLOONG64SLLVconst)
|
||||
v.AuxInt = int64ToAuxInt(log64(c))
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (DIVVU x (MOVVconst [1])))
|
||||
// result: x
|
||||
for {
|
||||
@ -7206,30 +7122,6 @@ func rewriteValueLOONG64_OpSelect1(v *Value) bool {
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (Select1 (MULVU (MOVVconst [c]) (MOVVconst [d])))
|
||||
// result: (MOVVconst [c*d])
|
||||
for {
|
||||
if v_0.Op != OpLOONG64MULVU {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
c := auxIntToInt64(v_0_0.AuxInt)
|
||||
if v_0_1.Op != OpLOONG64MOVVconst {
|
||||
continue
|
||||
}
|
||||
d := auxIntToInt64(v_0_1.AuxInt)
|
||||
v.reset(OpLOONG64MOVVconst)
|
||||
v.AuxInt = int64ToAuxInt(c * d)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (DIVV (MOVVconst [c]) (MOVVconst [d])))
|
||||
// cond: d != 0
|
||||
// result: (MOVVconst [c/d])
|
||||
|
Loading…
Reference in New Issue
Block a user