From e2cfc1eb3affe8bcdfeca4a9f0a2d7902dbb940f Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Fri, 12 Sep 2025 20:54:49 +1000 Subject: cmd/internal/obj/riscv: improve handling of float point moves Translate moves from an integer register to a floating point register, or from a floating point register to an integer register, to the appropriate move instruction (i.e. FMVXW/FMVWX/FMVXD/FMVDX). Add support for MOVF with a constant - we previously added support for MOVD but not for MOVF. Add special handling for 0.0, which we can translate to a move from the zero register to a floating point register (leveraging the above mentioned change). Change-Id: If8df2f5610e69b4ec0af85efb884951024685f5b Reviewed-on: https://go-review.googlesource.com/c/go/+/703216 Reviewed-by: Meng Zhuo Reviewed-by: Mark Freeman Reviewed-by: Michael Knyszek LUCI-TryBot-Result: Go LUCI Reviewed-by: Mark Ryan --- src/cmd/internal/obj/riscv/obj.go | 56 ++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) (limited to 'src/cmd/internal/obj') diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 1538d03179..fcdea57460 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -29,6 +29,7 @@ import ( "internal/abi" "internal/buildcfg" "log" + "math" "math/bits" "strings" ) @@ -145,9 +146,29 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { p.From.Offset = 0 } + case AMOVF: + if p.From.Type == obj.TYPE_FCONST && p.From.Name == obj.NAME_NONE && p.From.Reg == obj.REG_NONE { + f64 := p.From.Val.(float64) + f32 := float32(f64) + if math.Float32bits(f32) == 0 { + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_ZERO + break + } + p.From.Type = obj.TYPE_MEM + p.From.Sym = ctxt.Float32Sym(f32) + p.From.Name = obj.NAME_EXTERN + p.From.Offset = 0 + } + case AMOVD: if p.From.Type == obj.TYPE_FCONST && p.From.Name == obj.NAME_NONE && p.From.Reg == obj.REG_NONE { f64 := p.From.Val.(float64) + if math.Float64bits(f64) == 0 { + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_ZERO + break + } p.From.Type = obj.TYPE_MEM p.From.Sym = ctxt.Float64Sym(f64) p.From.Name = obj.NAME_EXTERN @@ -3254,16 +3275,37 @@ func instructionsForMOV(p *obj.Prog) []*instruction { case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_REG: // Handle register to register moves. switch p.As { - case AMOV: // MOV Ra, Rb -> ADDI $0, Ra, Rb + case AMOV: + // MOV Ra, Rb -> ADDI $0, Ra, Rb ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, uint32(p.From.Reg), obj.REG_NONE, 0 - case AMOVW: // MOVW Ra, Rb -> ADDIW $0, Ra, Rb + case AMOVW: + // MOVW Ra, Rb -> ADDIW $0, Ra, Rb ins.as, ins.rs1, ins.rs2, ins.imm = AADDIW, uint32(p.From.Reg), obj.REG_NONE, 0 - case AMOVBU: // MOVBU Ra, Rb -> ANDI $255, Ra, Rb + case AMOVBU: + // MOVBU Ra, Rb -> ANDI $255, Ra, Rb ins.as, ins.rs1, ins.rs2, ins.imm = AANDI, uint32(p.From.Reg), obj.REG_NONE, 255 - case AMOVF: // MOVF Ra, Rb -> FSGNJS Ra, Ra, Rb - ins.as, ins.rs1 = AFSGNJS, uint32(p.From.Reg) - case AMOVD: // MOVD Ra, Rb -> FSGNJD Ra, Ra, Rb - ins.as, ins.rs1 = AFSGNJD, uint32(p.From.Reg) + case AMOVF: + // MOVF Ra, Rb -> FSGNJS Ra, Ra, Rb + // or -> FMVWX Ra, Rb + // or -> FMVXW Ra, Rb + if ins.rs2 >= REG_X0 && ins.rs2 <= REG_X31 && ins.rd >= REG_F0 && ins.rd <= REG_F31 { + ins.as = AFMVWX + } else if ins.rs2 >= REG_F0 && ins.rs2 <= REG_F31 && ins.rd >= REG_X0 && ins.rd <= REG_X31 { + ins.as = AFMVXW + } else { + ins.as, ins.rs1 = AFSGNJS, uint32(p.From.Reg) + } + case AMOVD: + // MOVD Ra, Rb -> FSGNJD Ra, Ra, Rb + // or -> FMVDX Ra, Rb + // or -> FMVXD Ra, Rb + if ins.rs2 >= REG_X0 && ins.rs2 <= REG_X31 && ins.rd >= REG_F0 && ins.rd <= REG_F31 { + ins.as = AFMVDX + } else if ins.rs2 >= REG_F0 && ins.rs2 <= REG_F31 && ins.rd >= REG_X0 && ins.rd <= REG_X31 { + ins.as = AFMVXD + } else { + ins.as, ins.rs1 = AFSGNJD, uint32(p.From.Reg) + } case AMOVB, AMOVH: if buildcfg.GORISCV64 >= 22 { // Use SEXTB or SEXTH to extend. -- cgit v1.3-5-g45d5 From ef05b66d6115209361dd99ff8f3ab978695fd74a Mon Sep 17 00:00:00 2001 From: lxq015 <1824368278@qq.com> Date: Wed, 17 Sep 2025 04:10:13 +0000 Subject: cmd/internal/obj/riscv: add support for Zicond instructions This patch implement assembler for the Zicond extension: CZEROEQZ and CZERONEZ. Follow-up to CL 631576 Updates #75350 Change-Id: Icf4be131fe61c3b7a3bde4811cf42dc807660907 GitHub-Last-Rev: 6539cc86cbf3c49c3247ed935bcbbb31bb886dea GitHub-Pull-Request: golang/go#75408 Reviewed-on: https://go-review.googlesource.com/c/go/+/702677 Reviewed-by: Mark Freeman Reviewed-by: Joel Sing Reviewed-by: Meng Zhuo Reviewed-by: Michael Knyszek Reviewed-by: Mark Ryan TryBot-Bypass: Joel Sing --- src/cmd/asm/internal/asm/testdata/riscv64.s | 6 ++++++ src/cmd/internal/obj/riscv/anames.go | 2 ++ src/cmd/internal/obj/riscv/cpu.go | 4 ++++ src/cmd/internal/obj/riscv/inst.go | 6 +++++- src/cmd/internal/obj/riscv/obj.go | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-) (limited to 'src/cmd/internal/obj') diff --git a/src/cmd/asm/internal/asm/testdata/riscv64.s b/src/cmd/asm/internal/asm/testdata/riscv64.s index 39d2faac25..07a898465f 100644 --- a/src/cmd/asm/internal/asm/testdata/riscv64.s +++ b/src/cmd/asm/internal/asm/testdata/riscv64.s @@ -195,6 +195,12 @@ start: RDTIME X5 // f32210c0 RDINSTRET X5 // f32220c0 + // 12.3: Integer Conditional Operations (Zicond) + CZEROEQZ X5, X6, X7 // b353530e + CZEROEQZ X5, X7 // b3d3530e + CZERONEZ X5, X6, X7 // b373530e + CZERONEZ X5, X7 // b3f3530e + // 13.1: Multiplication Operations MUL X5, X6, X7 // b3035302 MULH X5, X6, X7 // b3135302 diff --git a/src/cmd/internal/obj/riscv/anames.go b/src/cmd/internal/obj/riscv/anames.go index 88ac746573..a8807fc7a8 100644 --- a/src/cmd/internal/obj/riscv/anames.go +++ b/src/cmd/internal/obj/riscv/anames.go @@ -61,6 +61,8 @@ var Anames = []string{ "CSRRWI", "CSRRSI", "CSRRCI", + "CZEROEQZ", + "CZERONEZ", "MUL", "MULH", "MULHU", diff --git a/src/cmd/internal/obj/riscv/cpu.go b/src/cmd/internal/obj/riscv/cpu.go index e265e04482..305ef061e3 100644 --- a/src/cmd/internal/obj/riscv/cpu.go +++ b/src/cmd/internal/obj/riscv/cpu.go @@ -409,6 +409,10 @@ const ( ACSRRSI ACSRRCI + // 12.3: Integer Conditional Operations (Zicond) + ACZEROEQZ + ACZERONEZ + // 13.1: Multiplication Operations AMUL AMULH diff --git a/src/cmd/internal/obj/riscv/inst.go b/src/cmd/internal/obj/riscv/inst.go index a6a03dc565..a5b3acdb18 100644 --- a/src/cmd/internal/obj/riscv/inst.go +++ b/src/cmd/internal/obj/riscv/inst.go @@ -1,4 +1,4 @@ -// Code generated by ./parse.py -go rv64_a rv64_c rv64_d rv64_f rv64_i rv64_m rv64_q rv64_zba rv64_zbb rv64_zbs rv_a rv_c rv_c_d rv_d rv_f rv_i rv_m rv_q rv_s rv_system rv_v rv_zba rv_zbb rv_zbs rv_zicsr; DO NOT EDIT. +// Code generated by ./parse.py -go rv64_a rv64_c rv64_d rv64_f rv64_i rv64_m rv64_q rv64_zba rv64_zbb rv64_zbs rv_a rv_c rv_c_d rv_d rv_f rv_i rv_m rv_q rv_s rv_system rv_v rv_zba rv_zbb rv_zbs rv_zicond rv_zicsr; DO NOT EDIT. package riscv import "cmd/internal/obj" @@ -194,6 +194,10 @@ func encode(a obj.As) *inst { return &inst{0x13, 0x1, 0x0, 0x1, 1537, 0x30} case ACTZW: return &inst{0x1b, 0x1, 0x0, 0x1, 1537, 0x30} + case ACZEROEQZ: + return &inst{0x33, 0x5, 0x0, 0x0, 224, 0x7} + case ACZERONEZ: + return &inst{0x33, 0x7, 0x0, 0x0, 224, 0x7} case ADIV: return &inst{0x33, 0x4, 0x0, 0x0, 32, 0x1} case ADIVU: diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index fcdea57460..9d595f301c 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -1948,6 +1948,10 @@ var instructions = [ALAST & obj.AMask]instructionData{ ACSRRW & obj.AMask: {enc: iIIEncoding, immForm: ACSRRWI}, ACSRRWI & obj.AMask: {enc: iIIEncoding}, + // 12.3: "Zicond" Extension for Integer Conditional Operations + ACZERONEZ & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ACZEROEQZ & obj.AMask: {enc: rIIIEncoding, ternary: true}, + // 13.1: Multiplication Operations AMUL & obj.AMask: {enc: rIIIEncoding, ternary: true}, AMULH & obj.AMask: {enc: rIIIEncoding, ternary: true}, -- cgit v1.3-5-g45d5