0% found this document useful (0 votes)
21 views26 pages

RISC-V Load/Store Instruction Overview

Uploaded by

smartaditya029
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)
21 views26 pages

RISC-V Load/Store Instruction Overview

Uploaded by

smartaditya029
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

INDIAN INSTITUTE OF TECHNOLOGY ROORKEE

RISC-V ISA
Load/Store Instructions

Sparsh Mittal

INDIAN INSTITUTE OF TECHNOLOGY ROORKEE

Little- and big-endian

(This will be useful for


understanding load-store
instructions in RISC-V)
Units of memory

Units of memory Datatypes in C

 Byte = 8b  char = 8b
 Halfword = 16b  short = 16b
 Word = 32b  int = 32b
 Doubleword = 64b  Long int or double = 64b
Little vs Big Endian
• How are multibyte variables stored in memory ?
• Example : How is a 4 byte integer stored ?
• Save the 4 bytes in consecutive locations
• Little endian representation (used in ARM, RISC-V and x86)
→ The LSB is stored in the lowest location
• Big endian representation (Sun Sparc, IBM PPC) → The
MSB is stored in the lowest location

Many ARM processors are biendian, because they can be configured to efficiently handle both big
and little endian data.
Little Endian vs Big Endian

Big endian
87 65 43 21
0x87654321 0 1 2 3
Little endian
21 43 65 87
0 1 2 3

• Note the order of the storage of bytes


Solved Question

Is it big-endian or little-endian? Answer: big-endian


The first value (sum) is 000000FF. Here, the least-significant byte is FF, which is stored at highest
location, i.e., address 90000003.
INDIAN INSTITUTE OF TECHNOLOGY ROORKEE

Understanding sign/zero extension


Extension
• Extension is required when we want to preserve the numeric
value, while we represent a number using more bits; or store it
in a register with more number of bits.

• There are two possibilities: sign-extension and zero-extension


• Sign-extension: replicate the sign bit to the left
• Zero-extension: replicate zero bit to the left.
Understanding extension

Case 1: Assume our 8b data is 1101 0011. We need to store it in a 16b register.
Sign- extension Zero- extension

1111 1111 1101 0011 0000 0000 1101 0011

Case 2: Assume our 8b data is 0101 0011. We need to store it in a 16b register.
Sign- extension Zero- extension

0000 0000 0101 0011 0000 0000 0101 0011

Notice that in case 2, sign- and zero-extension have the same impact.
INDIAN INSTITUTE OF TECHNOLOGY ROORKEE

Load-store instructions
Solved question
• Is it a correct RISC-V instruction?
• sub x5, x6, 10(x7)
• Answer: No. In RISC-V, only load and store instructions can
access the memory directly. For all other instructions, all their
operands have to be register values.
• Another way to say: RISC-V is a load-store ISA.
• Correct way to write above instruction is
• ld x9, 10(x7)
• sub x5, x6, x9
Why zero-extension or sign-extension

• Remember: Memory is byte addressed


• Each address identifies a single byte (8b).
• A load from memory or store to memory is in multiple of
bytes.
• Assume we are moving data from memory to a register
• In RV64, register is 64b.
• On loading 8b (or 16b or 32b) from memory, how to fill remaining
bits?
• Answer: Do either zero-extension or sign-extension.
Load/store instructions in RV64
Command Full-form #Bits loaded Extension? #bits extended?
ld Load double-word 64 Not required N/A
lw Load word 32 Sign-extension 32
lwu Load word unsigned 32 Zero-extension 32
lh Load half-word 16 Sign-extension 48
lhu Load half-word unsigned 16 Zero-extension 48
lb Load byte 8 Sign-extension 56
lbu Load byte unsigned 8 Zero-extension 56
Syntax: lwu rd, offset(rs1)
Example: lwu x6, 40(x21)
Command Full-form Bits stored in memory
sd Store double-word 64
sw Store word 32 Syntax: sw rs2, offset(rs1)
sh Store half-word 16 Example: sw x7, 40(x21)
sb Store byte 8
Solved example
Assume “long int” variables (8B). Base address of Arr is in a0. i is in a1. val is in a2

C code Simplified C code RISC-V code


Arr[i] =5; temp=5 li a3, 5
offset = i*8 slli a4, a1, 3
addr = Arr+offset add a5, a4, a0
Memory[addr] = temp sd a3, 0(a5)
val = Arr[8] ld a2, 64(a0)
Arr[i]++ offset = i*8 slli a4, a1, 3
addr = Arr+offset add a5, a4, a0
temp = Memory[addr] ld a6, 0(a5)
temp++; addi a6, a6, 1
Memory[addr] = temp sd a6, 0(a5)

Common mistake: ld a2, a3(a4)


This offset has to be an immediate, not a register value
MEMORY Solved example on load-instructions
Byte addresses
1011
1012 68 RISC-V is little endian
1013 24 Assume RV64.
1014 E0 Let x20= 1016
1015 AC Show the result of
1016 09 (i) ld x19, 0(x20)
1017 EF (ii) lw x19, 0(x20)
1018 CD (iii) lwu x19, 0(x20)
1019 AB (iv) lh x19, 0(x20)
1020 78 (v) lhu x19, 0(x20)
1021 56 (vi) lb x19, 0(x20)
1022 34 (vii) lbu x19, 0(x20)
1023 12
1024 5A
1025 4B
1026 7C
MEMORY Solved example on load-instructions
Byte addresses
1011
1012 68 RISC-V is little endian
1013 24 Assume RV64.
1014 E0 Let x20= 1016
Value of x19 after executing instructions
1015 AC Show the result of
1016 09 (i) ld x19, 0(x20) 12 34 56 78 AB CD EF 09
1017 EF (ii) lw x19, 0(x20) FF FF FF FF AB CD EF 09
1018 CD (iii) lwu x19, 0(x20) 00 00 00 00 AB CD EF 09
1019 AB (iv) lh x19, 0(x20) FF FF FF FF FF FF EF 09
1020 78 (v) lhu x19, 0(x20) 00 00 00 00 00 00 EF 09
1021 56 (vi) lb x19, 0(x20) 00 00 00 00 00 00 00 09
1022 34 (vii) lbu x19, 0(x20) 00 00 00 00 00 00 00 09
1023 12
1024 5A Selected explanations:
1025 4B (ii) For A=1010, the sign-bit is 1. Hence, sign-extension of 11…
(iv) For E=1110, the sign-bit is 1. Hence, sign-extension of 11…
1026 7C (vi) For 0 in 09, the sign-bit is 0. Hence, sign-extension of 00…
Do we need sign/zero extension while
storing also?
• Answer: No
• Reason:
• Memory is byte addressed. Register is 64b.
• If we store entire 64b register content to memory, it would take 8 bytes
• If we store 32b register content to memory, it would take 4 bytes
• If we store 16b register content to memory, it would take 2 bytes
• If we store 8b register content to memory, it would take 1 byte
• Summary: extension is required only when storing lower-width data to
higher-width storage location. Register is 8B (64b), whereas memory is
byte addressable (1B granularity).
Solved example on store-instructions

Initial value of x19

12 34 56 78 AB CD EF 09
MSB LSB
Assume RV64.
Let x20= 1016

Show the result of


(i) sd x19, 0(x20)
(ii) sw x19, 0(x20)
(iii) sh x19, 0(x20)
(iv) sb x19, 0(x20)

RISC-V is little endian


Solved example on store-instructions Initial value of x19
MSB LSB
x20= 1016 12 34 56 78 AB CD EF 09

sd x19, 0(x20) sw x19, 0(x20) sh x19, 0(x20) sb x19, 0(x20)


1012 1012 1012 1012
1013 1013 1013 1013
1014 1014 1014 1014
1015 1015 1015 1015
1016 09 1016 09 1016 09 1016 09
1017 EF 1017 EF 1017 EF 1017
1018 CD 1018 CD 1018 1018
1019 AB 1019 AB 1019 1019
1020 78 1020 1020 1020
1021 56 1021 1021 1021
1022 34 1022 1022 1022
1023 12 1023 1023 1023
1024 1024 1024 1024
1025 1025 1025 1025
Load/store Instruction Examples

li a0, 305419912 # data (0x12345688) li a0, 305419896 # data (0x12345678)


li a1, 0x12000000 # address li a1, 0x12000000 # address
sw a0, 0(a1) # store at addr. sw a0, 0(a1) # store at addr.
lw a2, 0(a1) # a2 <- 0x12345688 lw a2, 0(a1) # a2 <- 0x12348678
lh a3,0(a1) # a3 <- 0x00005688 lh a3,0(a1) # a3 <- 0xffff8678
lhu a4,0(a1) # a4 <- 0x00005688 lhu a4,0(a1) # a4 <- 0x00008678
lb a5,0(a1) # a5 <- 0xffffff88 lb a5,0(a1) # a5 <- 0x00000078
lbu a6,0(a1) # a6 <- 0x00000088 lbu a6,0(a1) # a6 <- 0x00000078
INDIAN INSTITUTE OF TECHNOLOGY ROORKEE

Addresses and pointers in C/C++

(This will be useful for doing


load-store on array operands in
RISC-V)
Understanding pointers
int *ptr;
int arr[5];
ptr = arr;

The address between ptr and ptr + 1 differs by 4 bytes.


Reason: ptr points to int, which is 4B
Displaying values

• Displaying address using arrays:


• &arr[0] = 0x61fef0
• &arr[1] = 0x61fef4
• &arr[2] = 0x61fef8

• Displaying address using pointers:


• ptr + 0 = 0x61fef0
• ptr + 1 = 0x61fef4
• ptr + 2 = 0x61fef8
Finding address of variable

Base address of Arr is 1000


Arr[2] starts from 1008

Question: Let the base address of an array Arr be BaseAddress. The size of
each variable is K bytes, find the address of the element Arr[i]
Answer: BaseAddress+K*i
Solved example: Convert array accesses
• C code:
A[12] = h + A[7];
• h in x21, base address of A in x22

• Corresponding RISC-V code: Every doubleword has 8B, hence, index


7 requires offset of 7*8(=56). Index 12 requires offset of 12*8(=96).
C/C++ code (with simple operations) RISC-V code

addr = A+7*8; val = Memory[addr] ld x9, 56(x22)


temp = val +h; add x9, x21, x9
addr = A+12*8; Memory[addr] = temp sd x9, 96(x22)
Courtesy: Jin-Soo Kim

You might also like