diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index 54afacce7f..8193b4e321 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -141,7 +141,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpLOONG64MULD, ssa.OpLOONG64DIVF, ssa.OpLOONG64DIVD, - ssa.OpLOONG64MULV, ssa.OpLOONG64MULHV, ssa.OpLOONG64MULHVU: + ssa.OpLOONG64MULV, ssa.OpLOONG64MULHV, ssa.OpLOONG64MULHVU, + ssa.OpLOONG64DIVV, ssa.OpLOONG64REMV, ssa.OpLOONG64DIVVU, ssa.OpLOONG64REMVU: p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_REG p.From.Reg = v.Args[1].Reg() @@ -175,32 +176,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.OpLOONG64DIVV: - p := s.Prog(loong64.ADIVV) - 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.AREMV) - 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.OpLOONG64DIVVU: - p := s.Prog(loong64.ADIVVU) - 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.AREMVU) - 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.OpLOONG64MOVVconst: r := v.Reg() p := s.Prog(v.Op.Asm()) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index ab7774ed4e..4a47c4cd47 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -20,24 +20,24 @@ (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)) -(Div32 x y) => (Select1 (DIVV (SignExt32to64 x) (SignExt32to64 y))) -(Div32u x y) => (Select1 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y))) -(Div16 x y) => (Select1 (DIVV (SignExt16to64 x) (SignExt16to64 y))) -(Div16u x y) => (Select1 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y))) -(Div8 x y) => (Select1 (DIVV (SignExt8to64 x) (SignExt8to64 y))) -(Div8u x y) => (Select1 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y))) +(Div64 x y) => (DIVV x y) +(Div64u ...) => (DIVVU ...) +(Div32 x y) => (DIVV (SignExt32to64 x) (SignExt32to64 y)) +(Div32u x y) => (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)) +(Div16 x y) => (DIVV (SignExt16to64 x) (SignExt16to64 y)) +(Div16u x y) => (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)) +(Div8 x y) => (DIVV (SignExt8to64 x) (SignExt8to64 y)) +(Div8u x y) => (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)) (Div(32|64)F ...) => (DIV(F|D) ...) -(Mod64 x y) => (Select0 (DIVV x y)) -(Mod64u x y) => (Select0 (DIVVU x y)) -(Mod32 x y) => (Select0 (DIVV (SignExt32to64 x) (SignExt32to64 y))) -(Mod32u x y) => (Select0 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y))) -(Mod16 x y) => (Select0 (DIVV (SignExt16to64 x) (SignExt16to64 y))) -(Mod16u x y) => (Select0 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y))) -(Mod8 x y) => (Select0 (DIVV (SignExt8to64 x) (SignExt8to64 y))) -(Mod8u x y) => (Select0 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y))) +(Mod64 x y) => (REMV x y) +(Mod64u ...) => (REMVU ...) +(Mod32 x y) => (REMV (SignExt32to64 x) (SignExt32to64 y)) +(Mod32u x y) => (REMVU (ZeroExt32to64 x) (ZeroExt32to64 y)) +(Mod16 x y) => (REMV (SignExt16to64 x) (SignExt16to64 y)) +(Mod16u x y) => (REMVU (ZeroExt16to64 x) (ZeroExt16to64 y)) +(Mod8 x y) => (REMV (SignExt8to64 x) (SignExt8to64 y)) +(Mod8u x y) => (REMVU (ZeroExt8to64 x) (ZeroExt8to64 y)) (Select0 (Add64carry x y c)) => (ADDV (ADDV x y) c) (Select1 (Add64carry x y c)) => @@ -598,10 +598,10 @@ (MULV x (MOVVconst [c])) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x) // div by constant -(Select1 (DIVVU x (MOVVconst [1]))) => x -(Select1 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x) -(Select0 (DIVVU _ (MOVVconst [1]))) => (MOVVconst [0]) // mod -(Select0 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod +(DIVVU x (MOVVconst [1])) => x +(DIVVU x (MOVVconst [c])) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x) +(REMVU _ (MOVVconst [1])) => (MOVVconst [0]) // mod +(REMVU x (MOVVconst [c])) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod // generic simplifications (ADDV x (NEGV y)) => (SUBV x y) @@ -636,10 +636,10 @@ (SRLVconst [c] (MOVVconst [d])) => (MOVVconst [int64(uint64(d)>>uint64(c))]) (SRAVconst [c] (MOVVconst [d])) => (MOVVconst [d>>uint64(c)]) (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 -(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod +(DIVV (MOVVconst [c]) (MOVVconst [d])) && d != 0 => (MOVVconst [c/d]) +(DIVVU (MOVVconst [c]) (MOVVconst [d])) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))]) +(REMV (MOVVconst [c]) (MOVVconst [d])) && d != 0 => (MOVVconst [c%d]) // mod +(REMVU (MOVVconst [c]) (MOVVconst [d])) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod (ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d]) (ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) (ORconst [c] (MOVVconst [d])) => (MOVVconst [c|d]) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index b593d3d41a..23f20fddeb 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -124,7 +124,6 @@ func init() { // Common individual register masks var ( gp = buildReg("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") // R1 is LR, R2 is thread pointer, R3 is stack pointer, R21-unused, R22 is g, R30 is REGTMP - gps = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") | buildReg("g") gpg = gp | buildReg("g") gpsp = gp | buildReg("SP") gpspg = gpg | buildReg("SP") @@ -142,7 +141,6 @@ func init() { gp11 = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}} gp11sp = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}} gp21 = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}} - gp22 = regInfo{inputs: []regMask{gps, gps}, outputs: []regMask{gp, gp}} gpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}} gpstore = regInfo{inputs: []regMask{gpspsbg, gpg}} gpstore0 = regInfo{inputs: []regMask{gpspsbg}} @@ -166,8 +164,10 @@ func init() { {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: "DIVV", argLength: 2, reg: gp21, asm: "DIVV", typ: "Int64"}, // arg0 / arg1, signed + {name: "DIVVU", argLength: 2, reg: gp21, asm: "DIVVU", typ: "UInt64"}, // arg0 / arg1, unsigned + {name: "REMV", argLength: 2, reg: gp21, asm: "REMV", typ: "Int64"}, // arg0 / arg1, signed + {name: "REMVU", argLength: 2, reg: gp21, asm: "REMVU", typ: "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 2f51869c24..16052abbde 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1723,6 +1723,8 @@ const ( OpLOONG64MULHVU OpLOONG64DIVV OpLOONG64DIVVU + OpLOONG64REMV + OpLOONG64REMVU OpLOONG64ADDF OpLOONG64ADDD OpLOONG64SUBF @@ -22992,32 +22994,58 @@ var opcodeTable = [...]opInfo{ }, }, { - name: "DIVV", - argLen: 2, - resultNotInArgs: true, + name: "DIVV", + argLen: 2, + asm: loong64.ADIVV, 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: "DIVVU", - argLen: 2, - resultNotInArgs: true, + name: "DIVVU", + argLen: 2, + asm: loong64.ADIVVU, 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: "REMV", + argLen: 2, + asm: loong64.AREMV, + 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 + }, + }, + }, + { + name: "REMVU", + argLen: 2, + asm: loong64.AREMVU, + 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 d0fb54fc03..e88b74cb22 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -166,7 +166,8 @@ func rewriteValueLOONG64(v *Value) bool { v.Op = OpLOONG64DIVD return true case OpDiv64u: - return rewriteValueLOONG64_OpDiv64u(v) + v.Op = OpLOONG64DIVVU + return true case OpDiv8: return rewriteValueLOONG64_OpDiv8(v) case OpDiv8u: @@ -223,6 +224,10 @@ func rewriteValueLOONG64(v *Value) bool { return rewriteValueLOONG64_OpLOONG64AND(v) case OpLOONG64ANDconst: return rewriteValueLOONG64_OpLOONG64ANDconst(v) + case OpLOONG64DIVV: + return rewriteValueLOONG64_OpLOONG64DIVV(v) + case OpLOONG64DIVVU: + return rewriteValueLOONG64_OpLOONG64DIVVU(v) case OpLOONG64LoweredAtomicAdd32: return rewriteValueLOONG64_OpLOONG64LoweredAtomicAdd32(v) case OpLOONG64LoweredAtomicAdd64: @@ -299,6 +304,10 @@ func rewriteValueLOONG64(v *Value) bool { return rewriteValueLOONG64_OpLOONG64OR(v) case OpLOONG64ORconst: return rewriteValueLOONG64_OpLOONG64ORconst(v) + case OpLOONG64REMV: + return rewriteValueLOONG64_OpLOONG64REMV(v) + case OpLOONG64REMVU: + return rewriteValueLOONG64_OpLOONG64REMVU(v) case OpLOONG64ROTR: return rewriteValueLOONG64_OpLOONG64ROTR(v) case OpLOONG64ROTRV: @@ -418,7 +427,8 @@ func rewriteValueLOONG64(v *Value) bool { case OpMod64: return rewriteValueLOONG64_OpMod64(v) case OpMod64u: - return rewriteValueLOONG64_OpMod64u(v) + v.Op = OpLOONG64REMVU + return true case OpMod8: return rewriteValueLOONG64_OpMod8(v) case OpMod8u: @@ -915,18 +925,16 @@ func rewriteValueLOONG64_OpDiv16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div16 x y) - // result: (Select1 (DIVV (SignExt16to64 x) (SignExt16to64 y))) + // result: (DIVV (SignExt16to64 x) (SignExt16to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64DIVV) + v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -936,18 +944,16 @@ func rewriteValueLOONG64_OpDiv16u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div16u x y) - // result: (Select1 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y))) + // result: (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64DIVVU) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -957,18 +963,16 @@ func rewriteValueLOONG64_OpDiv32(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div32 x y) - // result: (Select1 (DIVV (SignExt32to64 x) (SignExt32to64 y))) + // result: (DIVV (SignExt32to64 x) (SignExt32to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64DIVV) + v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -978,52 +982,29 @@ func rewriteValueLOONG64_OpDiv32u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div32u x y) - // result: (Select1 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y))) + // result: (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64DIVVU) + v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } func rewriteValueLOONG64_OpDiv64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types // match: (Div64 x y) - // result: (Select1 (DIVV x y)) + // result: (DIVV x y) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) - v0.AddArg2(x, y) - v.AddArg(v0) - return true - } -} -func rewriteValueLOONG64_OpDiv64u(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Div64u x y) - // result: (Select1 (DIVVU x y)) - for { - x := v_0 - y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) - v0.AddArg2(x, y) - v.AddArg(v0) + v.reset(OpLOONG64DIVV) + v.AddArg2(x, y) return true } } @@ -1033,18 +1014,16 @@ func rewriteValueLOONG64_OpDiv8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div8 x y) - // result: (Select1 (DIVV (SignExt8to64 x) (SignExt8to64 y))) + // result: (DIVV (SignExt8to64 x) (SignExt8to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64DIVV) + v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -1054,18 +1033,16 @@ func rewriteValueLOONG64_OpDiv8u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div8u x y) - // result: (Select1 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y))) + // result: (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64DIVVU) + v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -1526,6 +1503,81 @@ func rewriteValueLOONG64_OpLOONG64ANDconst(v *Value) bool { } return false } +func rewriteValueLOONG64_OpLOONG64DIVV(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (DIVV (MOVVconst [c]) (MOVVconst [d])) + // cond: d != 0 + // result: (MOVVconst [c/d]) + for { + if v_0.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpLOONG64MOVVconst { + break + } + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(c / d) + return true + } + return false +} +func rewriteValueLOONG64_OpLOONG64DIVVU(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (DIVVU x (MOVVconst [1])) + // result: x + for { + x := v_0 + if v_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_1.AuxInt) != 1 { + break + } + v.copyOf(x) + return true + } + // match: (DIVVU x (MOVVconst [c])) + // cond: isPowerOfTwo64(c) + // result: (SRLVconst [log64(c)] x) + for { + x := v_0 + if v_1.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { + break + } + v.reset(OpLOONG64SRLVconst) + v.AuxInt = int64ToAuxInt(log64(c)) + v.AddArg(x) + return true + } + // match: (DIVVU (MOVVconst [c]) (MOVVconst [d])) + // cond: d != 0 + // result: (MOVVconst [int64(uint64(c)/uint64(d))]) + for { + if v_0.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpLOONG64MOVVconst { + break + } + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d))) + return true + } + return false +} func rewriteValueLOONG64_OpLOONG64LoweredAtomicAdd32(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] @@ -3467,6 +3519,81 @@ func rewriteValueLOONG64_OpLOONG64ORconst(v *Value) bool { } return false } +func rewriteValueLOONG64_OpLOONG64REMV(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (REMV (MOVVconst [c]) (MOVVconst [d])) + // cond: d != 0 + // result: (MOVVconst [c%d]) + for { + if v_0.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpLOONG64MOVVconst { + break + } + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(c % d) + return true + } + return false +} +func rewriteValueLOONG64_OpLOONG64REMVU(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (REMVU _ (MOVVconst [1])) + // result: (MOVVconst [0]) + for { + if v_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_1.AuxInt) != 1 { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + // match: (REMVU x (MOVVconst [c])) + // cond: isPowerOfTwo64(c) + // result: (ANDconst [c-1] x) + for { + x := v_0 + if v_1.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { + break + } + v.reset(OpLOONG64ANDconst) + v.AuxInt = int64ToAuxInt(c - 1) + v.AddArg(x) + return true + } + // match: (REMVU (MOVVconst [c]) (MOVVconst [d])) + // cond: d != 0 + // result: (MOVVconst [int64(uint64(c)%uint64(d))]) + for { + if v_0.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpLOONG64MOVVconst { + break + } + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d))) + return true + } + return false +} func rewriteValueLOONG64_OpLOONG64ROTR(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -5131,18 +5258,16 @@ func rewriteValueLOONG64_OpMod16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod16 x y) - // result: (Select0 (DIVV (SignExt16to64 x) (SignExt16to64 y))) + // result: (REMV (SignExt16to64 x) (SignExt16to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64REMV) + v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -5152,18 +5277,16 @@ func rewriteValueLOONG64_OpMod16u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod16u x y) - // result: (Select0 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y))) + // result: (REMVU (ZeroExt16to64 x) (ZeroExt16to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64REMVU) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -5173,18 +5296,16 @@ func rewriteValueLOONG64_OpMod32(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod32 x y) - // result: (Select0 (DIVV (SignExt32to64 x) (SignExt32to64 y))) + // result: (REMV (SignExt32to64 x) (SignExt32to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64REMV) + v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -5194,52 +5315,29 @@ func rewriteValueLOONG64_OpMod32u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod32u x y) - // result: (Select0 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y))) + // result: (REMVU (ZeroExt32to64 x) (ZeroExt32to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64REMVU) + v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } func rewriteValueLOONG64_OpMod64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types // match: (Mod64 x y) - // result: (Select0 (DIVV x y)) + // result: (REMV x y) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) - v0.AddArg2(x, y) - v.AddArg(v0) - return true - } -} -func rewriteValueLOONG64_OpMod64u(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod64u x y) - // result: (Select0 (DIVVU x y)) - for { - x := v_0 - y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) - v0.AddArg2(x, y) - v.AddArg(v0) + v.reset(OpLOONG64REMV) + v.AddArg2(x, y) return true } } @@ -5249,18 +5347,16 @@ func rewriteValueLOONG64_OpMod8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod8 x y) - // result: (Select0 (DIVV (SignExt8to64 x) (SignExt8to64 y))) + // result: (REMV (SignExt8to64 x) (SignExt8to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64REMV) + v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -5270,18 +5366,16 @@ func rewriteValueLOONG64_OpMod8u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod8u x y) - // result: (Select0 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y))) + // result: (REMVU (ZeroExt8to64 x) (ZeroExt8to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64REMVU) + v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -6919,93 +7013,6 @@ func rewriteValueLOONG64_OpSelect0(v *Value) bool { v.AddArg2(v0, c) return true } - // match: (Select0 (DIVVU _ (MOVVconst [1]))) - // result: (MOVVconst [0]) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(0) - return true - } - // match: (Select0 (DIVVU x (MOVVconst [c]))) - // cond: isPowerOfTwo64(c) - // result: (ANDconst [c-1] x) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - x := v_0.Args[0] - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_1.AuxInt) - if !(isPowerOfTwo64(c)) { - break - } - v.reset(OpLOONG64ANDconst) - v.AuxInt = int64ToAuxInt(c - 1) - v.AddArg(x) - return true - } - // match: (Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) - // cond: d != 0 - // result: (MOVVconst [c%d]) - for { - if v_0.Op != OpLOONG64DIVV { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_0.AuxInt) - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - d := auxIntToInt64(v_0_1.AuxInt) - if !(d != 0) { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(c % d) - return true - } - // match: (Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) - // cond: d != 0 - // result: (MOVVconst [int64(uint64(c)%uint64(d))]) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_0.AuxInt) - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - d := auxIntToInt64(v_0_1.AuxInt) - if !(d != 0) { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d))) - return true - } return false } func rewriteValueLOONG64_OpSelect1(v *Value) bool { @@ -7085,93 +7092,6 @@ func rewriteValueLOONG64_OpSelect1(v *Value) bool { v.AddArg2(v0, v2) return true } - // match: (Select1 (DIVVU x (MOVVconst [1]))) - // result: x - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - x := v_0.Args[0] - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 { - break - } - v.copyOf(x) - return true - } - // match: (Select1 (DIVVU x (MOVVconst [c]))) - // cond: isPowerOfTwo64(c) - // result: (SRLVconst [log64(c)] x) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - x := v_0.Args[0] - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_1.AuxInt) - if !(isPowerOfTwo64(c)) { - break - } - v.reset(OpLOONG64SRLVconst) - v.AuxInt = int64ToAuxInt(log64(c)) - v.AddArg(x) - return true - } - // match: (Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) - // cond: d != 0 - // result: (MOVVconst [c/d]) - for { - if v_0.Op != OpLOONG64DIVV { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_0.AuxInt) - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - d := auxIntToInt64(v_0_1.AuxInt) - if !(d != 0) { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(c / d) - return true - } - // match: (Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) - // cond: d != 0 - // result: (MOVVconst [int64(uint64(c)/uint64(d))]) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_0.AuxInt) - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - d := auxIntToInt64(v_0_1.AuxInt) - if !(d != 0) { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d))) - return true - } return false } func rewriteValueLOONG64_OpSlicemask(v *Value) bool {