From 6fc67c1fbc84ff24a43469946f672285a2796dc2 Mon Sep 17 00:00:00 2001 From: Michael McLoughlin Date: Thu, 27 Dec 2018 15:44:52 -0800 Subject: [PATCH] examples/geohash: first version Adds helper for constants as DATA sections. --- build/global.go | 2 ++ build/pseudo.go | 7 ++++++ examples/geohash/asm.go | 40 ++++++++++++++++++++++++++++++++ examples/geohash/geohash.s | 34 +++++++++++++++++++++++++++ examples/geohash/geohash_test.go | 13 +++++++++++ examples/geohash/stub.go | 5 ++++ 6 files changed, 101 insertions(+) create mode 100644 examples/geohash/asm.go create mode 100644 examples/geohash/geohash.s create mode 100644 examples/geohash/geohash_test.go create mode 100644 examples/geohash/stub.go diff --git a/build/global.go b/build/global.go index b4eba59..0c3fdbc 100644 --- a/build/global.go +++ b/build/global.go @@ -58,3 +58,5 @@ func Load(src gotypes.Component, dst reg.Register) reg.Register { return ctx.Loa func Store(src reg.Register, dst gotypes.Component) { ctx.Store(src, dst) } func AllocLocal(size int) operand.Mem { return ctx.AllocLocal(size) } + +func ConstData(name string, v operand.Constant) operand.Mem { return ctx.ConstData(name, v) } diff --git a/build/pseudo.go b/build/pseudo.go index d5ed6e7..f394c40 100644 --- a/build/pseudo.go +++ b/build/pseudo.go @@ -1,6 +1,7 @@ package build import ( + "github.com/mmcloughlin/avo/operand" "github.com/mmcloughlin/avo/reg" "github.com/mmcloughlin/avo/gotypes" @@ -42,3 +43,9 @@ func (c *Context) Store(src reg.Register, dst gotypes.Component) { } c.mov(src, b.Addr, int(src.Bytes()), int(gotypes.Sizes.Sizeof(b.Type)), b.Type) } + +func (c *Context) ConstData(name string, v operand.Constant) operand.Mem { + g := c.StaticGlobal(name) + c.AppendDatum(v) + return g +} diff --git a/examples/geohash/asm.go b/examples/geohash/asm.go new file mode 100644 index 0000000..213baad --- /dev/null +++ b/examples/geohash/asm.go @@ -0,0 +1,40 @@ +// +build ignore + +package main + +import ( + . "github.com/mmcloughlin/avo/build" + . "github.com/mmcloughlin/avo/operand" +) + +func main() { + TEXT("EncodeInt", "func(lat, lng float64) uint64") + lat := Load(Param("lat"), Xv()) + lng := Load(Param("lng"), Xv()) + + MULSD(ConstData("reciprocal180", F64(1/180.0)), lat) + onepointfive := ConstData("onepointfive", F64(1.5)) + ADDSD(onepointfive, lat) + + MULSD(ConstData("reciprocal360", F64(1/360.0)), lng) + ADDSD(onepointfive, lng) + + lngi, lati := GP64v(), GP64v() + MOVQ(lat, lati) + SHRQ(U8(20), lati) + MOVQ(lng, lngi) + SHRQ(U8(20), lngi) + + mask := ConstData("mask", U64(0x5555555555555555)) + ghsh := GP64v() + PDEPQ(mask, lati, ghsh) + temp := GP64v() + PDEPQ(mask, lngi, temp) + SHLQ(U8(1), temp) + XORQ(temp, ghsh) + + Store(ghsh, ReturnIndex(0)) + RET() + + Generate() +} diff --git a/examples/geohash/geohash.s b/examples/geohash/geohash.s new file mode 100644 index 0000000..4cde229 --- /dev/null +++ b/examples/geohash/geohash.s @@ -0,0 +1,34 @@ +// Code generated by command: go run asm.go -out geohash.s -stubs stub.go. DO NOT EDIT. + +#include "textflag.h" + +// func EncodeInt(lat float64, lng float64) uint64 +TEXT ·EncodeInt(SB), 0, $0-24 + MOVSD lat(FP), X0 + MOVSD lng+8(FP), X1 + MULSD reciprocal180<>(SB), X0 + ADDSD onepointfive<>(SB), X0 + MULSD reciprocal360<>(SB), X1 + ADDSD onepointfive<>(SB), X1 + MOVQ X0, CX + SHRQ $0x14, CX + MOVQ X1, AX + SHRQ $0x14, AX + PDEPQ mask<>(SB), CX, CX + PDEPQ mask<>(SB), AX, AX + SHLQ $0x01, AX + XORQ AX, CX + MOVQ CX, ret+16(FP) + RET + +DATA reciprocal180<>(SB)/8, $(0.005555555555555556) +GLOBL reciprocal180<>(SB), RODATA, $8 + +DATA onepointfive<>(SB)/8, $(1.5) +GLOBL onepointfive<>(SB), RODATA, $8 + +DATA reciprocal360<>(SB)/8, $(0.002777777777777778) +GLOBL reciprocal360<>(SB), RODATA, $8 + +DATA mask<>(SB)/8, $0x5555555555555555 +GLOBL mask<>(SB), RODATA, $8 diff --git a/examples/geohash/geohash_test.go b/examples/geohash/geohash_test.go new file mode 100644 index 0000000..6605ada --- /dev/null +++ b/examples/geohash/geohash_test.go @@ -0,0 +1,13 @@ +package geohash + +import ( + "testing" +) + +//go:generate go run asm.go -out geohash.s -stubs stub.go + +func TestEncodeIntMountEverest(t *testing.T) { + if EncodeInt(27.988056, 86.925278) != 0xceb7f254240fd612 { + t.Fail() + } +} diff --git a/examples/geohash/stub.go b/examples/geohash/stub.go new file mode 100644 index 0000000..65ab94f --- /dev/null +++ b/examples/geohash/stub.go @@ -0,0 +1,5 @@ +// Code generated by command: go run asm.go -out geohash.s -stubs stub.go. DO NOT EDIT. + +package geohash + +func EncodeInt(lat float64, lng float64) uint64