]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: simplify specific addition operations using the ADDV16 instruction
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>
Wed, 3 Sep 2025 07:43:21 +0000 (15:43 +0800)
committerGopher Robot <gobot@golang.org>
Fri, 5 Sep 2025 15:18:04 +0000 (08:18 -0700)
On loong64, the addi.d instruction can only directly handle 12-bit
immediate numbers. If a larger immediate number needs to be processed,
it must first be placed in a register, and then the add.d instruction
is used to complete the processing of the larger immediate number.
If a larger immediate number c satisfies is32Bit(c) && c&0xffff == 0,
then the ADDV16 instruction can be used to complete the addition operation.

Removes 164 instructions from the go binary on loong64.

Change-Id: I404de93cc4eaaa12fe424f5a0d61b03231215d1a
Reviewed-on: https://go-review.googlesource.com/c/go/+/700536
Reviewed-by: Meidan Li <limeidan@loongson.cn>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.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 134575c85ca658e25acef3d0e097925b53a6db5f..40fa10c6de7d3d509775642185d31e90e303d8f3 100644 (file)
@@ -276,6 +276,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                p.To.Type = obj.TYPE_REG
                p.To.Reg = v.Reg()
        case ssa.OpLOONG64ADDVconst,
+               ssa.OpLOONG64ADDV16const,
                ssa.OpLOONG64SUBVconst,
                ssa.OpLOONG64ANDconst,
                ssa.OpLOONG64ORconst,
index 3fa4f363f6551594a1dd407ec20e1d6c3aa4f377..501d3745292c05e030ac07ccc1ac14e8b4b7df2b 100644 (file)
 (SUBVconst [c] (SUBVconst [d] x)) && is32Bit(-c-d) => (ADDVconst [-c-d] x)
 (SUBVconst [c] (ADDVconst [d] x)) && is32Bit(-c+d) => (ADDVconst [-c+d] x)
 (SUBV (MOVVconst [c]) (NEGV (SUBVconst [d] x))) => (ADDVconst [c-d] x)
+(ADDVconst [c] x) && is32Bit(c) && c&0xffff == 0 && c != 0 => (ADDV16const [c] x)
 (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)])
index bee619f6d93a78abc6da2e064ae14e08dce756a4..0d5e0eb76f8832ec6193eb31782f7874cc20fbe9 100644 (file)
@@ -189,10 +189,11 @@ func init() {
                {name: "VPCNT16", argLength: 1, reg: fp11, asm: "VPCNTH"}, // count set bits for each 16-bit unit and store the result in each 16-bit unit
 
                // binary ops
-               {name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true},   // arg0 + arg1
-               {name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"}, // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
-               {name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"},                      // arg0 - arg1
-               {name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"},   // arg0 - auxInt
+               {name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true},      // arg0 + arg1
+               {name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"},    // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
+               {name: "ADDV16const", argLength: 1, reg: gp11sp, asm: "ADDV16", aux: "Int64"}, // arg0 + auxInt. auxInt is signed 32-bit and is a multiple of 65536, also in other *const ops.
+               {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: 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
index 4aef2d2aa1e9c57e3a855fe012e57cd6550c77a3..d9cccb27ba90008ac31399e3b846d3658f8bab52 100644 (file)
@@ -1790,6 +1790,7 @@ const (
        OpLOONG64VPCNT16
        OpLOONG64ADDV
        OpLOONG64ADDVconst
+       OpLOONG64ADDV16const
        OpLOONG64SUBV
        OpLOONG64SUBVconst
        OpLOONG64MULV
@@ -24067,6 +24068,20 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:    "ADDV16const",
+               auxType: auxInt64,
+               argLen:  1,
+               asm:     loong64.AADDV16,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1073741820}, // SP 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:   "SUBV",
                argLen: 2,
index 5890fe050a222b8c6ff3cdbf5c42ef75d14452fd..c49ce31ae43e30c128bd8e21e8a61728a7b9af47 100644 (file)
@@ -2008,6 +2008,20 @@ func rewriteValueLOONG64_OpLOONG64ADDVconst(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (ADDVconst [c] x)
+       // cond: is32Bit(c) && c&0xffff == 0 && c != 0
+       // result: (ADDV16const [c] x)
+       for {
+               c := auxIntToInt64(v.AuxInt)
+               x := v_0
+               if !(is32Bit(c) && c&0xffff == 0 && c != 0) {
+                       break
+               }
+               v.reset(OpLOONG64ADDV16const)
+               v.AuxInt = int64ToAuxInt(c)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValueLOONG64_OpLOONG64AND(v *Value) bool {
index beabfe24eb95c75de1e3b4b5457d23a6aeeddf03..7055db3dc9f72f2f1682ecd30abd663210c666d9 100644 (file)
@@ -51,6 +51,11 @@ func AddLargeConst(a uint64, out []uint64) {
        out[9] = a - 32769
 }
 
+func AddLargeConst2(a int, out []int) {
+       // loong64: -"ADDVU","ADDV16"
+       out[0] = a + 0x10000
+}
+
 // ----------------- //
 //    Subtraction    //
 // ----------------- //