CA I - Chapter 2 ISA 2 RISC V
CA I - Chapter 2 ISA 2 RISC V
[Adapted from Computer Organization and Design, RISC-V Edition, Patterson & Hennessy, © 2018, MK]
[Adapted from Great ideas in Computer Architecture (CS 61C) lecture slides, Garcia and Nikolíc, © 2020, UC Berkeley]
09/21/2021 1
RV32 So Far…
• Add/sub
add rd, rs1, rs2
• Branching
sub rd, rs1, rs2 beq rs1, rs2, Label
bne rs1, rs2, Label
• Add immediate bge rs1, rs2, Label
addi rd, rs1, imm blt rs1, rs2, Label
bgeu rs1, rs2, Label
• Load/store
lw lb bltu rs1, rs2, Label
lbu rd, j Label
swrs1, rs2, imm
sbrs1, rs2, imm
09/21/2021 2
RISC-V Logical
Instructions
• Useful to operate on fields of bits within a word
• e.g., characters within a word (8 bits)
• Operations to pack /unpack bits into words
• Called logical operations
C Java RISC-V
Logical operations operators operators instructions
Bit-by-bit AND & & and
Bit-by-bit OR | | or
Bit-by-bit XOR ^ ^ xor
Shift left logical << << sll
Shift right logical >> >> srl
09/21/2021
RISC-V Logical
Instructions
• Always two variants
• Register: and x5, x6, x7 # x5 = x6 & x7
• Immediate: andi x5, x6, 3 # x5 = x6 & 3
• Used for ‘masks’
• andi with 0000 00FFhex isolates the least significant
byte
• andi with FF00 0000hex isolates the most significant
byte
• There is no logical NOT in RISC-V
• Use xor with 11111111two
•
09/21/2021
Remember - simplicity… 4
Logical
Shifting
• Shift Left Logical (sll) and immediate (slli):
slli x11,x12,2 #x11=x12<<2
• Store in x11 the value from x12 shifted by 2 bits to the left (they
fall off end), inserting 0’s on right; << in C.
• Before: 0000 0002hex
0000 0000 0000 0000 0000 0000 0000 0010two
• After: 0000 0008hex
0000 0000 0000 0000 0000 0000 0000 1000two
• What arithmetic effect does shift left have?
• Shift Right: srl is opposite shift; >>
09/21/2021 5
Arithmetic
Shifting
• Shift right arithmetic (sra, srai) moves n bits to the right
(insert high-order sign bit into empty bits)
• For example, if register x10 contained
1111 1111 1111 1111 1111 1111 1110 0111two= -25ten
• If execute srai x10, x10, 4, result is:
1111 1111 1111 1111 1111 1111 1111 1110two= -2ten
• Unfortunately, this is NOT same as dividing by 2n
• Fails for odd negative numbers
• C arithmetic semantics is that division should round towards 0
09/21/2021 6
Assembler to Machine Code (More Later in
Course)
foo.S bar.S Assembler source files (text)
09/21/2021 7
How Program is Stored
Memory
Program
Bytes
One
RISC-
V
Instru
ction
09/21/2021
= 32 8
RISC-V (63)
Program
Execution
Processor Memory
PC (program counter)
Control Read is a register internal to
Instruction
the processor that
holds byte address of
Datapath Program next instruction to be
Program Counter (PC)
Instruction
Address
executed
Registers
Bytes
Arithmetic-Logic
Instruction is fetched
Unit (ALU)
Data from memory, then control unit executes instruction
09/21/2021 10
RISC V Function calls
main() {
int i,j,k,m;
... What information mus
i = mult(j,k); ... compiler/programmer
m = mult(i,i); ... keep track of?
/* really dumb mult function */
int mult (int mcand, int mlier){
int product = 0;
while (mlier > 0) { What instructions can
product = product + mcand; accomplish this?
mlier = mlier -1; }
return product;
}
09/21/2021 11
Six Fundamental Steps in Calling a
Function
1. Put arguments in a place where function can access
them
2. Transfer control to function
3. Acquire (local) storage resources needed for
function
4. Perform desired task of the function
5. Put return value in a place where calling code can
access it and restore any registers you used; release
local storage
6. Return control to point of origin, since a function can
be called from several points in a program
09/21/2021 12
RISC-V Function Call
Conventions
• Registers faster than memory, so use them
• a0–a7 (x10-x17): eight argument registers to pass
parameters and two return values (a0-a1)
• ra: one return address register to return to the point of
origin (x1)
• Also s0-s1 (x8-x9) and s2-s11 (x18-x27):
saved registers (more about those later)
09/21/2021 13
Instruction Support for Functions
(1/4)
... sum(a,b);... /* a,b:s0,s1 */
}
int sum(int x, int y) {
C
return x+y;
}
09/21/2021 18
Summary of Instruction
Support
Actually, only two instructions:
jal rd, Label – jump-and-link
jalr rd, rs, imm – jump-and-link register
09/21/2021 19
RISC-V Instruction Representation
High Level Language
Program (e.g., C)
lw x3, 0(x10) Anything can be represented
Assembly Language x4, 4(x10) as a number,
lw x4, 0(x10)
Program (e.g., RISC-V) x3, 4(x10)
i.e., data or
sw instructions
Assembler
Machine Language sw
Program (RISC-V)
2
pc 0
Out = AB+CD
B
C D
20
09/21/2021
Instructions as Numbers
(1/2)
Most data we work with is in words (32-bit chunks):
Each register is a word
lw and sw both access memory one word at a time
So how do we represent instructions?
Remember: Computer only understands 1s and 0s, so assembler
string “add x10,x11,x0” is meaningless to hardware
RISC-V seeks simplicity: since data is in words, make instructions be
fixed-size 32-bit words also
Same 32-bit instructions used for RV32, RV64, RV128
09/21/2021 21
Instructions as Numbers
(2/2)
One word is 32 bits, so divide instruction word into “fields”
Each field tells processor something about instruction
We could define different fields for each instruction, but RISC-V
seeks simplicity, so define six basic types of instruction formats:
R-format for register-register arithmetic operations
I-format for register-immediate arithmetic operations and loads
S-format for stores
B-format for branches (minor variant of S-format)
U-format for 20-bit upper immediate instructions
J-format for jumps (minor variant of U-format)
09/21/2021 22
R-Format Instruction
Layout Field’s bit positions
31 25 20 1514 12 76 0
funct7 24 rs2 19 rs1 funct311 rd opcode
7 5 5 3 5 7
Name of field
Number of bits in field
09/21/2021 23
R-Format Instructions opcode/funct
Fields
31 25 24 20 19 1514 12 11 76 0
funct7 rs2 rs1 funct3 rd opcode
7 5 5 3 5 7
opcode: partially specifies what instruction it is
Note: This field is equal to 0110011two for all R-Format register-register
arithmetic instructions
funct7+funct3: combined with opcode, these two fields describe
what operation to perform
Question: You have been professing simplicity, so why aren’t opcode
and funct7 and funct3 a single 17- bit field?
We’ll answer this later
09/21/2021 24
R-Format Instructions Register
Specifiers
31 25 20 15 12 7 0
funct7 24 rs2 19 rs1 14 funct3 11 rd 6 opcode
7 5 5 3 5 7
31 25 20 1514 12 76 0
funct7 24 rs2 19 rs1 funct311 rd opcode
7 5 5 3 5 7
31 25 20 1514 12 76 0
0000000 24 01010 19 10011 000 11 10010 0110011
7 5 5 3 5 7
09/21/2021 26
Your
Turn
What is correct encoding of add x4, x3, x2 ?
1) 4021 8233hex
2) 0021 82b3hex
3) 4021 82b3hex
4) 0021 8233hex
5) 0021 8234hex
31 2524 2019 15 14 12 11 7 6 0
09/21/2021 29
I-Format Instruction
Layout
31 25 24 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode
12 5 3 5 7
09/21/2021 30
25 24 20 19 15 14 12 11 7 6
imm[11:0] rs1 funct3 rd opcode
imm[11:0] rs1 000 rd 0010011 addi
imm[11:0] rs1 010 rd 0010011 slti
imm[11:0] rs1 011 rd 0010011 sltiu
imm[11:0] rs1 100 rd 0010011 xori
imm[11:0] rs1 110 rd 0010011 ori
imm[11:0] rs1 111 rd 0010011 andi
09/21/2021 31
I-Format
Example
RISC-V Assembly Instruction:
addi x15,x1,-50
31 20 19 1514 12 76 0
imm[11:0] rs1 funct311 rd opcode
12 5 7
5
3
111111001110 00001 000 01111 0010011
imm=-50 rs1=1 add rd=15 OP-Imm
09/21/2021 32
All RV32 I-format Arithmetic
Instructions
imm[11:0] rs1 000 rd 0010011 addi
imm[11:0] rs1 010 rd 0010011 slti
imm[11:0] rs1 011 rd 0010011 sltiu
imm[11:0] rs1 100 rd 0010011 xori
imm[11:0] rs1 110 rd 0010011 ori
imm[11:0] rs1 111 rd 0010011 andi
0000000 shamt rs1 001 rd 0010011 slli
0000000 shamt rs1 101 rd 0010011 srli
0100000 shamt rs1 101 rd 0010011 srai
One of the higher-order immediate bits “Shift-by-immediate” instructions only use
is used to distinguish “shift right lower 5 bits of the immediate value for shift
logical” (SRLI) from “shift right amount (can only shift by 0-31 bit
arithmetic” (SRAI) positions)
09/21/2021 33
Xác định mã máy (Hệ hex) cho các lệnh sau
• add x1, x2, x3 : 0x003100B3
• addi x8, x6, -10: 0xFF630413
• ori x7, x10, 0x04: 0x00456393
• slli x5, x12, 2: 0x00261293
0000 000 0 0011 0001 0 000 0000 1 011 0011 add
09/21/2021 34
Load Instructions are also I-
Type
31 20 19 1514 12 76 0
imm[11:0] rs1 funct311 rd opcode
12 5 3 5 7
offset[11:0] base width dest LOAD
09/21/2021 35
I-Format Load
Example
RISC-V Assembly Instruction:
lw x14, 8(x2)
31 20 19 1514 12 76 0
imm[11:0] rs1 funct311 rd opcode
12 5 3 5 7
offset[11: base width dest LOAD
0]
offset[11:5] offset[4:0]
=0 rs2=14 rs1=2 SW =8 STORE
09/21/2021 40
RISC-V Conditional Branches
09/21/2021 41
Branching Instruction Usage
Branches typically used for loops (if-else,
while, for)
Loops are generally small (< 50 instructions)
Function calls and unconditional jumps handled with jump instructions
(J-Format)
Recall: Instructions stored in a localized area of memory
(Code/Text)
Largest branch distance limited by size of code
Address of current instruction stored in the program counter (PC)
09/21/2021 42
PC-Relative Addressing
PC-Relative Addressing: Use the immediate field as a
two’s-complement offset to PC
Branches generally change the PC by a small amount
Can specify ± 211 ‘unit’ addresses from the PC
(We will see in a bit that we can encode 12-bit offsets as
immediates)
Why not use byte as a unit of offset from PC?
Because instructions are 32-bits (4-bytes)
We don’t branch into middle of instruction
09/21/2021 43
Scaling Branch Offset
One idea: To improve the reach of a single branch instruction,
multiply the offset by four bytes before adding to PC
This would allow one branch instruction to reach ± 211 ×
32-bit instructions either side of PC
Four times greater reach than using byte offset
09/21/2021 44
Branch Calculation
If we don’t take the branch:
PC = PC + 4 (i.e., next instruction)
If we do take the branch:
PC = PC + immediate*4
Observations:
immediate is number of instructions to jump (remember,
specifies words) either forward (+) or backwards (–)
09/21/2021 45
RISC-V Feature, n×16-bit Instructions
Extensions to RISC-V base ISA support 16-bit compressed
instructions and also variable-length instructions that are
multiples of 16-bits in length
To enable this, RISC-V scales the branch offset by 2 bytes even
when there are no 16-bit instructions
Reduces branch reach by half and means that ½ of possible targets
will be errors on RISC-V processors that only support 32-bit
instructions (as used in this class)
RISC-V conditional branches can only reach ± 210
× 32-bit instructions on either side of PC
09/21/2021 46
RISC-V B-Format for Branches
09/21/2021 47
Branch Example, Determine Offset
RISC-V Code: Count instructions
from branch
Loop: beq x19,x10,End
1
add x18,x18,x10
2
addi x19,x19,-1
3
j Loop
4
End: # target instruction
Branch offset =
4×32-bit instructions = 16 bytes
(Branch with offset of 0,
branches to itself)
09/21/2021 48
Branch Example, Determine Offset
RISC-V Code: Count instructions
from branch
Loop: beq x19,x10,End
1
add x18,x18,x10
2
addi x19,x19,-1
3
j Loop
End: # target instruction
4
09/21/2021 49
Branch Example, Determine Offset
RISC-V Code: Offset = 16 bytes
=8x2
Loop: beq x19,x10,End
1
add x18,x18,x10
2
addi x19,x19,-1
3
j Loop
End: # target instruction
4
01000
??????? 01010 10011 000 ????? 1100011
imm rs2=10 rs1=19 BEQ imm BRANCH
09/21/2021 50
RISC-V Immediate Encoding
Instruction encodings, inst[31:0]
31 30 25 24 20 19 15 14 12 11 8 7 0
funct7 rs2 rs1 funct3 rd 6 opcode R-type
imm[11:0] rs1 funct3 rd opcode I-type
imm[11:5] rs2 rs1 funct3 imm[4:0] opcode
S-
imm[12|10:5] rs2 rs1 funct3 imm[4:1|11] opcode type
32-bit immediates produced, imm[31:0] B-type
31 25 24 12 11 10 5 4 1 0
-inst[31]- inst[30:25] inst[24:21] inst[20]
I-imm.
-inst[31]- inst[30:25] inst[11:8] inst[7]
S-imm.
-inst[31]- inst[7] inst[30:25] inst[11:8] 0
B-imm.
Only bit 7 of instruction changes role
Upper bits sign-extended from inst[31]
in immediate between S and B
always09/21/2021 51
Branch Example, Complete
Encoding
beq x19,x10, offset = 16 bytes
13-bit immediate, imm[12:0], with value 16
imm[0]
0000000010000 discarded,
always zero
imm[12] imm[11]
0 000000 01010 10011 000 1000 0 1100011
imm[10:5] rs2=10 BEQ imm[4:1] BRANCH
rs1=19
09/21/2021 52
All RISC-V Branch Instructions
09/21/2021 53
Questions on PC-addressing
Does the value in branch immediate field change if we
move the code?
If moving individual lines of code, then yes
If moving all of code, then no (‘position-independent code’)
What do we do if destination is > 210 instructions
away from branch?
Other instructions save us
09/21/2021 54
Questions on PC-addressing
Does the value in branch immediate field change if we
move the code?
If moving individual lines of code, then yes
If moving all of code, then no (‘position-independent code’)
What do we do if destination is > 210 instructions
away from branch?
Other instructions save us
beq x10,x0,far
# next instr bne x10,x0,next
j far
next: # next instr
09/21/2021 55
U-Format for “Upper Immediate”
Instructions
31
imm[31:12] 12 11 rd 7 opcode 0
6
20 7
U-immediate[31:12] 5 LUI
U-
dest
immediate[31:12] AUIPC
Has 20-bit immediate in upper 20 bits of 32-bit instruction
dest
word
One destination register, rd
Used for two instructions
lui – Load Upper Immediate
auipc – Add Upper Immediate to PC
09/21/2021 56
LUI to Create Long Immediates
LUI writes the upper 20 bits of the destination with the
immediate value, and clears the lower 12 bits.
Together with an addi to set low 12 bits, can create
any 32-bit value in a register using two instructions
(lui/addi).
09/21/2021 57
One Corner Case
How to set 0xDEADBEEF?
lui x10, 0xDEADB # x10 = 0xDEADB000
addi x10, x10, 0xEEF # x10 = 0xDEADAEEF
09/21/2021 58
Solution
How to set 0xDEADBEEF?
LUI x10, 0xDEADC # x10 = 0xDEADC000
09/21/2021 60
J-Format for Jump Instructions
7 0
31 imm[10:1]21
30 20
imm[11] imm[19:12]12 11
19 rd 6 opcode
imm[20]
1 10 1 5 7
8 dest JAL
offset[20:1]
jal saves PC+4 in register rd (the return address)
Assembler “j” jump is pseudo-instruction, uses JAL but sets
rd=x0 to discard return address
Set PC = PC + offset (PC-relative jump)
Target somewhere within ±219 locations, 2 bytes apart
±218 32-bit instructions
Immediate encoding optimized similarly to branch instruction to
reduce hardware cost
09/21/2021 61
Uses of JAL
# j pseudo-instruction
j Label = jal x0, Label # Discard return
address
09/21/2021 62
JALR Instruction (I-Format)
15 7 0
31 imm[11:0] 20 19 rs1 func3 12 11 rd
6 opcode
14
12 5 3 5 7
offset[11:0] base 0 dest JALR
09/21/2021 63
Uses of JALR
# ret and jr psuedo-instructions
ret = jr ra = jalr x0, ra, 0
# Call function at any 32-bit absolute
address
lui x1, <hi20bits>
jalr ra, x1, <lo12bits>
# Jump PC-relative with 32-bit offset
auipc x1, <hi20bits>
jalr x0, x1, <lo12bits>
09/21/2021 64
Summary of RISC-V Instruction
Formats
31 30 25 24 21 20 19 15 14 12 11 8 7 0
funct7 6 rs2 rs1 funct3 rdR-type opcode
imm[11:0] rs1 funct3 rd opcode I-type
imm[11:5] rs2 rs1 funct3 imm[4:0] opcode
S-
imm[12|10:5] rs2 rs1 funct3 im m[4:1|11] opcode
type
imm[31:12] rd opcode B-type
imm[20|10:1|11]] imm[19:12] rd opcode U-
type
J-type
09/21/2021 65
Complete RV32I ISA
Open Reference Card ¨
Base Integer Instructions: RV32I
Branches Branch =
I SLTIU rd,rs1,imm
B BEQ rs1,rs2,imm Synch Synch thread I
FENCE Not in 61C
Branch ≠ B BNE rs1,rs2,imm