]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: 386 port now works
authorKeith Randall <khr@golang.org>
Thu, 21 Jul 2016 17:37:59 +0000 (10:37 -0700)
committerKeith Randall <khr@golang.org>
Thu, 21 Jul 2016 20:41:18 +0000 (20:41 +0000)
GOARCH=386 SSATEST=1 ./all.bash passes

Caveat: still needs changes to test/ files to use *_ssa.go versions.  I
won't check those changes in with this CL because the builders will
complain as they don't have SSATEST=1.

Mostly minor fixes.

Implement float <-> uint32 in assembly.  It seems the simplest option
for now.

GO386=387 does not work.  That's why I can't make SSA the default for
386 yet.

Change-Id: Ic4d4402104d32bcfb1fd612f5bb6539f9acb8ae0
Reviewed-on: https://go-review.googlesource.com/25119
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/gc/builtin.go
src/cmd/compile/internal/gc/builtin/runtime.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/ssa/gen/386.rules
src/cmd/compile/internal/ssa/gen/dec64.rules
src/cmd/compile/internal/ssa/rewrite386.go
src/cmd/compile/internal/ssa/rewritedec64.go
src/cmd/compile/internal/ssa/schedule.go
src/runtime/asm_386.s

index c1a641874eef59a3d76e780f8b5543cba262edbb..95208705143431e7750b458d56d11275739f7136 100644 (file)
@@ -95,14 +95,15 @@ const runtimeimport = "" +
        "4div\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64div\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x0fint64" +
        "mod\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64mod\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x1bfloat6" +
        "4toint64\x00\x01\x1a\x00\x01\n\x00\t\x1dfloat64touint64\x00\x01\x1a\x00\x01\x14\x00\t" +
-       "\x1bint64tofloat64\x00\x01\n\x00\x01\x1a\x00\t\x1duint64tofloat64\x00" +
-       "\x01\x14\x00\x01\x1a\x00\t\x19complex128div\x00\x04\x1e\vnum·2\x00\x00\x1e\vden·" +
-       "3\x00\x00\x02\x1e\vquo·1\x00\x00\t\x19racefuncenter\x00\x01\x16d\x00\t\x17race" +
-       "funcexit\x00\x00\x00\t\x0fraceread\x00\x01\x16d\x00\t\x11racewrite\x00\x01\x16" +
-       "d\x00\t\x19racereadrange\x00\x04\x16\raddr·1\x00d\x16\rsize·2\x00" +
-       "d\x00\t\x1bracewriterange\x00\x04\x16\x94\x03\x00d\x16\x96\x03\x00d\x00\t\x0fmsanrea" +
-       "d\x00\x04\x16\x94\x03\x00d\x16\x96\x03\x00d\x00\t\x11msanwrite\x00\x04\x16\x94\x03\x00d\x16\x96\x03\x00d\x00\v\xf4" +
-       "\x01\x02\v\x00\x01\x00\n$$\n"
+       "\x1dfloat64touint32\x00\x01\x1a\x00\x01\x12\x00\t\x1bint64tofloat64\x00" +
+       "\x01\n\x00\x01\x1a\x00\t\x1duint64tofloat64\x00\x01\x14\x00\x01\x1a\x00\t\x1duint32to" +
+       "float64\x00\x01\x12\x00\x01\x1a\x00\t\x19complex128div\x00\x04\x1e\vnum·2\x00" +
+       "\x00\x1e\vden·3\x00\x00\x02\x1e\vquo·1\x00\x00\t\x19racefuncenter\x00\x01\x16" +
+       "d\x00\t\x17racefuncexit\x00\x00\x00\t\x0fraceread\x00\x01\x16d\x00\t\x11race" +
+       "write\x00\x01\x16d\x00\t\x19racereadrange\x00\x04\x16\raddr·1\x00d\x16\r" +
+       "size·2\x00d\x00\t\x1bracewriterange\x00\x04\x16\x98\x03\x00d\x16\x9a\x03\x00d\x00\t" +
+       "\x0fmsanread\x00\x04\x16\x98\x03\x00d\x16\x9a\x03\x00d\x00\t\x11msanwrite\x00\x04\x16\x98\x03\x00d" +
+       "\x16\x9a\x03\x00d\x00\v\xf8\x01\x02\v\x00\x01\x00\n$$\n"
 
 const unsafeimport = "" +
        "cn\x00\x03v1\x01\vunsafe\x00\x05\r\rPointer\x00\x16\x00\t\x0fOffsetof\x00\x01" +
index e9316cb31317f445cf010d16fe47d3c917727694..ef7e4089594151e20f961b6c007aa505793eeb6d 100644 (file)
@@ -150,8 +150,10 @@ func int64mod(int64, int64) int64
 func uint64mod(uint64, uint64) uint64
 func float64toint64(float64) int64
 func float64touint64(float64) uint64
+func float64touint32(float64) uint32
 func int64tofloat64(int64) float64
 func uint64tofloat64(uint64) float64
+func uint32tofloat64(uint32) float64
 
 func complex128div(num complex128, den complex128) (quo complex128)
 
index 64a504a68024a83d2cebf3849697fca6a5507287..43dbcf54ca2db23654237256a6d02403572c1b3e 100644 (file)
@@ -4323,7 +4323,7 @@ func CheckLoweredPhi(v *ssa.Value) {
 func CheckLoweredGetClosurePtr(v *ssa.Value) {
        entry := v.Block.Func.Entry
        if entry != v.Block || entry.Values[0] != v {
-               Fatalf("badly placed LoweredGetClosurePtr: %v %v", v.Block, v)
+               Fatalf("in %s, badly placed LoweredGetClosurePtr: %v %v", v.Block.Func.Name, v.Block, v)
        }
 }
 
index f2d27f207c613e87ddab466af20a8e476eaaed11..c6aeddb172a6e794a4a04df43e775d62b1ed8aa6 100644 (file)
@@ -1105,6 +1105,39 @@ opswitch:
                        }
                }
 
+               if Thearch.LinkArch.Family == sys.I386 {
+                       if n.Left.Type.IsFloat() {
+                               if n.Type.Etype == TINT64 {
+                                       n = mkcall("float64toint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
+                                       break
+                               }
+
+                               if n.Type.Etype == TUINT64 {
+                                       n = mkcall("float64touint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
+                                       break
+                               }
+                               if n.Type.Etype == TUINT32 || n.Type.Etype == TUINTPTR {
+                                       n = mkcall("float64touint32", n.Type, init, conv(n.Left, Types[TFLOAT64]))
+                                       break
+                               }
+                       }
+                       if n.Type.IsFloat() {
+                               if n.Left.Type.Etype == TINT64 {
+                                       n = conv(mkcall("int64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TINT64])), n.Type)
+                                       break
+                               }
+
+                               if n.Left.Type.Etype == TUINT64 {
+                                       n = conv(mkcall("uint64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT64])), n.Type)
+                                       break
+                               }
+                               if n.Left.Type.Etype == TUINT32 || n.Left.Type.Etype == TUINTPTR {
+                                       n = conv(mkcall("uint32tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT32])), n.Type)
+                                       break
+                               }
+                       }
+               }
+
                n.Left = walkexpr(n.Left, init)
 
        case OANDNOT:
index 0587be4367b806ae6a0edb7dff96d8b664c61611..46edb6f66f7223c23988772f8f386161b557c9f5 100644 (file)
@@ -99,7 +99,7 @@
 (ZeroExt16to32 x) -> (MOVWLZX x)
 
 (Signmask x) -> (SARLconst x [31])
-(Zeromask x) -> (SBBLcarrymask (CMPL (MOVLconst [0]) x))
+(Zeromask <t> x) -> (XORLconst [-1] (SBBLcarrymask <t> (CMPL x (MOVLconst [1]))))
 
 // Lowering truncation
 // Because we ignore high parts of registers, truncates are just copies.
 (Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 -> (Const8 [0])
 (Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 -> (Const8 [0])
 
+// large constant signed right shift, we leave the sign bit
+(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 -> (SARLconst x [31])
+(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 -> (SARWconst x [15])
+(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 -> (SARBconst x [7])
+
 // Lowering comparisons
 (Less32  x y) -> (SETL (CMPL x y))
 (Less16  x y) -> (SETL (CMPW x y))
index 8b2fd276690f44bf560ca0bf94ab1088ad3ae262..e419c741b664b2735039c1394ef7b4aa58e3a1d8 100644 (file)
 (Lrot64 (Int64Make hi lo) [c]) && c > 32 -> (Lrot64 (Int64Make lo hi) [c-32])
 
 (Const64 <t> [c]) && t.IsSigned() ->
-       (Int64Make (Const32 <config.fe.TypeInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [c&0xffffffff]))
+       (Int64Make (Const32 <config.fe.TypeInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [int64(int32(c))]))
 (Const64 <t> [c]) && !t.IsSigned() ->
-       (Int64Make (Const32 <config.fe.TypeUInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [c&0xffffffff]))
+       (Int64Make (Const32 <config.fe.TypeUInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [int64(int32(c))]))
 
 (Eq64 x y) ->
        (AndB
index 5d571c588fec7ab59c75615fe6c36aef9364206c..a6ded59452979b2237b3134691475e3953cb9541 100644 (file)
@@ -10432,6 +10432,24 @@ func rewriteValue386_OpRsh16x64(v *Value, config *Config) bool {
                v.AuxInt = c
                return true
        }
+       // match: (Rsh16x64 x (Const64 [c]))
+       // cond: uint64(c) >= 16
+       // result: (SARWconst x [15])
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) >= 16) {
+                       break
+               }
+               v.reset(Op386SARWconst)
+               v.AddArg(x)
+               v.AuxInt = 15
+               return true
+       }
        return false
 }
 func rewriteValue386_OpRsh16x8(v *Value, config *Config) bool {
@@ -10647,6 +10665,24 @@ func rewriteValue386_OpRsh32x64(v *Value, config *Config) bool {
                v.AuxInt = c
                return true
        }
+       // match: (Rsh32x64 x (Const64 [c]))
+       // cond: uint64(c) >= 32
+       // result: (SARLconst x [31])
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) >= 32) {
+                       break
+               }
+               v.reset(Op386SARLconst)
+               v.AddArg(x)
+               v.AuxInt = 31
+               return true
+       }
        return false
 }
 func rewriteValue386_OpRsh32x8(v *Value, config *Config) bool {
@@ -10862,6 +10898,24 @@ func rewriteValue386_OpRsh8x64(v *Value, config *Config) bool {
                v.AuxInt = c
                return true
        }
+       // match: (Rsh8x64 x (Const64 [c]))
+       // cond: uint64(c) >= 8
+       // result: (SARBconst x [7])
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(uint64(c) >= 8) {
+                       break
+               }
+               v.reset(Op386SARBconst)
+               v.AddArg(x)
+               v.AuxInt = 7
+               return true
+       }
        return false
 }
 func rewriteValue386_OpRsh8x8(v *Value, config *Config) bool {
@@ -13015,17 +13069,21 @@ func rewriteValue386_OpZeroExt8to32(v *Value, config *Config) bool {
 func rewriteValue386_OpZeromask(v *Value, config *Config) bool {
        b := v.Block
        _ = b
-       // match: (Zeromask x)
+       // match: (Zeromask <t> x)
        // cond:
-       // result: (SBBLcarrymask (CMPL (MOVLconst [0]) x))
+       // result: (XORLconst [-1] (SBBLcarrymask <t> (CMPL x (MOVLconst [1]))))
        for {
+               t := v.Type
                x := v.Args[0]
-               v.reset(Op386SBBLcarrymask)
-               v0 := b.NewValue0(v.Line, Op386CMPL, TypeFlags)
-               v1 := b.NewValue0(v.Line, Op386MOVLconst, config.fe.TypeUInt32())
-               v1.AuxInt = 0
+               v.reset(Op386XORLconst)
+               v.AuxInt = -1
+               v0 := b.NewValue0(v.Line, Op386SBBLcarrymask, t)
+               v1 := b.NewValue0(v.Line, Op386CMPL, TypeFlags)
+               v1.AddArg(x)
+               v2 := b.NewValue0(v.Line, Op386MOVLconst, config.fe.TypeUInt32())
+               v2.AuxInt = 1
+               v1.AddArg(v2)
                v0.AddArg(v1)
-               v0.AddArg(x)
                v.AddArg(v0)
                return true
        }
index ecd39b1f5e854a42a037370e60219b7b14e2f516..d2fbfb9f10c247de9778c8ec25346547f45a891b 100644 (file)
@@ -263,7 +263,7 @@ func rewriteValuedec64_OpConst64(v *Value, config *Config) bool {
        _ = b
        // match: (Const64 <t> [c])
        // cond: t.IsSigned()
-       // result: (Int64Make (Const32 <config.fe.TypeInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [c&0xffffffff]))
+       // result: (Int64Make (Const32 <config.fe.TypeInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [int64(int32(c))]))
        for {
                t := v.Type
                c := v.AuxInt
@@ -275,13 +275,13 @@ func rewriteValuedec64_OpConst64(v *Value, config *Config) bool {
                v0.AuxInt = c >> 32
                v.AddArg(v0)
                v1 := b.NewValue0(v.Line, OpConst32, config.fe.TypeUInt32())
-               v1.AuxInt = c & 0xffffffff
+               v1.AuxInt = int64(int32(c))
                v.AddArg(v1)
                return true
        }
        // match: (Const64 <t> [c])
        // cond: !t.IsSigned()
-       // result: (Int64Make (Const32 <config.fe.TypeUInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [c&0xffffffff]))
+       // result: (Int64Make (Const32 <config.fe.TypeUInt32()> [c>>32]) (Const32 <config.fe.TypeUInt32()> [int64(int32(c))]))
        for {
                t := v.Type
                c := v.AuxInt
@@ -293,7 +293,7 @@ func rewriteValuedec64_OpConst64(v *Value, config *Config) bool {
                v0.AuxInt = c >> 32
                v.AddArg(v0)
                v1 := b.NewValue0(v.Line, OpConst32, config.fe.TypeUInt32())
-               v1.AuxInt = c & 0xffffffff
+               v1.AuxInt = int64(int32(c))
                v.AddArg(v1)
                return true
        }
index 4fa5f613f13ddc513dab9dba0524f29c846113b0..5dab018117122d23cfed4b7e16ebf5e999be9067 100644 (file)
@@ -84,7 +84,7 @@ func schedule(f *Func) {
                // Compute score. Larger numbers are scheduled closer to the end of the block.
                for _, v := range b.Values {
                        switch {
-                       case v.Op == OpAMD64LoweredGetClosurePtr || v.Op == OpARMLoweredGetClosurePtr:
+                       case v.Op == OpAMD64LoweredGetClosurePtr || v.Op == OpARMLoweredGetClosurePtr || v.Op == Op386LoweredGetClosurePtr:
                                // We also score GetLoweredClosurePtr as early as possible to ensure that the
                                // context register is not stomped. GetLoweredClosurePtr should only appear
                                // in the entry block where there are no phi functions, so there is no
index ea11b2b2fb59d6be1bbef663913d7192e0355b9a..1c1a4938de2201aed2eb3c74919897efa1966a97 100644 (file)
@@ -1637,3 +1637,48 @@ TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
        MOVL    AX, moduledata_next(DX)
        MOVL    AX, runtime·lastmoduledatap(SB)
        RET
+
+TEXT runtime·uint32tofloat64(SB),NOSPLIT,$0-12
+       // TODO: condition on GO386 env var.
+       MOVL    a+0(FP), AX
+
+       // Check size.
+       CMPL    AX, $0x80000000
+       JAE     large
+
+       // Less than 2**31, convert directly.
+       CVTSL2SD        AX, X0
+       MOVSD   X0, ret+4(FP)
+       RET
+large:
+       // >= 2**31.  Subtract 2**31 (uint32), convert, then add 2**31 (float64).
+       SUBL    $0x80000000, AX
+       CVTSL2SD        AX, X0
+       ADDSD   twotothe31<>(SB), X0
+       MOVSD   X0, ret+4(FP)
+       RET
+
+TEXT runtime·float64touint32(SB),NOSPLIT,$0-12
+       // TODO: condition on GO386 env var.
+       MOVSD   a+0(FP), X0
+
+       // Check size.
+       MOVSD   twotothe31<>(SB), X1
+       UCOMISD X1, X0 //note: args swapped relative to CMPL
+       JAE     large
+
+       // Less than 2**31, convert directly.
+       CVTTSD2SL X0, AX
+       MOVL    AX, ret+8(FP)
+       RET
+large:
+       // >= 2**31.  Subtract 2**31 (float64), convert, then add 2**31 (uint32).
+       SUBSD   X1, X0
+       CVTTSD2SL       X0, AX
+       ADDL    $0x80000000, AX
+       MOVL    AX, ret+8(FP)
+       RET
+
+// 2**31 as a float64.
+DATA   twotothe31<>+0x00(SB)/8, $0x41e0000000000000
+GLOBL  twotothe31<>(SB),RODATA,$8