3
points.A
We would like to implement an operation to reverse a linked list in memory, where the operand to this operation is the memory address of a pointer to the first node in the linked list (a pointer to a pointer). This operation has no destination register, but the operation zeroes the register specified by the operand upon completion (it does not preserve the operand).
Every node in the linked list has the following structure.
Assume that pointers are 32 bits wide in this architecture. The next pointer is either the memory address of the next node in the list or is equal to 0 (NULL
) to indicate the end of the linked list.
The equivalent C code for this operation is provided below.
The RISC-V assembly implementation is shown as following:
Please complete the unfinished assembly to make the above work as the C counterpart does. You don't have to manipulate the RISC-V function calls for this operation.
- A01 = ?
- A02 = ?
B
Consider the following C code:
We can translate into the optimized RISC-V assembly, so that fewer dynamic instructions are executed for large values of x
and y
.
A simple optimization is loop unrolling. With some careful bookkeeping, this can reduce the number of additions. This implementation keeps x + x
as a temporary value to cut the number of additions approximately in half.
The following is more efficient than
simply translating from C.
- B01 = ?
- B02 = ?
- B03 = ?
C
The function strtriple
receives as input a null-terminated string, and writes a string where every letter is repeated three times. For example, if we called stringtriple on the input string "Hello World!"
, we would get the output string "HHHeeellllllooo WWWooorrrlllddd!!!"
.
More specifically: strtriple
has the following inputs: a0
stores a null-terminated string. It is guaranteed that the string is well-formatted. Let the string have strlen of n
. a1
contains a pointer to a buffer of length at least characters, potentially containing garbage data. You may assume that the buffer does not overlap with the string stored in a0
.
strtriple
outputs the following: a0
should return the pointer to the buffer we initially received in a1
. The buffer should contain the string originally provided in a0
, with every character tripled. You must properly null-terminate the string, and for full credit must NOT replicate the null terminator at the end. For full credit, you must follow proper calling convention.
Please complete the unfinished assembly to make the above work as expected.
- C01 = ?
- C02 = ?
- C03 = ?
- C04 = ?
- C05 = ?
D
Consider the following Skip List implementation:
Its find
operation is shown below:
In translating the code cmp(find, sl->next[level]->data))
into RISC-V, we need to store arguments on the stack. So we will have find
at sp(0)
, level
at sp(4)
, sl
at sp(8)
and cmp
at sp(12)
. We are going to break up the translation into pieces. Please write down the RISC-V assembly accordingly.
a0
- D01 = ?
sl->next[level]->data
into a1
.sl
into t0
)
- D02 = ?
level
into t1
- D03 = ?
sl->next
into t0
- D04 = ?
sl->next[level]
into t0
- D05 = ?
a0
- D06 = ?
cmp
(using t0
as a temporary):
- D07 = ?
- D08 = ?
E
You are supposed to implement RISC-V code per requested as less instructions as possible. Follow calling convention, use register mnemonic names (e.g., refer to t0
rather than x6
), and add commas and a single space between registers/arguments (e.g. addi a0, a1, 2
). If you do not follow this, you may be misgraded.
a0
and a1
are positive non-NaN IEEE-754 32-bit floating point numbers.a0
returns 1
if a0 < a1
and 0
otherwise.a0
and a1
were 1.2
and 1.25
, the expected output would be 1
. If a0
and a1
were 1.1
and 1.1
respectively, the expected output would be 0
.
- E01 = ?
a0
is a pointer to a nonempty stringa0
returns a pointer immediately after the end of the string.a0
be the pointer 0x10000000
to string s, which is the string "Hello"
. Then the expected output would be 0x10000006
.strlen
or any other library function.
- E02 = ?
- E03 = ?
- E04 = ?
- E05 = ?
- E06 = ?
- E07 = ?
- E08 = ?
sub
, mul
or pseudo instructions.
- E09 = ?
For example, if the input to this function is 10
, then the output would be 1010
. The equivalent RISC-V code:
Hint:
+
and 10 *
- E10 = ?
- E11 = ?
- E12 = ?
- E13 = ?
- E14 = ?
char *
arguments and copies up to the first n
characters from source into destination. If it reaches a null terminator, then it copies that value into destination and stops copying in characters. If there is no null terminator among the first n characters of source, the string placed in destination will not be null-terminated. strncpy
returns a pointer to the destination string. You may not store anything on the stack for this problem.
char* strncpy(char *destination, char *source, unsigned int n);
- E15 = ?
- E16 = ?
F
Evaluate the RISC-V code. Write down the specific value in HEX. Reminder: always include the prefix in your answer.
Write down the value of t0
in HEX.
- F01 = ?
Write down the value of t0
in hex. Assume big-endianness.
- F02 = ?
G
Bloom filter is a very clever datastructure for efficiently and probabilistically storing a set. Typically, it has two functions: check and insert. The basic idea for checking is that you hash what you are looking for multiple times. Each hash tells you a particular bit you need to set or check. So for checking you see if the bit is set. You repeat this for multiple iteration, with the hash including the iteration count (so each hash is different). If not all bits are set then the element does not exist in the bloom filter. If all bits are set then the element PROBABLY exists in the bloom filter. Similarly, for setting an element as present in a bloom filter you just set all those bits to 1
.
We define the following structure.
For the insertion function, we need to set the appropriate bit for each iteration.
We also have the following function to allocate a new bloom filter
Complete the RISC-V translation necessary to allocate this: We will put ret
in s0
.
- G01 = ?
- G02 = ?
- G03 = ?
- G04 = ?
- G05 = ?
- G06 = ?
- G07 = ?
H
Please complete the translation by filling in the lines below with RISC-V assembly. The prologue and epilogue have been written correctly but are not shown.
strlen()
, both as a C function and RISC-V procedure, takes in one string as an argument and returns the length of the string (not including the null terminator).
The translated RISC-V Assembly:
- H01 = ?
- H02 = ?
- H03 = ?
- H04 = ?