Skip to content

Commit e2cfc1e

Browse files
committed
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 <[email protected]> Reviewed-by: Mark Freeman <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Mark Ryan <[email protected]>
1 parent 281c632 commit e2cfc1e

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

src/cmd/asm/internal/asm/testdata/riscv64.s

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1952,12 +1952,23 @@ start:
19521952
MOVF 4(X5), F0 // 07a04200
19531953
MOVF F0, 4(X5) // 27a20200
19541954
MOVF F0, F1 // d3000020
1955+
MOVF X1, F3 // d38100f0
1956+
MOVF F3, X1 // d38001e0
1957+
MOVF X0, F3 // d30100f0
1958+
MOVF $(0.0), F3 // d30100f0
1959+
1960+
// Converted to load of symbol (AUIPC + FLW)
1961+
MOVF $(709.78271289338397), F3 // 970f000087a10f00
19551962

19561963
MOVD 4(X5), F0 // 07b04200
19571964
MOVD F0, 4(X5) // 27b20200
19581965
MOVD F0, F1 // d3000022
1966+
MOVD F3, X1 // d38001e2
1967+
MOVD X1, F3 // d38100f2
1968+
MOVD X0, F3 // d30100f2
1969+
MOVD $(0.0), F3 // d30100f2
19591970

1960-
// Convert to load of symbol (AUIPC + FLD)
1971+
// Converted to load of symbol (AUIPC + FLD)
19611972
MOVD $(709.78271289338397), F3 // 970f000087b10f00
19621973

19631974
// TLS load with local-exec (LUI + ADDIW + ADD of TP + load)

src/cmd/internal/obj/riscv/obj.go

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"internal/abi"
3030
"internal/buildcfg"
3131
"log"
32+
"math"
3233
"math/bits"
3334
"strings"
3435
)
@@ -145,9 +146,29 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
145146
p.From.Offset = 0
146147
}
147148

149+
case AMOVF:
150+
if p.From.Type == obj.TYPE_FCONST && p.From.Name == obj.NAME_NONE && p.From.Reg == obj.REG_NONE {
151+
f64 := p.From.Val.(float64)
152+
f32 := float32(f64)
153+
if math.Float32bits(f32) == 0 {
154+
p.From.Type = obj.TYPE_REG
155+
p.From.Reg = REG_ZERO
156+
break
157+
}
158+
p.From.Type = obj.TYPE_MEM
159+
p.From.Sym = ctxt.Float32Sym(f32)
160+
p.From.Name = obj.NAME_EXTERN
161+
p.From.Offset = 0
162+
}
163+
148164
case AMOVD:
149165
if p.From.Type == obj.TYPE_FCONST && p.From.Name == obj.NAME_NONE && p.From.Reg == obj.REG_NONE {
150166
f64 := p.From.Val.(float64)
167+
if math.Float64bits(f64) == 0 {
168+
p.From.Type = obj.TYPE_REG
169+
p.From.Reg = REG_ZERO
170+
break
171+
}
151172
p.From.Type = obj.TYPE_MEM
152173
p.From.Sym = ctxt.Float64Sym(f64)
153174
p.From.Name = obj.NAME_EXTERN
@@ -3254,16 +3275,37 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
32543275
case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_REG:
32553276
// Handle register to register moves.
32563277
switch p.As {
3257-
case AMOV: // MOV Ra, Rb -> ADDI $0, Ra, Rb
3278+
case AMOV:
3279+
// MOV Ra, Rb -> ADDI $0, Ra, Rb
32583280
ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, uint32(p.From.Reg), obj.REG_NONE, 0
3259-
case AMOVW: // MOVW Ra, Rb -> ADDIW $0, Ra, Rb
3281+
case AMOVW:
3282+
// MOVW Ra, Rb -> ADDIW $0, Ra, Rb
32603283
ins.as, ins.rs1, ins.rs2, ins.imm = AADDIW, uint32(p.From.Reg), obj.REG_NONE, 0
3261-
case AMOVBU: // MOVBU Ra, Rb -> ANDI $255, Ra, Rb
3284+
case AMOVBU:
3285+
// MOVBU Ra, Rb -> ANDI $255, Ra, Rb
32623286
ins.as, ins.rs1, ins.rs2, ins.imm = AANDI, uint32(p.From.Reg), obj.REG_NONE, 255
3263-
case AMOVF: // MOVF Ra, Rb -> FSGNJS Ra, Ra, Rb
3264-
ins.as, ins.rs1 = AFSGNJS, uint32(p.From.Reg)
3265-
case AMOVD: // MOVD Ra, Rb -> FSGNJD Ra, Ra, Rb
3266-
ins.as, ins.rs1 = AFSGNJD, uint32(p.From.Reg)
3287+
case AMOVF:
3288+
// MOVF Ra, Rb -> FSGNJS Ra, Ra, Rb
3289+
// or -> FMVWX Ra, Rb
3290+
// or -> FMVXW Ra, Rb
3291+
if ins.rs2 >= REG_X0 && ins.rs2 <= REG_X31 && ins.rd >= REG_F0 && ins.rd <= REG_F31 {
3292+
ins.as = AFMVWX
3293+
} else if ins.rs2 >= REG_F0 && ins.rs2 <= REG_F31 && ins.rd >= REG_X0 && ins.rd <= REG_X31 {
3294+
ins.as = AFMVXW
3295+
} else {
3296+
ins.as, ins.rs1 = AFSGNJS, uint32(p.From.Reg)
3297+
}
3298+
case AMOVD:
3299+
// MOVD Ra, Rb -> FSGNJD Ra, Ra, Rb
3300+
// or -> FMVDX Ra, Rb
3301+
// or -> FMVXD Ra, Rb
3302+
if ins.rs2 >= REG_X0 && ins.rs2 <= REG_X31 && ins.rd >= REG_F0 && ins.rd <= REG_F31 {
3303+
ins.as = AFMVDX
3304+
} else if ins.rs2 >= REG_F0 && ins.rs2 <= REG_F31 && ins.rd >= REG_X0 && ins.rd <= REG_X31 {
3305+
ins.as = AFMVXD
3306+
} else {
3307+
ins.as, ins.rs1 = AFSGNJD, uint32(p.From.Reg)
3308+
}
32673309
case AMOVB, AMOVH:
32683310
if buildcfg.GORISCV64 >= 22 {
32693311
// Use SEXTB or SEXTH to extend.

0 commit comments

Comments
 (0)