doc: README for args example
Also started a README in the root examples directory. Updates #14
This commit is contained in:
117
examples/args/README.md
Normal file
117
examples/args/README.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# args
|
||||
|
||||
Demonstrates how to reference function parameters in `avo`.
|
||||
|
||||
## Basics
|
||||
|
||||
Use `Param()` to reference arguments by name. The `Load()` function can be used to load the argument into a register (this will select the correct `MOV` instruction for you). Likewise `Store` and `ReturnIndex` can be used to write the return value. The following function will return its second argument.
|
||||
|
||||
[embedmd]:# (asm.go go /.*TEXT.*Second/ /RET.*/)
|
||||
```go
|
||||
TEXT("Second", "func(x, y int32) int32")
|
||||
y := Load(Param("y"), GP32v())
|
||||
Store(y, ReturnIndex(0))
|
||||
RET()
|
||||
```
|
||||
|
||||
This `avo` code will generate the following assembly. Note that parameter references are named to conform to [`asmdecl`](https://godoc.org/golang.org/x/tools/go/analysis/passes/asmdecl) rules enforced by `go vet`.
|
||||
|
||||
[embedmd]:# (args.s s /.*func Second/ /RET/)
|
||||
```s
|
||||
// func Second(x int32, y int32) int32
|
||||
TEXT ·Second(SB), $0-12
|
||||
MOVL y+4(FP), AX
|
||||
MOVL AX, ret+8(FP)
|
||||
RET
|
||||
```
|
||||
|
||||
Primitive types can be loaded as above. Other types consist of sub-components which must be loaded into registers independently; for example strings, slices, arrays, structs and complex values.
|
||||
|
||||
## Strings and Slices
|
||||
|
||||
Strings and slices actually consist of multiple components under the hood: see [`reflect.StringHeader`](https://golang.org/pkg/reflect/#StringHeader) and [`reflect.SliceHeader`](https://golang.org/pkg/reflect/#SliceHeader). The following `avo` code allows you to load the string length.
|
||||
|
||||
[embedmd]:# (asm.go go /.*TEXT.*StringLen/ /RET.*/)
|
||||
```go
|
||||
TEXT("StringLen", "func(s string) int")
|
||||
strlen := Load(Param("s").Len(), GP64v())
|
||||
Store(strlen, ReturnIndex(0))
|
||||
RET()
|
||||
```
|
||||
|
||||
The same code would work for a slice argument. Likewise `Param(...).Base()` and `Param(...).Cap()` will load the base pointer and capacity (slice only).
|
||||
|
||||
## Array Indexing
|
||||
|
||||
Arrays can be indexed with the `Index()` method. For example, the following returns the third element of the passed array.
|
||||
|
||||
[embedmd]:# (asm.go go /.*TEXT.*ArrayThree/ /RET.*/)
|
||||
```go
|
||||
TEXT("ArrayThree", "func(a [7]uint64) uint64")
|
||||
a3 := Load(Param("a").Index(3), GP64v())
|
||||
Store(a3, ReturnIndex(0))
|
||||
RET()
|
||||
```
|
||||
|
||||
## Struct Fields
|
||||
|
||||
Struct fields can be accessed with the `Field()` method. Note that this _requires_ the package to be specified, so that `avo` can parse the type definition. In this example we specify the package with the line:
|
||||
|
||||
[embedmd]:# (asm.go go /.*Package\(.*/)
|
||||
```go
|
||||
Package("github.com/mmcloughlin/avo/examples/args")
|
||||
```
|
||||
|
||||
This package contains the struct definition:
|
||||
|
||||
[embedmd]:# (args.go go /type Struct/ /^}/)
|
||||
```go
|
||||
type Struct struct {
|
||||
Byte byte
|
||||
Int8 int8
|
||||
Uint16 uint16
|
||||
Int32 int32
|
||||
Uint64 uint64
|
||||
Float32 float32
|
||||
Float64 float64
|
||||
String string
|
||||
Slice []Sub
|
||||
Array [5]Sub
|
||||
Complex64 complex64
|
||||
Complex128 complex128
|
||||
}
|
||||
```
|
||||
|
||||
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())
|
||||
Store(f64, ReturnIndex(0))
|
||||
RET()
|
||||
```
|
||||
|
||||
## Complex Values
|
||||
|
||||
Complex types `complex{64,128}` are actually just pairs of `float{32,64}` values. These can be accessed with the `Real()` and `Imag()` methods. For example the following function returns the imaginary part of the `Complex64` struct field.
|
||||
|
||||
[embedmd]:# (asm.go go /.*TEXT.*FieldComplex64Imag/ /RET.*/)
|
||||
```go
|
||||
TEXT("FieldComplex64Imag", "func(s Struct) float32")
|
||||
c64i := Load(Param("s").Field("Complex64").Imag(), Xv())
|
||||
Store(c64i, ReturnIndex(0))
|
||||
RET()
|
||||
```
|
||||
|
||||
## Nested Data Structures
|
||||
|
||||
The above methods may be composed to reference arbitrarily nested data structures. For example, the following returns `s.Array[2].B[2]`.
|
||||
|
||||
[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())
|
||||
Store(b2, ReturnIndex(0))
|
||||
RET()
|
||||
```
|
||||
Reference in New Issue
Block a user