]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use 32x32->64 multiplies on loong64
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>
Tue, 18 Nov 2025 05:00:15 +0000 (13:00 +0800)
committerabner chenc <chenguoqi@loongson.cn>
Mon, 24 Nov 2025 07:54:44 +0000 (23:54 -0800)
Gets rid of some sign extensions, like arm64.

Change-Id: I9fc37e15a82718bfcf53db8cab0c4e7baaa0a747
Reviewed-on: https://go-review.googlesource.com/c/go/+/721522
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Meidan Li <limeidan@loongson.cn>
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/loong64/ssa.go
src/cmd/compile/internal/ssa/_gen/LOONG64.rules
src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteLOONG64.go
test/codegen/arithmetic.go

index 71953109c464b3e186872f871d124414af53c2e7..dc737732f1b09da786be795614f7f615a0eee19f 100644 (file)
@@ -187,6 +187,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                ssa.OpLOONG64DIVD,
                ssa.OpLOONG64MULV, ssa.OpLOONG64MULHV, ssa.OpLOONG64MULHVU, ssa.OpLOONG64MULH, ssa.OpLOONG64MULHU,
                ssa.OpLOONG64DIVV, ssa.OpLOONG64REMV, ssa.OpLOONG64DIVVU, ssa.OpLOONG64REMVU,
+               ssa.OpLOONG64MULWVW, ssa.OpLOONG64MULWVWU,
                ssa.OpLOONG64FCOPYSGD:
                p := s.Prog(v.Op.Asm())
                p.From.Type = obj.TYPE_REG
index 2beba0b1c5caa246ef7420f84a0d0ec017a767e8..b15043032c075547562285232a824d5e330b93bb 100644 (file)
 (Select0 (Mul64uover x y)) => (MULV x y)
 (Select1 (Mul64uover x y)) => (SGTU <typ.Bool> (MULHVU x y) (MOVVconst <typ.UInt64> [0]))
 
+// 32 mul 32 -> 64
+(MULV r:(MOVWUreg x) s:(MOVWUreg y)) && r.Uses == 1 && s.Uses == 1 => (MULWVWU x y)
+(MULV r:(MOVWreg  x) s:(MOVWreg  y)) && r.Uses == 1 && s.Uses == 1 =>  (MULWVW x y)
+
 (Hmul64 ...)  => (MULHV  ...)
 (Hmul64u ...) => (MULHVU ...)
 (Hmul32 ...)  => (MULH  ...)
index 81d3a3665bdb4fb34acd3b03ea9fc1e125e03b07..9fd5ede869ee6ddf1c08e9429779c36f42721217 100644 (file)
@@ -205,6 +205,8 @@ func init() {
                {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: "MULWVW", argLength: 2, reg: gp21, asm: "MULWVW", commutative: true},                // arg0 * arg1, signed, 32-bit mult results in 64-bit
+               {name: "MULWVWU", argLength: 2, reg: gp21, asm: "MULWVWU", commutative: true},              // arg0 * arg1, unsigned, 32-bit mult results in 64-bit
 
                {name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
                {name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
index f13373d2c05f75dfccfad0c81e5bfc27dedb6616..26ab2cacce23da034016e4c542c9e9263ebada56 100644 (file)
@@ -1814,6 +1814,8 @@ const (
        OpLOONG64DIVVU
        OpLOONG64REMV
        OpLOONG64REMVU
+       OpLOONG64MULWVW
+       OpLOONG64MULWVWU
        OpLOONG64ADDF
        OpLOONG64ADDD
        OpLOONG64SUBF
@@ -24380,6 +24382,36 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:        "MULWVW",
+               argLen:      2,
+               commutative: true,
+               asm:         loong64.AMULWVW,
+               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
+                               {1, 1073741817}, // ZERO 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:        "MULWVWU",
+               argLen:      2,
+               commutative: true,
+               asm:         loong64.AMULWVWU,
+               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
+                               {1, 1073741817}, // ZERO 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:        "ADDF",
                argLen:      2,
index bf2dd114a93a33d8bc5702b4648d7bcc2276fec0..30ce419d40a428965faa0d9863d2ffa1ffc204bb 100644 (file)
@@ -5866,6 +5866,54 @@ func rewriteValueLOONG64_OpLOONG64MULV(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       // match: (MULV r:(MOVWUreg x) s:(MOVWUreg y))
+       // cond: r.Uses == 1 && s.Uses == 1
+       // result: (MULWVWU x y)
+       for {
+               for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+                       r := v_0
+                       if r.Op != OpLOONG64MOVWUreg {
+                               continue
+                       }
+                       x := r.Args[0]
+                       s := v_1
+                       if s.Op != OpLOONG64MOVWUreg {
+                               continue
+                       }
+                       y := s.Args[0]
+                       if !(r.Uses == 1 && s.Uses == 1) {
+                               continue
+                       }
+                       v.reset(OpLOONG64MULWVWU)
+                       v.AddArg2(x, y)
+                       return true
+               }
+               break
+       }
+       // match: (MULV r:(MOVWreg x) s:(MOVWreg y))
+       // cond: r.Uses == 1 && s.Uses == 1
+       // result: (MULWVW x y)
+       for {
+               for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+                       r := v_0
+                       if r.Op != OpLOONG64MOVWreg {
+                               continue
+                       }
+                       x := r.Args[0]
+                       s := v_1
+                       if s.Op != OpLOONG64MOVWreg {
+                               continue
+                       }
+                       y := s.Args[0]
+                       if !(r.Uses == 1 && s.Uses == 1) {
+                               continue
+                       }
+                       v.reset(OpLOONG64MULWVW)
+                       v.AddArg2(x, y)
+                       return true
+               }
+               break
+       }
        // match: (MULV _ (MOVVconst [0]))
        // result: (MOVVconst [0])
        for {
index 29764bf817b3f1b63b0fa0e511a2360f29a2b734..7cc6cf77e1d95c4fa1a081956988b30bb08b1961 100644 (file)
@@ -335,11 +335,13 @@ func Fold2NegMul(a, b int) int {
 
 func Mul32(a, b int32) int64 {
        // arm64:"SMULL" -"MOVW"
+       // loong64:"MULWVW" -"MOVW"
        return int64(a) * int64(b)
 }
 
 func Mul32U(a, b uint32) uint64 {
        // arm64:"UMULL" -"MOVWU"
+       // loong64:"MULWVWU" -"MOVWU"
        return uint64(a) * uint64(b)
 }