From: Joel Sing Date: Sun, 3 Nov 2019 17:08:26 +0000 (+1100) Subject: cmd/internal/obj/riscv: handle FEQ/FNEG/SEQZ/SNEZ X-Git-Tag: go1.14rc1~211 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=24f08103d2dad591a77c2b716f9a13fc7bb234fc;p=gostls13.git cmd/internal/obj/riscv: handle FEQ/FNEG/SEQZ/SNEZ Based on riscv-go port. Updates #27532 Change-Id: I5e7f45955e1dfdb9d09cc6a4e6f3ce81216d411d Reviewed-on: https://go-review.googlesource.com/c/go/+/204628 Reviewed-by: Cherry Zhang --- diff --git a/src/cmd/asm/internal/asm/testdata/riscvenc.s b/src/cmd/asm/internal/asm/testdata/riscvenc.s index 21d1c40d9d..3e9319954b 100644 --- a/src/cmd/asm/internal/asm/testdata/riscvenc.s +++ b/src/cmd/asm/internal/asm/testdata/riscvenc.s @@ -282,3 +282,25 @@ start: // real address and updates the immediates for both instructions. CALL asmtest(SB) // 970f0000 JMP asmtest(SB) // 970f0000 + + SEQZ X15, X15 // 93b71700 + SNEZ X15, X15 // b337f000 + + // F extension + FNEGS F0, F1 // d3100020 + + // TODO(jsing): FNES gets encoded as FEQS+XORI - this should + // be handled as a single *obj.Prog so that the full two + // instruction encoding is tested here. + FNES F0, F1, X7 // d3a300a0 + + // D extension + FNEGD F0, F1 // d3100022 + FEQD F0, F1, X5 // d3a200a2 + FLTD F0, F1, X5 // d39200a2 + FLED F0, F1, X5 // d38200a2 + + // TODO(jsing): FNED gets encoded as FEQD+XORI - this should + // be handled as a single *obj.Prog so that the full two + // instruction encoding is tested here. + FNED F0, F1, X5 // d3a200a2 diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index e539683d35..903b2a0eeb 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -221,6 +221,27 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { case AFCVTWS, AFCVTLS, AFCVTWUS, AFCVTLUS, AFCVTWD, AFCVTLD, AFCVTWUD, AFCVTLUD: // Set the rounding mode in funct3 to round to zero. p.Scond = 1 + + case ASEQZ: + // SEQZ rs, rd -> SLTIU $1, rs, rd + p.As = ASLTIU + p.Reg = p.From.Reg + p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 1} + + case ASNEZ: + // SNEZ rs, rd -> SLTU rs, x0, rd + p.As = ASLTU + p.Reg = REG_ZERO + + case AFNEGS: + // FNEGS rs, rd -> FSGNJNS rs, rs, rd + p.As = AFSGNJNS + p.Reg = p.From.Reg + + case AFNEGD: + // FNEGD rs, rd -> FSGNJND rs, rs, rd + p.As = AFSGNJND + p.Reg = p.From.Reg } } @@ -595,6 +616,37 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { jalrToSym(ctxt, p, newprog, REG_ZERO) } } + + // Replace FNE[SD] with FEQ[SD] and NOT. + case AFNES: + if p.To.Type != obj.TYPE_REG { + ctxt.Diag("progedit: FNES needs an integer register output") + } + dst := p.To.Reg + p.As = AFEQS + p = obj.Appendp(p, newprog) + + p.As = AXORI // [bit] xor 1 = not [bit] + p.From.Type = obj.TYPE_CONST + p.From.Offset = 1 + p.Reg = dst + p.To.Type = obj.TYPE_REG + p.To.Reg = dst + + case AFNED: + if p.To.Type != obj.TYPE_REG { + ctxt.Diag("progedit: FNED needs an integer register output") + } + dst := p.To.Reg + p.As = AFEQD + p = obj.Appendp(p, newprog) + + p.As = AXORI // [bit] xor 1 = not [bit] + p.From.Type = obj.TYPE_CONST + p.From.Offset = 1 + p.Reg = dst + p.To.Type = obj.TYPE_REG + p.To.Reg = dst } }