diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index 81ea25781e..54afacce7f 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -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 diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index e034fb2654..e68baf07f6 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -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 (MULVU x y)) -(Select1 (Mul64uover x y)) => (SGTU (Select0 (MULVU x y)) (MOVVconst [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 (MULHVU x y) (MOVVconst [0])) -(Hmul64 x y) => (Select0 (MULV x y)) -(Hmul64u x y) => (Select0 (MULVU x y)) -(Hmul32 x y) => (SRAVconst (Select1 (MULV (SignExt32to64 x) (SignExt32to64 y))) [32]) -(Hmul32u x y) => (SRLVconst (Select1 (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< (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 diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index b104660767..b593d3d41a 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -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 diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 26ed4e552f..4a24012b1d 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -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 }, }, }, diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go index fdd19bf167..8eacc1fda7 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -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 (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 (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 (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 (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 (Select0 (MULVU x y)) (MOVVconst [0])) + // result: (SGTU (MULHVU x y) (MOVVconst [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 (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])