mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <me@carlosedp.com> Reviewed-by: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
88ed322afc
commit
1424889921
2 changed files with 58 additions and 7 deletions
|
|
@ -77,3 +77,57 @@ func TestNoRet(t *testing.T) {
|
||||||
t.Errorf("%v\n%s", err, out)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -716,11 +716,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
|
|
||||||
// <load> $imm, REG, TO (load $imm+(REG), TO)
|
// <load> $imm, REG, TO (load $imm+(REG), TO)
|
||||||
// <store> $imm, REG, TO (store $imm+(TO), REG)
|
// <store> $imm, REG, TO (store $imm+(TO), REG)
|
||||||
case ALD, ALB, ALH, ALW, ALBU, ALHU, ALWU,
|
case ALB, ALH, ALW, ALD, ALBU, ALHU, ALWU, AFLW, AFLD, ASB, ASH, ASW, ASD, AFSW, AFSD:
|
||||||
ASD, ASB, ASH, ASW:
|
|
||||||
// LUI $high, TMP
|
|
||||||
// ADDI $low, TMP, TMP
|
|
||||||
q := *p
|
|
||||||
low, high, err := Split32BitImmediate(p.From.Offset)
|
low, high, err := Split32BitImmediate(p.From.Offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxt.Diag("%v: constant %d too large", p, p.From.Offset)
|
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
|
break // no need to split
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q := *p
|
||||||
switch q.As {
|
switch q.As {
|
||||||
case ALD, ALB, ALH, ALW, ALBU, ALHU, ALWU:
|
case ALB, ALH, ALW, ALD, ALBU, ALHU, ALWU, AFLW, AFLD:
|
||||||
// LUI $high, TMP
|
// LUI $high, TMP
|
||||||
// ADD TMP, REG, TMP
|
// ADD TMP, REG, TMP
|
||||||
// <load> $low, TMP, TO
|
// <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.From = obj.Addr{Type: obj.TYPE_CONST, Offset: low}
|
||||||
p.Reg = REG_TMP
|
p.Reg = REG_TMP
|
||||||
|
|
||||||
case ASD, ASB, ASH, ASW:
|
case ASB, ASH, ASW, ASD, AFSW, AFSD:
|
||||||
// LUI $high, TMP
|
// LUI $high, TMP
|
||||||
// ADD TMP, TO, TMP
|
// ADD TMP, TO, TMP
|
||||||
// <store> $low, REG, TMP
|
// <store> $low, REG, TMP
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue