]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: generate float 0 more efficiently on ppc64x
authorLynn Boger <laboger@linux.vnet.ibm.com>
Wed, 26 Sep 2018 14:43:15 +0000 (10:43 -0400)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Wed, 10 Oct 2018 12:31:23 +0000 (12:31 +0000)
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>
src/cmd/asm/internal/asm/testdata/ppc64enc.s
src/cmd/internal/obj/ppc64/asm9.go
src/cmd/internal/obj/ppc64/obj9.go

index 7ab1a578f867261dd3f5deec6bf2179a46128160..0133a85b98e609882c6ab57bddd240c614b79137 100644 (file)
@@ -98,4 +98,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        LDAR (R4),$0,R5                 // 7ca020a8
        LDAR (R3),R5                    // 7ca018a8
 
+       // float constants
+       FMOVD $(0.0), F1                // f0210cd0
+       FMOVD $(-0.0), F1               // f0210cd0fc200850
        RET
index 756170bc5529bb8233b47daceac02e6a64263c7c..66a77b308ccd1211b11ba38b029be4f4883683bc 100644 (file)
@@ -35,6 +35,7 @@ import (
        "encoding/binary"
        "fmt"
        "log"
+       "math"
        "sort"
 )
 
@@ -342,6 +343,8 @@ var optab = []Optab{
        {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_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_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
        {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:
                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,
                obj.TYPE_ADDR:
                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)
                }
 
+       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:
                /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
                v := c.regoff(&p.From)
index f42d6758050ba80fa713497ee81069efc6cd79ec..7a07b5058c3c11bb570be1aa4c0043d82ba2b8fe 100644 (file)
@@ -67,10 +67,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
        case AFMOVD:
                if p.From.Type == obj.TYPE_FCONST {
                        f64 := p.From.Val.(float64)
-                       p.From.Type = obj.TYPE_MEM
-                       p.From.Sym = ctxt.Float64Sym(f64)
-                       p.From.Name = obj.NAME_EXTERN
-                       p.From.Offset = 0
+                       // Constant not needed in memory for float +/- 0
+                       if f64 != 0 {
+                               p.From.Type = obj.TYPE_MEM
+                               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