### RV32I HINT Instruction Examples Source: https://docs.riscv.org/reference/isa/unpriv/rv32 Illustrates how common RV32I instructions can function as HINTs when the destination register is x0. These examples show that simple implementations can execute these as regular instructions with no architecturally visible side effects. ```assembly ADD x0, x1, x2 // ADD instruction used as a HINT when rd=x0 FENCE 0, 1 // FENCE instruction used as a HINT when rd=x0, rs1=x0, fm=0, pred=0, succ!=0 ``` -------------------------------- ### RISC-V Stripmining Example Source: https://docs.riscv.org/reference/isa/unpriv/v-st-ext An example demonstrating how SEW (Standard Element Width) and LMUL (Lanes Multiplier) settings can be dynamically changed within a single loop for high throughput on mixed-width operations. ```assembly # Example: Load 16-bit values, widen multiply to 32b, shift 32b result # right by 3, store 32b values. # On entry: # a0 holds the total number of elements to process # a1 holds the address of the source array ``` -------------------------------- ### RISC-V Unit-Stride Segment Load Examples Source: https://docs.riscv.org/reference/isa/unpriv/v-st-ext Examples demonstrating the usage of RISC-V unit-stride segment load instructions. The first example loads packed RGB pixels, distributing red, green, and blue components into separate vector registers. The second example loads complex numbers, storing the real and imaginary parts into consecutive vector registers. ```assembly # Example 1 # Memory structure holds packed RGB pixels (24-bit data structure, 8bpp) vsetvli a1, t0, e8, m1, ta, ma vlseg3e8.v v8, (a0), vm # v8 holds the red pixels # v9 holds the green pixels # v10 holds the blue pixels # Example 2 # Memory structure holds complex values, 32b for real and 32b for imaginary vsetvli a1, t0, e32, m1, ta, ma vlseg2e32.v v8, (a0), vm # v8 holds real # v9 holds imaginary ``` -------------------------------- ### RISC-V PUSH Instruction Expansion Example Source: https://docs.riscv.org/reference/isa/unpriv/zc Demonstrates the software expansion of the `cm.push` instruction, showing the sequence of store operations for registers and the final stack pointer adjustment. This highlights how multiple stores can occur before the stack pointer is updated, and how these operations are re-executed after a trap. ```assembly cm.push {ra, s0-s5}, -64 ``` ```assembly # any bytes from sp-1 to sp-28 may be written multiple times before # the instruction completes therefore these updates may be visible in # the interrupt/exception handler below the stack pointer sw s5, -4(sp) sw s4, -8(sp) sw s3,-12(sp) sw s2,-16(sp) sw s1,-20(sp) sw s0,-24(sp) sw ra,-28(sp) # this must only execute once, and will only execute after all stores # completed without any precise faults, therefore this update is only # visible in the interrupt/exception handler if cm.push has completed addi sp, sp, -64 ``` -------------------------------- ### RISC-V Litmus Test MP+fence.w.w+fre-rfi-addr Example Source: https://docs.riscv.org/reference/isa/unpriv/mm-eplan This snippet demonstrates the RISC-V litmus test MP+fence.w.w+fre-rfi-addr, illustrating a scenario where a load can forward from a store buffer, leading to a specific outcome. It highlights the interaction between stores, loads, and fences in a multi-hart environment. ```assembly Hart 0 | Hart 1 li t1, 1 | li t2, 2 (a) sw t1,0(s0) | (d) lw a0,0(s1) (b) fence w, w | (e) sw t2,0(s1) (c) sw t1,0(s1) | (f) lw a1,0(s1) | (g) xor t3,a1,a1 | (h) add s0,s0,t3 | (i) lw a2,0(s0) Outcome: a0=1, a1=2, a2=0 ``` -------------------------------- ### strlen Example using RISC-V Unit-Stride Fault-Only-First Loads Source: https://docs.riscv.org/reference/isa/unpriv/v-st-ext This C function example demonstrates how to implement `strlen` using RISC-V vector instructions, specifically the unit-stride fault-only-first load (`vle8ff.v`). It loads bytes, checks for null terminators, and calculates the string length efficiently. ```assembly strlen example using unit-stride fault-only-first instruction # size_t strlen(const char *str) # a0 holds *str strlen: mv a3, a0 # Save start loop: vsetvli a1, x0, e8, m8, ta, ma # Vector of bytes of maximum length vle8ff.v v8, (a3) # Load bytes csrr a1, vl # Get bytes read vmseq.vi v0, v8, 0 # Set v0[i] where v8[i] = 0 vfirst.m a2, v0 # Find first set bit add a3, a3, a1 # Bump pointer bltz a2, loop # Not found? add a0, a0, a1 # Sum start + bump add a3, a3, a2 # Add index sub a0, a3, a0 # Subtract start address+bump ret ``` -------------------------------- ### RV32 SHA2-512 Sigma1 Transform Example Source: https://docs.riscv.org/reference/isa/unpriv/scalar-crypto Example sequence for computing the full Sigma1 transform for SHA2-512 on RV32 using sha512sig1l and sha512sig1h instructions. It shows the correct register ordering for combining the low and high parts of the transformation. ```assembly sha512sig1l t0, a0, a1 sha512sig1h t1, a1, a0 ``` -------------------------------- ### RISC-V Multi-Word Arithmetic Accumulation Example Source: https://docs.riscv.org/reference/isa/unpriv/v-st-ext This example demonstrates a sequence for multi-word arithmetic accumulation using `vadc` and `vmadc`. It involves calculating the sum with carry and then updating the carry for the next word, requiring temporary storage and register manipulation. ```assembly # Example multi-word arithmetic sequence, accumulating into v4 vmadc.vvm v1, v4, v8, v0 # Get carry into temp register v1 vadc.vvm v4, v4, v8, v0 # Calc new sum vmmv.m v0, v1 # Move temp carry into v0 for next word ``` -------------------------------- ### Semihosting HINT Instructions Source: https://docs.riscv.org/reference/isa/unpriv/rv32 Demonstrates the specific RV32I HINT instructions designated for semihosting calls. These instructions, SLLI and SRAI with specific immediate values, are used as standard HINTs for semihosting entry and exit markers. ```assembly slli x0, x0, 0x1f // Semihosting entry marker HINT srai x0, x0, 7 // Semihosting exit marker HINT ``` -------------------------------- ### RISC-V POPRET Instruction Expansion Example Source: https://docs.riscv.org/reference/isa/unpriv/zc Illustrates the software expansion of the `cm.popretz` instruction, detailing the sequence of load operations for registers, the stack pointer adjustment, and the final `li a0, 0` and `ret` instructions. It shows how loads can execute before a trap, and how subsequent operations are committed atomically. ```assembly cm.popretz {ra, s0-s3}, 32; ``` ```assembly # any or all of these load instructions may execute multiple times # therefore these updates may be visible in the interrupt/exception handler lw s3, 28(sp) lw s2, 24(sp) lw s1, 20(sp) lw s0, 16(sp) lw ra, 12(sp) # these must only execute once, will only execute after all loads # complete successfully all instructions must execute atomically # therefore these updates are not visible in the interrupt/exception handler li a0, 0 addi sp, sp, 32 ret ``` -------------------------------- ### RV32 SHA2-512 Sigma0 Transform Example Source: https://docs.riscv.org/reference/isa/unpriv/scalar-crypto Example sequence for computing the full Sigma0 transform for SHA2-512 on RV32 using sha512sig0l and sha512sig0h instructions. It demonstrates the register usage and order for combining the low and high halves. ```assembly sha512sig0l t0, a0, a1 sha512sig0h t1, a1, a0 ``` -------------------------------- ### RV64I HINT Instructions - Semihosting Markers Source: https://docs.riscv.org/reference/isa/unpriv/rv64 Specific HINT instructions used for semihosting operations. SLLI with specific immediate values and SRAI with specific immediate values are designated as standard HINTs for semihosting entry and exit. ```assembly slli x0, x0, 0x1f # Semihosting entry marker srai x0, x0, 7 # Semihosting exit marker ``` -------------------------------- ### RISC-V Mask Undisturbed Policy Example Source: https://docs.riscv.org/reference/isa/unpriv/v-st-ext This example demonstrates how vector comparison instructions can be used to implement logical AND operations on masks, particularly when the destination register is v0, adhering to a mask-undisturbed policy. This allows for efficient chaining of comparisons. ```assembly # (a < b) && (b < c) in two instructions when mask-undisturbed vmslt.vv v0, va, vb # All body elements written vmslt.vv v0, vb, vc, v0.t # Only update at set mask ``` -------------------------------- ### Synthesizing vdecompress using iota and vrgather (RISC-V) Source: https://docs.riscv.org/reference/isa/unpriv/v-st-ext Demonstrates how to synthesize the functionality of a 'vdecompress' instruction using a combination of 'viota.m' to calculate indices from a mask and 'vrgather.vv' to expand the packed data into the destination vector. ```assembly # v0 holds mask # v1 holds packed data # v11 holds input expanded vector and result viota.m v10, v0 # Calc iota from mask in v0 vrgather.vv v11, v1, v10, v0.t # Expand into destination ``` -------------------------------- ### RISC-V Pipeline Dependency Rule 12 Example (Forbidden Outcome) Source: https://docs.riscv.org/reference/isa/unpriv/mm-eplan Illustrates Rule 12 where a load (e) depends on a store (d) with a data dependency. The example shows a scenario where the global memory order is violated because (f) cannot execute before (d) has performed, leading to a forbidden outcome. ```riscv Hart 0: li t1, 1 # (a) sw t1,0(s0) # (b) fence w, w # (c) sw t1,0(s1) # (d) Hart 1: lw a0, 0(s1) # (e) sw a0, 0(s2) # (f) lw a1, 0(s2) # (g) xor a2,a1,a1 add s0,s0,a2 lw a3,0(s0) # (h) Outcome: `a0=1`, `a3=0` (Forbidden) ``` -------------------------------- ### Vector Unit-Stride Instructions Source: https://docs.riscv.org/reference/isa/unpriv/v-st-ext Provides documentation for vector unit-stride load and store instructions, including those for 8-bit, 16-bit, 32-bit, and 64-bit elements, as well as mask load/store operations. ```APIDOC ## Vector Unit-Stride Instructions ### Description These instructions perform vector loads and stores with a constant stride of one element. They support various data element widths and include special instructions for loading and storing mask values. ### Method - `vle.v vd, (rs1), vm` - `vse.v vs3, (rs1), vm` - `vlm.v vd, (rs1)` - `vsm.v vs3, (rs1)` ### Endpoint N/A (These are assembly instructions, not REST API endpoints) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```assembly # Vector unit-stride loads vle8.v vd, (rs1), vm # 8-bit unit-stride load vle16.v vd, (rs1), vm # 16-bit unit-stride load vle32.v vd, (rs1), vm # 32-bit unit-stride load vle64.v vd, (rs1), vm # 64-bit unit-stride load # Vector unit-stride stores vse8.v vs3, (rs1), vm # 8-bit unit-stride store vse16.v vs3, (rs1), vm # 16-bit unit-stride store vse32.v vs3, (rs1), vm # 32-bit unit-stride store vse64.v vs3, (rs1), vm # 64-bit unit-stride store # Vector unit-stride mask load/store vlm.v vd, (rs1) # Load byte vector of length ceil(vl/8) vsm.v vs3, (rs1) # Store byte vector of length ceil(vl/8) ``` ### Response #### Success Response (200) N/A (These are assembly instructions) #### Response Example N/A ### Notes - `vd`: Destination vector register. - `rs1`: Source register holding the base address. - `vs3`: Source vector register holding the data to store. - `vm`: Mask encoding (e.g., `v0.t` or ``). - `vlm.v` and `vsm.v` operate as byte loads/stores with EEW=8 and EMUL=1. The effective vector length is `evl`=ceil(`vl`/8). - `vlm.v` and `vsm.v` use the same `width[2:0]` encoding as `vle8.v` and `vse8.v` but are distinguished by different `lumop` and `sumop` encodings. - `vstart` is in units of bytes for `vlm.v` and `vsm.v`. - `vlm.v` and `vsm.v` respect the `vill` field in `vtype`. - Older assembler mnemonics `vle1.v` and `vse1.v` are retained as aliases for `vlm.v` and `vsm.v` respectively. ``` -------------------------------- ### Sample RISC-V Litmus Test Instructions Source: https://docs.riscv.org/reference/isa/unpriv/mm-eplan This snippet shows a sample litmus test with two harts, demonstrating memory operations and register assignments. It assumes pre-set register values and memory initialization. ```assembly li t1,1 sw t1,0(s0) li t2,2 sw t2,0(s0) lw a0,0(s0) li t3,3 sw t3,0(s0) ``` ```assembly li t4,4 sw t4,0(s0) li t5,5 sw t5,0(s0) ``` -------------------------------- ### Alloy: Define Non-Initializing Events Source: https://docs.riscv.org/reference/isa/unpriv/mm-formal Defines a set of events that do not initiate a hart. These events are part of the program order (po) starting from a hart. ```alloy fun NonInit : set Event { Hart.start.*po } ``` -------------------------------- ### Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions Source: https://docs.riscv.org/reference/isa/unpriv/v-st-ext Instructions for multi-word integer arithmetic supporting carry and borrow bits. Includes instructions for calculating the result and generating carry/borrow outputs. ```APIDOC ## Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions ### Description Supports multi-word integer arithmetic by providing instructions that operate on a carry bit. Two instructions are provided for each operation (add or subtract): one for the result (SEW width) and one for the carry output (single bit encoded as a mask boolean). ### Method Vector Assembly Instructions ### Endpoint N/A (Assembly Instructions) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```assembly # Produce sum with carry. # vd[i] = vs2[i] + vs1[i] + v0.mask[i] vadc.vvm vd, vs2, vs1, v0 # Vector-vector # vd[i] = vs2[i] + x[rs1] + v0.mask[i] vadc.vxm vd, vs2, rs1, v0 # Vector-scalar # vd[i] = vs2[i] + imm + v0.mask[i] vadc.vim vd, vs2, imm, v0 # Vector-immediate # Produce carry out in mask register format # vd.mask[i] = carry_out(vs2[i] + vs1[i] + v0.mask[i]) vmadc.vvm vd, vs2, vs1, v0 # Vector-vector # vd.mask[i] = carry_out(vs2[i] + x[rs1] + v0.mask[i]) vmadc.vxm vd, vs2, rs1, v0 # Vector-scalar # vd.mask[i] = carry_out(vs2[i] + imm + v0.mask[i]) vmadc.vim vd, vs2, imm, v0 # Vector-immediate # vd.mask[i] = carry_out(vs2[i] + vs1[i]) vmadc.vv vd, vs2, vs1 # Vector-vector, no carry-in # vd.mask[i] = carry_out(vs2[i] + x[rs1]) vmadc.vx vd, vs2, rs1 # Vector-scalar, no carry-in # vd.mask[i] = carry_out(vs2[i] + imm) vmadc.vi vd, vs2, imm # Vector-immediate, no carry-in # Produce difference with borrow. # vd[i] = vs2[i] - vs1[i] - v0.mask[i] vsbc.vvm vd, vs2, vs1, v0 # Vector-vector # vd[i] = vs2[i] - x[rs1] - v0.mask[i] vsbc.vxm vd, vs2, rs1, v0 # Vector-scalar # Produce borrow out in mask register format # vd.mask[i] = borrow_out(vs2[i] - vs1[i] - v0.mask[i]) vmsbc.vvm vd, vs2, vs1, v0 # Vector-vector # vd.mask[i] = borrow_out(vs2[i] - x[rs1] - v0.mask[i]) vmsbc.vxm vd, vs2, rs1, v0 # Vector-scalar # vd.mask[i] = borrow_out(vs2[i] - vs1[i]) vmsbc.vv vd, vs2, vs1 # Vector-vector, no borrow-in # vd.mask[i] = borrow_out(vs2[i] - x[rs1]) vmsbc.vx vd, vs2, rs1 # Vector-scalar, no borrow-in ``` ### Response #### Success Response (200) N/A (Assembly Instructions) #### Response Example N/A ``` -------------------------------- ### AES Get Byte Function (RISC-V) Source: https://docs.riscv.org/reference/isa/unpriv/vector-crypto Extracts a specific byte from a 64-bit value. This function is a utility for byte manipulation within AES operations. ```SystemVerilog val getbyte : (bits(64), int) -> bits(8) function getbyte(x, i) = (x >> to_bits(6, i * 8))[7..0] ``` -------------------------------- ### RV64I HINT Instructions - General Use Source: https://docs.riscv.org/reference/isa/unpriv/rv64 Microarchitectural HINT instructions in RV64I. This includes instructions designated for future standard use, custom use, and those with specific constraints for their HINT functionality. ```assembly LUI rd, imm # Designated for future standard use (when rd=x0) AUIPC rd, imm # (when rd=x0) ADDI rd, rs1, imm # (when rd=x0, and either rs1 != x0 or imm != 0) ANDI rd, rs1, imm # (when rd=x0) ORI rd, rs1, imm # (when rd=x0) XORI rd, rs1, imm # (when rd=x0) ADDIW rd, rs1, imm # (when rd=x0) ADD rd, rs1, rs2 # (when rd=x0, rs1 != x0) ADD rd, rs1, rs2 # (when rd=x0, rs1 = x0, rs2 != x2-x5) ADD rd, rs1, rs2 # (when rd=x0, rs1 = x0, rs2 = x2-x5) SLLI rd, rs1, shamt # (when rd=x0, rs1 != x0 or shamt != 31) SRLI rd, rs1, shamt # (when rd=x0) SRAI rd, rs1, shamt # (when rd=x0, and either rs1 != x0 or shamt != 7) SUB rd, rs1, rs2 # (when rd=x0) AND rd, rs1, rs2 # (when rd=x0) OR rd, rs1, rs2 # (when rd=x0) XOR rd, rs1, rs2 # (when rd=x0) SLL rd, rs1, rs2 # (when rd=x0) SRL rd, rs1, rs2 # (when rd=x0) SRA rd, rs1, rs2 # (when rd=x0) ADDW rd, rs1, rs2 # (when rd=x0) SUBW rd, rs1, rs2 # (when rd=x0) SLLW rd, rs1, rs2 # (when rd=x0) SRLW rd, rs1, rs2 # (when rd=x0) SRAW rd, rs1, rs2 # (when rd=x0) FENCE rdx, rsy, imm # (various constraints) SLTI rd, rs1, imm # Designated for custom use (when rd=x0) SLTIU rd, rs1, imm # (when rd=x0) SLT rd, rs1, rs2 # (when rd=x0) SLTU rd, rs1, rs2 # (when rd=x0) SLLI rd, rs1, shamt # (when rd=x0, and either rs1 != x0 or shamt != 31) SRLI rd, rs1, shamt # (when rd=x0) SRAI rd, rs1, shamt # (when rd=x0, and either rs1 != x0 or shamt != 7) SLLIW rd, rs1, imm # (when rd=x0) SRLIW rd, rs1, imm # (when rd=x0) SRAIW rd, rs1, imm # (when rd=x0) ``` -------------------------------- ### AES Get Column Operation Source: https://docs.riscv.org/reference/isa/unpriv/vector-crypto Extracts a 32-bit column from a 128-bit AES state. This is a utility function used in various AES operations, particularly those involving state manipulation. ```N/A val aes_get_column : (bits(128), nat) -> bits(32) function aes_get_column(state,c) = (state >> (to_bits(7, 32 * c)))[31..0] ``` -------------------------------- ### Alloy: Fact for Single Init Store Per Address Source: https://docs.riscv.org/reference/isa/unpriv/mm-formal Guarantees that for every address, there is exactly one initializing store operation. ```alloy fact { all a: Address | one Init & a.~address } ```