From: Joel Sing Date: Wed, 18 Sep 2019 16:34:06 +0000 (+1000) Subject: cmd/internal/obj/riscv: implement AUIPC and LUI instructions X-Git-Tag: go1.14beta1~956 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=430d2aa3493c3a057f83af886cd866291cbf04ea;p=gostls13.git cmd/internal/obj/riscv: implement AUIPC and LUI instructions Add support for assembling AUIPC and LUI instructions. Based on the riscv-go port. Updates #27532 Change-Id: I178868b6dcc6fdc6b8527454569a3538ed50723e Reviewed-on: https://go-review.googlesource.com/c/go/+/196840 Reviewed-by: Cherry Zhang Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/asm/internal/asm/testdata/riscvenc.s b/src/cmd/asm/internal/asm/testdata/riscvenc.s index f0d31fda87..c58bb0fe07 100644 --- a/src/cmd/asm/internal/asm/testdata/riscvenc.s +++ b/src/cmd/asm/internal/asm/testdata/riscvenc.s @@ -57,6 +57,15 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 XOR $1, X5, X6 // 13c31200 XOR $1, X5 // 93c21200 + AUIPC $0, X10 // 17050000 + AUIPC $0, X11 // 97050000 + AUIPC $1, X10 // 17150000 + AUIPC $1048575, X10 // 17f5ffff + + LUI $0, X15 // b7070000 + LUI $167, X15 // b7770a00 + LUI $1048575, X15 // b7f7ffff + SLL X6, X5, X7 // b3936200 SLL X5, X6 // 33135300 SLL $1, X5, X6 // 13931200 diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 578b4e8cce..543a3b4a04 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -192,33 +192,61 @@ func regFAddr(a obj.Addr) uint32 { return regAddr(a, REG_F0, REG_F31) } -// immFits reports whether immediate value x fits in nbits bits as a -// signed integer. -func immFits(x int64, nbits uint) bool { +// immIFits reports whether immediate value x fits in nbits bits +// as a signed integer. +func immIFits(x int64, nbits uint) bool { nbits-- var min int64 = -1 << nbits var max int64 = 1<>5)<<25 | rs2<<20 | rs1<<15 | i.funct3<<12 | (imm&0x1f)<<7 | i.opcode + return (imm>>5)<<25 | rs2<<20 | rs1<<15 | ins.funct3<<12 | (imm&0x1f)<<7 | ins.opcode } func encodeSI(p *obj.Prog) uint32 { @@ -410,6 +443,21 @@ func encodeSF(p *obj.Prog) uint32 { return encodeS(p, regF(p.Reg)) } +// encodeU encodes a U-type RISC-V instruction. +func encodeU(p *obj.Prog) uint32 { + // The immediates for encodeU are the upper 20 bits of a 32 bit value. + // 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) + rd := regIAddr(p.To) + ins := encode(p.As) + if ins == nil { + panic("encodeU: could not encode instruction") + } + return imm<<12 | rd<<7 | ins.opcode +} + // encodeRaw encodes a raw instruction value. func encodeRaw(p *obj.Prog) uint32 { // Treat the raw value specially as a 32-bit unsigned integer. @@ -455,6 +503,8 @@ var ( sIEncoding = encoding{encode: encodeSI, validate: validateSI, length: 4} sFEncoding = encoding{encode: encodeSF, validate: validateSF, length: 4} + uEncoding = encoding{encode: encodeU, validate: validateU, length: 4} + // rawEncoding encodes a raw instruction byte sequence. rawEncoding = encoding{encode: encodeRaw, validate: validateRaw, length: 4} @@ -483,6 +533,8 @@ var encodingForAs = [ALAST & obj.AMask]encoding{ ASLLI & obj.AMask: iIEncoding, ASRLI & obj.AMask: iIEncoding, ASRAI & obj.AMask: iIEncoding, + ALUI & obj.AMask: uEncoding, + AAUIPC & obj.AMask: uEncoding, AADD & obj.AMask: rIIIEncoding, ASLT & obj.AMask: rIIIEncoding, ASLTU & obj.AMask: rIIIEncoding,