From d8e052667f6bb93eb444cc372d03a866973d4c1b Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Thu, 23 Jan 2020 03:38:31 +1100 Subject: [PATCH] cmd/internal/obj/riscv: use signed immediates for U-instructions On RISCV64, the U-instructions (AUIPC and LUI) take 20 bits, append 12 bits of zeros and sign extend to 64-bits. As such, the 20 bit immediate value is signed not unsigned. Updates #27532 Change-Id: I725215a1dc500106dbfdc0a4425f3c0b2a6f411e Reviewed-on: https://go-review.googlesource.com/c/go/+/216257 Reviewed-by: Cherry Zhang --- src/cmd/asm/internal/asm/testdata/riscvenc.s | 22 +++++++------ src/cmd/internal/obj/riscv/obj.go | 34 ++------------------ 2 files changed, 15 insertions(+), 41 deletions(-) diff --git a/src/cmd/asm/internal/asm/testdata/riscvenc.s b/src/cmd/asm/internal/asm/testdata/riscvenc.s index 3e9319954b..8a905514db 100644 --- a/src/cmd/asm/internal/asm/testdata/riscvenc.s +++ b/src/cmd/asm/internal/asm/testdata/riscvenc.s @@ -60,11 +60,13 @@ start: AUIPC $0, X10 // 17050000 AUIPC $0, X11 // 97050000 AUIPC $1, X10 // 17150000 - AUIPC $1048575, X10 // 17f5ffff + AUIPC $-524288, X15 // 97070080 + AUIPC $524287, X10 // 17f5ff7f LUI $0, X15 // b7070000 LUI $167, X15 // b7770a00 - LUI $1048575, X15 // b7f7ffff + LUI $-524288, X15 // b7070080 + LUI $524287, X15 // b7f7ff7f SLL X6, X5, X7 // b3936200 SLL X5, X6 // 33135300 @@ -89,15 +91,15 @@ start: // to 2 because they transfer control to the second instruction // in the function (the first instruction being an invisible // stack pointer adjustment). - JAL X5, start // JAL X5, 2 // eff2dff0 + JAL X5, start // JAL X5, 2 // eff25ff0 JALR X6, (X5) // 67830200 JALR X6, 4(X5) // 67834200 - BEQ X5, X6, start // BEQ X5, X6, 2 // e38062f0 - BNE X5, X6, start // BNE X5, X6, 2 // e39e62ee - BLT X5, X6, start // BLT X5, X6, 2 // e3cc62ee - BLTU X5, X6, start // BLTU X5, X6, 2 // e3ea62ee - BGE X5, X6, start // BGE X5, X6, 2 // e3d862ee - BGEU X5, X6, start // BGEU X5, X6, 2 // e3f662ee + BEQ X5, X6, start // BEQ X5, X6, 2 // e38c62ee + BNE X5, X6, start // BNE X5, X6, 2 // e39a62ee + BLT X5, X6, start // BLT X5, X6, 2 // e3c862ee + BLTU X5, X6, start // BLTU X5, X6, 2 // e3e662ee + BGE X5, X6, start // BGE X5, X6, 2 // e3d462ee + BGEU X5, X6, start // BGEU X5, X6, 2 // e3f262ee // 2.6: Load and Store Instructions LW (X5), X6 // 03a30200 @@ -271,7 +273,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 // 6ff05fcd + JMP start // JMP 2 // 6ff0dfcc JMP (X5) // 67800200 JMP 4(X5) // 67804200 diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 6b36a94daa..e90769eb20 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -1287,13 +1287,6 @@ func immIFits(x int64, nbits uint) bool { return min <= x && x <= max } -// immUFits reports whether immediate value x fits in nbits bits -// as an unsigned integer. -func immUFits(x int64, nbits uint) bool { - var max int64 = 1< max { p.Ctxt.Diag("%v\texpected %s register in %s position but got non-%s register %s", p, descr, pos, descr, RegName(int(r))) @@ -1457,7 +1429,7 @@ func validateU(p *obj.Prog) { // to represent this state? return } - wantImmU(p, "from", p.From, 20) + wantImmI(p, "from", p.From, 20) wantIntRegAddr(p, "to", &p.To) } @@ -1578,7 +1550,7 @@ func encodeU(p *obj.Prog) uint32 { // Rather than have the user/compiler generate a 32 bit constant, the // bottommost bits of which must all be zero, instead accept just the // top bits. - imm := immU(p.From, 20) + imm := immI(p.From, 20) rd := regIAddr(p.To) ins := encode(p.As) if ins == nil { @@ -1627,7 +1599,7 @@ func EncodeSImmediate(imm int64) (int64, error) { } func EncodeUImmediate(imm int64) (int64, error) { - if !immUFits(imm, 20) { + if !immIFits(imm, 20) { return 0, fmt.Errorf("immediate %#x does not fit in 20 bits", imm) } return imm << 12, nil -- 2.50.0