]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/riscv: support additional register to register moves
authorJoel Sing <joel@sing.id.au>
Fri, 23 Oct 2020 16:53:53 +0000 (03:53 +1100)
committerJoel Sing <joel@sing.id.au>
Sat, 24 Oct 2020 08:12:11 +0000 (08:12 +0000)
Add support for signed and unsigned register to register moves of various
sizes. This makes it easier to handle zero and sign extension and will allow
for further changes that improve the compiler optimisations for riscv64.

While here, change the existing register to register moves from obj.Prog
rewriting to instruction generation.

Change-Id: Id21911019b76922367a134da13c3449a84a1fb08
Reviewed-on: https://go-review.googlesource.com/c/go/+/264657
Trust: Joel Sing <joel@sing.id.au>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/asm/internal/asm/testdata/riscvenc.s
src/cmd/internal/obj/riscv/obj.go

index 8d301f2dd5e36851dcd851d5aea22484d484409e..e30a576473d74aa7b97892fc66a90c00a7d1896c 100644 (file)
@@ -297,6 +297,13 @@ start:
        MOVW    X5, (X6)                                // 23205300
        MOVW    X5, 4(X6)                               // 23225300
 
+       MOVB    X5, X6                                  // 1393820313538343
+       MOVH    X5, X6                                  // 1393020313530343
+       MOVW    X5, X6                                  // 1b830200
+       MOVBU   X5, X6                                  // 13f3f20f
+       MOVHU   X5, X6                                  // 1393020313530303
+       MOVWU   X5, X6                                  // 1393020213530302
+
        MOVF    4(X5), F0                               // 07a04200
        MOVF    F0, 4(X5)                               // 27a20200
        MOVF    F0, F1                                  // d3000020
@@ -318,7 +325,7 @@ start:
        // These jumps can get printed as jumps to 2 because they go to the
        // second instruction in the function (the first instruction is an
        // invisible stack pointer adjustment).
-       JMP     start           // JMP  2               // 6ff01fc5
+       JMP     start           // JMP  2               // 6ff09fc2
        JMP     (X5)                                    // 67800200
        JMP     4(X5)                                   // 67804200
 
@@ -331,16 +338,16 @@ start:
        JMP     asmtest(SB)                             // 970f0000
 
        // Branch pseudo-instructions
-       BEQZ    X5, start       // BEQZ X5, 2           // e38a02c2
-       BGEZ    X5, start       // BGEZ X5, 2           // e3d802c2
-       BGT     X5, X6, start   // BGT  X5, X6, 2       // e3c662c2
-       BGTU    X5, X6, start   // BGTU X5, X6, 2       // e3e462c2
-       BGTZ    X5, start       // BGTZ X5, 2           // e34250c2
-       BLE     X5, X6, start   // BLE  X5, X6, 2       // e3d062c2
-       BLEU    X5, X6, start   // BLEU X5, X6, 2       // e3fe62c0
-       BLEZ    X5, start       // BLEZ X5, 2           // e35c50c0
-       BLTZ    X5, start       // BLTZ X5, 2           // e3ca02c0
-       BNEZ    X5, start       // BNEZ X5, 2           // e39802c0
+       BEQZ    X5, start       // BEQZ X5, 2           // e38602c0
+       BGEZ    X5, start       // BGEZ X5, 2           // e3d402c0
+       BGT     X5, X6, start   // BGT  X5, X6, 2       // e3c262c0
+       BGTU    X5, X6, start   // BGTU X5, X6, 2       // e3e062c0
+       BGTZ    X5, start       // BGTZ X5, 2           // e34e50be
+       BLE     X5, X6, start   // BLE  X5, X6, 2       // e3dc62be
+       BLEU    X5, X6, start   // BLEU X5, X6, 2       // e3fa62be
+       BLEZ    X5, start       // BLEZ X5, 2           // e35850be
+       BLTZ    X5, start       // BLTZ X5, 2           // e3c602be
+       BNEZ    X5, start       // BNEZ X5, 2           // e39402be
 
        // Set pseudo-instructions
        SEQZ    X15, X15                                // 93b71700
index 045c2250b5ef45487fe89f430800d08e6e05cb41..7bd3984e51db671b0c180b1246a8591f9609ee20 100644 (file)
@@ -252,19 +252,7 @@ func rewriteMOV(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog) {
                switch p.To.Type {
                case obj.TYPE_REG:
                        switch p.As {
-                       case AMOV: // MOV Ra, Rb -> ADDI $0, Ra, Rb
-                               p.As = AADDI
-                               p.Reg = p.From.Reg
-                               p.From = obj.Addr{Type: obj.TYPE_CONST}
-
-                       case AMOVF: // MOVF Ra, Rb -> FSGNJS Ra, Ra, Rb
-                               p.As = AFSGNJS
-                               p.Reg = p.From.Reg
-
-                       case AMOVD: // MOVD Ra, Rb -> FSGNJD Ra, Ra, Rb
-                               p.As = AFSGNJD
-                               p.Reg = p.From.Reg
-
+                       case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
                        default:
                                ctxt.Diag("unsupported register-register move at %v", p)
                        }
@@ -1805,6 +1793,44 @@ func instructionsForProg(p *obj.Prog) []*instruction {
                }
                ins.imm = p.To.Offset
 
+       case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
+               // Handle register to register moves.
+               if p.From.Type != obj.TYPE_REG || p.To.Type != obj.TYPE_REG {
+                       break
+               }
+               switch p.As {
+               case AMOV: // MOV Ra, Rb -> ADDI $0, Ra, Rb
+                       ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, uint32(p.From.Reg), obj.REG_NONE, 0
+               case AMOVW: // MOVW Ra, Rb -> ADDIW $0, Ra, Rb
+                       ins.as, ins.rs1, ins.rs2, ins.imm = AADDIW, uint32(p.From.Reg), obj.REG_NONE, 0
+               case AMOVBU: // MOVBU Ra, Rb -> ANDI $255, Ra, Rb
+                       ins.as, ins.rs1, ins.rs2, ins.imm = AANDI, uint32(p.From.Reg), obj.REG_NONE, 255
+               case AMOVF: // MOVF Ra, Rb -> FSGNJS Ra, Ra, Rb
+                       ins.as, ins.rs1 = AFSGNJS, uint32(p.From.Reg)
+               case AMOVD: // MOVD Ra, Rb -> FSGNJD Ra, Ra, Rb
+                       ins.as, ins.rs1 = AFSGNJD, uint32(p.From.Reg)
+               case AMOVB, AMOVH:
+                       // Use SLLI/SRAI to extend.
+                       ins.as, ins.rs1, ins.rs2 = ASLLI, uint32(p.From.Reg), obj.REG_NONE
+                       if p.As == AMOVB {
+                               ins.imm = 56
+                       } else if p.As == AMOVH {
+                               ins.imm = 48
+                       }
+                       ins2 := &instruction{as: ASRAI, rd: ins.rd, rs1: ins.rd, imm: ins.imm}
+                       inss = append(inss, ins2)
+               case AMOVHU, AMOVWU:
+                       // Use SLLI/SRLI to extend.
+                       ins.as, ins.rs1, ins.rs2 = ASLLI, uint32(p.From.Reg), obj.REG_NONE
+                       if p.As == AMOVHU {
+                               ins.imm = 48
+                       } else if p.As == AMOVWU {
+                               ins.imm = 32
+                       }
+                       ins2 := &instruction{as: ASRLI, rd: ins.rd, rs1: ins.rd, imm: ins.imm}
+                       inss = append(inss, ins2)
+               }
+
        case ALW, ALWU, ALH, ALHU, ALB, ALBU, ALD, AFLW, AFLD:
                if p.From.Type != obj.TYPE_MEM {
                        p.Ctxt.Diag("%v requires memory for source", p)
@@ -1859,13 +1885,13 @@ func instructionsForProg(p *obj.Prog) []*instruction {
                } else {
                        ins.as = AFEQD
                }
-               ins = &instruction{
+               ins2 := &instruction{
                        as:  AXORI, // [bit] xor 1 = not [bit]
                        rd:  ins.rd,
                        rs1: ins.rd,
                        imm: 1,
                }
-               inss = append(inss, ins)
+               inss = append(inss, ins2)
 
        case AFSQRTS, AFSQRTD:
                // These instructions expect a zero (i.e. float register 0)