diff options
author | armvixl <> | 2013-06-14 11:42:37 +0100 |
---|---|---|
committer | armvixl <> | 2013-06-18 16:55:15 +0100 |
commit | ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dc8 (patch) | |
tree | 11017e875811dc153d4f9ba7acb599394c007d78 /doc | |
download | vixl-ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dc8.tar.gz |
VIXL Release 1.0
Refer to the README.md and LICENCE files for details.
Diffstat (limited to 'doc')
-rw-r--r-- | doc/getting-started.md | 206 | ||||
-rw-r--r-- | doc/supported-instructions.md | 1133 |
2 files changed, 1339 insertions, 0 deletions
diff --git a/doc/getting-started.md b/doc/getting-started.md new file mode 100644 index 00000000..7d32a326 --- /dev/null +++ b/doc/getting-started.md @@ -0,0 +1,206 @@ +Getting Started with VIXL +========================= + + +This guide will show you how to use the VIXL framework. We will see how to set +up the VIXL assembler and generate some code. We will also go into details on a +few useful features provided by VIXL and see how to run the generated code in +the VIXL simulator. + +The source code of the example developed in this guide can be found in the +`examples` directory (`examples/getting-started.cc`). + + +Creating the macro assembler and the simulator. +----------------------------------------------- + +First of all you need to make sure that the header files for the assembler and +the simulator are included. You should have the following lines at the beginning +of your source file: + + #include "a64/simulator-a64.h" + #include "a64/macro-assembler-a64.h" + +VIXL's assembler will generate some code at run-time, and this code needs to +be stored in a buffer. It must be large enough to contain all of the +instructions and data that will be generated. In this guide we will use a +default value of 4096 but you are free to change it to something that suits your +needs. + + #define BUF_SIZE (4096) + +All VIXL components are declared in the `vixl` namespace, so let's add this to +the beginning of the file for convenience: + + using namespace vixl; + +Now we are ready to create and initialize the different components. + +First of all we need to allocate the code buffer and to create a macro +assembler object which uses this buffer. + + byte assm_buf[BUF_SIZE]; + MacroAssembler masm(assm_buf, BUF_SIZE); + +We also need to set-up the simulator. The simulator uses a Decoder object to +read and decode the instructions from the code buffer. We need to create a +decoder and bind our simulator to this decoder. + + Decoder decoder; + Simulator simulator(&decoder); + + +Generating some code. +--------------------- + +We are now ready to generate some code. The macro assembler provides methods +for all the instructions that you can use. As it's a macro assembler, +the instructions that you tell it to generate may not directly map to a single +hardware instruction. Instead, it can produce a short sequence of instructions +that has the same effect. + +For instance, the hardware `add` instruction can only take a 12-bit immediate +optionally shifted by 12, but the macro assembler can generate one or more +instructions to handle any 64-bit immediate. For example, `Add(x0, x0, -1)` +will be turned into `Sub(x0, x0, 1)`. + +Before looking at how to generate some code, let's introduce a simple but handy +macro: + + #define __ masm-> + +It allows us to write `__ Mov(x0, 42);` instead of `masm->Mov(x0, 42);` to +generate code. + +Now we are going to write a C++ function to generate our first assembly +code fragment. + + void GenerateDemoFunction(MacroAssembler *masm) { + __ Ldr(x1, 0x1122334455667788); + __ And(x0, x0, x1); + __ Ret(); + } + +The generated code corresponds to a function with the following C prototype: + + uint64_t demo_function(uint64_t x); + +This function doesn't perform any useful operation. It loads the value +0x1122334455667788 into x1 and performs a bitwise `and` operation with +the function's argument (stored in x0). The result of this `and` operation +is returned by the function in x0. + +Now in our program main function, we only need to create a label to represent +the entry point of the assembly function and to call `GenerateDemoFunction` to +generate the code. + + Label demo_function; + masm.Bind(&demo_function); + GenerateDemoFunction(&masm); + masm.Finalize(); + +Now we are going to learn a bit more on a couple of interesting VIXL features +which are used in this example. + +### Label + +VIXL's assembler provides a mechanism to represent labels with `Label` objects. +They are easy to use: simply create the C++ object and bind it to a location in +the generated instruction stream. + +Creating a label is easy, since you only need to define the variable and bind it +to a location using the macro assembler. + + Label my_label; // Create the label object. + __ Bind(&my_label); // Bind it to the current location. + +The target of a branch using a label will be the address to which it has been +bound. For example, let's consider the following code fragment: + + Label foo; + + __ B(&foo); // Branch to foo. + __ Mov(x0, 42); + __ Bind(&foo); // Actual address of foo is here. + __ Mov(x1, 0xc001); + +If we run this code fragment the `Mov(x0, 42)` will never be executed since +the first thing this code does is to jump to `foo`, which correspond to the +`Mov(x1, 0xc001)` instruction. + +When working with labels you need to know that they are only to be used for +local branches, and should be passed around with care. There are two reasons +for this: + + - They can't safely be passed or returned by value because this can trigger + multiple constructor and destructor calls. The destructor has assertions + to check that we don't try to branch to a label that hasn't been bound. + + - The `B` instruction does not branch to labels which are out of range of the + branch. The `B` instruction has a range of 2^28 bytes, but other variants + (such as conditional or `CBZ`-like branches) have smaller ranges. Confining + them to local ranges doesn't mean that we won't hit these limits, but it + makes the lifetime of the labels much shorter and eases the debugging of + these kinds of issues. + + +### Literal Pool + +On ARMv8 instructions are 32 bits long, thus immediate values encoded in the +instructions have limited size. If you want to load a constant bigger than this +limit you have two possibilities: + +1. Use multiple instructions to load the constant in multiple steps. This + solution is already handled in VIXL. For instance you can write: + + `__ Mov(x0, 0x1122334455667788);` + + The previous instruction would not be legal since the immediate value is too + big. However, VIXL's macro assembler will automatically rewrite this line into + multiple instructions to efficiently generate the value. + + +2. Store the constant in memory and load this value from the memory. The value + needs to be written near the code that will load it since we use a PC-relative + offset to indicate the address of this value. This solution has the advantage + of making the value easily modifiable at run-time; since it does not reside + in the instruction stream, it doesn't require cache maintenance when updated. + + VIXL also provides a way to do this: + + `__ Ldr(x0, 0x1122334455667788);` + + The assembler will store the immediate value in a "literal pool", a set of + constants embedded in the code. VIXL will emit literal pools after natural + breaks in the control flow, such as unconditional branches or return + instructions. + + Literal pools are emitted regularly, such that they are within range of the + instructions that refer to them. However, you can force a literal pool to be + emitted using `masm.EmitLiteralPool()`. + + +Running the code in the simulator. +---------------------------------- + +Now we are going to see how to use the simulator to run the code that we +generated previously. + +Use the simulator to assign a value to the registers. Our previous code example +uses the register x0 as an input, so let's set the value of this register. + + simulator.set_xreg(0, 0x8899aabbccddeeff); + +Now we can jump to the "entry" label to execute the code: + + simulator.RunFrom(entry.target()); + +When the execution is finished and the simulator returned, you can inspect +the value of the registers after the execution. For instance: + + printf("x0 = %" PRIx64 "\n", simulator.xreg(0)); + +The example shown in this tutorial is very simple, because the goal was to +demonstrate the basics of the VIXL framework. There are more complex code +examples in the VIXL `examples` directory showing more features of both the +macro assembler and the ARMv8 architecture. diff --git a/doc/supported-instructions.md b/doc/supported-instructions.md new file mode 100644 index 00000000..90d63ec9 --- /dev/null +++ b/doc/supported-instructions.md @@ -0,0 +1,1133 @@ +VIXL Supported Instruction List +=============================== + +This is a list of the AArch64 instructions supported by the VIXL assembler, +disassembler and simulator. The simulator may not support all floating point +operations to the precision required by AArch64 - please check the simulator +source code for details. + +AArch64 integer instructions +---------------------------- + +### adc ### + +Add with carry bit. + + void adc(const Register& rd, + const Register& rn, + const Operand& operand, + FlagsUpdate S = LeaveFlags) + + +### add ### + +Add. + + void add(const Register& rd, + const Register& rn, + const Operand& operand, + FlagsUpdate S = LeaveFlags) + + +### adr ### + +Calculate the address of a PC offset. + + void adr(const Register& rd, int imm21) + + +### adr ### + +Calculate the address of a label. + + void adr(const Register& rd, Label* label) + + +### asr ### + +Arithmetic shift right. + + inline void asr(const Register& rd, const Register& rn, unsigned shift) + + +### asrv ### + +Arithmetic shift right by variable. + + void asrv(const Register& rd, const Register& rn, const Register& rm) + + +### b ### + +Branch to PC offset. + + void b(int imm26, Condition cond = al) + + +### b ### + +Branch to label. + + void b(Label* label, Condition cond = al) + + +### bfi ### + +Bitfield insert. + + inline void bfi(const Register& rd, + const Register& rn, + unsigned lsb, + unsigned width) + + +### bfm ### + +Bitfield move. + + void bfm(const Register& rd, + const Register& rn, + unsigned immr, + unsigned imms) + + +### bfxil ### + +Bitfield extract and insert low. + + inline void bfxil(const Register& rd, + const Register& rn, + unsigned lsb, + unsigned width) + + +### bic ### + +Bit clear (A & ~B). + + void bic(const Register& rd, + const Register& rn, + const Operand& operand, + FlagsUpdate S = LeaveFlags) + + +### bl ### + +Branch with link to PC offset. + + void bl(int imm26) + + +### bl ### + +Branch with link to label. + + void bl(Label* label) + + +### blr ### + +Branch with link to register. + + void blr(const Register& xn) + + +### br ### + +Branch to register. + + void br(const Register& xn) + + +### brk ### + +Monitor debug-mode breakpoint. + + void brk(int code) + + +### cbnz ### + +Compare and branch to PC offset if not zero. + + void cbnz(const Register& rt, int imm19) + + +### cbnz ### + +Compare and branch to label if not zero. + + void cbnz(const Register& rt, Label* label) + + +### cbz ### + +Compare and branch to PC offset if zero. + + void cbz(const Register& rt, int imm19) + + +### cbz ### + +Compare and branch to label if zero. + + void cbz(const Register& rt, Label* label) + + +### ccmn ### + +Conditional compare negative. + + void ccmn(const Register& rn, + const Operand& operand, + StatusFlags nzcv, + Condition cond) + + +### ccmp ### + +Conditional compare. + + void ccmp(const Register& rn, + const Operand& operand, + StatusFlags nzcv, + Condition cond) + + +### cinc ### + +Conditional increment: rd = cond ? rn + 1 : rn. + + void cinc(const Register& rd, const Register& rn, Condition cond) + + +### cinv ### + +Conditional invert: rd = cond ? ~rn : rn. + + void cinv(const Register& rd, const Register& rn, Condition cond) + + +### cls ### + +Count leading sign bits. + + void cls(const Register& rd, const Register& rn) + + +### clz ### + +Count leading zeroes. + + void clz(const Register& rd, const Register& rn) + + +### cmn ### + +Compare negative. + + void cmn(const Register& rn, const Operand& operand) + + +### cmp ### + +Compare. + + void cmp(const Register& rn, const Operand& operand) + + +### cneg ### + +Conditional negate: rd = cond ? -rn : rn. + + void cneg(const Register& rd, const Register& rn, Condition cond) + + +### csel ### + +Conditional select: rd = cond ? rn : rm. + + void csel(const Register& rd, + const Register& rn, + const Register& rm, + Condition cond) + + +### cset ### + +Conditional set: rd = cond ? 1 : 0. + + void cset(const Register& rd, Condition cond) + + +### csetm ### + +Conditional set mask: rd = cond ? -1 : 0. + + void csetm(const Register& rd, Condition cond) + + +### csinc ### + +Conditional select increment: rd = cond ? rn : rm + 1. + + void csinc(const Register& rd, + const Register& rn, + const Register& rm, + Condition cond) + + +### csinv ### + +Conditional select inversion: rd = cond ? rn : ~rm. + + void csinv(const Register& rd, + const Register& rn, + const Register& rm, + Condition cond) + + +### csneg ### + +Conditional select negation: rd = cond ? rn : -rm. + + void csneg(const Register& rd, + const Register& rn, + const Register& rm, + Condition cond) + + +### eon ### + +Bitwise enor/xnor (A ^ ~B). + + void eon(const Register& rd, const Register& rn, const Operand& operand) + + +### eor ### + +Bitwise eor/xor (A ^ B). + + void eor(const Register& rd, const Register& rn, const Operand& operand) + + +### extr ### + +Extract. + + void extr(const Register& rd, + const Register& rn, + const Register& rm, + unsigned lsb) + + +### hint ### + +System hint. + + void hint(SystemHint code) + + +### hlt ### + +Halting debug-mode breakpoint. + + void hlt(int code) + + +### ldnp ### + +Load integer or FP register pair, non-temporal. + + void ldnp(const CPURegister& rt, const CPURegister& rt2, + const MemOperand& src) + + +### ldp ### + +Load integer or FP register pair. + + void ldp(const CPURegister& rt, const CPURegister& rt2, + const MemOperand& src) + + +### ldpsw ### + +Load word pair with sign extension. + + void ldpsw(const Register& rt, const Register& rt2, const MemOperand& src) + + +### ldr ### + +Load integer or FP register. + + void ldr(const CPURegister& rt, const MemOperand& src) + + +### ldr ### + +Load literal to FP register. + + void ldr(const FPRegister& ft, double imm) + + +### ldr ### + +Load literal to register. + + void ldr(const Register& rt, uint64_t imm) + + +### ldrb ### + +Load byte. + + void ldrb(const Register& rt, const MemOperand& src) + + +### ldrh ### + +Load half-word. + + void ldrh(const Register& rt, const MemOperand& src) + + +### ldrsb ### + +Load byte with sign extension. + + void ldrsb(const Register& rt, const MemOperand& src) + + +### ldrsh ### + +Load half-word with sign extension. + + void ldrsh(const Register& rt, const MemOperand& src) + + +### ldrsw ### + +Load word with sign extension. + + void ldrsw(const Register& rt, const MemOperand& src) + + +### lsl ### + +Logical shift left. + + inline void lsl(const Register& rd, const Register& rn, unsigned shift) + + +### lslv ### + +Logical shift left by variable. + + void lslv(const Register& rd, const Register& rn, const Register& rm) + + +### lsr ### + +Logical shift right. + + inline void lsr(const Register& rd, const Register& rn, unsigned shift) + + +### lsrv ### + +Logical shift right by variable. + + void lsrv(const Register& rd, const Register& rn, const Register& rm) + + +### madd ### + +Multiply and accumulate. + + void madd(const Register& rd, + const Register& rn, + const Register& rm, + const Register& ra) + + +### mneg ### + +Negated multiply. + + void mneg(const Register& rd, const Register& rn, const Register& rm) + + +### mov ### + +Move register to register. + + void mov(const Register& rd, const Register& rn) + + +### movk ### + +Move immediate and keep. + + void movk(const Register& rd, uint64_t imm, int shift = -1) + + +### movn ### + +Move inverted immediate. + + void movn(const Register& rd, uint64_t imm, int shift = -1) + + +### movz ### + +Move immediate. + + void movz(const Register& rd, uint64_t imm, int shift = -1) + + +### mrs ### + +Move to register from system register. + + void mrs(const Register& rt, SystemRegister sysreg) + + +### msr ### + +Move from register to system register. + + void msr(SystemRegister sysreg, const Register& rt) + + +### msub ### + +Multiply and subtract. + + void msub(const Register& rd, + const Register& rn, + const Register& rm, + const Register& ra) + + +### mul ### + +Multiply. + + void mul(const Register& rd, const Register& rn, const Register& rm) + + +### mvn ### + +Move inverted operand to register. + + void mvn(const Register& rd, const Operand& operand) + + +### neg ### + +Negate. + + void neg(const Register& rd, + const Operand& operand, + FlagsUpdate S = LeaveFlags) + + +### ngc ### + +Negate with carry bit. + + void ngc(const Register& rd, + const Operand& operand, + FlagsUpdate S = LeaveFlags) + + +### nop ### + +No-op. + + void nop() + + +### orn ### + +Bitwise nor (A | ~B). + + void orn(const Register& rd, const Register& rn, const Operand& operand) + + +### orr ### + +Bitwise or (A | B). + + void orr(const Register& rd, const Register& rn, const Operand& operand) + + +### rbit ### + +Bit reverse. + + void rbit(const Register& rd, const Register& rn) + + +### ret ### + +Branch to register with return hint. + + void ret(const Register& xn = lr) + + +### rev ### + +Reverse bytes. + + void rev(const Register& rd, const Register& rn) + + +### rev16 ### + +Reverse bytes in 16-bit half words. + + void rev16(const Register& rd, const Register& rn) + + +### rev32 ### + +Reverse bytes in 32-bit words. + + void rev32(const Register& rd, const Register& rn) + + +### ror ### + +Rotate right. + + inline void ror(const Register& rd, const Register& rs, unsigned shift) + + +### rorv ### + +Rotate right by variable. + + void rorv(const Register& rd, const Register& rn, const Register& rm) + + +### sbc ### + +Subtract with carry bit. + + void sbc(const Register& rd, + const Register& rn, + const Operand& operand, + FlagsUpdate S = LeaveFlags) + + +### sbfiz ### + +Signed bitfield insert with zero at right. + + inline void sbfiz(const Register& rd, + const Register& rn, + unsigned lsb, + unsigned width) + + +### sbfm ### + +Signed bitfield move. + + void sbfm(const Register& rd, + const Register& rn, + unsigned immr, + unsigned imms) + + +### sbfx ### + +Signed bitfield extract. + + inline void sbfx(const Register& rd, + const Register& rn, + unsigned lsb, + unsigned width) + + +### scvtf ### + +Convert signed integer or fixed point to FP. + + void scvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0) + + +### sdiv ### + +Signed integer divide. + + void sdiv(const Register& rd, const Register& rn, const Register& rm) + + +### smaddl ### + +Signed long multiply and accumulate: 32 x 32 + 64 -> 64-bit. + + void smaddl(const Register& rd, + const Register& rn, + const Register& rm, + const Register& ra) + + +### smsubl ### + +Signed long multiply and subtract: 64 - (32 x 32) -> 64-bit. + + void smsubl(const Register& rd, + const Register& rn, + const Register& rm, + const Register& ra) + + +### smulh ### + +Signed multiply high: 64 x 64 -> 64-bit <127:64>. + + void smulh(const Register& xd, const Register& xn, const Register& xm) + + +### smull ### + +Signed long multiply: 32 x 32 -> 64-bit. + + void smull(const Register& rd, const Register& rn, const Register& rm) + + +### stnp ### + +Store integer or FP register pair, non-temporal. + + void stnp(const CPURegister& rt, const CPURegister& rt2, + const MemOperand& dst) + + +### stp ### + +Store integer or FP register pair. + + void stp(const CPURegister& rt, const CPURegister& rt2, + const MemOperand& dst) + + +### str ### + +Store integer or FP register. + + void str(const CPURegister& rt, const MemOperand& dst) + + +### strb ### + +Store byte. + + void strb(const Register& rt, const MemOperand& dst) + + +### strh ### + +Store half-word. + + void strh(const Register& rt, const MemOperand& dst) + + +### sub ### + +Subtract. + + void sub(const Register& rd, + const Register& rn, + const Operand& operand, + FlagsUpdate S = LeaveFlags) + + +### sxtb ### + +Signed extend byte. + + inline void sxtb(const Register& rd, const Register& rn) + + +### sxth ### + +Signed extend halfword. + + inline void sxth(const Register& rd, const Register& rn) + + +### sxtw ### + +Signed extend word. + + inline void sxtw(const Register& rd, const Register& rn) + + +### tbnz ### + +Test bit and branch to PC offset if not zero. + + void tbnz(const Register& rt, unsigned bit_pos, int imm14) + + +### tbnz ### + +Test bit and branch to label if not zero. + + void tbnz(const Register& rt, unsigned bit_pos, Label* label) + + +### tbz ### + +Test bit and branch to PC offset if zero. + + void tbz(const Register& rt, unsigned bit_pos, int imm14) + + +### tbz ### + +Test bit and branch to label if zero. + + void tbz(const Register& rt, unsigned bit_pos, Label* label) + + +### tst ### + +Bit test and set flags. + + void tst(const Register& rn, const Operand& operand) + + +### ubfiz ### + +Unsigned bitfield insert with zero at right. + + inline void ubfiz(const Register& rd, + const Register& rn, + unsigned lsb, + unsigned width) + + +### ubfm ### + +Unsigned bitfield move. + + void ubfm(const Register& rd, + const Register& rn, + unsigned immr, + unsigned imms) + + +### ubfx ### + +Unsigned bitfield extract. + + inline void ubfx(const Register& rd, + const Register& rn, + unsigned lsb, + unsigned width) + + +### ucvtf ### + +Convert unsigned integer or fixed point to FP. + + void ucvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0) + + +### udiv ### + +Unsigned integer divide. + + void udiv(const Register& rd, const Register& rn, const Register& rm) + + +### umaddl ### + +Unsigned long multiply and accumulate: 32 x 32 + 64 -> 64-bit. + + void umaddl(const Register& rd, + const Register& rn, + const Register& rm, + const Register& ra) + + +### umsubl ### + +Unsigned long multiply and subtract: 64 - (32 x 32) -> 64-bit. + + void umsubl(const Register& rd, + const Register& rn, + const Register& rm, + const Register& ra) + + +### uxtb ### + +Unsigned extend byte. + + inline void uxtb(const Register& rd, const Register& rn) + + +### uxth ### + +Unsigned extend halfword. + + inline void uxth(const Register& rd, const Register& rn) + + +### uxtw ### + +Unsigned extend word. + + inline void uxtw(const Register& rd, const Register& rn) + + + +AArch64 floating point instructions +----------------------------------- + +### fabs ### + +FP absolute. + + void fabs(const FPRegister& fd, const FPRegister& fn) + + +### fadd ### + +FP add. + + void fadd(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) + + +### fccmp ### + +FP conditional compare. + + void fccmp(const FPRegister& fn, + const FPRegister& fm, + StatusFlags nzcv, + Condition cond) + + +### fcmp ### + +FP compare immediate. + + void fcmp(const FPRegister& fn, double value) + + +### fcmp ### + +FP compare registers. + + void fcmp(const FPRegister& fn, const FPRegister& fm) + + +### fcsel ### + +FP conditional select. + + void fcsel(const FPRegister& fd, + const FPRegister& fn, + const FPRegister& fm, + Condition cond) + + +### fcvt ### + +FP convert single to double precision. + + void fcvt(const FPRegister& fd, const FPRegister& fn) + + +### fcvtms ### + +Convert FP to signed integer (round towards -infinity). + + void fcvtms(const Register& rd, const FPRegister& fn) + + +### fcvtmu ### + +Convert FP to unsigned integer (round towards -infinity). + + void fcvtmu(const Register& rd, const FPRegister& fn) + + +### fcvtns ### + +Convert FP to signed integer (nearest with ties to even). + + void fcvtns(const Register& rd, const FPRegister& fn) + + +### fcvtnu ### + +Convert FP to unsigned integer (nearest with ties to even). + + void fcvtnu(const Register& rd, const FPRegister& fn) + + +### fcvtzs ### + +Convert FP to signed integer (round towards zero). + + void fcvtzs(const Register& rd, const FPRegister& fn) + + +### fcvtzu ### + +Convert FP to unsigned integer (round towards zero). + + void fcvtzu(const Register& rd, const FPRegister& fn) + + +### fdiv ### + +FP divide. + + void fdiv(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) + + +### fmax ### + +FP maximum. + + void fmax(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) + + +### fmin ### + +FP minimum. + + void fmin(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) + + +### fmov ### + +Move FP register to FP register. + + void fmov(FPRegister fd, FPRegister fn) + + +### fmov ### + +Move FP register to register. + + void fmov(Register rd, FPRegister fn) + + +### fmov ### + +Move immediate to FP register. + + void fmov(FPRegister fd, double imm) + + +### fmov ### + +Move register to FP register. + + void fmov(FPRegister fd, Register rn) + + +### fmsub ### + +FP multiply and subtract. + + void fmsub(const FPRegister& fd, + const FPRegister& fn, + const FPRegister& fm, + const FPRegister& fa) + + +### fmul ### + +FP multiply. + + void fmul(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) + + +### fneg ### + +FP negate. + + void fneg(const FPRegister& fd, const FPRegister& fn) + + +### frintn ### + +FP round to integer (nearest with ties to even). + + void frintn(const FPRegister& fd, const FPRegister& fn) + + +### frintz ### + +FP round to integer (towards zero). + + void frintz(const FPRegister& fd, const FPRegister& fn) + + +### fsqrt ### + +FP square root. + + void fsqrt(const FPRegister& fd, const FPRegister& fn) + + +### fsub ### + +FP subtract. + + void fsub(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) + + + +Additional or pseudo instructions +--------------------------------- + +### bind ### + +Bind a label to the current PC. + + void bind(Label* label) + + +### dc32 ### + +Emit 32 bits of data into the instruction stream. + + inline void dc32(uint32_t data) + + +### dc64 ### + +Emit 64 bits of data into the instruction stream. + + inline void dc64(uint64_t data) + + +### dci ### + +Emit raw instructions into the instruction stream. + + inline void dci(Instr raw_inst) + + +### debug ### + +Debug control pseudo instruction, only supported by the debugger. + + void debug(const char* message, uint32_t code, Instr params = BREAK) + + + |