]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/riscv: improve code generation for loading of constants
authorJoel Sing <joel@sing.id.au>
Mon, 9 Aug 2021 08:14:04 +0000 (08:14 +0000)
committerJoel Sing <joel@sing.id.au>
Sat, 4 Sep 2021 19:33:54 +0000 (19:33 +0000)
Loading of constants that are 12 bits or smaller is currently performed using a single
ADDIW instruction, while constants between 13 bits and 32 bits are loaded using a
LUI+ADDIW pair.

Instead, use a single ADDI instruction for the 12 bits or smaller case - this
translates to the LI pseudo-instruction, making objdump more readable and giving:

   11c7c:       fff00293                li      t0,-1
   11c80:       00000313                li      t1,0

Rather than:

   11c7c:       fff0029b                addiw   t0,zero,-1
   11c80:       0000031b                sext.w  t1,zero

In the case where a constant exceeds 12 bits, an LUI instruction is required,
however if the lower 12 bits are zero, the ADDIW instruction can be omitted.
The same applies to the case where immediate splitting is performed for other
immediate instructions.

This removes around 900 instructions from the Go binary.

Change-Id: Id6c77774b3b429fa525da018a6926b85df838a2f
Reviewed-on: https://go-review.googlesource.com/c/go/+/344457
Trust: Joel Sing <joel@sing.id.au>
Run-TryBot: Joel Sing <joel@sing.id.au>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/asm/internal/asm/testdata/riscv64.s
src/cmd/internal/obj/riscv/obj.go

index 5a209ac17ec33347aa363f5583045baea50cdc8e..1977d92f62a35692a612e6bfa1431bf5bc030392 100644 (file)
@@ -295,10 +295,14 @@ start:
 
        // MOV pseudo-instructions
        MOV     X5, X6                                  // 13830200
-       MOV     $2047, X5                               // 9b02f07f
-       MOV     $-2048, X5                              // 9b020080
+       MOV     $2047, X5                               // 9302f07f
+       MOV     $-2048, X5                              // 93020080
        MOV     $2048, X5                               // b71200009b820280
        MOV     $-2049, X5                              // b7f2ffff9b82f27f
+       MOV     $4096, X5                               // b7120000
+       MOV     $2147479552, X5                         // b7f2ff7f
+       MOV     $2147483647, X5                         // b70200809b82f2ff
+       MOV     $-2147483647, X5                        // b70200809b821200
 
        // Converted to load of symbol (AUIPC + LD)
        MOV     $4294967296, X5                         // 9702000083b20200
index b4aded3768c4c60071fbc36a1000ff3ecf934c58..1140542739013fc8ed73a9f33f40195411c90628 100644 (file)
@@ -1669,6 +1669,9 @@ func instructionsForOpImmediate(p *obj.Prog, as obj.As, rs int16) []*instruction
                return nil
        }
        ins.rs2 = REG_TMP
+       if low == 0 {
+               return []*instruction{insLUI, ins}
+       }
        return []*instruction{insLUI, insADDIW, ins}
 }
 
@@ -1768,7 +1771,7 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
                }
 
                // MOV $c, R -> ADD $c, ZERO, R
-               ins.as, ins.rs1, ins.rs2, ins.imm = AADDIW, REG_ZERO, obj.REG_NONE, low
+               ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, REG_ZERO, obj.REG_NONE, low
 
                // LUI is only necessary if the constant does not fit in 12 bits.
                if high == 0 {
@@ -1778,8 +1781,11 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
                // LUI top20bits(c), R
                // ADD bottom12bits(c), R, R
                insLUI := &instruction{as: ALUI, rd: ins.rd, imm: high}
-               ins.rs1 = ins.rd
-               inss = []*instruction{insLUI, ins}
+               inss = []*instruction{insLUI}
+               if low != 0 {
+                       ins.as, ins.rs1 = AADDIW, ins.rd
+                       inss = append(inss, ins)
+               }
 
        case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_REG:
                // Handle register to register moves.