@@ -17,8 +17,8 @@ import (
|
||||
func main() {
|
||||
TEXT("Add", "func(x, y uint64) uint64")
|
||||
Doc("Add adds x and y.")
|
||||
x := Load(Param("x"), GP64v())
|
||||
y := Load(Param("y"), GP64v())
|
||||
x := Load(Param("x"), GP64())
|
||||
y := Load(Param("y"), GP64())
|
||||
ADDQ(x, y)
|
||||
Store(y, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
func main() {
|
||||
TEXT("Add", "func(x, y uint64) uint64")
|
||||
Doc("Add adds x and y.")
|
||||
x := Load(Param("x"), GP64v())
|
||||
y := Load(Param("y"), GP64v())
|
||||
x := Load(Param("x"), GP64())
|
||||
y := Load(Param("y"), GP64())
|
||||
ADDQ(x, y)
|
||||
Store(y, ReturnIndex(0))
|
||||
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.*/)
|
||||
```go
|
||||
TEXT("Second", "func(x, y int32) int32")
|
||||
y := Load(Param("y"), GP32v())
|
||||
y := Load(Param("y"), GP32())
|
||||
Store(y, ReturnIndex(0))
|
||||
RET()
|
||||
```
|
||||
@@ -34,7 +34,7 @@ Strings and slices actually consist of multiple components under the hood: see [
|
||||
[embedmd]:# (asm.go go /.*TEXT.*StringLen/ /RET.*/)
|
||||
```go
|
||||
TEXT("StringLen", "func(s string) int")
|
||||
strlen := Load(Param("s").Len(), GP64v())
|
||||
strlen := Load(Param("s").Len(), GP64())
|
||||
Store(strlen, ReturnIndex(0))
|
||||
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.*/)
|
||||
```go
|
||||
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))
|
||||
RET()
|
||||
```
|
||||
@@ -87,7 +87,7 @@ The following function will return the `Float64` field from this struct.
|
||||
[embedmd]:# (asm.go go /.*TEXT.*FieldFloat64/ /RET.*/)
|
||||
```go
|
||||
TEXT("FieldFloat64", "func(s Struct) float64")
|
||||
f64 := Load(Param("s").Field("Float64"), Xv())
|
||||
f64 := Load(Param("s").Field("Float64"), XMM())
|
||||
Store(f64, ReturnIndex(0))
|
||||
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.*/)
|
||||
```go
|
||||
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))
|
||||
RET()
|
||||
```
|
||||
@@ -111,7 +111,7 @@ The above methods may be composed to reference arbitrarily nested data structure
|
||||
[embedmd]:# (asm.go go /.*TEXT.*FieldArrayTwoBTwo/ /RET.*/)
|
||||
```go
|
||||
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))
|
||||
RET()
|
||||
```
|
||||
|
||||
@@ -10,92 +10,92 @@ func main() {
|
||||
Package("github.com/mmcloughlin/avo/examples/args")
|
||||
|
||||
TEXT("Second", "func(x, y int32) int32")
|
||||
y := Load(Param("y"), GP32v())
|
||||
y := Load(Param("y"), GP32())
|
||||
Store(y, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("StringLen", "func(s string) int")
|
||||
strlen := Load(Param("s").Len(), GP64v())
|
||||
strlen := Load(Param("s").Len(), GP64())
|
||||
Store(strlen, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("SliceLen", "func(s []int) int")
|
||||
slicelen := Load(Param("s").Len(), GP64v())
|
||||
slicelen := Load(Param("s").Len(), GP64())
|
||||
Store(slicelen, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("SliceCap", "func(s []int) int")
|
||||
slicecap := Load(Param("s").Cap(), GP64v())
|
||||
slicecap := Load(Param("s").Cap(), GP64())
|
||||
Store(slicecap, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
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))
|
||||
RET()
|
||||
|
||||
TEXT("FieldByte", "func(s Struct) byte")
|
||||
b := Load(Param("s").Field("Byte"), GP8v())
|
||||
b := Load(Param("s").Field("Byte"), GP8())
|
||||
Store(b, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("FieldInt8", "func(s Struct) int8")
|
||||
i8 := Load(Param("s").Field("Int8"), GP8v())
|
||||
i8 := Load(Param("s").Field("Int8"), GP8())
|
||||
Store(i8, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("FieldUint16", "func(s Struct) uint16")
|
||||
u16 := Load(Param("s").Field("Uint16"), GP16v())
|
||||
u16 := Load(Param("s").Field("Uint16"), GP16())
|
||||
Store(u16, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("FieldInt32", "func(s Struct) int32")
|
||||
i32 := Load(Param("s").Field("Int32"), GP32v())
|
||||
i32 := Load(Param("s").Field("Int32"), GP32())
|
||||
Store(i32, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("FieldUint64", "func(s Struct) uint64")
|
||||
u64 := Load(Param("s").Field("Uint64"), GP64v())
|
||||
u64 := Load(Param("s").Field("Uint64"), GP64())
|
||||
Store(u64, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("FieldFloat32", "func(s Struct) float32")
|
||||
f32 := Load(Param("s").Field("Float32"), Xv())
|
||||
f32 := Load(Param("s").Field("Float32"), XMM())
|
||||
Store(f32, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("FieldFloat64", "func(s Struct) float64")
|
||||
f64 := Load(Param("s").Field("Float64"), Xv())
|
||||
f64 := Load(Param("s").Field("Float64"), XMM())
|
||||
Store(f64, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
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))
|
||||
RET()
|
||||
|
||||
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))
|
||||
RET()
|
||||
|
||||
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))
|
||||
RET()
|
||||
|
||||
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))
|
||||
RET()
|
||||
|
||||
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))
|
||||
RET()
|
||||
|
||||
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))
|
||||
RET()
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ The `Real()` and `Imag()` parameter methods may be used to load the sub-componen
|
||||
```go
|
||||
TEXT("Norm", "func(z complex128) float64")
|
||||
Doc("Norm returns the complex norm of z.")
|
||||
r = Load(Param("z").Real(), Xv())
|
||||
i = Load(Param("z").Imag(), Xv())
|
||||
r = Load(Param("z").Real(), XMM())
|
||||
i = Load(Param("z").Imag(), XMM())
|
||||
MULSD(r, r)
|
||||
MULSD(i, i)
|
||||
ADDSD(i, r)
|
||||
n := Xv()
|
||||
n := XMM()
|
||||
SQRTSD(r, n)
|
||||
Store(n, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
@@ -9,24 +9,24 @@ import (
|
||||
func main() {
|
||||
TEXT("Real", "func(z complex128) float64")
|
||||
Doc("Real returns the real part of z.")
|
||||
r := Load(Param("z").Real(), Xv())
|
||||
r := Load(Param("z").Real(), XMM())
|
||||
Store(r, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("Imag", "func(z complex128) float64")
|
||||
Doc("Imag returns the imaginary part of z.")
|
||||
i := Load(Param("z").Imag(), Xv())
|
||||
i := Load(Param("z").Imag(), XMM())
|
||||
Store(i, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
TEXT("Norm", "func(z complex128) float64")
|
||||
Doc("Norm returns the complex norm of z.")
|
||||
r = Load(Param("z").Real(), Xv())
|
||||
i = Load(Param("z").Imag(), Xv())
|
||||
r = Load(Param("z").Real(), XMM())
|
||||
i = Load(Param("z").Imag(), XMM())
|
||||
MULSD(r, r)
|
||||
MULSD(i, i)
|
||||
ADDSD(i, r)
|
||||
n := Xv()
|
||||
n := XMM()
|
||||
SQRTSD(r, n)
|
||||
Store(n, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
@@ -23,10 +23,10 @@ The `GLOBL` function returns a reference which may be used in assembly code. The
|
||||
```go
|
||||
TEXT("DataAt", "func(i int) byte")
|
||||
Doc("DataAt returns byte i in the 'bytes' global data section.")
|
||||
i := Load(Param("i"), GP64v())
|
||||
ptr := Mem{Base: GP64v()}
|
||||
i := Load(Param("i"), GP64())
|
||||
ptr := Mem{Base: GP64()}
|
||||
LEAQ(bytes, ptr.Base)
|
||||
b := GP8v()
|
||||
b := GP8()
|
||||
MOVB(ptr.Idx(i, 1), b)
|
||||
Store(b, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
@@ -23,10 +23,10 @@ func main() {
|
||||
|
||||
TEXT("DataAt", "func(i int) byte")
|
||||
Doc("DataAt returns byte i in the 'bytes' global data section.")
|
||||
i := Load(Param("i"), GP64v())
|
||||
ptr := Mem{Base: GP64v()}
|
||||
i := Load(Param("i"), GP64())
|
||||
ptr := Mem{Base: GP64()}
|
||||
LEAQ(bytes, ptr.Base)
|
||||
b := GP8v()
|
||||
b := GP8()
|
||||
MOVB(ptr.Idx(i, 1), b)
|
||||
Store(b, ReturnIndex(0))
|
||||
RET()
|
||||
|
||||
@@ -12,14 +12,14 @@ var unroll = 6
|
||||
|
||||
func main() {
|
||||
TEXT("Dot", "func(x, y []float32) float32")
|
||||
x := Mem{Base: Load(Param("x").Base(), GP64v())}
|
||||
y := Mem{Base: Load(Param("y").Base(), GP64v())}
|
||||
n := Load(Param("x").Len(), GP64v())
|
||||
x := Mem{Base: Load(Param("x").Base(), GP64())}
|
||||
y := Mem{Base: Load(Param("y").Base(), GP64())}
|
||||
n := Load(Param("x").Len(), GP64())
|
||||
|
||||
// Allocate accumulation registers.
|
||||
acc := make([]VecVirtual, unroll)
|
||||
for i := 0; i < unroll; i++ {
|
||||
acc[i] = Yv()
|
||||
acc[i] = YMM()
|
||||
}
|
||||
|
||||
// Zero initialization.
|
||||
@@ -37,7 +37,7 @@ func main() {
|
||||
// Load x.
|
||||
xs := make([]VecVirtual, unroll)
|
||||
for i := 0; i < unroll; i++ {
|
||||
xs[i] = Yv()
|
||||
xs[i] = YMM()
|
||||
}
|
||||
|
||||
for i := 0; i < unroll; i++ {
|
||||
@@ -56,14 +56,14 @@ func main() {
|
||||
|
||||
// Process any trailing entries.
|
||||
LABEL("tail")
|
||||
tail := Xv()
|
||||
tail := XMM()
|
||||
VXORPS(tail, tail, tail)
|
||||
|
||||
LABEL("tailloop")
|
||||
CMPQ(n, U32(0))
|
||||
JE(LabelRef("reduce"))
|
||||
|
||||
xt := Xv()
|
||||
xt := XMM()
|
||||
VMOVSS(x, xt)
|
||||
VFMADD231SS(y, xt, tail)
|
||||
|
||||
@@ -79,7 +79,7 @@ func main() {
|
||||
}
|
||||
|
||||
result := acc[0].AsX()
|
||||
top := Xv()
|
||||
top := XMM()
|
||||
VEXTRACTF128(U8(1), acc[0], top)
|
||||
VADDPS(result, top, result)
|
||||
VADDPS(result, tail, result)
|
||||
|
||||
@@ -12,18 +12,18 @@ const (
|
||||
func main() {
|
||||
TEXT("Hash64", "func(data []byte) uint64")
|
||||
Doc("Hash64 computes the FNV-1a hash of data.")
|
||||
ptr := Load(Param("data").Base(), GP64v())
|
||||
n := Load(Param("data").Len(), GP64v())
|
||||
ptr := Load(Param("data").Base(), GP64())
|
||||
n := Load(Param("data").Len(), GP64())
|
||||
|
||||
h := reg.RAX
|
||||
MOVQ(operand.Imm(OffsetBasis), h)
|
||||
p := GP64v()
|
||||
p := GP64()
|
||||
MOVQ(operand.Imm(Prime), p)
|
||||
|
||||
LABEL("loop")
|
||||
CMPQ(n, operand.Imm(0))
|
||||
JE(operand.LabelRef("done"))
|
||||
b := GP64v()
|
||||
b := GP64()
|
||||
MOVBQZX(operand.Mem{Base: ptr}, b)
|
||||
XORQ(b, h)
|
||||
MULQ(p)
|
||||
|
||||
@@ -16,18 +16,18 @@ const (
|
||||
func main() {
|
||||
TEXT("Hash64", "func(data []byte) uint64")
|
||||
Doc("Hash64 computes the FNV-1a hash of data.")
|
||||
ptr := Load(Param("data").Base(), GP64v())
|
||||
n := Load(Param("data").Len(), GP64v())
|
||||
ptr := Load(Param("data").Base(), GP64())
|
||||
n := Load(Param("data").Len(), GP64())
|
||||
|
||||
h := reg.RAX
|
||||
MOVQ(operand.Imm(OffsetBasis), h)
|
||||
p := GP64v()
|
||||
p := GP64()
|
||||
MOVQ(operand.Imm(Prime), p)
|
||||
|
||||
LABEL("loop")
|
||||
CMPQ(n, operand.Imm(0))
|
||||
JE(operand.LabelRef("done"))
|
||||
b := GP64v()
|
||||
b := GP64()
|
||||
MOVBQZX(operand.Mem{Base: ptr}, b)
|
||||
XORQ(b, h)
|
||||
MULQ(p)
|
||||
|
||||
@@ -9,8 +9,8 @@ Refer to ["Geohash in Golang Assembly"](https://mmcloughlin.com/posts/geohash-as
|
||||
func main() {
|
||||
TEXT("EncodeInt", "func(lat, lng float64) uint64")
|
||||
Doc("EncodeInt computes the 64-bit integer geohash of (lat, lng).")
|
||||
lat := Load(Param("lat"), Xv())
|
||||
lng := Load(Param("lng"), Xv())
|
||||
lat := Load(Param("lat"), XMM())
|
||||
lng := Load(Param("lng"), XMM())
|
||||
|
||||
MULSD(ConstData("reciprocal180", F64(1/180.0)), lat)
|
||||
onepointfive := ConstData("onepointfive", F64(1.5))
|
||||
@@ -19,16 +19,16 @@ func main() {
|
||||
MULSD(ConstData("reciprocal360", F64(1/360.0)), lng)
|
||||
ADDSD(onepointfive, lng)
|
||||
|
||||
lngi, lati := GP64v(), GP64v()
|
||||
lngi, lati := GP64(), GP64()
|
||||
MOVQ(lat, lati)
|
||||
SHRQ(U8(20), lati)
|
||||
MOVQ(lng, lngi)
|
||||
SHRQ(U8(20), lngi)
|
||||
|
||||
mask := ConstData("mask", U64(0x5555555555555555))
|
||||
ghsh := GP64v()
|
||||
ghsh := GP64()
|
||||
PDEPQ(mask, lati, ghsh)
|
||||
temp := GP64v()
|
||||
temp := GP64()
|
||||
PDEPQ(mask, lngi, temp)
|
||||
SHLQ(U8(1), temp)
|
||||
XORQ(temp, ghsh)
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
func main() {
|
||||
TEXT("EncodeInt", "func(lat, lng float64) uint64")
|
||||
Doc("EncodeInt computes the 64-bit integer geohash of (lat, lng).")
|
||||
lat := Load(Param("lat"), Xv())
|
||||
lng := Load(Param("lng"), Xv())
|
||||
lat := Load(Param("lat"), XMM())
|
||||
lng := Load(Param("lng"), XMM())
|
||||
|
||||
MULSD(ConstData("reciprocal180", F64(1/180.0)), lat)
|
||||
onepointfive := ConstData("onepointfive", F64(1.5))
|
||||
@@ -20,16 +20,16 @@ func main() {
|
||||
MULSD(ConstData("reciprocal360", F64(1/360.0)), lng)
|
||||
ADDSD(onepointfive, lng)
|
||||
|
||||
lngi, lati := GP64v(), GP64v()
|
||||
lngi, lati := GP64(), GP64()
|
||||
MOVQ(lat, lati)
|
||||
SHRQ(U8(20), lati)
|
||||
MOVQ(lng, lngi)
|
||||
SHRQ(U8(20), lngi)
|
||||
|
||||
mask := ConstData("mask", U64(0x5555555555555555))
|
||||
ghsh := GP64v()
|
||||
ghsh := GP64()
|
||||
PDEPQ(mask, lati, ghsh)
|
||||
temp := GP64v()
|
||||
temp := GP64()
|
||||
PDEPQ(mask, lngi, temp)
|
||||
SHLQ(U8(1), temp)
|
||||
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.",
|
||||
"Demonstrates multiple unnamed return values.",
|
||||
)
|
||||
start := Load(Param("start"), GP64v())
|
||||
size := Load(Param("size"), GP64v())
|
||||
start := Load(Param("start"), GP64())
|
||||
size := Load(Param("size"), GP64())
|
||||
end := size
|
||||
ADDQ(start, end)
|
||||
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).",
|
||||
"Demonstrates multiple named return values.",
|
||||
)
|
||||
x0 := Load(Param("x0"), Xv())
|
||||
x1 := Load(Param("x1"), Xv())
|
||||
y0, y1 := Xv(), Xv()
|
||||
x0 := Load(Param("x0"), XMM())
|
||||
x1 := Load(Param("x1"), XMM())
|
||||
y0, y1 := XMM(), XMM()
|
||||
MOVSD(x0, y0)
|
||||
ADDSD(x1, y0)
|
||||
MOVSD(x0, y1)
|
||||
@@ -58,7 +58,7 @@ The following code returns an array type.
|
||||
"Septuple returns an array of seven of the given byte.",
|
||||
"Demonstrates returning array values.",
|
||||
)
|
||||
b := Load(ParamIndex(0), GP8v())
|
||||
b := Load(ParamIndex(0), GP8())
|
||||
for i := 0; i < 7; 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.",
|
||||
"Demonstrates returning complex values.",
|
||||
)
|
||||
t := Load(Param("t"), Xv())
|
||||
half := Xv()
|
||||
t := Load(Param("t"), XMM())
|
||||
half := XMM()
|
||||
MOVSD(ConstData("half", F64(0.5)), half)
|
||||
Store(half, ReturnIndex(0).Real())
|
||||
Store(t, ReturnIndex(0).Imag())
|
||||
@@ -91,10 +91,10 @@ You can even build a struct:
|
||||
"NewStruct initializes a Struct value.",
|
||||
"Demonstrates returning struct values.",
|
||||
)
|
||||
w := Load(Param("w"), GP16v())
|
||||
x := Load(Param("p").Index(0), Xv())
|
||||
y := Load(Param("p").Index(1), Xv())
|
||||
q := Load(Param("q"), GP64v())
|
||||
w := Load(Param("w"), GP16())
|
||||
x := Load(Param("p").Index(0), XMM())
|
||||
y := Load(Param("p").Index(1), XMM())
|
||||
q := Load(Param("q"), GP64())
|
||||
Store(w, ReturnIndex(0).Field("Word"))
|
||||
Store(x, ReturnIndex(0).Field("Point").Index(0))
|
||||
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.",
|
||||
"Demonstrates multiple unnamed return values.",
|
||||
)
|
||||
start := Load(Param("start"), GP64v())
|
||||
size := Load(Param("size"), GP64v())
|
||||
start := Load(Param("start"), GP64())
|
||||
size := Load(Param("size"), GP64())
|
||||
end := size
|
||||
ADDQ(start, end)
|
||||
Store(start, ReturnIndex(0))
|
||||
@@ -28,9 +28,9 @@ func main() {
|
||||
"Butterfly performs a 2-dimensional butterfly operation: computes (x0+x1, x0-x1).",
|
||||
"Demonstrates multiple named return values.",
|
||||
)
|
||||
x0 := Load(Param("x0"), Xv())
|
||||
x1 := Load(Param("x1"), Xv())
|
||||
y0, y1 := Xv(), Xv()
|
||||
x0 := Load(Param("x0"), XMM())
|
||||
x1 := Load(Param("x1"), XMM())
|
||||
y0, y1 := XMM(), XMM()
|
||||
MOVSD(x0, y0)
|
||||
ADDSD(x1, y0)
|
||||
MOVSD(x0, y1)
|
||||
@@ -44,7 +44,7 @@ func main() {
|
||||
"Septuple returns an array of seven of the given byte.",
|
||||
"Demonstrates returning array values.",
|
||||
)
|
||||
b := Load(ParamIndex(0), GP8v())
|
||||
b := Load(ParamIndex(0), GP8())
|
||||
for i := 0; i < 7; 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.",
|
||||
"Demonstrates returning complex values.",
|
||||
)
|
||||
t := Load(Param("t"), Xv())
|
||||
half := Xv()
|
||||
t := Load(Param("t"), XMM())
|
||||
half := XMM()
|
||||
MOVSD(ConstData("half", F64(0.5)), half)
|
||||
Store(half, ReturnIndex(0).Real())
|
||||
Store(t, ReturnIndex(0).Imag())
|
||||
@@ -67,10 +67,10 @@ func main() {
|
||||
"NewStruct initializes a Struct value.",
|
||||
"Demonstrates returning struct values.",
|
||||
)
|
||||
w := Load(Param("w"), GP16v())
|
||||
x := Load(Param("p").Index(0), Xv())
|
||||
y := Load(Param("p").Index(1), Xv())
|
||||
q := Load(Param("q"), GP64v())
|
||||
w := Load(Param("w"), GP16())
|
||||
x := Load(Param("p").Index(0), XMM())
|
||||
y := Load(Param("p").Index(1), XMM())
|
||||
q := Load(Param("q"), GP64())
|
||||
Store(w, ReturnIndex(0).Field("Word"))
|
||||
Store(x, ReturnIndex(0).Field("Point").Index(0))
|
||||
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() {
|
||||
TEXT("block", "func(h *[5]uint32, m []byte)")
|
||||
Doc("block SHA-1 hashes the 64-byte message m into the running state h.")
|
||||
h := Mem{Base: Load(Param("h"), GP64v())}
|
||||
m := Mem{Base: Load(Param("m").Base(), GP64v())}
|
||||
h := Mem{Base: Load(Param("h"), GP64())}
|
||||
m := Mem{Base: Load(Param("m").Base(), GP64())}
|
||||
|
||||
// Store message values on the stack.
|
||||
w := AllocLocal(64)
|
||||
W := func(r int) Mem { return w.Offset((r % 16) * 4) }
|
||||
|
||||
// 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(4), h1)
|
||||
@@ -26,7 +26,7 @@ func main() {
|
||||
MOVL(h.Offset(16), h4)
|
||||
|
||||
// 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(h1, b)
|
||||
@@ -49,7 +49,7 @@ func main() {
|
||||
q := quarter[r/20]
|
||||
|
||||
// Load message value.
|
||||
u := GP32v()
|
||||
u := GP32()
|
||||
if r < 16 {
|
||||
MOVL(m.Offset(4*r), u)
|
||||
BSWAPL(u)
|
||||
@@ -63,7 +63,7 @@ func main() {
|
||||
MOVL(u, W(r))
|
||||
|
||||
// Compute the next state register.
|
||||
t := GP32v()
|
||||
t := GP32()
|
||||
MOVL(a, t)
|
||||
ROLL(U8(5), t)
|
||||
ADDL(q.F(b, c, d), t)
|
||||
|
||||
@@ -11,15 +11,15 @@ import (
|
||||
func main() {
|
||||
TEXT("block", "func(h *[5]uint32, m []byte)")
|
||||
Doc("block SHA-1 hashes the 64-byte message m into the running state h.")
|
||||
h := Mem{Base: Load(Param("h"), GP64v())}
|
||||
m := Mem{Base: Load(Param("m").Base(), GP64v())}
|
||||
h := Mem{Base: Load(Param("h"), GP64())}
|
||||
m := Mem{Base: Load(Param("m").Base(), GP64())}
|
||||
|
||||
// Store message values on the stack.
|
||||
w := AllocLocal(64)
|
||||
W := func(r int) Mem { return w.Offset((r % 16) * 4) }
|
||||
|
||||
// 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(4), h1)
|
||||
@@ -28,7 +28,7 @@ func main() {
|
||||
MOVL(h.Offset(16), h4)
|
||||
|
||||
// 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(h1, b)
|
||||
@@ -51,7 +51,7 @@ func main() {
|
||||
q := quarter[r/20]
|
||||
|
||||
// Load message value.
|
||||
u := GP32v()
|
||||
u := GP32()
|
||||
if r < 16 {
|
||||
MOVL(m.Offset(4*r), u)
|
||||
BSWAPL(u)
|
||||
@@ -65,7 +65,7 @@ func main() {
|
||||
MOVL(u, W(r))
|
||||
|
||||
// Compute the next state register.
|
||||
t := GP32v()
|
||||
t := GP32()
|
||||
MOVL(a, t)
|
||||
ROLL(U8(5), t)
|
||||
ADDL(q.F(b, c, d), t)
|
||||
@@ -97,7 +97,7 @@ func main() {
|
||||
}
|
||||
|
||||
func choose(b, c, d Register) Register {
|
||||
r := GP32v()
|
||||
r := GP32()
|
||||
MOVL(d, r)
|
||||
XORL(c, r)
|
||||
ANDL(b, r)
|
||||
@@ -106,7 +106,7 @@ func choose(b, c, d Register) Register {
|
||||
}
|
||||
|
||||
func xor(b, c, d Register) Register {
|
||||
r := GP32v()
|
||||
r := GP32()
|
||||
MOVL(b, r)
|
||||
XORL(c, r)
|
||||
XORL(d, r)
|
||||
@@ -114,7 +114,7 @@ func xor(b, c, d Register) Register {
|
||||
}
|
||||
|
||||
func majority(b, c, d Register) Register {
|
||||
t, r := GP32v(), GP32v()
|
||||
t, r := GP32(), GP32()
|
||||
MOVL(b, t)
|
||||
ORL(c, t)
|
||||
ANDL(d, t)
|
||||
|
||||
@@ -23,7 +23,7 @@ const (
|
||||
)
|
||||
|
||||
func imul(k uint64, r Register) {
|
||||
t := GP64v()
|
||||
t := GP64()
|
||||
MOVQ(U64(k), t)
|
||||
IMULQ(t, r)
|
||||
}
|
||||
@@ -41,16 +41,16 @@ func main() {
|
||||
TEXT("Hash", "func(state *State, key []byte) uint64")
|
||||
Doc("Hash computes the Stadtx hash.")
|
||||
|
||||
statePtr := Load(Param("state"), GP64v())
|
||||
ptr := Load(Param("key").Base(), GP64v())
|
||||
n := Load(Param("key").Len(), GP64v())
|
||||
statePtr := Load(Param("state"), GP64())
|
||||
ptr := Load(Param("key").Base(), GP64())
|
||||
n := Load(Param("key").Len(), GP64())
|
||||
|
||||
v0 := GP64v() // reg_v0 = GeneralPurposeRegister64()
|
||||
v1 := GP64v() // reg_v1 = GeneralPurposeRegister64()
|
||||
v0 := GP64() // reg_v0 = GeneralPurposeRegister64()
|
||||
v1 := GP64() // reg_v1 = GeneralPurposeRegister64()
|
||||
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])
|
||||
|
||||
t := GP64v() // t = GeneralPurposeRegister64()
|
||||
t := GP64() // t = GeneralPurposeRegister64()
|
||||
MOVQ(n, t) // MOV(t, reg_ptr_len)
|
||||
ADDQ(U32(1), t) // ADD(t, 1)
|
||||
imul(k0U64, t) // imul(t, k0U64)
|
||||
@@ -65,7 +65,7 @@ func main() {
|
||||
CMPQ(n, U32(32)) // CMP(reg_ptr_len, 32)
|
||||
JGE(LabelRef(long)) // JGE(coreLong)
|
||||
//
|
||||
u64s := GP64v() // reg_u64s = GeneralPurposeRegister64()
|
||||
u64s := GP64() // reg_u64s = GeneralPurposeRegister64()
|
||||
MOVQ(n, u64s) // MOV(reg_u64s, reg_ptr_len)
|
||||
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):
|
||||
LABEL(labels[i]) // LABEL(labels[i])
|
||||
r := GP64v() // r = GeneralPurposeRegister64()
|
||||
r := GP64() // r = GeneralPurposeRegister64()
|
||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||
imul(k3U64, r) // imul(r, k3U64)
|
||||
ADDQ(r, v0) // ADD(reg_v0, r)
|
||||
@@ -100,7 +100,7 @@ func main() {
|
||||
//
|
||||
after := "shortAfter" // after = Label("shortAfter")
|
||||
//
|
||||
ch := GP64v() // reg_ch = GeneralPurposeRegister64()
|
||||
ch := GP64() // reg_ch = GeneralPurposeRegister64()
|
||||
//
|
||||
LABEL(labels[7]) // LABEL(labels[7])
|
||||
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
||||
@@ -189,8 +189,8 @@ func main() {
|
||||
//
|
||||
LABEL(long) // LABEL(coreLong)
|
||||
//
|
||||
v2 := GP64v() // reg_v2 = GeneralPurposeRegister64()
|
||||
v3 := GP64v() // reg_v3 = GeneralPurposeRegister64()
|
||||
v2 := GP64() // reg_v2 = 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: 24}, v3) // MOV(reg_v3, [reg_state_ptr+24])
|
||||
@@ -206,7 +206,7 @@ func main() {
|
||||
imul(k3U64, t) // imul(t, k3U64)
|
||||
XORQ(t, v3) // XOR(reg_v3, t)
|
||||
//
|
||||
r := GP64v() // r = GeneralPurposeRegister64()
|
||||
r := GP64() // r = GeneralPurposeRegister64()
|
||||
loop := "block" // with Loop() as loop:
|
||||
LABEL(loop)
|
||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||
@@ -240,8 +240,8 @@ func main() {
|
||||
JGE(LabelRef(loop)) // JGE(loop.begin)
|
||||
//
|
||||
//
|
||||
nsave := GP64v() // reg_ptr_len_saved = GeneralPurposeRegister64()
|
||||
MOVQ(n, nsave) // MOV(reg_ptr_len_saved, reg_ptr_len)
|
||||
nsave := GP64() // reg_ptr_len_saved = GeneralPurposeRegister64()
|
||||
MOVQ(n, nsave) // MOV(reg_ptr_len_saved, reg_ptr_len)
|
||||
//
|
||||
// reg_u64s = GeneralPurposeRegister64()
|
||||
MOVQ(n, u64s) // MOV(reg_u64s, reg_ptr_len)
|
||||
|
||||
@@ -7,9 +7,9 @@ Sum a slice of `uint64`s.
|
||||
func main() {
|
||||
TEXT("Sum", "func(xs []uint64) uint64")
|
||||
Doc("Sum returns the sum of the elements in xs.")
|
||||
ptr := Load(Param("xs").Base(), GP64v())
|
||||
n := Load(Param("xs").Len(), GP64v())
|
||||
s := GP64v()
|
||||
ptr := Load(Param("xs").Base(), GP64())
|
||||
n := Load(Param("xs").Len(), GP64())
|
||||
s := GP64()
|
||||
XORQ(s, s)
|
||||
LABEL("loop")
|
||||
CMPQ(n, operand.Imm(0))
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
func main() {
|
||||
TEXT("Sum", "func(xs []uint64) uint64")
|
||||
Doc("Sum returns the sum of the elements in xs.")
|
||||
ptr := Load(Param("xs").Base(), GP64v())
|
||||
n := Load(Param("xs").Len(), GP64v())
|
||||
s := GP64v()
|
||||
ptr := Load(Param("xs").Base(), GP64())
|
||||
n := Load(Param("xs").Len(), GP64())
|
||||
s := GP64()
|
||||
XORQ(s, s)
|
||||
LABEL("loop")
|
||||
CMPQ(n, operand.Imm(0))
|
||||
|
||||
Reference in New Issue
Block a user