mirror of
https://github.com/yuzu-mirror/oaknut.git
synced 2026-02-18 19:14:44 +01:00
oaknut: Update README
This commit is contained in:
parent
3fe32849aa
commit
9eb7cca885
85
README.md
85
README.md
|
|
@ -6,9 +6,14 @@ Oaknut is a header-only library that allows one to dynamically assemble code in-
|
|||
|
||||
## Usage
|
||||
|
||||
Provide `oaknut::CodeGenerator` with a pointer to a block of memory. Call functions on it to emit code.
|
||||
|
||||
Simple example:
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
#include <oaknut/oaknut.hpp>
|
||||
|
||||
using EmittedFunction = int (*)();
|
||||
|
||||
EmittedFunction EmitExample(oaknut::CodeGenerator& code, int value)
|
||||
|
|
@ -17,13 +22,91 @@ EmittedFunction EmitExample(oaknut::CodeGenerator& code, int value)
|
|||
|
||||
EmittedFunction result = code.ptr<EmittedFunction>();
|
||||
|
||||
code.MOVZ(W0, value);
|
||||
code.MOV(W0, value);
|
||||
code.RET();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
oaknut::CodeBlock mem{4096};
|
||||
oaknut::CodeGenerator code{mem.ptr()};
|
||||
|
||||
mem.unprotect();
|
||||
|
||||
EmittedFunction fn = EmitExample(code, 42);
|
||||
|
||||
mem.protect();
|
||||
mem.invalidate_all();
|
||||
|
||||
std::printf("%i\n", fn()); // Output: 42
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Instructions
|
||||
|
||||
Each AArch64 instruction corresponds to one emitter function. For a list of emitter functions see:
|
||||
* ARMv8.0: [general instructions](include/oaknut/impl/mnemonics_generic_v8.0.inc.hpp), [FP & SIMD instructions](include/oaknut/impl/mnemonics_fpsimd_v8.0.inc.hpp)
|
||||
* ARMv8.1: [general instructions](include/oaknut/impl/mnemonics_generic_v8.1.inc.hpp), [FP & SIMD instructions](include/oaknut/impl/mnemonics_fpsimd_v8.1.inc.hpp)
|
||||
|
||||
### Operands
|
||||
|
||||
The `oaknut::util` namespace provides convenient names for operands for instructions. For example:
|
||||
|
||||
|Name|Class| |
|
||||
|----|----|----|
|
||||
|W0, W1, ..., W30|`WReg`|32-bit general purpose registers|
|
||||
|X0, X1, ..., X30|`XReg`|64-bit general purpose registers|
|
||||
|WZR|WzrReg (convertable to `WReg`)|32-bit zero register|
|
||||
|XZR|ZrReg (convertable to `XReg`)|64-bit zero register|
|
||||
|WSP|WspReg (convertable to `WRegSp`)|32-bit stack pointer|
|
||||
|SP|SpReg (convertable to `XRegSp`)|64-bit stack pointer|
|
||||
|B0, B1, ..., B31|`BReg`|8-bit scalar SIMD register|
|
||||
|H0, H1, ..., H31|`HReg`|16-bit scalar SIMD register|
|
||||
|S0, S1, ..., S31|`SReg`|32-bit scalar SIMD register|
|
||||
|D0, D1, ..., D31|`DReg`|64-bit scalar SIMD register|
|
||||
|Q0, Q1, ..., Q31|`QReg`|128-bit scalar SIMD register|
|
||||
|
||||
For vector operations, you can specify registers like so:
|
||||
|
||||
|Name|Class| |
|
||||
|----|----|----|
|
||||
|V0.B8(), ...|`VReg_B8`|8 elements each 8 bits in size|
|
||||
|V0.B16(), ...|`VReg_B16`|16 elements each 8 bits in size|
|
||||
|V0.H4(), ...|`VReg_H4`|4 elements each 16 bits in size|
|
||||
|V0.H8(), ...|`VReg_H8`|8 elements each 16 bits in size|
|
||||
|V0.S2(), ...|`VReg_S2`|2 elements each 32 bits in size|
|
||||
|V0.S4(), ...|`VReg_S4`|4 elements each 32 bits in size|
|
||||
|V0.D1(), ...|`VReg_D1`|1 elements each 64 bits in size|
|
||||
|V0.D2(), ...|`VReg_D2`|2 elements each 64 bits in size|
|
||||
|
||||
And you can specify elements like so:
|
||||
|
||||
|Name|Class| |
|
||||
|----|----|----|
|
||||
|V0.B()[0]|`BElem`|0th 8-bit element of V0 register|
|
||||
|V0.H()[0]|`HElem`|0th 16-bit element of V0 register|
|
||||
|V0.S()[0]|`SElem`|0th 32-bit element of V0 register|
|
||||
|V0.D()[0]|`DElem`|0th 64-bit element of V0 register|
|
||||
|
||||
Register lists are specified using `List`:
|
||||
|
||||
```
|
||||
List{V0.B16(), V1.B16(), V2.B16()} // This expression has type List<VReg_16B, 3>
|
||||
```
|
||||
|
||||
And lists of elements similarly (both forms are equivalent):
|
||||
|
||||
```
|
||||
List{V0.B()[1], V1.B()[1], V2.B()[1]} // This expression has type List<BElem, 3>
|
||||
List{V0.B(), V1.B(), V2.B()}[1] // This expression has type List<BElem, 3>
|
||||
```
|
||||
|
||||
You can find examples of instruction use in [tests/general.cpp](tests/general.cpp) and [tests/fpsimd.cpp](tests/fpsimd.cpp).
|
||||
|
||||
## License
|
||||
|
||||
This project is [MIT licensed](LICENSE).
|
||||
|
|
|
|||
Loading…
Reference in a new issue