]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/riscv: absorb rewriteMOV into instruction generation
authorJoel Sing <joel@sing.id.au>
Sat, 21 Aug 2021 09:06:25 +0000 (09:06 +0000)
committerJoel Sing <joel@sing.id.au>
Wed, 8 Sep 2021 06:38:19 +0000 (06:38 +0000)
Replace the now poorly named rewriteMOV function with a markRelocs function,
absorbing the MOV validation into the instruction generation code.

Change-Id: I6ae94553f7f300862c40310343ef0be8f44a4b0f
Reviewed-on: https://go-review.googlesource.com/c/go/+/344459
Trust: Joel Sing <joel@sing.id.au>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/internal/obj/riscv/obj.go

index 443f761ad91ce07734251b1f693726036f3b6f7f..fd5026f25b2ea0bddabd5b96bd98e97361df7723 100644 (file)
@@ -218,64 +218,28 @@ func movToStore(mnemonic obj.As) obj.As {
        }
 }
 
-// rewriteMOV rewrites MOV pseudo-instructions.
-func rewriteMOV(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog) {
+// markRelocs marks an obj.Prog that specifies a MOV pseudo-instruction and
+// requires relocation.
+func markRelocs(p *obj.Prog) {
        switch p.As {
        case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
-       default:
-               panic(fmt.Sprintf("%+v is not a MOV pseudo-instruction", p.As))
-       }
-
-       switch {
-       case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_REG:
-
-       case p.From.Type == obj.TYPE_MEM && p.To.Type == obj.TYPE_REG:
-               switch p.From.Name {
-               case obj.NAME_AUTO, obj.NAME_NONE, obj.NAME_PARAM:
-               case obj.NAME_EXTERN, obj.NAME_STATIC:
-                       p.Mark |= NEED_PCREL_ITYPE_RELOC
-               default:
-                       ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
-               }
-
-       case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_MEM:
-               switch p.As {
-               case AMOVBU, AMOVHU, AMOVWU:
-                       ctxt.Diag("unsupported unsigned store at %v", p)
-               }
-               switch p.To.Name {
-               case obj.NAME_AUTO, obj.NAME_NONE, obj.NAME_PARAM:
-               case obj.NAME_EXTERN, obj.NAME_STATIC:
-                       p.Mark |= NEED_PCREL_STYPE_RELOC
-               default:
-                       ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
-               }
-
-       case p.From.Type == obj.TYPE_CONST:
-               if p.As != AMOV {
-                       ctxt.Diag("%v: unsupported constant load", p)
-               }
-               if p.To.Type != obj.TYPE_REG {
-                       ctxt.Diag("%v: constant load must target register", p)
-               }
-
-       case p.From.Type == obj.TYPE_ADDR:
-               if p.As != AMOV {
-                       ctxt.Diag("%v: unsupported address load", p)
-               }
-               if p.To.Type != obj.TYPE_REG {
-                       ctxt.Diag("%v: address load must target register", p)
-               }
-               switch p.From.Name {
-               case obj.NAME_AUTO, obj.NAME_NONE, obj.NAME_PARAM:
-               case obj.NAME_EXTERN, obj.NAME_STATIC:
-                       p.Mark |= NEED_PCREL_ITYPE_RELOC
-               default:
-                       ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
+               switch {
+               case p.From.Type == obj.TYPE_ADDR && p.To.Type == obj.TYPE_REG:
+                       switch p.From.Name {
+                       case obj.NAME_EXTERN, obj.NAME_STATIC:
+                               p.Mark |= NEED_PCREL_ITYPE_RELOC
+                       }
+               case p.From.Type == obj.TYPE_MEM && p.To.Type == obj.TYPE_REG:
+                       switch p.From.Name {
+                       case obj.NAME_EXTERN, obj.NAME_STATIC:
+                               p.Mark |= NEED_PCREL_ITYPE_RELOC
+                       }
+               case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_MEM:
+                       switch p.To.Name {
+                       case obj.NAME_EXTERN, obj.NAME_STATIC:
+                               p.Mark |= NEED_PCREL_STYPE_RELOC
+                       }
                }
-
-       default:
-               ctxt.Diag("unsupported MOV at %v", p)
        }
 }
 
@@ -641,14 +605,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                }
        }
 
-       // Rewrite MOV pseudo-instructions. This cannot be done in
-       // progedit, as SP offsets need to be applied before we split
-       // up some of the Addrs.
        for p := cursym.Func().Text; p != nil; p = p.Link {
-               switch p.As {
-               case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
-                       rewriteMOV(ctxt, newprog, p)
-               }
+               markRelocs(p)
        }
 
        // Compute instruction addresses.  Once we do that, we need to check for
@@ -1746,6 +1704,11 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
        switch {
        case p.From.Type == obj.TYPE_CONST && p.To.Type == obj.TYPE_REG:
                // Handle constant to register moves.
+               if p.As != AMOV {
+                       p.Ctxt.Diag("%v: unsupported constant load", p)
+                       return nil
+               }
+
                low, high, err := Split32BitImmediate(ins.imm)
                if err != nil {
                        p.Ctxt.Diag("%v: constant %d too large: %v", p, ins.imm, err)
@@ -1769,6 +1732,10 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
                        inss = append(inss, ins)
                }
 
+       case p.From.Type == obj.TYPE_CONST && p.To.Type != obj.TYPE_REG:
+               p.Ctxt.Diag("%v: constant load must target register", p)
+               return nil
+
        case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_REG:
                // Handle register to register moves.
                switch p.As {
@@ -1820,13 +1787,17 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
                        insAUIPC := &instruction{as: AAUIPC, rd: ins.rd}
                        ins.as, ins.rs1, ins.rs2, ins.imm = movToLoad(p.As), ins.rd, obj.REG_NONE, 0
                        inss = []*instruction{insAUIPC, ins}
+
+               default:
+                       p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
+                       return nil
                }
 
        case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_MEM:
                // Register to memory stores.
                switch p.As {
                case AMOVBU, AMOVHU, AMOVWU:
-                       // rewriteMOV should have already added an error for these.
+                       p.Ctxt.Diag("%v: unsupported unsigned store", p)
                        return nil
                }
                switch p.To.Name {
@@ -1843,11 +1814,18 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
                        insAUIPC := &instruction{as: AAUIPC, rd: REG_TMP}
                        ins.as, ins.rd, ins.rs1, ins.rs2, ins.imm = movToStore(p.As), REG_TMP, uint32(p.From.Reg), obj.REG_NONE, 0
                        inss = []*instruction{insAUIPC, ins}
+
+               default:
+                       p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
+                       return nil
                }
 
        case p.From.Type == obj.TYPE_ADDR && p.To.Type == obj.TYPE_REG:
                // MOV $sym+off(SP/SB), R
-
+               if p.As != AMOV {
+                       p.Ctxt.Diag("%v: unsupported address load", p)
+                       return nil
+               }
                switch p.From.Name {
                case obj.NAME_AUTO, obj.NAME_PARAM, obj.NAME_NONE:
                        inss = instructionsForOpImmediate(p, AADDI, addrToReg(p.From))
@@ -1861,15 +1839,19 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
                        insAUIPC := &instruction{as: AAUIPC, rd: ins.rd}
                        ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, ins.rd, obj.REG_NONE, 0
                        inss = []*instruction{insAUIPC, ins}
-               }
 
-       default:
-               // If we get here with a MOV pseudo-instruction it is going to
-               // remain unhandled. For now we trust rewriteMOV to catch these.
-               switch p.As {
-               case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
+               default:
+                       p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
                        return nil
                }
+
+       case p.From.Type == obj.TYPE_ADDR && p.To.Type != obj.TYPE_REG:
+               p.Ctxt.Diag("%v: address load must target register", p)
+               return nil
+
+       default:
+               p.Ctxt.Diag("%v: unsupported MOV", p)
+               return nil
        }
 
        return inss