1
0
mirror of https://github.com/golang/go synced 2024-11-17 09:04:44 -07:00

cmd/internal/obj/ppc64: generate float 0 more efficiently on ppc64x

This change makes use of a VSX instruction to generate the
float 0 value instead of generating a constant in memory and
loading it from there.

This uses 1 instruction instead of 2 and avoids a memory reference.
in the +0 case, uses 2 instructions in the -0 case but avoids
the memory reference.

Since this is done in the assembler for ppc64x, an update has
been made to the assembler test.

Change-Id: Ief7dddcb057bfb602f78215f6947664e8c841464
Reviewed-on: https://go-review.googlesource.com/c/139420
Reviewed-by: Michael Munday <mike.munday@ibm.com>
This commit is contained in:
Lynn Boger 2018-09-26 10:43:15 -04:00
parent 8f9902da26
commit f776d51bf7
3 changed files with 32 additions and 4 deletions

View File

@ -98,4 +98,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
LDAR (R4),$0,R5 // 7ca020a8 LDAR (R4),$0,R5 // 7ca020a8
LDAR (R3),R5 // 7ca018a8 LDAR (R3),R5 // 7ca018a8
// float constants
FMOVD $(0.0), F1 // f0210cd0
FMOVD $(-0.0), F1 // f0210cd0fc200850
RET RET

View File

@ -35,6 +35,7 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"log" "log"
"math"
"sort" "sort"
) )
@ -342,6 +343,8 @@ var optab = []Optab{
{AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB}, {AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB},
{AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP}, {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP},
{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO}, {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO},
{AFMOVD, C_ZCON, C_NONE, C_NONE, C_FREG, 24, 4, 0},
{AFMOVD, C_ADDCON, C_NONE, C_NONE, C_FREG, 24, 8, 0},
{AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0}, {AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0},
{AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
{AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
@ -829,6 +832,18 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
case obj.TYPE_TEXTSIZE: case obj.TYPE_TEXTSIZE:
return C_TEXTSIZE return C_TEXTSIZE
case obj.TYPE_FCONST:
// The only cases where FCONST will occur are with float64 +/- 0.
// All other float constants are generated in memory.
f64 := a.Val.(float64)
if f64 == 0 {
if math.Signbit(f64) {
return C_ADDCON
}
return C_ZCON
}
log.Fatalf("Unexpected nonzero FCONST operand %v", a)
case obj.TYPE_CONST, case obj.TYPE_CONST,
obj.TYPE_ADDR: obj.TYPE_ADDR:
switch a.Name { switch a.Name {
@ -2763,6 +2778,13 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
c.ctxt.Diag("%v is not supported", p) c.ctxt.Diag("%v is not supported", p)
} }
case 24: /* lfd fA,float64(0) -> xxlxor xsA,xsaA,xsaA + fneg for -0 */
o1 = AOP_XX3I(c.oprrr(AXXLXOR), uint32(p.To.Reg), uint32(p.To.Reg), uint32(p.To.Reg), uint32(0))
// This is needed for -0.
if o.size == 8 {
o2 = AOP_RRR(c.oprrr(AFNEG), uint32(p.To.Reg), 0, uint32(p.To.Reg))
}
case 25: case 25:
/* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */ /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
v := c.regoff(&p.From) v := c.regoff(&p.From)

View File

@ -67,10 +67,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
case AFMOVD: case AFMOVD:
if p.From.Type == obj.TYPE_FCONST { if p.From.Type == obj.TYPE_FCONST {
f64 := p.From.Val.(float64) f64 := p.From.Val.(float64)
p.From.Type = obj.TYPE_MEM // Constant not needed in memory for float +/- 0
p.From.Sym = ctxt.Float64Sym(f64) if f64 != 0 {
p.From.Name = obj.NAME_EXTERN p.From.Type = obj.TYPE_MEM
p.From.Offset = 0 p.From.Sym = ctxt.Float64Sym(f64)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
} }
// Put >32-bit constants in memory and load them // Put >32-bit constants in memory and load them