RISC-V

RISC-V Instruction Quick Search Table

Quick search RISC-V instruction.
Instruction Extension Note Description
ADDI rd, rs1, imm[11:0] RV32I adds the sign-extended 12-bit immediate to register rs1.
SLTI rd, rs1, imm[11:0] RV32I Set less than immediate. Places the value 1 in register rd if register rs1 is less than the sign-extended immediate when both are treated as signed numbers, else 0 is written to rd.
SLTIU rd, rs1, imm[11:0] RV32I Set less than immediate. Places the value 1 in register rd if register rs1 is less than the immediate when both are treated as unsigned numbers, else 0 is written to rd.
ANDI rd, rs1, imm[11:0] RV32I Perform bitwise AND on register rs1 and the sign-extended 12-bit immediate and place the result in rd.
ORI rd, rs1, imm[11:0] RV32I Perform bitwise OR on register rs1 and the sign-extended 12-bit immediate and place the result in rd.
XORI rd, rs1, imm[11:0] RV32I Perform bitwise XOR on register rs1 and the sign-extended 12-bit immediate and place the result in rd.
SLLI rd, rs1, imm[4:0] RV32I Logical left shift (zeros are shifted into the lower bits).
SRLI rd, rs1, imm[4:0] RV32I Logical right shift (zeros are shifted into the upper bits).
SRAI rd, rs1, imm[4:0] RV32I Arithmetic right shift (the original sign bit is copied into the vacated upper bits).
LUI rd, imm[31:12] RV32I Places the U-immediate value in the top 20 bits of the destination register rd, filling in the lowest 12 bits with zeros.
AUIPC rd, imm[31:12] RV32I Forms a 32-bit offset from the 20-bit U-immediate, filling in the lowest 12 bits with zeros, adds this offset to the address of the AUIPC instruction, then places the result in register rd.
ADD rd, rs1, rs2 RV32I Performs the addition of rs1 and rs2.
SUB rd, rs1, rs2 RV32I Performs the subtraction of rs2 from rs1.
SLT rd, rs1, rs2 RV32I Perform signed compares, writing 1 to rd if rs1 < rs2, 0 otherwise.
SLTU rd, rs1, rs2 RV32I Perform unsigned compares, writing 1 to rd if rs1 < rs2, 0 otherwise.
ADD rd, rs1, rs2 RV32I Perform bitwise AND on register rs1 and rs2 and place the result in rd.
OR rd, rs1, rs2 RV32I Perform bitwise OR on register rs1 and rs2 and place the result in rd.
XOR rd, rs1, rs2 RV32I Perform bitwise XOR on register rs1 and rs2 and place the result in rd.
SLL rd, rs1, rs2 RV32I Perform logical left shifts on the value in register rs1 by the shift amount held in the lower 5 bits of register rs2.
SRL rd, rs1, rs2 RV32I Perform logical right shifts on the value in register rs1 by the shift amount held in the lower 5 bits of register rs2.
SLA rd, rs1, rs2 RV32I Perform arithmetic right shifts on the value in register rs1 by the shift amount held in the lower 5 bits of register rs2.
JAL rd, offset[20:1] RV32I The offset is sign-extended and added to the address of the jump instruction to form the jump target address. JAL stores the address of the instruction following the jump (pc+4) into register rd.
JALR rd, rs1, offset[11:0] RV32I The target address is obtained by adding the sign-extended 12-bit I-immediate to the register rs1, then setting the least-significant bit of the result to zero. The address of the instruction following the jump (pc+4) is written to register rd.
BEQ rs1, rs2, offset[12:1] RV32I Take the branch if rs1 and rs2 are equal.
BNE rs1, rs2, offset[12:1] RV32I Take the branch if rs1 and rs2 are unequal.
BLT rs1, rs2, offset[12:1] RV32I Take the branch if rs1 is less than rs2, using signed comparison.
BLTU rs1, rs2, offset[12:1] RV32I Take the branch if rs1 is less than rs2, using unsigned comparison.
BGE rs1, rs2, offset[12:1] RV32I Take the branch if rs1 is greater than rs2, using signed comparison.
BGEU rs1, rs2, offset[12:1] RV32I Take the branch if rs1 is greater than rs2, using unsigned comparison.
LW rd, offset[11:0](rs1) RV32I Loads a 32-bit value from memory into rd. The effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.
LH rd, offset[11:0](rs1) RV32I Loads a 16-bit value from memory, then sign-extends to 32-bits before storing in rd. The effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.
LHU rd, offset[11:0](rs1) RV32I Loads a 16-bit value from memory, then zero-extends to 32-bits before storing in rd. The effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.
LB rd, offset[11:0](rs1) RV32I Loads a 8-bit value from memory, then sign-extends to 32-bits before storing in rd. The effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.
LBU rd, offset[11:0](rs1) RV32I Loads a 8-bit value from memory, then zero-extends to 32-bits before storing in rd. The effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.
SW rs2, offset[11:0](rs1) RV32I Store 32-bit value from the low bits of register rs2 to memory.
SH rs2, offset[11:0](rs1) RV32I Store 16-bit value from the low bits of register rs2 to memory.
SB rs2, offset[11:0](rs1) RV32I Store 8-bit value from the low bits of register rs2 to memory.
FENCE RV32I Order device I/O and memory accesses as viewed by other RISCV harts and external devices or coprocessors.
ECALL M-PRIV Make a service request to the execution environment.
EBREAK RV32I Return control to a debugging environment.
HINT RV32I HINTs are usually used to communicate performance hints to the microarchitecture. HINTs are encoded as integer computational.
FENCE.I Zifencei Ensures that a subsequent instruction fetch on a RISC-V hart will see any previous data stores already visible to the same RISC-V hart.
ADDIW rd, rs1, imm[11:0] RV64I Adds the sign-extended 12-bit immediate to register rs1 and produces the proper sign-extension of a 32-bit result in rd.
SSLIW rd, rs1, shamt[4:0] RV64I Logical left shift. Operate on 32-bit values and produce signed 32-bit results.
SRLIW rd, rs1, shamt[4:0] RV64I Logical right shift. Operate on 32-bit values and produce signed 32-bit results.
SRAIW rd, rs1, shamt[4:0] RV64I Arithmetic right shift. Operate on 32-bit values and produce signed 32-bit results.
ADDW rd, rs1, rs2 RV64I Performs the addition of rs1 and rs2. Operate on 32-bit values and produce signed 32-bit results.
SUBW rd, rs1, rs2 RV64I Performs the subtraction of rs2 from rs1. Operate on 32-bit values and produce signed 32-bit results
SLLW rd, rs1, rs2 RV64I Perform logical left shifts on the value in register rs1 by the shift amount held in the lower 5 bits of register rs2. Operate on 32-bit values and produce signed 32-bit results.
SRLW rd, rs1, rs2 RV64I Perform logical right shifts on the value in register rs1 by the shift amount held in the lower 5 bits of register rs2. Operate on 32-bit values and produce signed 32-bit results.
SLAW rd, rs1, rs2 RV64I Perform arithmetic right shifts on the value in register rs1 by the shift amount held in the lower 5 bits of register rs2. Operate on 32-bit values and produce signed 32-bit results.
LD rd, offset[11:0](rs1) RV64I Loads a 64-bit value from memory into register rd for RV64I.
SD rs2, offset[11:0](rs1) RV32I Store 64-bit value from the low bits of register rs2 to memory.
MUL rd, rs1, rs2 M Performs an XLEN-bit×XLEN-bit multiplication of rs1 by rs2 and places the lower XLEN bits in the destination register.
MULH rd, rs1, rs2 M Performs an XLEN-bit×XLEN-bit, signed×signed multiplication of rs1 by rs2 and places the upper XLEN bits of the full 2×XLEN-bit product in the destination register.
MULHU rd, rs1, rs2 M Performs an XLEN-bit×XLEN-bit, unsigned×unsigned multiplication of rs1 by rs2 and places the upper XLEN bits of the full 2×XLEN-bit product in the destination register.
MULHSU rd, rs1, rs2 M Performs an XLEN-bit×XLEN-bit, signed rs1×unsigned rs2 multiplication of rs1 by rs2 and places the upper XLEN bits of the full 2×XLEN-bit product in the destination register.
MULW rd, rs1, rs2 M, RV64 Multiplies the lower 32 bits of the source registers, placing the sign-extension of the lower 32 bits of the result into the destination register.
DIV rd, rs1, rs2 M Perform an XLEN bits by XLEN bits signed integer division of rs1 by rs2, rounding towards zero.
DIVU rd, rs1, rs2 M Perform an XLEN bits by XLEN bits unsigned integer division of rs1 by rs2, rounding towards zero.
REM rd, rs1, rs2 M Provide the remainder of the signed integer division operation.
REMU rd, rs1, rs2 M Provide the remainder of the unsigned integerdivision operation.
DIVW rd, rs1, rs2 M, RV64 Divide the lower 32 bits of rs1 by the lower 32 bits of rs2, treating them as signed integers, placing the 32-bit quotient in rd, sign-extended to 64 bits.
DIVU rd, rs1, rs2 M, RV64 Divide the lower 32 bits of rs1 by the lower 32 bits of rs2, treating them as unsigned integers, placing the 32-bit quotient in rd, sign-extended to 64 bits.
REMW rd, rs1, rs2 M, RV64 Provide the remainder of the 32-bit signed integer division operation. It always sign-extend the 32-bit result to 64 bits, including on a divide by zero.
REMUW rd, rs1, rs2 M, RV64 Provide the remainder of the 32-bit unsigned integer division operation. It always sign-extend the 32-bit result to 64 bits, including on a divide by zero.
LR.W rd, (rs1) A Loads a word from the address in rs1, places the sign-extended value in rd, and registers a reservation set—a set of bytes that subsumes the bytes in the addressed word.
LR.D rd, (rs1) A, RV64 Loads double words from the address in rs1, places the value in rd, and registers a reservation set—a set of bytes that subsumes the bytes in the addressed words.
SC.W rd, rs2, (rs1) A Conditionally writes a word in rs2 to the address (1) in rs1: the SC.W succeeds only if the reservation is still valid and the reservation set contains the bytes being written. If the SC.W succeeds, the instruction writes the word in rs2 to memory, and it writes zero to rd. If the SC.W fails, the instruction does not write to memory, and it writes a nonzero value to rd. Regardless of success or failure, executing an SC.W instruction invalidates any reservation held by this hart.
SC.D rd, rs2, (rs1) A, RV64 Conditionally writes double words in rs2 to the address (2) in rs1: the SC.D succeeds only if the reservation is still valid and the reservation set contains the bytes being written. If the SC.D succeeds, the instruction writes the word in rs2 to memory, and it writes zero to rd. If the SC.D fails, the instruction does not write to memory, and it writes a nonzero value to rd. Regardless of success or failure, executing an SC.D instruction invalidates any reservation held by this hart.
AMOSWAP.W rd, rs2, (rs1) A $rd = *rs1, *rs1 = rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a swap operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOSWAP.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 = rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a swap operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOADD.W rd, rs2, (rs1) A $rd = *rs1, *rs1 += rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a add operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOADD.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 += rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a add operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOAND.W rd, rs2, (rs1) A $rd = *rs1, *rs1 \space \&= rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a and operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOAND.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 \space \&= rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a and operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOOR.W rd, rs2, (rs1) A $rd = *rs1, *rs1 \space |= rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a or operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOOR.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 \space |= rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a or operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOXOR.W rd, rs2, (rs1) A $rd = *rs1, *rs1 \space \text{\textasciicircum}= rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a xor operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOXOR.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 \space \text{\textasciicircum}= rs2$ Atomically load a data value from the address in rs1, place the value into register rd, apply a xor operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOMAX.W rd, rs2, (rs1) A $rd = *rs1, *rs1 = MAX(rs2, *rs1)$ Atomically load a data value from the address in rs1, place the value into register rd, apply a signed integer maximum operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOMAXU.W rd, rs2, (rs1) A $rd = *rs1, *rs1 = UMAX(rs2, *rs1)$ Atomically load a data value from the address in rs1, place the value into register rd, apply a unsigned integer maximum operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOMAX.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 = MAX(rs2, *rs1)$ Atomically load a data value from the address in rs1, place the value into register rd, apply a signed integer maximum operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOMAXU.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 = UMAX(rs2, *rs1)$ Atomically load a data value from the address in rs1, place the value into register rd, apply a unsigned integer maximum operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOMIN.W rd, rs2, (rs1) A $rd = *rs1, *rs1 = MIN(rs2, *rs1)$ Atomically load a data value from the address in rs1, place the value into register rd, apply a signed integer minimum operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOMINU.W rd, rs2, (rs1) A $rd = *rs1, *rs1 = UMIN(rs2, *rs1)$ Atomically load a data value from the address in rs1, place the value into register rd, apply a unsigned integer minimum operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOMIN.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 = MIN(rs2, *rs1)$ Atomically load a data value from the address in rs1, place the value into register rd, apply a signed integer minimum operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
AMOMINU.D rd, rs2, (rs1) A, RV64 $rd = *rs1, *rs1 = UMIN(rs2, *rs1)$ Atomically load a data value from the address in rs1, place the value into register rd, apply a unsigned integer minimum operator to the loaded value and the original value in rs2, then store the result back to the address in rs1.
CSRRW rd, csr, rs1 Zicsr $ rd = csr, csr = rs1 $ Reads the old value of the csr, zero-extends the value to XLEN bits, then writes it to integer register rd. The initial value in rs1 is written to the csr.
CSRRS rd, csr, rs1 Zicsr $ rd = csr, csr \space |= rs1 $ Reads the value of the csr, zero-extends the value to XLEN bits, and writes it to integer register rd. The initial value in integer register rs1 is treated as a bit mask that specifies bit positions to be set in the csr.
CSRRC rd, csr, rs1 Zicsr $ rd = csr, csr \space \&= ~rs1 $ Reads the value of the csr, zero-extends the value to XLEN bits, and writes it to integer register rd. The initial value in integer register rs1 is treated as a bit mask that specifies bit positions to be cleared in the csr.
CSRRWI, rd, csr, uimm[4:0] Zicsr $ rd = csr, csr = uimm $ Reads the old value of the csr, zero-extends the value to XLEN bits, then writes it to integer register rd. The immediate uimm is written to the csr.
CSRRSI rd, csr, uimm[4:0] Zicsr $ rd = csr, csr \space |= uimm $ Reads the value of the csr, zero-extends the value to XLEN bits, and writes it to integer register rd. The immediate uimm is treated as a bit mask that specifies bit positions to be set in the csr.
CSRRCI rd, csr, uimm[4:0] Zicsr $ rd = csr, csr \space \&= ~uimm $ Reads the value of the csr, zero-extends the value to XLEN bits, and writes it to integer register rd. The immediate uimm is treated as a bit mask that specifies bit positions to be cleared in the csr.
RDCYCLE rd Pseudo-Instruction Reads the low XLEN bits of the cycle CSR which holds a count of the number of clock cycles executed by the processor core on which the hart is running from an arbitrary start time in the past.
RDCYCLEH rd RV32I Reads bits 63–32 of the cycle CSR.
RDTIME rd Pseudo-Instruction Reads the low XLEN bits of the time CSR, which counts wall-clock real time that has passed from an arbitrary start time in the past.
RDTIMEH rd RV32I Reads bits 63–32 of the time CSR.
RDINSTRET Pseudo-Instruction Reads the low XLEN bits of the instret CSR, which counts the number of instructions retired by this hart from some arbitrary start point in the past.
RDINSTRETH rd RV32I $ rd = instret $ Reads bits 63–32 of the instret CSR.
FRCSR rd Pseudo-Instruction $ rd = fcsr $ Reads fcsr by copying it into integer register rd.
FSCSR rd, rs1 Pseudo-Instruction $ rd = fcsr, fcsr = rs1 $ Swaps the value in fcsr by copying the original value into integer register rd, and then writing a new value obtained from integer register rs1 into fcsr.
FRRM rd Pseudo-Instruction $ rd = fcsr.frm $ Reads the Rounding Mode field frm and copies it into the least-significant three bits of integer register rd, with zero in all other bits.
FSRM rd, rs1 Pseudo-Instruction $ rd = fcsr.frm, fcsr.frm = rs1[2:0] $ Swaps the value in frm by copying the original value into integer register rd, and then writing a new value obtained from the three least-significant bits of integer register rs1 into frm.
FRFLAGS rd Pseudo-Instruction $ rd = fcsr.fflags $ Reads the Accrued Exceptions field fflags and copies it into the least-significant five bits of integer register rd, with zero in all other bits.
FSFLAGS rd, rs1 Pseudo-Instruction $ rd = fcsr.fflags, fcsr.fflags = rs1[4:0] $ Swaps the value in fflags by copying the original value into integer register rd, and then writing a new value obtained from the five least-significant bits of integer register rs1 into frm.
FLW rd, offset[11:0](rs1) F $ rd = *(rs1 + offset) $ Loads a single-precision floating-point value from memory into floating-point register rd.
FSW rs2, offset[11:0](rs1) F $ *(rs1 + offset) = rs2 $ Stores a single-precision value from floating-point register rs2 to memory.
FADD.S rd, rs1, rs2 F $ rd = rs2 + rs1 $ Perform single-precision floating-point addition.
FMUL.S rd, rs1, rs2 F $ rd = rs2 \times rs1 $ Perform single-precision floating-point multiplication.
FSUB.S rd, rs1, rs2 F $ rd = rs1 - rs2 $ Perform single-precision floating-point subtraction of rs2 from rs1.
FDIV.S rd, rs1, rs2 F $ rd = rs1 \div rs2 $ Performs the single-precision floating-point division of rs1 by rs2.
FSQRT.S rd, rs1 F $ rd = \sqrt{rs1} $ Computes the square root of rs1.
FMIN.S rd, rs1, rs2 F $ rd = MIN(rs1, rs2) $ Write the smaller of rs1 and rs2 to rd.
FMAX.S rd, rs1, rs2 F $ rd = MAX(rs1, rs2) $ Write the larger of rs1 and rs2 to rd.
FMADD.S rd, rs1, rs2, rs3 F $ rd = rs1 \times rs2 + rs3 $ Multiplies the values in rs1 and rs2, adds the value in rs3, and writes the final result to rd.
FMSUB.S rd, rs1, rs2, rs3 F $ rd = rs1 \times rs2 - rs3 $ Multiplies the values in rs1 and rs2, subtracts the value in rs3, and writes the final result to rd.
FNMSUB.S rd, rs1, rs2, rs3 F $ rd = -(rs1 \times rs2) + rs3 $ Multiplies the values in rs1 and rs2, negates the product, adds the value in rs3, and writes the final result to rd.
FNMADD.S rd, rs1, rs2, rs3 F $ rd = -(rs1 \times rs2) - rs3 $ Multiplies the values in rs1 and rs2, negates the product, subtracts the value in rs3,
and writes the final result to rd.
FCVT.W.S rd, rs1 F Converts a floating-point number in floating-point register rs1 to a signed 32-bit in integer register rd.
FCVT.L.S rd, rs1 F, RV64 Converts a floating-point number in floating-point register rs1 to a signed 64-bit in integer register rd.
FCVT.S.W rd, rs1 F Converts a 32-bit signed integer in integer register rs1 into a floating-point number in floating-point register rd.
FCVT.S.L rd, rs1 F, RV64 Converts a 64-bit signed integer in integer register rs1 into a floating-point number in floating-point register rd.
FCVT.WU.S rd, rs1 F Converts a floating-point number in floating-point register rs1 to a unsigned 32-bit in integer register rd.
FCVT.LU.S rd, rs1 F, RV64 Converts a floating-point number in floating-point register rs1 to a unsigned 64-bit in integer register rd.
FCVT.S.WU rd, rs1 F Converts a 32-bit unsigned integer in integer register rs1 into a floating-point number in floating-point register rd.
FCVT.S.LU rd, rs1 F, RV64 Converts a 64-bit unsigned integer in integer register rs1 into a floating-point number in floating-point register rd.
FSGNJ.S rd, rs1, rs2 F $ rd = rs2[31] \space | \space rs1[30:0] $ Produce a result that takes all bits except the sign bit from rs1 and the result’s sign bit is rs2’s sign bit.
FSGNJN.S rd, rs1, rs2 F $ rd = (\text{\textasciitilde}rs2[31]) \space | \space rs1[30:0] $ Produce a result that takes all bits except the sign bit from rs1 and the result’s sign bit is the opposite of rs2’s sign bit.
FSGNJX.S rd, rs1, rs2 F $ rd = (rs1[31] \space \text{\textasciicircum} \space rs2[31]) \space | \space rs1[30:0] $ Produce a result that takes all bits except the sign bit from rs1 and the result’s sign bit is the XOR of the sign bits of rs1 and rs2.
FMV.X.W rd, rs1 F Moves the single-precision value in floating-point register rs1 represented in IEEE 754-2008 encoding to the lower 32 bits of integer register rd. The bits are not modified in the transfer.
FMV.W.X rd, rs1 F Moves the single-precision value encoded in IEEE 754-2008 standard encoding from the lower 32 bits of integer register rs1 to the floating-point register rd. The bits are not modified in the transfer.
FEQ.S rd, rs1, rs2 F Writes 1 to the integer register rd if $ rs1 == rs2 $, and 0 otherwise.
FLT.S rd, rs1, rs2 F Writes 1 to the integer register rd if $ rs1 < rs2 $, and 0 otherwise.
FLE.S rd, rs1, rs2 F Writes 1 to the integer register rd if $ rs1 <= rs2 $, and 0 otherwise.
FCLASS.S rd, rs1 F Examines the value in floating-point register rs1 and writes to integer register rd a 10-bit mask that indicates the class of the floating-point number.
RET Pseudo-Instruction Return from subroutine. It's base on jalr x0, 0(x1).
MRET/SRET M-PRIV To return after handling a trap, there are separate trap return instructions per privilege level, MRET and SRET. xRET sets the pc to the value stored in the xEPC.

ADDI will first perform the sign-expansion for immediate operand and then perform the addition operation. Therefore, the result of a2 in the following code is 0xfffff9ff.

addi a0, x0, 0x100
addi a2, a0, 0x8ff // 0x8ff is expanded to 0xfffff8ff, finally a2 = 0xfffff9ff

addi a0, zero, 0
auipc a1, 0x200 // pc = 4, a1 = (0x200 << 12) + pc = 0x200004

0x00 : addi a0, zero, 0
0x04 : addi a1, zero, 0
0x08 : beq a0, a1, 0x8 // a0 == a1, jump to `pc + 0x8 = 0x10`
0x0c : addi a2, zero, 0x100 // Bypass this line of code.
0x10 : addi a3, zero, 0x200 // a2 = 0, a3 = 0x200

0x00 : addi a0, zero, -1
0x04 : addi a1, zero, 0
0x08 : blt a0, a1, 0x8 // // -1 < 0, jump to `pc + 0x8 = 0x10`
0x0c : addi a2, zero, 0x100 // Bypass this line of code.
0x10 : addi a3, zero, 0x200 // a2 = 0, a3 = 0x200

0x00 : addi a0, zero, -1
0x04 : addi a1, zero, 0
0x08 : bltu a0, a1, 0x8 // // 0xffffffffu > 0, no jump to `pc + 0x8 = 0x10`
0x0c : addi a2, zero, 0x100 // a2 = 0x100
0x10 : addi a3, zero, 0x200 // a2 = 0x100, a3 = 0x200

addi a0, zero, 0x8
addi a1, zero, 0xff
sw a1, 4(a0) // Store `0x000000ff` to `address 0xc`
lb a2, 4(a0) // Load `0xff` from `address 0xc` to `a2`, a2 = 0xffffffff
sb a2, 9(a0) // Store `0xff` to `address 0x11`

  • FENCE orders all memory operations in its predecessor set before all memory operations in its successor set.
  • FENCE.TSO rders all load operations in its predecessor set before all memory operations in its successor set, and all store operations in its predecessor set before all store operations in its successor set.

The standard A extension defines constrained LR/SC loops, which have the following properties:

  • The loop comprises only an LR/SC sequence and code to retry the sequence in the case of failure, and must comprise at most 16 instructions placed sequentially in memory.
  • An LR/SC sequence begins with an LR instruction and ends with an SC instruction. The dynamic code executed between the LR and SC instructions can only contain instructions from the base I instruction set, excluding loads, stores, backward jumps, taken backward branches, JALR, FENCE, FENCE.I, and SYSTEM instructions. If the C extension is supported, then compressed forms of the aforementioned I instructions are also permitted.
  • The code to retry a failing LR/SC sequence can contain backwards jumps and/or branches to repeat the LR/SC sequence, but otherwise has the same constraint as the code between the LR and SC.
  • The LR and SC addresses must lie within a memory region with the LR/SC eventuality property. The execution environment is responsible for communicating which regions have this property.
  • The SC must be to the same effective address and of the same data size as the latest LR executed by the same hart.

D, Q.

(1) the address must be aligned to 32-bit.
(2) the address must be aligned to 64-bit.
R​ E Z​ J H