From: Joel Sing Date: Thu, 16 Jan 2020 15:51:40 +0000 (+1100) Subject: cmd/internal/obj/riscv: correctly split immediates for FLW/FLD/FSW/FSD X-Git-Tag: go1.14rc1~92 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1424889921159ed28866dff40b5d54884aaddd9c;p=gostls13.git cmd/internal/obj/riscv: correctly split immediates for FLW/FLD/FSW/FSD 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 Reviewed-by: Cherry Zhang Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/internal/obj/riscv/asm_test.go b/src/cmd/internal/obj/riscv/asm_test.go index 0fe0cafcb2..849a87b706 100644 --- a/src/cmd/internal/obj/riscv/asm_test.go +++ b/src/cmd/internal/obj/riscv/asm_test.go @@ -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) + } +} diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 721908fe9d..2da95122d9 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -716,11 +716,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // $imm, REG, TO (load $imm+(REG), TO) // $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 // $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 // $low, REG, TMP