srai

srai

RISC-V Assembly Reference

lyszt.net covers srai and other RISC-V instructions in more detail.

Encoding format

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

Description

srai moves bits right by a fixed amount and copies the sign bit into the vacated top positions, which keeps negative numbers negative. It is the constant-amount form of sra, which is why the fill preserves the sign. The i means immediate, a constant encoded in the instruction.

The syntax of srai appears below, with amount as a constant between 0 and 31.

srai rd, rs1, amount

A right shift of one place halves a number and leaves the sign unchanged, so srai divides a signed number by a power of two. The next line divides a signed value by 8, for both positive and negative inputs.

srai t0, t0, 3

srai rounds down, toward the more negative value. Shifting -7 right by 1 gives -4, while div with a divisor of 2 gives -3 because it rounds toward zero. The two agree on non-negative numbers and on divisions with no remainder. They differ by one only when a negative number leaves a remainder. Graphics, audio and signal code generally needs the downward rounding.

The RISC-V manual encodes constant shifts as a specialization of the I-type format, one of the standard instruction layouts. The shift amount occupies the lower 5 bits of the immediate field, and bit 30 of the instruction distinguishes the two right shifts. srai performs an arithmetic right shift, and the original sign bit fills the vacated upper bits.

Of the four shifts, srai handles signed numbers being divided and srli handles raw bits or numbers that never go negative. The forms without i, sra and srl, take a shift distance computed while the program runs.

Example

li t0, -8
srai t1, t0, 1   # t1 = -4 (sign-filled)