0% found this document useful (0 votes)
9 views66 pages

RISC-V Instruction Set Architecture Overview

Uploaded by

tantianyi.309
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views66 pages

RISC-V Instruction Set Architecture Overview

Uploaded by

tantianyi.309
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Ripasso concetti base:

ISA RISC-V
Andrea Bartolini <[Link]@[Link]>
(Architettura dei) Calcolatori Elettronici, 2023/2024
Instruction Count and CPI
– The Iron Law of processor Performance
Clock Cycles = Instructio n Count  Cycles per Instructio n
CPU Time = Instructio n Count  CPI  Clock Cycle Time
Instructio n Count  CPI
=
Clock Rate

Courtesy of Andrea Marongiu


Instruction Count and CPI
– The Iron Law of processor Performance
Clock Cycles = Instructio n Count  Cycles per Instructio n
CPU Time = Instructio n Count  CPI  Clock Cycle Time
Instructio n Count  CPI
=
Clock Rate

• Instruction Count for a program


• Determined by program, ISA and compiler

• Average cycles per instruction (CPI)


• Determined by CPU hardware
• If different instructions have different CPI
• Average CPI affected by instruction mix
Courtesy of Andrea Marongiu
CPI Example
• Computer A: Cycle Time = 250ps, CPI = 2.0
• Computer B: Cycle Time = 500ps, CPI = 1.2
• Same ISA
• Which is faster, and by how much?
CPU Time = Instructio n Count  CPI  Cycle Time
A A A
= I  2.0  250ps = I  500ps A is faster…
CPU Time = Instructio n Count  CPI  Cycle Time
B B B
= I  1.2  500ps = I  600ps

B = I  600ps = 1.2
CPU Time
CPU Time I  500ps …by this much
A
Courtesy of Andrea Marongiu
CPI Example
• Computer A: Cycle Time = 250ps, CPI = 2.0
• Computer B: Cycle Time = 500ps, CPI = 1.2
• Same ISA
• Which is faster, and by how much?
CPU Time = Instructio n Count  CPI  Cycle Time
A A A
= I  2.0  250ps = I  500ps A is faster…
CPU Time = Instructio n Count  CPI  Cycle Time
B B B
= I  1.2  500ps = I  600ps

B = I  600ps = 1.2
CPU Time
CPU Time I  500ps …by this much
A
Courtesy of Andrea Marongiu
CPI Example
• Computer A: Cycle Time = 250ps, CPI = 2.0
• Computer B: Cycle Time = 500ps, CPI = 1.2
• Same ISA
• Which is faster, and by how much?
CPU Time = Instructio n Count  CPI  Cycle Time
A A A
= I  2.0  250ps = I  500ps A is faster…
CPU Time = Instructio n Count  CPI  Cycle Time
B B B
= I  1.2  500ps = I  600ps

B = I  600ps = 1.2
CPU Time
CPU Time I  500ps …by this much
A
Courtesy of Andrea Marongiu
CPI Example
• Computer A: Cycle Time = 250ps, CPI = 2.0
• Computer B: Cycle Time = 500ps, CPI = 1.2
• Same ISA
• Which is faster, and by how much?
CPU Time = Instructio n Count  CPI  Cycle Time
A A A
= I  2.0  250ps = I  500ps A is faster…
CPU Time = Instructio n Count  CPI  Cycle Time
B B B
= I  1.2  500ps = I  600ps

B = I  600ps = 1.2
CPU Time
CPU Time I  500ps …by this much
A
Courtesy of Andrea Marongiu
CPI Example
• Computer A: Cycle Time = 250ps, CPI = 2.0
• Computer B: Cycle Time = 500ps, CPI = 1.2
• Same ISA
• Which is faster, and by how much?
CPU Time = Instructio n Count  CPI  Cycle Time
A A A
= I  2.0  250ps = I  500ps A is faster…
CPU Time = Instructio n Count  CPI  Cycle Time
B B B
= I  1.2  500ps = I  600ps

B = I  600ps = 1.2
CPU Time
CPU Time I  500ps …by this much
A
Courtesy of Andrea Marongiu
CPI Example
• Computer A: Cycle Time = 250ps, CPI = 2.0
• Computer B: Cycle Time = 500ps, CPI = 1.2
• Same ISA
• Which is faster, and by how much?
CPU Time = Instructio n Count  CPI  Cycle Time
A A A
= I  2.0  250ps = I  500ps A is faster…
CPU Time = Instructio n Count  CPI  Cycle Time
B B B
= I  1.2  500ps = I  600ps

B = I  600ps = 1.2
CPU Time
CPU Time I  500ps …by this much
A
Courtesy of Andrea Marongiu
CPI Example
• Computer A: Cycle Time = 250ps, CPI = 2.0
• Computer B: Cycle Time = 500ps, CPI = 1.2
• Same ISA
• Which is faster, and by how much?
CPU Time = Instructio n Count  CPI  Cycle Time
A A A
= I  2.0  250ps = I  500ps A is faster…
CPU Time = Instructio n Count  CPI  Cycle Time
B B B
= I  1.2  500ps = I  600ps

B = I  600ps = 1.2
CPU Time
CPU Time I  500ps …by this much
A
Courtesy of Andrea Marongiu
CPI Example
• Computer A: Cycle Time = 250ps, CPI = 2.0
• Computer B: Cycle Time = 500ps, CPI = 1.2
• Same ISA
• Which is faster, and by how much?
CPU Time = Instructio n Count  CPI  Cycle Time
A A A
= I  2.0  250ps = I  500ps A is faster…
CPU Time = Instructio n Count  CPI  Cycle Time
B B B
= I  1.2  500ps = I  600ps

B = I  600ps = 1.2
CPU Time
CPU Time I  500ps …by this much
A
Courtesy of Andrea Marongiu
Instruction Set Architecture
CISC, RISC, RISC-V
In the Beginning…
People programmed in assembly and machine code!
• Needed as many addressing modes as possible
• Memory was (and still is) slow

CPUs had relatively few registers


• Register’s were more “expensive” than external mem
• Large number of registers requires many bits to index

Memories were small


• Encouraged highly encoded microcodes as instructions
• Variable length instructions, load/store, conditions, etc
13
Complex Instruction Set Computer (CISC)
The number of available registers greatly influenced the instruction set
architecture (ISA)

Complex Instruction Set Computers were very complex


• Necessary to reduce the number of instructions required to fit a program into
memory.
• However, also greatly increased the complexity of the ISA as well.
Reduced Instruction Set Computer (RISC)
Dave Patterson John L. Hennessy
• RISC Project, 1982 • MIPS, 1981
• UC Berkeley • Stanford
• RISC-I: ½ transistors & 3x faster • Simple, full pipeline
• Influences: Sun SPARC, namesake • Influences: MIPS computer
of industry system, PlayStation,
Nintendo

15
Reduced Instruction Set Computer (RISC)
Developed at UC Berkeley as open ISA starting in 2010
RISC-V Design Principles
Now managed by the RISC-V Foundation ([Link])
Simplicity favors regularity • Manages the standardization, trademark, compliancy check
• 32 bit instructions
• Same instruction format works at Typical of many modern ISAs
16/32/64/128-bit data formats
Similar ISAs have a large share of embedded core market
Smaller is faster Applications in consumer electronics, network/storage
• Small register file equipment, cameras, printers, …

Make the common case fast


• Include support for constants

Good design demands good compromises


• Support for different type of interpretations/classes

16
RISC-V ISA is divided into extensions
• Kept very simple and extendable
I Integer instructions (frozen)
• Wide range of applications from IoT to HPC
E Reduced number of registers • RV + word-width + extensions
Multiplication and Division • RV32IMC: 32bit, integer, multiplication,
M (frozen) compressed
A Atomic instructions (frozen) • User specification:
Single-Precision Floating-Point • Separated into extensions, only I is mandatory
F (frozen)
• Privileged Specification:
Double-Precision Floating-Point • Governs OS functionality: Exceptions,
D (frozen)
Interrupts
C Compressed Instructions (frozen) • Virtual Addressing
• Privilege Levels
X Non Standard Extensions
Working with RISC-V
Ratified Extensions as for today

• [Link]
splay/HOME/Ratified+E
xtensions
Reduced Instruction
Privilege Set: Multiply/Divide
all in one (M) page
Basic Instructions (I) Mode

Atomic Extensions (A)

Floating Point Extensions


Compressed
Instructions (C)

24
[Link]
Why RISC-V?

Courtesy of Andrea Marongiu


RISC-V vs CISC
x86 = Complex Instruction Set Computer (ClSC) RISC-V = Reduced Instruction Set Computer (RlSC)
• > 1000 instructions, 1 to 15 bytes each • ≈ 200 instructions, 32 bits each, 4 formats
• operands in dedicated registers, general purpose • all operands in registers
registers, memory, on stack, … • almost all are 32 bits each
• can be 1, 2, 4, 8 bytes, signed or unsigned • ≈ 1 addressing mode:
• 10s of addressing modes Mem[reg + imm]
e.g. Mem[segment + reg + reg*scale + offset]

CISC RISC
Emphasis on hardware Emphasis on software
Includes multi-clock complex instructions Single-clock, reduced instruction only
Memory-to-memory: "LOAD" and "STORE" Register to register: "LOAD" and "STORE"
incorporated in instructions are independent instructions
Small code sizes, high cycles per instruction Low cycles per istruction, large code sizes
Transistors used for storing complex instructions Spends more transistors on memory registers

26
C code:

Arithmetic Operations f = (g + h) - (i + j);


• f, …, j in x19, x20, …, x23

Compiled RISC-V code:


• Add and subtract, three operands add x5, x20, x21
• Two sources and one destination add x6, x22, x23
sub x19, x5, x6
add a, b, c // a gets b + c

• All arithmetic operations have this form

Design Principle 1: Simplicity favours regularity


• Regularity makes implementation simpler
• Simplicity enables higher performance at lower cost
Courtesy of Andrea Marongiu
Register Operands
› Arithmetic instructions use register operands
• x0: the constant value 0
• x1: return address
› RISC-V has a 32 × 64-bit register file • x2: stack pointer
– Use for frequently accessed data • x3: global pointer
– 64-bit data is called a “doubleword” • x4: thread pointer
› 32 x 64-bit general purpose registers x0 to x31
• x5 – x7, x28 – x31: temporaries
– 32-bit data is called a “word” • x8: frame pointer
• x9, x18 – x27: saved registers
• x10 – x11: function arguments/results
Design Principle 2: Smaller is faster • x12 – x17: function arguments
• c.f. main memory: millions of locations

Courtesy of Andrea Marongiu


C code:
Memory Operands A[12] = h + A[8];
h in x21, base address of A in x22

• Main memory used for composite data Compiled RISC-V code:


• Arrays, structures, dynamic data
• Index 8 requires offset of 64
• To apply arithmetic operations • 8 bytes per doubleword
• Load values from memory into registers
• Store result from register to memory ld x9, 64(x22)
add x9, x21, x9
• Memory is byte addressed sd x9, 96(x22)
• Each address identifies an 8-bit byte

• RISC-V is Little Endian RISC-V does not


• Least-significant byte at least address of a word
require words to
• c.f. Big Endian: most-significant byte at least address
be aligned in
memory
Courtesy of Andrea Marongiu
Immediate Operands
• Constant data specified in an instruction
addi x22, x22, 4

• Make the common case fast


• Small constants are common
• Immediate operand avoids a load instruction

Courtesy of Andrea Marongiu


Logical Operations
• Instructions for bitwise manipulation
Operation C Java RISC-V
Shift left << << slli
Shift right >> >>> srli
Bit-by-bit AND & & and, andi
Bit-by-bit OR | | or, ori
Bit-by-bit XOR ^ ^ xor, xori
Bit-by-bit NOT ~ ~ xori FF..F

◼ Useful for extracting and inserting groups of bits in a word


More Load/Store Operations: Byte/Halfword
• RISC-V byte/halfword load/store
• Load byte/halfword: Sign extend to 64 bits in rd
• lb rd, offset(rs1)
• lh rd, offset(rs1)

• Load byte/halfword unsigned: Zero extend to 64 bits in rd


• lbu rd, offset(rs1)
• lhu rd, offset(rs1)

• Store byte/halfword: Store rightmost 8/16 bits


• sb rs2, offset(rs1)
• sh rs2, offset(rs1)

Courtesy of Andrea Marongiu


More Load/Store Operations: Word/Doubleword

• RISC-V word/doubleword load/store


• Load word/doubleword: Sign extend to 64 bits in rd
• lw rd, offset(rs1)
• ld rd, offset(rs1)

• Load word/doubleword unsigned: Zero extend to 64 bits in rd


• lwu rd, offset(rs1)
• ldu rd, offset(rs1)

• Store word/doubleword: Store rightmost 32/64 bits


• sw rs2, offset(rs1)
• sd rs2, offset(rs1)

Courtesy of Andrea Marongiu


Conditional Operations
› Branch to a labeled instruction if a condition is true
– Otherwise, continue sequentially
C code:
› beq rs1, rs2, L1 if (i==j) f = g+h;
else f = g-h;
– if (rs1 == rs2) branch to instruction labeled L1
• f, g, … in x19, x20, …
› bne rs1, rs2, L1 Compiled RISC-V code:
– if (rs1 != rs2) branch to instruction labeled L1 bne x22, x23, Else
add x19, x20, x21
beq x0, x0, Exit
Else: sub x19, x20, x21
Exit: …
Assembler calculates addresses
Courtesy of Andrea Marongiu
Compiling Loop Statements
• C code:
while (save[i] == k) i += 1;
• i in x22, k in x24, address of save in x25

• Compiled RISC-V code:


Loop: slli x10, x22, 3
add x10, x10, x25
ld x9, 0(x10)
bne x9, x24, Exit
addi x22, x22, 1
beq x0, x0, Loop
Exit: …

Courtesy of Andrea Marongiu


More Conditional Operations
› blt rs1, rs2, L1
C code:
– if (rs1 < rs2) branch to instruction labeled L1
if (a > b) a += 1;
› bge rs1, rs2, L1
• a in x22, b in x23
– if (rs1 >= rs2) branch to instruction labeled L1
Compiled RISC-V code:
bge x23, x22, Exit
addi x22, x22, 1
Exit: …
• Signed comparison: blt, bge
• Unsigned comparison: bltu, bgeu

Courtesy of Andrea Marongiu


RISC-V assembly language

Courtesy of Andrea Marongiu


RISC-V assembly language (2)

Courtesy of Andrea Marongiu


RISC-V Instruction Encoding
R-type Arithmetic with register operands
I-type Loads & arithmetic with immediate operand
S-type Stores
SB-type Conditional branch
UJ-type Unconditional jump
U-type Upper immediate

32-bit instruction • Instructions are encoded in binary


• Called machine code
0x00 Instr 1
0x04 Instr 2 • RISC-V instructions
0x08 Instr 3 • Encoded as 32-bit instruction words
program
0x0C Instr 4 • Small number of formats encoding operation code (opcode),
0x10 Instr 5 register numbers, …
instruction memory • Regularity!
… …
Courtesy of Andrea Marongiu
RISC-V R-format Instructions
Instruction fields
• opcode: operation code
• rd: destination register number
• funct3: 3-bit function code (additional opcode)
• rs1: the first source register number funct7 rs2 rs1 funct3 rd opcode
• rs2: the second source register number
7 bits 5 bits 5 bits 3 bits 5 bits 7 bits
• funct7: 7-bit function code (additional opcode)

add x9,x20,x21
0 21 20 0 9 51

0000000 10101 10100 000 01001 0110011

Courtesy of Andrea Marongiu


RISC-V I-format Instructions
Immediate arithmetic and load instructions
• rs1: source or base address register number immediate rs1 funct3 rd opcode
• immediate: constant operand, or offset added to base 12 bits 5 bits 3 bits 5 bits 7 bits
address
• 2s-complement, sign extended
addi x10,x10,128 // second operand is an immediate
Design Principle 3: Good design
demands good compromises 128 10 0 10 19
• Different formats complicate decoding,
but allow 32-bit instructions uniformly 0000 1000 0000 01010 000 01010 0010011
• Keep formats as similar as possible
ld x9,64(x22)

64 22 3 9 3
0000 0100 0000 1011 0 011 0100 1 000 0011
Courtesy of Andrea Marongiu
Shift Operations

• I-format with just 6 bits for immediate


• immed: how many positions to shift
• Shift left logical
• Shift left and fill with 0 bits
• slli by i bits multiplies by 2i
• Shift right logical
• Shift right and fill with 0 bits
• srli by i bits divides by 2i (unsigned only)

Courtesy of Andrea Marongiu


RISC-V S-format Instructions
Different immediate format for store instructions
• rs1: base address register number
• rs2: source operand register number
• immediate: offset added to base address
• Split so that rs1 and rs2 fields always in the same place

5 least significant bits of (64)10


sd x9,64(x22)
2 22 9 7 0 35
64 >> 5
= 64 / 25
= 64/32 = 2
0000 010 1 0110 0100 1 111 0000 0 010 0011

Courtesy of Andrea Marongiu


RISC-V SB-format Instructions (branch
addressing)
• Branch instructions specify
• Opcode, two registers, target address
• Most branch targets are near branch
• Forward or backward

imm imm
[10:5] rs2 rs1 funct3 [4:1] opcode

imm[12] imm[11]

◼ PC-relative addressing
◼ Target address = PC + immediate × 2
(Addressing instructions down to halfword)

Courtesy of Andrea Marongiu


RISC-V UJ-format Instructions (jump
addressing)
• Jump and link (jal) uses 20-bit immediate for larger range

◼ For long jumps, eg, to 32-bit absolute address


◼ lui: load address[31:12] to temp register
◼ jalr: add address[11:0] and jump to target

Courtesy of Andrea Marongiu


More Load/Store Operations: 32-bit Constants
• Most constants are small
• 12-bit immediate is sufficient
• For the occasional 32-bit constant we need two instructions:
1. Load upper immediate (lui)
lui rd, constant
• Copies 20-bit constant to bits [31:12] of rd
• Extends bit 31 to bits [63:32]
• Clears bits [11:0] of rd to 0
2. Any other instruction that populates lower bits [11:0]
• e.g., addi

Courtesy of Andrea Marongiu


RISC-V Addressing Summary

Courtesy of Andrea Marongiu


RISC-V Encoding Summary

Courtesy of Andrea Marongiu


RISC-V Encoding Summary

and the
funct6/7 bits
opcode is which get
same for a differentiated
family of by the funct3
instructions bits
Courtesy of Andrea Marongiu
RISC-V Encoding Summary

Courtesy of Andrea Marongiu


RISC-V Encoding Summary

Courtesy of Andrea Marongiu


RISC-V procedure Calling
• Steps required
1. Place parameters in registers x10 to x17
2. Transfer control to procedure
3. Acquire storage for procedure
4. Perform procedure’s operations
5. Place result in register for caller
6. Return to place of call (address in x1)

Courtesy of Andrea Marongiu


Procedure Call Instructions
• Procedure call: jump and link
jal x1, ProcedureLabel
• Address of following instruction put in x1
• Jumps to target address (ProcedureLabel)
• Procedure return: jump and link register
jalr x0, 0(x1)
• Like jal, but jumps to 0 + address in x1
• Use x0 as rd (x0 cannot be changed)
• Can also be used for computed jumps
• e.g., for case/switch statements

Courtesy of Andrea Marongiu


Leaf Procedure Example A procedures that doesn’t call other procedures

C code: RISC-V code:


typedef long long int lli; addi sp,sp,-24
lli leaf_example (lli g, lli h, lli i, lli j) sd x5,16(sp) Save x5, x6, x20 on stack
{ sd x6,8(sp)
lli f;
f = (g + h) - (i + j); sd x20,0(sp)
return f; add x5,x10,x11 x5 = g + h
}
add x6,x12,x13 x6 = i + j
sub x20,x5,x6 f = x5 – x6
• Arguments g, …, j in x10, …, x13
addi x10,x20,0 copy f to return register
• f in x20
ld x20,0(sp) Restore x5,x6,x20 from stack
• temporaries x5, x6
ld x6,8(sp)
• Need to save x5, x6, x20 on stack
(spill to mem) ld x5,16(sp)
addi sp,sp,24
jalr x0,0(x1) Return to caller
Courtesy of Andrea Marongiu
Local Data on the Stack

Courtesy of Andrea Marongiu


Register Usage – Calling convention
• x5 – x7, x28 – x31: temporary registers
• Not preserved by the callee (volatile across calls, must be saved by the caller if
later used)

• x8 – x9, x18 – x27: saved registers


• Preserved across calls. If used,
the callee saves and restores them

• In previous example, the


stores/loads on x5 and x6
can be dropped
caller: who calls a function
callee: the function itself
Courtesy of Andrea Marongiu
Register Usage – Calling convention
• x5 – x7, x28 – x31: temporary registers
• Not preserved by the callee (volatile across calls, must be saved by the caller if
later used)

• x8 – x9, x18 – x27: saved registers


• Preserved across calls. If used,
the callee saves and restores them

• In previous example, the


stores/loads on x5 and x6
can be dropped

[Link]
Courtesy of Andrea Marongiu
FP Instructions in RISC-V
• Separate FP registers: f0, …, f31
• double-precision
• single-precision values stored in the lower 32 bits

• FP instructions operate only on FP registers


• Programs generally don’t do integer ops on FP data, or vice versa
• More registers with minimal code-size impact

• FP load and store instructions


• flw, fld
• fsw, fsd

Courtesy of Andrea Marongiu


FP Instructions in RISC-V
• Single-precision arithmetic
• fadd.s, fsub.s, fmul.s, fdiv.s, fsqrt.s
• e.g., fadds.s f2, f4, f6
• Double-precision arithmetic
• fadd.d, fsub.d, fmul.d, fdiv.d, fsqrt.d
• e.g., fadd.d f2, f4, f6
• Single- and double-precision comparison
• feq.s, flt.s, fle.s
• feq.d, flt.d, fle.d
• Result is 0 or 1 in integer destination register
• Use beq, bne to branch on comparison result

• Branch on FP condition code true or false


• [Link]

Courtesy of Andrea Marongiu


Backup
Work continues on new RISC-V extensions
• Foundation members work in
Q Quad-precision Floating-Point
task-groups
• Dedicated task-groups L Decimal Floating Point

• Formal specification B Bit Manipulation


• Memory Model
• Marketing T Transactional Memory
• External Debug Specification
P Packed SIMD

Dynamically Translated
J Languages

V Vector Operations
For more updated extensions status:
[Link] N User-Level Interrupts
Working with RISC-V
Work continues on new RISC-V extensions
• Example of the process:
• Vector Operation – V extension Q Quad-precision Floating-Point

• Frozen, not yet ratified L Decimal Floating Point

B Bit Manipulation

T Transactional Memory

P Packed SIMD

Dynamically Translated
J Languages

GitHub - riscv/riscv-v-spec: Working draft of the proposed RISC-V V Vector Operations


V vector extension

[Link]
N User-Level Interrupts
ons Working with RISC-V
Reduced Instruction Set: all in one page

Privilege Multiply/Divide (M)


Basic Instructions (I) Mode

Atomic Extensions (A)

Floating Point Extensions


Compressed
Instructions (C)
Encoding of the instructions, main groups
• Reserved opcodes for standard extensions
• Rest of opcodes free for custom implementations
• Standard extensions will be frozen/not change in the future

Working with RISC-V


FP Example: °F to °C
› C code:
float f2c (float fahr) {
return ((5.0/9.0)*(fahr - 32.0));
}
– fahr in f10, result in f10, literals in global memory space

› Compiled RISC-V code:


f2c:
flw f0,const5(x3) // f0 = 5.0f
flw f1,const9(x3) // f1 = 9.0f
fdiv.s f0, f0, f1 // f0 = 5.0f / 9.0f
flw f1,const32(x3) // f1 = 32.0f
fsub.s f10,f10,f1 // f10 = fahr – 32.0
fmul.s f10,f0,f10 // f10 = (5.0f/9.0f) * (fahr–32.0f)
jalr x0,0(x1) // return
FP Example: Array Multiplication
• C=C+A×B
• All 32 × 32 matrices, 64-bit double-precision elements
• DGEMM (Double precision GEneral Matrix Multiply)
• C code:
void mm (double c[][],
double a[][], double b[][]) {
size_t i, j, k;
for (i = 0; i < 32; i = i + 1)
for (j = 0; j < 32; j = j + 1)
for (k = 0; k < 32; k = k + 1)
c[i][j] = c[i][j]
+ a[i][k] * b[k][j];
}
• Addresses of c, a, b in x10, x11, x12, and
i, j, k in x5, x6, x7
FP Example: Array Multiplication
• RISC-V code:
mm:...
li x28,32 // x28 = 32 (row size/loop end)
li x5,0 // i = 0; initialize 1st for loop
L1: li x6,0 // j = 0; initialize 2nd for loop
L2: li x7,0 // k = 0; initialize 3rd for loop
slli x30,x5,5 // x30 = i * 2**5 (size of row of c)
add x30,x30,x6 // x30 = i * size(row) + j
slli x30,x30,3 // x30 = byte offset of [i][j]
add x30,x10,x30 // x30 = byte address of c[i][j]
fld f0,0(x30) // f0 = c[i][j]
L3: slli x29,x7,5 // x29 = k * 2**5 (size of row of b)
add x29,x29,x6 // x29 = k * size(row) + j
slli x29,x29,3 // x29 = byte offset of [k][j]
add x29,x12,x29 // x29 = byte address of b[k][j]
fld f1,0(x29) // f1 = b[k][j]
FP Example: Array Multiplication

slli x29,x5,5 // x29 = i * 2**5 (size of row of a)


add x29,x29,x7 // x29 = i * size(row) + k
slli x29,x29,3 // x29 = byte offset of [i][k]
add x29,x11,x29 // x29 = byte address of a[i][k]
fld f2,0(x29) // f2 = a[i][k]
fmul.d f1, f2, f1 // f1 = a[i][k] * b[k][j]
fadd.d f0, f0, f1 // f0 = c[i][j] + a[i][k] * b[k][j]
addi x7,x7,1 // k = k + 1
bltu x7,x28,L3 // if (k < 32) go to L3
fsd f0,0(x30) // c[i][j] = f0
addi x6,x6,1 // j = j + 1

bltu x6,x28,L2 // if (j < 32) go to L2


addi x5,x5,1 // i = i + 1
bltu x5,x28,L1 // if (i < 32) go to L1
Pitfall: Right Shift and Division
• Left shift by i places multiplies an integer by 2i
• Right shift divides by 2i?
• Only for unsigned integers
• For signed integers
• Arithmetic right shift: replicate the sign bit
• e.g., –5 / 4
• 111110112 >> 2 = 111111102 = –2
• Rounds toward –∞
• c.f. 111110112 >> 2 = 001111102 = +62
What is one advantage of a CISC ISA?

A. It naturally supports a faster clock.


B. Instructions are easier to decode.
C. The static footprint of the code will be smaller.
D. The code is easier for a compiler to optimize.
E. You have a lot of registers to use.

75
More than 1,500 RISC-V Members
across 70 Countries

94 Chip 4 Systems
SoC, IP, FPGA ODM, OEM

4 I/O 13 Industry
Memory, network, storage Cloud, mobile, HPC, ML, automotive

12 Services 81 Research
Fab, design services Universities, Labs, other alliances

40 Software 1,000+ Individuals


Dev tools, firmware, OS RISC-V engineers and advocates

March 2021
In 2020, RISC-V membership grew 133% 76

You might also like