18
README.md
18
README.md
@@ -43,8 +43,8 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Add", "func(x, y uint64) uint64")
|
TEXT("Add", "func(x, y uint64) uint64")
|
||||||
Doc("Add adds x and y.")
|
Doc("Add adds x and y.")
|
||||||
x := Load(Param("x"), GP64v())
|
x := Load(Param("x"), GP64())
|
||||||
y := Load(Param("y"), GP64v())
|
y := Load(Param("y"), GP64())
|
||||||
ADDQ(x, y)
|
ADDQ(x, y)
|
||||||
Store(y, ReturnIndex(0))
|
Store(y, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
@@ -101,9 +101,9 @@ Sum a slice of `uint64`s:
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Sum", "func(xs []uint64) uint64")
|
TEXT("Sum", "func(xs []uint64) uint64")
|
||||||
Doc("Sum returns the sum of the elements in xs.")
|
Doc("Sum returns the sum of the elements in xs.")
|
||||||
ptr := Load(Param("xs").Base(), GP64v())
|
ptr := Load(Param("xs").Base(), GP64())
|
||||||
n := Load(Param("xs").Len(), GP64v())
|
n := Load(Param("xs").Len(), GP64())
|
||||||
s := GP64v()
|
s := GP64()
|
||||||
XORQ(s, s)
|
XORQ(s, s)
|
||||||
LABEL("loop")
|
LABEL("loop")
|
||||||
CMPQ(n, operand.Imm(0))
|
CMPQ(n, operand.Imm(0))
|
||||||
@@ -126,7 +126,7 @@ func main() {
|
|||||||
[embedmd]:# (examples/args/asm.go go /.*TEXT.*StringLen/ /Load.*/)
|
[embedmd]:# (examples/args/asm.go go /.*TEXT.*StringLen/ /Load.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("StringLen", "func(s string) int")
|
TEXT("StringLen", "func(s string) int")
|
||||||
strlen := Load(Param("s").Len(), GP64v())
|
strlen := Load(Param("s").Len(), GP64())
|
||||||
```
|
```
|
||||||
|
|
||||||
Index an array:
|
Index an array:
|
||||||
@@ -134,7 +134,7 @@ Index an array:
|
|||||||
[embedmd]:# (examples/args/asm.go go /.*TEXT.*ArrayThree/ /Load.*/)
|
[embedmd]:# (examples/args/asm.go go /.*TEXT.*ArrayThree/ /Load.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("ArrayThree", "func(a [7]uint64) uint64")
|
TEXT("ArrayThree", "func(a [7]uint64) uint64")
|
||||||
a3 := Load(Param("a").Index(3), GP64v())
|
a3 := Load(Param("a").Index(3), GP64())
|
||||||
```
|
```
|
||||||
|
|
||||||
Access a struct field (provided you have loaded your package with the `Package` function):
|
Access a struct field (provided you have loaded your package with the `Package` function):
|
||||||
@@ -142,7 +142,7 @@ Access a struct field (provided you have loaded your package with the `Package`
|
|||||||
[embedmd]:# (examples/args/asm.go go /.*TEXT.*FieldFloat64/ /Load.*/)
|
[embedmd]:# (examples/args/asm.go go /.*TEXT.*FieldFloat64/ /Load.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("FieldFloat64", "func(s Struct) float64")
|
TEXT("FieldFloat64", "func(s Struct) float64")
|
||||||
f64 := Load(Param("s").Field("Float64"), Xv())
|
f64 := Load(Param("s").Field("Float64"), XMM())
|
||||||
```
|
```
|
||||||
|
|
||||||
Component accesses can be arbitrarily nested:
|
Component accesses can be arbitrarily nested:
|
||||||
@@ -150,7 +150,7 @@ Component accesses can be arbitrarily nested:
|
|||||||
[embedmd]:# (examples/args/asm.go go /.*TEXT.*FieldArrayTwoBTwo/ /Load.*/)
|
[embedmd]:# (examples/args/asm.go go /.*TEXT.*FieldArrayTwoBTwo/ /Load.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("FieldArrayTwoBTwo", "func(s Struct) byte")
|
TEXT("FieldArrayTwoBTwo", "func(s Struct) byte")
|
||||||
b2 := Load(Param("s").Field("Array").Index(2).Field("B").Index(2), GP8v())
|
b2 := Load(Param("s").Field("Array").Index(2).Field("B").Index(2), GP8())
|
||||||
```
|
```
|
||||||
|
|
||||||
Very similar techniques apply to writing return values. See [`examples/args`](examples/args) and [`examples/returns`](examples/returns) for more.
|
Very similar techniques apply to writing return values. See [`examples/args`](examples/args) and [`examples/returns`](examples/returns) for more.
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ func Constraints(t buildtags.ConstraintsConvertable) { ctx.Constraints(t) }
|
|||||||
func Constraint(t buildtags.ConstraintConvertable) { ctx.Constraint(t) }
|
func Constraint(t buildtags.ConstraintConvertable) { ctx.Constraint(t) }
|
||||||
func ConstraintExpr(expr string) { ctx.ConstraintExpr(expr) }
|
func ConstraintExpr(expr string) { ctx.ConstraintExpr(expr) }
|
||||||
|
|
||||||
func GP8v() reg.GPVirtual { return ctx.GP8v() }
|
func GP8() reg.GPVirtual { return ctx.GP8() }
|
||||||
func GP16v() reg.GPVirtual { return ctx.GP16v() }
|
func GP16() reg.GPVirtual { return ctx.GP16() }
|
||||||
func GP32v() reg.GPVirtual { return ctx.GP32v() }
|
func GP32() reg.GPVirtual { return ctx.GP32() }
|
||||||
func GP64v() reg.GPVirtual { return ctx.GP64v() }
|
func GP64() reg.GPVirtual { return ctx.GP64() }
|
||||||
func Xv() reg.VecVirtual { return ctx.Xv() }
|
func XMM() reg.VecVirtual { return ctx.XMM() }
|
||||||
func Yv() reg.VecVirtual { return ctx.Yv() }
|
func YMM() reg.VecVirtual { return ctx.YMM() }
|
||||||
func Zv() reg.VecVirtual { return ctx.Zv() }
|
func ZMM() reg.VecVirtual { return ctx.ZMM() }
|
||||||
|
|
||||||
func Param(name string) gotypes.Component { return ctx.Param(name) }
|
func Param(name string) gotypes.Component { return ctx.Param(name) }
|
||||||
func ParamIndex(i int) gotypes.Component { return ctx.ParamIndex(i) }
|
func ParamIndex(i int) gotypes.Component { return ctx.ParamIndex(i) }
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Add", "func(x, y uint64) uint64")
|
TEXT("Add", "func(x, y uint64) uint64")
|
||||||
Doc("Add adds x and y.")
|
Doc("Add adds x and y.")
|
||||||
x := Load(Param("x"), GP64v())
|
x := Load(Param("x"), GP64())
|
||||||
y := Load(Param("y"), GP64v())
|
y := Load(Param("y"), GP64())
|
||||||
ADDQ(x, y)
|
ADDQ(x, y)
|
||||||
Store(y, ReturnIndex(0))
|
Store(y, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Add", "func(x, y uint64) uint64")
|
TEXT("Add", "func(x, y uint64) uint64")
|
||||||
Doc("Add adds x and y.")
|
Doc("Add adds x and y.")
|
||||||
x := Load(Param("x"), GP64v())
|
x := Load(Param("x"), GP64())
|
||||||
y := Load(Param("y"), GP64v())
|
y := Load(Param("y"), GP64())
|
||||||
ADDQ(x, y)
|
ADDQ(x, y)
|
||||||
Store(y, ReturnIndex(0))
|
Store(y, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Use `Param()` to reference arguments by name. The `Load()` function can be used
|
|||||||
[embedmd]:# (asm.go go /.*TEXT.*Second/ /RET.*/)
|
[embedmd]:# (asm.go go /.*TEXT.*Second/ /RET.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("Second", "func(x, y int32) int32")
|
TEXT("Second", "func(x, y int32) int32")
|
||||||
y := Load(Param("y"), GP32v())
|
y := Load(Param("y"), GP32())
|
||||||
Store(y, ReturnIndex(0))
|
Store(y, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
```
|
```
|
||||||
@@ -34,7 +34,7 @@ Strings and slices actually consist of multiple components under the hood: see [
|
|||||||
[embedmd]:# (asm.go go /.*TEXT.*StringLen/ /RET.*/)
|
[embedmd]:# (asm.go go /.*TEXT.*StringLen/ /RET.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("StringLen", "func(s string) int")
|
TEXT("StringLen", "func(s string) int")
|
||||||
strlen := Load(Param("s").Len(), GP64v())
|
strlen := Load(Param("s").Len(), GP64())
|
||||||
Store(strlen, ReturnIndex(0))
|
Store(strlen, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
```
|
```
|
||||||
@@ -48,7 +48,7 @@ Arrays can be indexed with the `Index()` method. For example, the following retu
|
|||||||
[embedmd]:# (asm.go go /.*TEXT.*ArrayThree/ /RET.*/)
|
[embedmd]:# (asm.go go /.*TEXT.*ArrayThree/ /RET.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("ArrayThree", "func(a [7]uint64) uint64")
|
TEXT("ArrayThree", "func(a [7]uint64) uint64")
|
||||||
a3 := Load(Param("a").Index(3), GP64v())
|
a3 := Load(Param("a").Index(3), GP64())
|
||||||
Store(a3, ReturnIndex(0))
|
Store(a3, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
```
|
```
|
||||||
@@ -87,7 +87,7 @@ The following function will return the `Float64` field from this struct.
|
|||||||
[embedmd]:# (asm.go go /.*TEXT.*FieldFloat64/ /RET.*/)
|
[embedmd]:# (asm.go go /.*TEXT.*FieldFloat64/ /RET.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("FieldFloat64", "func(s Struct) float64")
|
TEXT("FieldFloat64", "func(s Struct) float64")
|
||||||
f64 := Load(Param("s").Field("Float64"), Xv())
|
f64 := Load(Param("s").Field("Float64"), XMM())
|
||||||
Store(f64, ReturnIndex(0))
|
Store(f64, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
```
|
```
|
||||||
@@ -99,7 +99,7 @@ Complex types `complex{64,128}` are actually just pairs of `float{32,64}` values
|
|||||||
[embedmd]:# (asm.go go /.*TEXT.*FieldComplex64Imag/ /RET.*/)
|
[embedmd]:# (asm.go go /.*TEXT.*FieldComplex64Imag/ /RET.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("FieldComplex64Imag", "func(s Struct) float32")
|
TEXT("FieldComplex64Imag", "func(s Struct) float32")
|
||||||
c64i := Load(Param("s").Field("Complex64").Imag(), Xv())
|
c64i := Load(Param("s").Field("Complex64").Imag(), XMM())
|
||||||
Store(c64i, ReturnIndex(0))
|
Store(c64i, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
```
|
```
|
||||||
@@ -111,7 +111,7 @@ The above methods may be composed to reference arbitrarily nested data structure
|
|||||||
[embedmd]:# (asm.go go /.*TEXT.*FieldArrayTwoBTwo/ /RET.*/)
|
[embedmd]:# (asm.go go /.*TEXT.*FieldArrayTwoBTwo/ /RET.*/)
|
||||||
```go
|
```go
|
||||||
TEXT("FieldArrayTwoBTwo", "func(s Struct) byte")
|
TEXT("FieldArrayTwoBTwo", "func(s Struct) byte")
|
||||||
b2 := Load(Param("s").Field("Array").Index(2).Field("B").Index(2), GP8v())
|
b2 := Load(Param("s").Field("Array").Index(2).Field("B").Index(2), GP8())
|
||||||
Store(b2, ReturnIndex(0))
|
Store(b2, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -10,92 +10,92 @@ func main() {
|
|||||||
Package("github.com/mmcloughlin/avo/examples/args")
|
Package("github.com/mmcloughlin/avo/examples/args")
|
||||||
|
|
||||||
TEXT("Second", "func(x, y int32) int32")
|
TEXT("Second", "func(x, y int32) int32")
|
||||||
y := Load(Param("y"), GP32v())
|
y := Load(Param("y"), GP32())
|
||||||
Store(y, ReturnIndex(0))
|
Store(y, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("StringLen", "func(s string) int")
|
TEXT("StringLen", "func(s string) int")
|
||||||
strlen := Load(Param("s").Len(), GP64v())
|
strlen := Load(Param("s").Len(), GP64())
|
||||||
Store(strlen, ReturnIndex(0))
|
Store(strlen, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("SliceLen", "func(s []int) int")
|
TEXT("SliceLen", "func(s []int) int")
|
||||||
slicelen := Load(Param("s").Len(), GP64v())
|
slicelen := Load(Param("s").Len(), GP64())
|
||||||
Store(slicelen, ReturnIndex(0))
|
Store(slicelen, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("SliceCap", "func(s []int) int")
|
TEXT("SliceCap", "func(s []int) int")
|
||||||
slicecap := Load(Param("s").Cap(), GP64v())
|
slicecap := Load(Param("s").Cap(), GP64())
|
||||||
Store(slicecap, ReturnIndex(0))
|
Store(slicecap, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("ArrayThree", "func(a [7]uint64) uint64")
|
TEXT("ArrayThree", "func(a [7]uint64) uint64")
|
||||||
a3 := Load(Param("a").Index(3), GP64v())
|
a3 := Load(Param("a").Index(3), GP64())
|
||||||
Store(a3, ReturnIndex(0))
|
Store(a3, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldByte", "func(s Struct) byte")
|
TEXT("FieldByte", "func(s Struct) byte")
|
||||||
b := Load(Param("s").Field("Byte"), GP8v())
|
b := Load(Param("s").Field("Byte"), GP8())
|
||||||
Store(b, ReturnIndex(0))
|
Store(b, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldInt8", "func(s Struct) int8")
|
TEXT("FieldInt8", "func(s Struct) int8")
|
||||||
i8 := Load(Param("s").Field("Int8"), GP8v())
|
i8 := Load(Param("s").Field("Int8"), GP8())
|
||||||
Store(i8, ReturnIndex(0))
|
Store(i8, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldUint16", "func(s Struct) uint16")
|
TEXT("FieldUint16", "func(s Struct) uint16")
|
||||||
u16 := Load(Param("s").Field("Uint16"), GP16v())
|
u16 := Load(Param("s").Field("Uint16"), GP16())
|
||||||
Store(u16, ReturnIndex(0))
|
Store(u16, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldInt32", "func(s Struct) int32")
|
TEXT("FieldInt32", "func(s Struct) int32")
|
||||||
i32 := Load(Param("s").Field("Int32"), GP32v())
|
i32 := Load(Param("s").Field("Int32"), GP32())
|
||||||
Store(i32, ReturnIndex(0))
|
Store(i32, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldUint64", "func(s Struct) uint64")
|
TEXT("FieldUint64", "func(s Struct) uint64")
|
||||||
u64 := Load(Param("s").Field("Uint64"), GP64v())
|
u64 := Load(Param("s").Field("Uint64"), GP64())
|
||||||
Store(u64, ReturnIndex(0))
|
Store(u64, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldFloat32", "func(s Struct) float32")
|
TEXT("FieldFloat32", "func(s Struct) float32")
|
||||||
f32 := Load(Param("s").Field("Float32"), Xv())
|
f32 := Load(Param("s").Field("Float32"), XMM())
|
||||||
Store(f32, ReturnIndex(0))
|
Store(f32, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldFloat64", "func(s Struct) float64")
|
TEXT("FieldFloat64", "func(s Struct) float64")
|
||||||
f64 := Load(Param("s").Field("Float64"), Xv())
|
f64 := Load(Param("s").Field("Float64"), XMM())
|
||||||
Store(f64, ReturnIndex(0))
|
Store(f64, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldStringLen", "func(s Struct) int")
|
TEXT("FieldStringLen", "func(s Struct) int")
|
||||||
l := Load(Param("s").Field("String").Len(), GP64v())
|
l := Load(Param("s").Field("String").Len(), GP64())
|
||||||
Store(l, ReturnIndex(0))
|
Store(l, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldSliceCap", "func(s Struct) int")
|
TEXT("FieldSliceCap", "func(s Struct) int")
|
||||||
c := Load(Param("s").Field("Slice").Cap(), GP64v())
|
c := Load(Param("s").Field("Slice").Cap(), GP64())
|
||||||
Store(c, ReturnIndex(0))
|
Store(c, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldArrayTwoBTwo", "func(s Struct) byte")
|
TEXT("FieldArrayTwoBTwo", "func(s Struct) byte")
|
||||||
b2 := Load(Param("s").Field("Array").Index(2).Field("B").Index(2), GP8v())
|
b2 := Load(Param("s").Field("Array").Index(2).Field("B").Index(2), GP8())
|
||||||
Store(b2, ReturnIndex(0))
|
Store(b2, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldArrayOneC", "func(s Struct) uint16")
|
TEXT("FieldArrayOneC", "func(s Struct) uint16")
|
||||||
c1 := Load(Param("s").Field("Array").Index(1).Field("C"), GP16v())
|
c1 := Load(Param("s").Field("Array").Index(1).Field("C"), GP16())
|
||||||
Store(c1, ReturnIndex(0))
|
Store(c1, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldComplex64Imag", "func(s Struct) float32")
|
TEXT("FieldComplex64Imag", "func(s Struct) float32")
|
||||||
c64i := Load(Param("s").Field("Complex64").Imag(), Xv())
|
c64i := Load(Param("s").Field("Complex64").Imag(), XMM())
|
||||||
Store(c64i, ReturnIndex(0))
|
Store(c64i, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("FieldComplex128Real", "func(s Struct) float64")
|
TEXT("FieldComplex128Real", "func(s Struct) float64")
|
||||||
c128r := Load(Param("s").Field("Complex128").Real(), Xv())
|
c128r := Load(Param("s").Field("Complex128").Real(), XMM())
|
||||||
Store(c128r, ReturnIndex(0))
|
Store(c128r, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ The `Real()` and `Imag()` parameter methods may be used to load the sub-componen
|
|||||||
```go
|
```go
|
||||||
TEXT("Norm", "func(z complex128) float64")
|
TEXT("Norm", "func(z complex128) float64")
|
||||||
Doc("Norm returns the complex norm of z.")
|
Doc("Norm returns the complex norm of z.")
|
||||||
r = Load(Param("z").Real(), Xv())
|
r = Load(Param("z").Real(), XMM())
|
||||||
i = Load(Param("z").Imag(), Xv())
|
i = Load(Param("z").Imag(), XMM())
|
||||||
MULSD(r, r)
|
MULSD(r, r)
|
||||||
MULSD(i, i)
|
MULSD(i, i)
|
||||||
ADDSD(i, r)
|
ADDSD(i, r)
|
||||||
n := Xv()
|
n := XMM()
|
||||||
SQRTSD(r, n)
|
SQRTSD(r, n)
|
||||||
Store(n, ReturnIndex(0))
|
Store(n, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|||||||
@@ -9,24 +9,24 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Real", "func(z complex128) float64")
|
TEXT("Real", "func(z complex128) float64")
|
||||||
Doc("Real returns the real part of z.")
|
Doc("Real returns the real part of z.")
|
||||||
r := Load(Param("z").Real(), Xv())
|
r := Load(Param("z").Real(), XMM())
|
||||||
Store(r, ReturnIndex(0))
|
Store(r, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("Imag", "func(z complex128) float64")
|
TEXT("Imag", "func(z complex128) float64")
|
||||||
Doc("Imag returns the imaginary part of z.")
|
Doc("Imag returns the imaginary part of z.")
|
||||||
i := Load(Param("z").Imag(), Xv())
|
i := Load(Param("z").Imag(), XMM())
|
||||||
Store(i, ReturnIndex(0))
|
Store(i, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|
||||||
TEXT("Norm", "func(z complex128) float64")
|
TEXT("Norm", "func(z complex128) float64")
|
||||||
Doc("Norm returns the complex norm of z.")
|
Doc("Norm returns the complex norm of z.")
|
||||||
r = Load(Param("z").Real(), Xv())
|
r = Load(Param("z").Real(), XMM())
|
||||||
i = Load(Param("z").Imag(), Xv())
|
i = Load(Param("z").Imag(), XMM())
|
||||||
MULSD(r, r)
|
MULSD(r, r)
|
||||||
MULSD(i, i)
|
MULSD(i, i)
|
||||||
ADDSD(i, r)
|
ADDSD(i, r)
|
||||||
n := Xv()
|
n := XMM()
|
||||||
SQRTSD(r, n)
|
SQRTSD(r, n)
|
||||||
Store(n, ReturnIndex(0))
|
Store(n, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ The `GLOBL` function returns a reference which may be used in assembly code. The
|
|||||||
```go
|
```go
|
||||||
TEXT("DataAt", "func(i int) byte")
|
TEXT("DataAt", "func(i int) byte")
|
||||||
Doc("DataAt returns byte i in the 'bytes' global data section.")
|
Doc("DataAt returns byte i in the 'bytes' global data section.")
|
||||||
i := Load(Param("i"), GP64v())
|
i := Load(Param("i"), GP64())
|
||||||
ptr := Mem{Base: GP64v()}
|
ptr := Mem{Base: GP64()}
|
||||||
LEAQ(bytes, ptr.Base)
|
LEAQ(bytes, ptr.Base)
|
||||||
b := GP8v()
|
b := GP8()
|
||||||
MOVB(ptr.Idx(i, 1), b)
|
MOVB(ptr.Idx(i, 1), b)
|
||||||
Store(b, ReturnIndex(0))
|
Store(b, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ func main() {
|
|||||||
|
|
||||||
TEXT("DataAt", "func(i int) byte")
|
TEXT("DataAt", "func(i int) byte")
|
||||||
Doc("DataAt returns byte i in the 'bytes' global data section.")
|
Doc("DataAt returns byte i in the 'bytes' global data section.")
|
||||||
i := Load(Param("i"), GP64v())
|
i := Load(Param("i"), GP64())
|
||||||
ptr := Mem{Base: GP64v()}
|
ptr := Mem{Base: GP64()}
|
||||||
LEAQ(bytes, ptr.Base)
|
LEAQ(bytes, ptr.Base)
|
||||||
b := GP8v()
|
b := GP8()
|
||||||
MOVB(ptr.Idx(i, 1), b)
|
MOVB(ptr.Idx(i, 1), b)
|
||||||
Store(b, ReturnIndex(0))
|
Store(b, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ var unroll = 6
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
TEXT("Dot", "func(x, y []float32) float32")
|
TEXT("Dot", "func(x, y []float32) float32")
|
||||||
x := Mem{Base: Load(Param("x").Base(), GP64v())}
|
x := Mem{Base: Load(Param("x").Base(), GP64())}
|
||||||
y := Mem{Base: Load(Param("y").Base(), GP64v())}
|
y := Mem{Base: Load(Param("y").Base(), GP64())}
|
||||||
n := Load(Param("x").Len(), GP64v())
|
n := Load(Param("x").Len(), GP64())
|
||||||
|
|
||||||
// Allocate accumulation registers.
|
// Allocate accumulation registers.
|
||||||
acc := make([]VecVirtual, unroll)
|
acc := make([]VecVirtual, unroll)
|
||||||
for i := 0; i < unroll; i++ {
|
for i := 0; i < unroll; i++ {
|
||||||
acc[i] = Yv()
|
acc[i] = YMM()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero initialization.
|
// Zero initialization.
|
||||||
@@ -37,7 +37,7 @@ func main() {
|
|||||||
// Load x.
|
// Load x.
|
||||||
xs := make([]VecVirtual, unroll)
|
xs := make([]VecVirtual, unroll)
|
||||||
for i := 0; i < unroll; i++ {
|
for i := 0; i < unroll; i++ {
|
||||||
xs[i] = Yv()
|
xs[i] = YMM()
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < unroll; i++ {
|
for i := 0; i < unroll; i++ {
|
||||||
@@ -56,14 +56,14 @@ func main() {
|
|||||||
|
|
||||||
// Process any trailing entries.
|
// Process any trailing entries.
|
||||||
LABEL("tail")
|
LABEL("tail")
|
||||||
tail := Xv()
|
tail := XMM()
|
||||||
VXORPS(tail, tail, tail)
|
VXORPS(tail, tail, tail)
|
||||||
|
|
||||||
LABEL("tailloop")
|
LABEL("tailloop")
|
||||||
CMPQ(n, U32(0))
|
CMPQ(n, U32(0))
|
||||||
JE(LabelRef("reduce"))
|
JE(LabelRef("reduce"))
|
||||||
|
|
||||||
xt := Xv()
|
xt := XMM()
|
||||||
VMOVSS(x, xt)
|
VMOVSS(x, xt)
|
||||||
VFMADD231SS(y, xt, tail)
|
VFMADD231SS(y, xt, tail)
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result := acc[0].AsX()
|
result := acc[0].AsX()
|
||||||
top := Xv()
|
top := XMM()
|
||||||
VEXTRACTF128(U8(1), acc[0], top)
|
VEXTRACTF128(U8(1), acc[0], top)
|
||||||
VADDPS(result, top, result)
|
VADDPS(result, top, result)
|
||||||
VADDPS(result, tail, result)
|
VADDPS(result, tail, result)
|
||||||
|
|||||||
@@ -12,18 +12,18 @@ const (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Hash64", "func(data []byte) uint64")
|
TEXT("Hash64", "func(data []byte) uint64")
|
||||||
Doc("Hash64 computes the FNV-1a hash of data.")
|
Doc("Hash64 computes the FNV-1a hash of data.")
|
||||||
ptr := Load(Param("data").Base(), GP64v())
|
ptr := Load(Param("data").Base(), GP64())
|
||||||
n := Load(Param("data").Len(), GP64v())
|
n := Load(Param("data").Len(), GP64())
|
||||||
|
|
||||||
h := reg.RAX
|
h := reg.RAX
|
||||||
MOVQ(operand.Imm(OffsetBasis), h)
|
MOVQ(operand.Imm(OffsetBasis), h)
|
||||||
p := GP64v()
|
p := GP64()
|
||||||
MOVQ(operand.Imm(Prime), p)
|
MOVQ(operand.Imm(Prime), p)
|
||||||
|
|
||||||
LABEL("loop")
|
LABEL("loop")
|
||||||
CMPQ(n, operand.Imm(0))
|
CMPQ(n, operand.Imm(0))
|
||||||
JE(operand.LabelRef("done"))
|
JE(operand.LabelRef("done"))
|
||||||
b := GP64v()
|
b := GP64()
|
||||||
MOVBQZX(operand.Mem{Base: ptr}, b)
|
MOVBQZX(operand.Mem{Base: ptr}, b)
|
||||||
XORQ(b, h)
|
XORQ(b, h)
|
||||||
MULQ(p)
|
MULQ(p)
|
||||||
|
|||||||
@@ -16,18 +16,18 @@ const (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Hash64", "func(data []byte) uint64")
|
TEXT("Hash64", "func(data []byte) uint64")
|
||||||
Doc("Hash64 computes the FNV-1a hash of data.")
|
Doc("Hash64 computes the FNV-1a hash of data.")
|
||||||
ptr := Load(Param("data").Base(), GP64v())
|
ptr := Load(Param("data").Base(), GP64())
|
||||||
n := Load(Param("data").Len(), GP64v())
|
n := Load(Param("data").Len(), GP64())
|
||||||
|
|
||||||
h := reg.RAX
|
h := reg.RAX
|
||||||
MOVQ(operand.Imm(OffsetBasis), h)
|
MOVQ(operand.Imm(OffsetBasis), h)
|
||||||
p := GP64v()
|
p := GP64()
|
||||||
MOVQ(operand.Imm(Prime), p)
|
MOVQ(operand.Imm(Prime), p)
|
||||||
|
|
||||||
LABEL("loop")
|
LABEL("loop")
|
||||||
CMPQ(n, operand.Imm(0))
|
CMPQ(n, operand.Imm(0))
|
||||||
JE(operand.LabelRef("done"))
|
JE(operand.LabelRef("done"))
|
||||||
b := GP64v()
|
b := GP64()
|
||||||
MOVBQZX(operand.Mem{Base: ptr}, b)
|
MOVBQZX(operand.Mem{Base: ptr}, b)
|
||||||
XORQ(b, h)
|
XORQ(b, h)
|
||||||
MULQ(p)
|
MULQ(p)
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ Refer to ["Geohash in Golang Assembly"](https://mmcloughlin.com/posts/geohash-as
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("EncodeInt", "func(lat, lng float64) uint64")
|
TEXT("EncodeInt", "func(lat, lng float64) uint64")
|
||||||
Doc("EncodeInt computes the 64-bit integer geohash of (lat, lng).")
|
Doc("EncodeInt computes the 64-bit integer geohash of (lat, lng).")
|
||||||
lat := Load(Param("lat"), Xv())
|
lat := Load(Param("lat"), XMM())
|
||||||
lng := Load(Param("lng"), Xv())
|
lng := Load(Param("lng"), XMM())
|
||||||
|
|
||||||
MULSD(ConstData("reciprocal180", F64(1/180.0)), lat)
|
MULSD(ConstData("reciprocal180", F64(1/180.0)), lat)
|
||||||
onepointfive := ConstData("onepointfive", F64(1.5))
|
onepointfive := ConstData("onepointfive", F64(1.5))
|
||||||
@@ -19,16 +19,16 @@ func main() {
|
|||||||
MULSD(ConstData("reciprocal360", F64(1/360.0)), lng)
|
MULSD(ConstData("reciprocal360", F64(1/360.0)), lng)
|
||||||
ADDSD(onepointfive, lng)
|
ADDSD(onepointfive, lng)
|
||||||
|
|
||||||
lngi, lati := GP64v(), GP64v()
|
lngi, lati := GP64(), GP64()
|
||||||
MOVQ(lat, lati)
|
MOVQ(lat, lati)
|
||||||
SHRQ(U8(20), lati)
|
SHRQ(U8(20), lati)
|
||||||
MOVQ(lng, lngi)
|
MOVQ(lng, lngi)
|
||||||
SHRQ(U8(20), lngi)
|
SHRQ(U8(20), lngi)
|
||||||
|
|
||||||
mask := ConstData("mask", U64(0x5555555555555555))
|
mask := ConstData("mask", U64(0x5555555555555555))
|
||||||
ghsh := GP64v()
|
ghsh := GP64()
|
||||||
PDEPQ(mask, lati, ghsh)
|
PDEPQ(mask, lati, ghsh)
|
||||||
temp := GP64v()
|
temp := GP64()
|
||||||
PDEPQ(mask, lngi, temp)
|
PDEPQ(mask, lngi, temp)
|
||||||
SHLQ(U8(1), temp)
|
SHLQ(U8(1), temp)
|
||||||
XORQ(temp, ghsh)
|
XORQ(temp, ghsh)
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("EncodeInt", "func(lat, lng float64) uint64")
|
TEXT("EncodeInt", "func(lat, lng float64) uint64")
|
||||||
Doc("EncodeInt computes the 64-bit integer geohash of (lat, lng).")
|
Doc("EncodeInt computes the 64-bit integer geohash of (lat, lng).")
|
||||||
lat := Load(Param("lat"), Xv())
|
lat := Load(Param("lat"), XMM())
|
||||||
lng := Load(Param("lng"), Xv())
|
lng := Load(Param("lng"), XMM())
|
||||||
|
|
||||||
MULSD(ConstData("reciprocal180", F64(1/180.0)), lat)
|
MULSD(ConstData("reciprocal180", F64(1/180.0)), lat)
|
||||||
onepointfive := ConstData("onepointfive", F64(1.5))
|
onepointfive := ConstData("onepointfive", F64(1.5))
|
||||||
@@ -20,16 +20,16 @@ func main() {
|
|||||||
MULSD(ConstData("reciprocal360", F64(1/360.0)), lng)
|
MULSD(ConstData("reciprocal360", F64(1/360.0)), lng)
|
||||||
ADDSD(onepointfive, lng)
|
ADDSD(onepointfive, lng)
|
||||||
|
|
||||||
lngi, lati := GP64v(), GP64v()
|
lngi, lati := GP64(), GP64()
|
||||||
MOVQ(lat, lati)
|
MOVQ(lat, lati)
|
||||||
SHRQ(U8(20), lati)
|
SHRQ(U8(20), lati)
|
||||||
MOVQ(lng, lngi)
|
MOVQ(lng, lngi)
|
||||||
SHRQ(U8(20), lngi)
|
SHRQ(U8(20), lngi)
|
||||||
|
|
||||||
mask := ConstData("mask", U64(0x5555555555555555))
|
mask := ConstData("mask", U64(0x5555555555555555))
|
||||||
ghsh := GP64v()
|
ghsh := GP64()
|
||||||
PDEPQ(mask, lati, ghsh)
|
PDEPQ(mask, lati, ghsh)
|
||||||
temp := GP64v()
|
temp := GP64()
|
||||||
PDEPQ(mask, lngi, temp)
|
PDEPQ(mask, lngi, temp)
|
||||||
SHLQ(U8(1), temp)
|
SHLQ(U8(1), temp)
|
||||||
XORQ(temp, ghsh)
|
XORQ(temp, ghsh)
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ Use `ReturnIndex` to reference unnamed return values. For example, the following
|
|||||||
"Interval returns the (start, end) of an interval with the given start and size.",
|
"Interval returns the (start, end) of an interval with the given start and size.",
|
||||||
"Demonstrates multiple unnamed return values.",
|
"Demonstrates multiple unnamed return values.",
|
||||||
)
|
)
|
||||||
start := Load(Param("start"), GP64v())
|
start := Load(Param("start"), GP64())
|
||||||
size := Load(Param("size"), GP64v())
|
size := Load(Param("size"), GP64())
|
||||||
end := size
|
end := size
|
||||||
ADDQ(start, end)
|
ADDQ(start, end)
|
||||||
Store(start, ReturnIndex(0))
|
Store(start, ReturnIndex(0))
|
||||||
@@ -33,9 +33,9 @@ Named return values are referenced much the same as arguments. For example, the
|
|||||||
"Butterfly performs a 2-dimensional butterfly operation: computes (x0+x1, x0-x1).",
|
"Butterfly performs a 2-dimensional butterfly operation: computes (x0+x1, x0-x1).",
|
||||||
"Demonstrates multiple named return values.",
|
"Demonstrates multiple named return values.",
|
||||||
)
|
)
|
||||||
x0 := Load(Param("x0"), Xv())
|
x0 := Load(Param("x0"), XMM())
|
||||||
x1 := Load(Param("x1"), Xv())
|
x1 := Load(Param("x1"), XMM())
|
||||||
y0, y1 := Xv(), Xv()
|
y0, y1 := XMM(), XMM()
|
||||||
MOVSD(x0, y0)
|
MOVSD(x0, y0)
|
||||||
ADDSD(x1, y0)
|
ADDSD(x1, y0)
|
||||||
MOVSD(x0, y1)
|
MOVSD(x0, y1)
|
||||||
@@ -58,7 +58,7 @@ The following code returns an array type.
|
|||||||
"Septuple returns an array of seven of the given byte.",
|
"Septuple returns an array of seven of the given byte.",
|
||||||
"Demonstrates returning array values.",
|
"Demonstrates returning array values.",
|
||||||
)
|
)
|
||||||
b := Load(ParamIndex(0), GP8v())
|
b := Load(ParamIndex(0), GP8())
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
Store(b, ReturnIndex(0).Index(i))
|
Store(b, ReturnIndex(0).Index(i))
|
||||||
}
|
}
|
||||||
@@ -74,8 +74,8 @@ Or a complex type:
|
|||||||
"CriticalLine returns the complex value 0.5 + it on Riemann's critical line.",
|
"CriticalLine returns the complex value 0.5 + it on Riemann's critical line.",
|
||||||
"Demonstrates returning complex values.",
|
"Demonstrates returning complex values.",
|
||||||
)
|
)
|
||||||
t := Load(Param("t"), Xv())
|
t := Load(Param("t"), XMM())
|
||||||
half := Xv()
|
half := XMM()
|
||||||
MOVSD(ConstData("half", F64(0.5)), half)
|
MOVSD(ConstData("half", F64(0.5)), half)
|
||||||
Store(half, ReturnIndex(0).Real())
|
Store(half, ReturnIndex(0).Real())
|
||||||
Store(t, ReturnIndex(0).Imag())
|
Store(t, ReturnIndex(0).Imag())
|
||||||
@@ -91,10 +91,10 @@ You can even build a struct:
|
|||||||
"NewStruct initializes a Struct value.",
|
"NewStruct initializes a Struct value.",
|
||||||
"Demonstrates returning struct values.",
|
"Demonstrates returning struct values.",
|
||||||
)
|
)
|
||||||
w := Load(Param("w"), GP16v())
|
w := Load(Param("w"), GP16())
|
||||||
x := Load(Param("p").Index(0), Xv())
|
x := Load(Param("p").Index(0), XMM())
|
||||||
y := Load(Param("p").Index(1), Xv())
|
y := Load(Param("p").Index(1), XMM())
|
||||||
q := Load(Param("q"), GP64v())
|
q := Load(Param("q"), GP64())
|
||||||
Store(w, ReturnIndex(0).Field("Word"))
|
Store(w, ReturnIndex(0).Field("Word"))
|
||||||
Store(x, ReturnIndex(0).Field("Point").Index(0))
|
Store(x, ReturnIndex(0).Field("Point").Index(0))
|
||||||
Store(y, ReturnIndex(0).Field("Point").Index(1))
|
Store(y, ReturnIndex(0).Field("Point").Index(1))
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ func main() {
|
|||||||
"Interval returns the (start, end) of an interval with the given start and size.",
|
"Interval returns the (start, end) of an interval with the given start and size.",
|
||||||
"Demonstrates multiple unnamed return values.",
|
"Demonstrates multiple unnamed return values.",
|
||||||
)
|
)
|
||||||
start := Load(Param("start"), GP64v())
|
start := Load(Param("start"), GP64())
|
||||||
size := Load(Param("size"), GP64v())
|
size := Load(Param("size"), GP64())
|
||||||
end := size
|
end := size
|
||||||
ADDQ(start, end)
|
ADDQ(start, end)
|
||||||
Store(start, ReturnIndex(0))
|
Store(start, ReturnIndex(0))
|
||||||
@@ -28,9 +28,9 @@ func main() {
|
|||||||
"Butterfly performs a 2-dimensional butterfly operation: computes (x0+x1, x0-x1).",
|
"Butterfly performs a 2-dimensional butterfly operation: computes (x0+x1, x0-x1).",
|
||||||
"Demonstrates multiple named return values.",
|
"Demonstrates multiple named return values.",
|
||||||
)
|
)
|
||||||
x0 := Load(Param("x0"), Xv())
|
x0 := Load(Param("x0"), XMM())
|
||||||
x1 := Load(Param("x1"), Xv())
|
x1 := Load(Param("x1"), XMM())
|
||||||
y0, y1 := Xv(), Xv()
|
y0, y1 := XMM(), XMM()
|
||||||
MOVSD(x0, y0)
|
MOVSD(x0, y0)
|
||||||
ADDSD(x1, y0)
|
ADDSD(x1, y0)
|
||||||
MOVSD(x0, y1)
|
MOVSD(x0, y1)
|
||||||
@@ -44,7 +44,7 @@ func main() {
|
|||||||
"Septuple returns an array of seven of the given byte.",
|
"Septuple returns an array of seven of the given byte.",
|
||||||
"Demonstrates returning array values.",
|
"Demonstrates returning array values.",
|
||||||
)
|
)
|
||||||
b := Load(ParamIndex(0), GP8v())
|
b := Load(ParamIndex(0), GP8())
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
Store(b, ReturnIndex(0).Index(i))
|
Store(b, ReturnIndex(0).Index(i))
|
||||||
}
|
}
|
||||||
@@ -55,8 +55,8 @@ func main() {
|
|||||||
"CriticalLine returns the complex value 0.5 + it on Riemann's critical line.",
|
"CriticalLine returns the complex value 0.5 + it on Riemann's critical line.",
|
||||||
"Demonstrates returning complex values.",
|
"Demonstrates returning complex values.",
|
||||||
)
|
)
|
||||||
t := Load(Param("t"), Xv())
|
t := Load(Param("t"), XMM())
|
||||||
half := Xv()
|
half := XMM()
|
||||||
MOVSD(ConstData("half", F64(0.5)), half)
|
MOVSD(ConstData("half", F64(0.5)), half)
|
||||||
Store(half, ReturnIndex(0).Real())
|
Store(half, ReturnIndex(0).Real())
|
||||||
Store(t, ReturnIndex(0).Imag())
|
Store(t, ReturnIndex(0).Imag())
|
||||||
@@ -67,10 +67,10 @@ func main() {
|
|||||||
"NewStruct initializes a Struct value.",
|
"NewStruct initializes a Struct value.",
|
||||||
"Demonstrates returning struct values.",
|
"Demonstrates returning struct values.",
|
||||||
)
|
)
|
||||||
w := Load(Param("w"), GP16v())
|
w := Load(Param("w"), GP16())
|
||||||
x := Load(Param("p").Index(0), Xv())
|
x := Load(Param("p").Index(0), XMM())
|
||||||
y := Load(Param("p").Index(1), Xv())
|
y := Load(Param("p").Index(1), XMM())
|
||||||
q := Load(Param("q"), GP64v())
|
q := Load(Param("q"), GP64())
|
||||||
Store(w, ReturnIndex(0).Field("Word"))
|
Store(w, ReturnIndex(0).Field("Word"))
|
||||||
Store(x, ReturnIndex(0).Field("Point").Index(0))
|
Store(x, ReturnIndex(0).Field("Point").Index(0))
|
||||||
Store(y, ReturnIndex(0).Field("Point").Index(1))
|
Store(y, ReturnIndex(0).Field("Point").Index(1))
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ Compare to the [`crypto/sha1`](https://github.com/golang/go/blob/204a8f55dc2e0ac
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("block", "func(h *[5]uint32, m []byte)")
|
TEXT("block", "func(h *[5]uint32, m []byte)")
|
||||||
Doc("block SHA-1 hashes the 64-byte message m into the running state h.")
|
Doc("block SHA-1 hashes the 64-byte message m into the running state h.")
|
||||||
h := Mem{Base: Load(Param("h"), GP64v())}
|
h := Mem{Base: Load(Param("h"), GP64())}
|
||||||
m := Mem{Base: Load(Param("m").Base(), GP64v())}
|
m := Mem{Base: Load(Param("m").Base(), GP64())}
|
||||||
|
|
||||||
// Store message values on the stack.
|
// Store message values on the stack.
|
||||||
w := AllocLocal(64)
|
w := AllocLocal(64)
|
||||||
W := func(r int) Mem { return w.Offset((r % 16) * 4) }
|
W := func(r int) Mem { return w.Offset((r % 16) * 4) }
|
||||||
|
|
||||||
// Load initial hash.
|
// Load initial hash.
|
||||||
h0, h1, h2, h3, h4 := GP32v(), GP32v(), GP32v(), GP32v(), GP32v()
|
h0, h1, h2, h3, h4 := GP32(), GP32(), GP32(), GP32(), GP32()
|
||||||
|
|
||||||
MOVL(h.Offset(0), h0)
|
MOVL(h.Offset(0), h0)
|
||||||
MOVL(h.Offset(4), h1)
|
MOVL(h.Offset(4), h1)
|
||||||
@@ -26,7 +26,7 @@ func main() {
|
|||||||
MOVL(h.Offset(16), h4)
|
MOVL(h.Offset(16), h4)
|
||||||
|
|
||||||
// Initialize registers.
|
// Initialize registers.
|
||||||
a, b, c, d, e := GP32v(), GP32v(), GP32v(), GP32v(), GP32v()
|
a, b, c, d, e := GP32(), GP32(), GP32(), GP32(), GP32()
|
||||||
|
|
||||||
MOVL(h0, a)
|
MOVL(h0, a)
|
||||||
MOVL(h1, b)
|
MOVL(h1, b)
|
||||||
@@ -49,7 +49,7 @@ func main() {
|
|||||||
q := quarter[r/20]
|
q := quarter[r/20]
|
||||||
|
|
||||||
// Load message value.
|
// Load message value.
|
||||||
u := GP32v()
|
u := GP32()
|
||||||
if r < 16 {
|
if r < 16 {
|
||||||
MOVL(m.Offset(4*r), u)
|
MOVL(m.Offset(4*r), u)
|
||||||
BSWAPL(u)
|
BSWAPL(u)
|
||||||
@@ -63,7 +63,7 @@ func main() {
|
|||||||
MOVL(u, W(r))
|
MOVL(u, W(r))
|
||||||
|
|
||||||
// Compute the next state register.
|
// Compute the next state register.
|
||||||
t := GP32v()
|
t := GP32()
|
||||||
MOVL(a, t)
|
MOVL(a, t)
|
||||||
ROLL(U8(5), t)
|
ROLL(U8(5), t)
|
||||||
ADDL(q.F(b, c, d), t)
|
ADDL(q.F(b, c, d), t)
|
||||||
|
|||||||
@@ -11,15 +11,15 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("block", "func(h *[5]uint32, m []byte)")
|
TEXT("block", "func(h *[5]uint32, m []byte)")
|
||||||
Doc("block SHA-1 hashes the 64-byte message m into the running state h.")
|
Doc("block SHA-1 hashes the 64-byte message m into the running state h.")
|
||||||
h := Mem{Base: Load(Param("h"), GP64v())}
|
h := Mem{Base: Load(Param("h"), GP64())}
|
||||||
m := Mem{Base: Load(Param("m").Base(), GP64v())}
|
m := Mem{Base: Load(Param("m").Base(), GP64())}
|
||||||
|
|
||||||
// Store message values on the stack.
|
// Store message values on the stack.
|
||||||
w := AllocLocal(64)
|
w := AllocLocal(64)
|
||||||
W := func(r int) Mem { return w.Offset((r % 16) * 4) }
|
W := func(r int) Mem { return w.Offset((r % 16) * 4) }
|
||||||
|
|
||||||
// Load initial hash.
|
// Load initial hash.
|
||||||
h0, h1, h2, h3, h4 := GP32v(), GP32v(), GP32v(), GP32v(), GP32v()
|
h0, h1, h2, h3, h4 := GP32(), GP32(), GP32(), GP32(), GP32()
|
||||||
|
|
||||||
MOVL(h.Offset(0), h0)
|
MOVL(h.Offset(0), h0)
|
||||||
MOVL(h.Offset(4), h1)
|
MOVL(h.Offset(4), h1)
|
||||||
@@ -28,7 +28,7 @@ func main() {
|
|||||||
MOVL(h.Offset(16), h4)
|
MOVL(h.Offset(16), h4)
|
||||||
|
|
||||||
// Initialize registers.
|
// Initialize registers.
|
||||||
a, b, c, d, e := GP32v(), GP32v(), GP32v(), GP32v(), GP32v()
|
a, b, c, d, e := GP32(), GP32(), GP32(), GP32(), GP32()
|
||||||
|
|
||||||
MOVL(h0, a)
|
MOVL(h0, a)
|
||||||
MOVL(h1, b)
|
MOVL(h1, b)
|
||||||
@@ -51,7 +51,7 @@ func main() {
|
|||||||
q := quarter[r/20]
|
q := quarter[r/20]
|
||||||
|
|
||||||
// Load message value.
|
// Load message value.
|
||||||
u := GP32v()
|
u := GP32()
|
||||||
if r < 16 {
|
if r < 16 {
|
||||||
MOVL(m.Offset(4*r), u)
|
MOVL(m.Offset(4*r), u)
|
||||||
BSWAPL(u)
|
BSWAPL(u)
|
||||||
@@ -65,7 +65,7 @@ func main() {
|
|||||||
MOVL(u, W(r))
|
MOVL(u, W(r))
|
||||||
|
|
||||||
// Compute the next state register.
|
// Compute the next state register.
|
||||||
t := GP32v()
|
t := GP32()
|
||||||
MOVL(a, t)
|
MOVL(a, t)
|
||||||
ROLL(U8(5), t)
|
ROLL(U8(5), t)
|
||||||
ADDL(q.F(b, c, d), t)
|
ADDL(q.F(b, c, d), t)
|
||||||
@@ -97,7 +97,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func choose(b, c, d Register) Register {
|
func choose(b, c, d Register) Register {
|
||||||
r := GP32v()
|
r := GP32()
|
||||||
MOVL(d, r)
|
MOVL(d, r)
|
||||||
XORL(c, r)
|
XORL(c, r)
|
||||||
ANDL(b, r)
|
ANDL(b, r)
|
||||||
@@ -106,7 +106,7 @@ func choose(b, c, d Register) Register {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func xor(b, c, d Register) Register {
|
func xor(b, c, d Register) Register {
|
||||||
r := GP32v()
|
r := GP32()
|
||||||
MOVL(b, r)
|
MOVL(b, r)
|
||||||
XORL(c, r)
|
XORL(c, r)
|
||||||
XORL(d, r)
|
XORL(d, r)
|
||||||
@@ -114,7 +114,7 @@ func xor(b, c, d Register) Register {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func majority(b, c, d Register) Register {
|
func majority(b, c, d Register) Register {
|
||||||
t, r := GP32v(), GP32v()
|
t, r := GP32(), GP32()
|
||||||
MOVL(b, t)
|
MOVL(b, t)
|
||||||
ORL(c, t)
|
ORL(c, t)
|
||||||
ANDL(d, t)
|
ANDL(d, t)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func imul(k uint64, r Register) {
|
func imul(k uint64, r Register) {
|
||||||
t := GP64v()
|
t := GP64()
|
||||||
MOVQ(U64(k), t)
|
MOVQ(U64(k), t)
|
||||||
IMULQ(t, r)
|
IMULQ(t, r)
|
||||||
}
|
}
|
||||||
@@ -41,16 +41,16 @@ func main() {
|
|||||||
TEXT("Hash", "func(state *State, key []byte) uint64")
|
TEXT("Hash", "func(state *State, key []byte) uint64")
|
||||||
Doc("Hash computes the Stadtx hash.")
|
Doc("Hash computes the Stadtx hash.")
|
||||||
|
|
||||||
statePtr := Load(Param("state"), GP64v())
|
statePtr := Load(Param("state"), GP64())
|
||||||
ptr := Load(Param("key").Base(), GP64v())
|
ptr := Load(Param("key").Base(), GP64())
|
||||||
n := Load(Param("key").Len(), GP64v())
|
n := Load(Param("key").Len(), GP64())
|
||||||
|
|
||||||
v0 := GP64v() // reg_v0 = GeneralPurposeRegister64()
|
v0 := GP64() // reg_v0 = GeneralPurposeRegister64()
|
||||||
v1 := GP64v() // reg_v1 = GeneralPurposeRegister64()
|
v1 := GP64() // reg_v1 = GeneralPurposeRegister64()
|
||||||
MOVQ(Mem{Base: statePtr}, v0) // MOV(reg_v0, [reg_state_ptr])
|
MOVQ(Mem{Base: statePtr}, v0) // MOV(reg_v0, [reg_state_ptr])
|
||||||
MOVQ(Mem{Base: statePtr, Disp: 8}, v1) // MOV(reg_v1, [reg_state_ptr+8])
|
MOVQ(Mem{Base: statePtr, Disp: 8}, v1) // MOV(reg_v1, [reg_state_ptr+8])
|
||||||
|
|
||||||
t := GP64v() // t = GeneralPurposeRegister64()
|
t := GP64() // t = GeneralPurposeRegister64()
|
||||||
MOVQ(n, t) // MOV(t, reg_ptr_len)
|
MOVQ(n, t) // MOV(t, reg_ptr_len)
|
||||||
ADDQ(U32(1), t) // ADD(t, 1)
|
ADDQ(U32(1), t) // ADD(t, 1)
|
||||||
imul(k0U64, t) // imul(t, k0U64)
|
imul(k0U64, t) // imul(t, k0U64)
|
||||||
@@ -65,7 +65,7 @@ func main() {
|
|||||||
CMPQ(n, U32(32)) // CMP(reg_ptr_len, 32)
|
CMPQ(n, U32(32)) // CMP(reg_ptr_len, 32)
|
||||||
JGE(LabelRef(long)) // JGE(coreLong)
|
JGE(LabelRef(long)) // JGE(coreLong)
|
||||||
//
|
//
|
||||||
u64s := GP64v() // reg_u64s = GeneralPurposeRegister64()
|
u64s := GP64() // reg_u64s = GeneralPurposeRegister64()
|
||||||
MOVQ(n, u64s) // MOV(reg_u64s, reg_ptr_len)
|
MOVQ(n, u64s) // MOV(reg_u64s, reg_ptr_len)
|
||||||
SHRQ(U8(3), u64s) // SHR(reg_u64s, 3)
|
SHRQ(U8(3), u64s) // SHR(reg_u64s, 3)
|
||||||
//
|
//
|
||||||
@@ -77,7 +77,7 @@ func main() {
|
|||||||
} //
|
} //
|
||||||
for i := 3; i > 0; i-- { // for i in range(3, 0, -1):
|
for i := 3; i > 0; i-- { // for i in range(3, 0, -1):
|
||||||
LABEL(labels[i]) // LABEL(labels[i])
|
LABEL(labels[i]) // LABEL(labels[i])
|
||||||
r := GP64v() // r = GeneralPurposeRegister64()
|
r := GP64() // r = GeneralPurposeRegister64()
|
||||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
imul(k3U64, r) // imul(r, k3U64)
|
imul(k3U64, r) // imul(r, k3U64)
|
||||||
ADDQ(r, v0) // ADD(reg_v0, r)
|
ADDQ(r, v0) // ADD(reg_v0, r)
|
||||||
@@ -100,7 +100,7 @@ func main() {
|
|||||||
//
|
//
|
||||||
after := "shortAfter" // after = Label("shortAfter")
|
after := "shortAfter" // after = Label("shortAfter")
|
||||||
//
|
//
|
||||||
ch := GP64v() // reg_ch = GeneralPurposeRegister64()
|
ch := GP64() // reg_ch = GeneralPurposeRegister64()
|
||||||
//
|
//
|
||||||
LABEL(labels[7]) // LABEL(labels[7])
|
LABEL(labels[7]) // LABEL(labels[7])
|
||||||
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
||||||
@@ -189,8 +189,8 @@ func main() {
|
|||||||
//
|
//
|
||||||
LABEL(long) // LABEL(coreLong)
|
LABEL(long) // LABEL(coreLong)
|
||||||
//
|
//
|
||||||
v2 := GP64v() // reg_v2 = GeneralPurposeRegister64()
|
v2 := GP64() // reg_v2 = GeneralPurposeRegister64()
|
||||||
v3 := GP64v() // reg_v3 = GeneralPurposeRegister64()
|
v3 := GP64() // reg_v3 = GeneralPurposeRegister64()
|
||||||
//
|
//
|
||||||
MOVQ(Mem{Base: statePtr, Disp: 16}, v2) // MOV(reg_v2, [reg_state_ptr+16])
|
MOVQ(Mem{Base: statePtr, Disp: 16}, v2) // MOV(reg_v2, [reg_state_ptr+16])
|
||||||
MOVQ(Mem{Base: statePtr, Disp: 24}, v3) // MOV(reg_v3, [reg_state_ptr+24])
|
MOVQ(Mem{Base: statePtr, Disp: 24}, v3) // MOV(reg_v3, [reg_state_ptr+24])
|
||||||
@@ -206,7 +206,7 @@ func main() {
|
|||||||
imul(k3U64, t) // imul(t, k3U64)
|
imul(k3U64, t) // imul(t, k3U64)
|
||||||
XORQ(t, v3) // XOR(reg_v3, t)
|
XORQ(t, v3) // XOR(reg_v3, t)
|
||||||
//
|
//
|
||||||
r := GP64v() // r = GeneralPurposeRegister64()
|
r := GP64() // r = GeneralPurposeRegister64()
|
||||||
loop := "block" // with Loop() as loop:
|
loop := "block" // with Loop() as loop:
|
||||||
LABEL(loop)
|
LABEL(loop)
|
||||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
@@ -240,8 +240,8 @@ func main() {
|
|||||||
JGE(LabelRef(loop)) // JGE(loop.begin)
|
JGE(LabelRef(loop)) // JGE(loop.begin)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
nsave := GP64v() // reg_ptr_len_saved = GeneralPurposeRegister64()
|
nsave := GP64() // reg_ptr_len_saved = GeneralPurposeRegister64()
|
||||||
MOVQ(n, nsave) // MOV(reg_ptr_len_saved, reg_ptr_len)
|
MOVQ(n, nsave) // MOV(reg_ptr_len_saved, reg_ptr_len)
|
||||||
//
|
//
|
||||||
// reg_u64s = GeneralPurposeRegister64()
|
// reg_u64s = GeneralPurposeRegister64()
|
||||||
MOVQ(n, u64s) // MOV(reg_u64s, reg_ptr_len)
|
MOVQ(n, u64s) // MOV(reg_u64s, reg_ptr_len)
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ Sum a slice of `uint64`s.
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Sum", "func(xs []uint64) uint64")
|
TEXT("Sum", "func(xs []uint64) uint64")
|
||||||
Doc("Sum returns the sum of the elements in xs.")
|
Doc("Sum returns the sum of the elements in xs.")
|
||||||
ptr := Load(Param("xs").Base(), GP64v())
|
ptr := Load(Param("xs").Base(), GP64())
|
||||||
n := Load(Param("xs").Len(), GP64v())
|
n := Load(Param("xs").Len(), GP64())
|
||||||
s := GP64v()
|
s := GP64()
|
||||||
XORQ(s, s)
|
XORQ(s, s)
|
||||||
LABEL("loop")
|
LABEL("loop")
|
||||||
CMPQ(n, operand.Imm(0))
|
CMPQ(n, operand.Imm(0))
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
TEXT("Sum", "func(xs []uint64) uint64")
|
TEXT("Sum", "func(xs []uint64) uint64")
|
||||||
Doc("Sum returns the sum of the elements in xs.")
|
Doc("Sum returns the sum of the elements in xs.")
|
||||||
ptr := Load(Param("xs").Base(), GP64v())
|
ptr := Load(Param("xs").Base(), GP64())
|
||||||
n := Load(Param("xs").Len(), GP64v())
|
n := Load(Param("xs").Len(), GP64())
|
||||||
s := GP64v()
|
s := GP64()
|
||||||
XORQ(s, s)
|
XORQ(s, s)
|
||||||
LABEL("loop")
|
LABEL("loop")
|
||||||
CMPQ(n, operand.Imm(0))
|
CMPQ(n, operand.Imm(0))
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
func TestAllocatorSimple(t *testing.T) {
|
func TestAllocatorSimple(t *testing.T) {
|
||||||
c := reg.NewCollection()
|
c := reg.NewCollection()
|
||||||
x, y := c.Xv(), c.Yv()
|
x, y := c.XMM(), c.YMM()
|
||||||
|
|
||||||
a, err := NewAllocatorForKind(reg.KindVector)
|
a, err := NewAllocatorForKind(reg.KindVector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ func TestLivenessBasic(t *testing.T) {
|
|||||||
// Build: a = 1, b = 2, a = a+b
|
// Build: a = 1, b = 2, a = a+b
|
||||||
ctx := build.NewContext()
|
ctx := build.NewContext()
|
||||||
ctx.Function("add")
|
ctx.Function("add")
|
||||||
a := ctx.GP64v()
|
a := ctx.GP64()
|
||||||
b := ctx.GP64v()
|
b := ctx.GP64()
|
||||||
ctx.MOVQ(operand.U64(1), a)
|
ctx.MOVQ(operand.U64(1), a)
|
||||||
ctx.MOVQ(operand.U64(2), b)
|
ctx.MOVQ(operand.U64(2), b)
|
||||||
ctx.ADDQ(a, b)
|
ctx.ADDQ(a, b)
|
||||||
|
|||||||
@@ -16,20 +16,20 @@ func (c *Collection) VirtualRegister(k Kind, s Size) Virtual {
|
|||||||
return NewVirtual(vid, k, s)
|
return NewVirtual(vid, k, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collection) GP8v() GPVirtual { return c.GPv(B8) }
|
func (c *Collection) GP8() GPVirtual { return c.GPv(B8) }
|
||||||
|
|
||||||
func (c *Collection) GP16v() GPVirtual { return c.GPv(B16) }
|
func (c *Collection) GP16() GPVirtual { return c.GPv(B16) }
|
||||||
|
|
||||||
func (c *Collection) GP32v() GPVirtual { return c.GPv(B32) }
|
func (c *Collection) GP32() GPVirtual { return c.GPv(B32) }
|
||||||
|
|
||||||
func (c *Collection) GP64v() GPVirtual { return c.GPv(B64) }
|
func (c *Collection) GP64() GPVirtual { return c.GPv(B64) }
|
||||||
|
|
||||||
func (c *Collection) GPv(s Size) GPVirtual { return newgpv(c.VirtualRegister(KindGP, s)) }
|
func (c *Collection) GPv(s Size) GPVirtual { return newgpv(c.VirtualRegister(KindGP, s)) }
|
||||||
|
|
||||||
func (c *Collection) Xv() VecVirtual { return c.Vecv(B128) }
|
func (c *Collection) XMM() VecVirtual { return c.Vecv(B128) }
|
||||||
|
|
||||||
func (c *Collection) Yv() VecVirtual { return c.Vecv(B256) }
|
func (c *Collection) YMM() VecVirtual { return c.Vecv(B256) }
|
||||||
|
|
||||||
func (c *Collection) Zv() VecVirtual { return c.Vecv(B512) }
|
func (c *Collection) ZMM() VecVirtual { return c.Vecv(B512) }
|
||||||
|
|
||||||
func (c *Collection) Vecv(s Size) VecVirtual { return newvecv(c.VirtualRegister(KindVector, s)) }
|
func (c *Collection) Vecv(s Size) VecVirtual { return newvecv(c.VirtualRegister(KindVector, s)) }
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func main() {
|
|||||||
"Split returns the low 64, 32, 16 and 8 bits of x.",
|
"Split returns the low 64, 32, 16 and 8 bits of x.",
|
||||||
"Tests the As() methods of virtual general-purpose registers.",
|
"Tests the As() methods of virtual general-purpose registers.",
|
||||||
)
|
)
|
||||||
x := GP64v()
|
x := GP64()
|
||||||
Load(Param("x"), x)
|
Load(Param("x"), x)
|
||||||
Store(x, Return("q"))
|
Store(x, Return("q"))
|
||||||
Store(x.As32(), Return("l"))
|
Store(x.As32(), Return("l"))
|
||||||
|
|||||||
Reference in New Issue
Block a user