]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/riscv: correctly split immediates for FLW/FLD/FSW/FSD
authorJoel Sing <joel@sing.id.au>
Thu, 16 Jan 2020 15:51:40 +0000 (02:51 +1100)
committerJoel Sing <joel@sing.id.au>
Tue, 21 Jan 2020 23:58:09 +0000 (23:58 +0000)
The FLW/FLD/FSW/FSD instructions can have immediates that exceed 12-bits and
therefore cannot be encoded in the RISCV instruction. Handle these as we do
for other load/store instructions. Also add test coverage for all load/store
instructions with large immediates.

Fixes compilation issue reported by Carlos Eduardo de Paula.

Updates #27532

Change-Id: Ifa62f19493b3acaba5a90ac31d2df209a3afea81
Reviewed-on: https://go-review.googlesource.com/c/go/+/215037
Reviewed-by: Carlos Eduardo de Paula <me@carlosedp.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/internal/obj/riscv/asm_test.go
src/cmd/internal/obj/riscv/obj.go

index 0fe0cafcb21c034d4ed005fceebd6ad8ab9fa3bf..849a87b7063ef861ea613c4c7b0daf42137c3220 100644 (file)
@@ -77,3 +77,57 @@ func TestNoRet(t *testing.T) {
                t.Errorf("%v\n%s", err, out)
        }
 }
+
+func TestImmediateSplitting(t *testing.T) {
+       dir, err := ioutil.TempDir("", "testimmsplit")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer os.RemoveAll(dir)
+       tmpfile := filepath.Join(dir, "x.s")
+       asm := `
+TEXT _stub(SB),$0-0
+       LB      4096(X5), X6
+       LH      4096(X5), X6
+       LW      4096(X5), X6
+       LD      4096(X5), X6
+       LBU     4096(X5), X6
+       LHU     4096(X5), X6
+       LWU     4096(X5), X6
+       SB      X6, 4096(X5)
+       SH      X6, 4096(X5)
+       SW      X6, 4096(X5)
+       SD      X6, 4096(X5)
+
+       FLW     4096(X5), F6
+       FLD     4096(X5), F6
+       FSW     F6, 4096(X5)
+       FSD     F6, 4096(X5)
+
+       MOVB    4096(X5), X6
+       MOVH    4096(X5), X6
+       MOVW    4096(X5), X6
+       MOV     4096(X5), X6
+       MOVBU   4096(X5), X6
+       MOVHU   4096(X5), X6
+       MOVWU   4096(X5), X6
+
+       MOVB    X6, 4096(X5)
+       MOVH    X6, 4096(X5)
+       MOVW    X6, 4096(X5)
+       MOV     X6, 4096(X5)
+
+       MOVF    4096(X5), F6
+       MOVD    4096(X5), F6
+       MOVF    F6, 4096(X5)
+       MOVD    F6, 4096(X5)
+`
+       if err := ioutil.WriteFile(tmpfile, []byte(asm), 0644); err != nil {
+               t.Fatal(err)
+       }
+       cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+       cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
+       if out, err := cmd.CombinedOutput(); err != nil {
+               t.Errorf("%v\n%s", err, out)
+       }
+}
index 721908fe9d783a85c447c281db7caf553418af24..2da95122d95b6d25a4e1adcc041cb92f17e96576 100644 (file)
@@ -716,11 +716,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 
                // <load> $imm, REG, TO (load $imm+(REG), TO)
                // <store> $imm, REG, TO (store $imm+(TO), REG)
-               case ALD, ALB, ALH, ALW, ALBU, ALHU, ALWU,
-                       ASD, ASB, ASH, ASW:
-                       // LUI $high, TMP
-                       // ADDI $low, TMP, TMP
-                       q := *p
+               case ALB, ALH, ALW, ALD, ALBU, ALHU, ALWU, AFLW, AFLD, ASB, ASH, ASW, ASD, AFSW, AFSD:
                        low, high, err := Split32BitImmediate(p.From.Offset)
                        if err != nil {
                                ctxt.Diag("%v: constant %d too large", p, p.From.Offset)
@@ -729,8 +725,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                break // no need to split
                        }
 
+                       q := *p
                        switch q.As {
-                       case ALD, ALB, ALH, ALW, ALBU, ALHU, ALWU:
+                       case ALB, ALH, ALW, ALD, ALBU, ALHU, ALWU, AFLW, AFLD:
                                // LUI $high, TMP
                                // ADD TMP, REG, TMP
                                // <load> $low, TMP, TO
@@ -752,7 +749,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: low}
                                p.Reg = REG_TMP
 
-                       case ASD, ASB, ASH, ASW:
+                       case ASB, ASH, ASW, ASD, AFSW, AFSD:
                                // LUI $high, TMP
                                // ADD TMP, TO, TMP
                                // <store> $low, REG, TMP