Project F

RISC-V Assembler: Logical

Published · Updated

In this post we look at RISC-V logical instructions, such as and and xori. These instructions are included in RV32I, the base integer instruction set. New to the series? Check out the first part on arithmetic instructions.

In the last few years, we’ve seen an explosion of RISC-V CPU designs, especially on FPGA. Thankfully, RISC-V is ideal for assembly programming with its compact, easy-to-learn instruction set. This series will help you learn and understand 32-bit RISC-V instructions (RV32) and the RISC-V ABI.

Share your thoughts with @WillFlux on Mastodon or Twitter. If you like what I do, sponsor me. 🙏

AND

The and and andi instructions perform logical AND on individual bits (bitwise). The “and” instructions are commonly used to mask parts of a register. Immediates are sign extended, see arithmetic sign extension for details.

and  rd, rs1, rs2  # rd = rs1 AND rs2
andi rd, rs, imm   # rd = rs AND imm

These examples select the 4 least significant bits from the register t0:

li   t0, 42       # t0 = 42 (0...101010)
li   t1, 15       # t1 = 15 (0...001111)

and  t2, t0, t1   # t2 = 42 (0...101010) AND 15 (0...001111) = 10 (0...001010)
andi t3, t0, 15   # t3 = 42 (0...101010) AND 15 (0...001111) = 10 (0...001010)

Binary values are in brackets with ... indicating many identical bits.

OR

The or and ori instructions perform logical OR on individual bits.

or  rd, rs1, rs2  # rd = rs1 OR rs2
ori rd, rs, imm   # rd = rs OR imm

Examples:

li   t0, 42      # t0 = 42 (0...101010)
li   t1, 15      # t1 = 15 (0...001111)

or   t2, t0, t1  # t2 = 42 (0...101010) OR 15 (0...001111) = 47 (0...101111)
ori  t3, t0, 15  # t3 = 42 (0...101010) OR 15 (0...001111) = 47 (0...101111)

XOR

The xor and xori instructions perform logical XOR (exclusive OR) on individual bits.

xor  rd, rs1, rs2  # rd = rs1 XOR rs2
xori rd, rs, imm   # rd = rs XOR imm

Examples:

li   t0, 42      # t0 = 42 (0...101010)
li   t1, 15      # t1 = 15 (0...001111)

xor  t2, t0, t1  # t2 = 42 (0...101010) XOR 15 (0...001111) = 37 (0...100101)
xori t3, t0, 15  # t3 = 42 (0...101010) XOR 15 (0...001111) = 37 (0...100101)

NOT

The not pseudoinstruction inverts the bits in a register (0 → 1 and 1 → 0). The assembler converts not to an xori instruction (see example below).

not  rd, rs      # rd = NOT rs (pseudoinstruction)

Example:

li   t0, 42      # t0 = 42 (0...101010)

# these two examples generate the same machine code
not  t2, t0      # t2 = NOT (0...101010) = (1...010101)
xori t3, t0, -1  # t3 = (0...101010) XOR (1...111111) = (1...010101)

Notice how -1 is sign extended to 32-bits so all the bits of the immediate are 1.

What’s Next?

The next instalment of RISC-V Assembler covers Shift Instructions.

Other parts of this series include: Arithmetic and Load Store. Or check out my FPGA & RISC-V Tutorials and my series on early Macintosh History.

References