This repository has been archived by the owner on Aug 18, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [lab03] Add starter code * Add venus * [lab03] Initial draft of calling convention exercise * [lab03] Export functions so CC checker checks them * [lab03] Update FIXME comments * [lab03] add missing ex2.c * Bump venus again * Bump venus again * [lab03] Fix prologue/epilogue typo * [lab03] Fix ex2 exit
- Loading branch information
Showing
7 changed files
with
437 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
.globl simple_fn naive_pow inc_arr | ||
|
||
.data | ||
failure_message: .asciiz "Test failed for some reason.\n" | ||
success_message: .asciiz "Sanity checks passed! Make sure there are no CC violations.\n" | ||
array: | ||
.word 1 2 3 4 5 | ||
exp_inc_array_result: | ||
.word 2 3 4 5 6 | ||
|
||
.text | ||
main: | ||
# We test our program by loading a bunch of random values | ||
# into a few saved registers - if any of these are modified | ||
# after these functions return, then we know calling | ||
# convention was broken by one of these functions | ||
li s0, 2623 | ||
li s1, 2910 | ||
# ... skipping middle registers so the file isn't too long | ||
# If we wanted to be rigorous, we would add checks for | ||
# s2-s20 as well | ||
li s11, 134 | ||
# Now, we call some functions | ||
# simple_fn: should return 1 | ||
jal simple_fn # Shorthand for "jal ra, simple_fn" | ||
li t0, 1 | ||
bne a0, t0, failure | ||
# naive_pow: should return 2 ** 7 = 128 | ||
li a0, 2 | ||
li a1, 7 | ||
jal naive_pow | ||
li t0, 128 | ||
bne a0, t0, failure | ||
# inc_arr: increments "array" in place | ||
la a0, array | ||
li a1, 5 | ||
jal inc_arr | ||
jal check_arr # Verifies inc_arr and jumps to "failure" on failure | ||
# Check the values in the saved registers for sanity | ||
li t0, 2623 | ||
li t1, 2910 | ||
li t2, 134 | ||
bne s0, t0, failure | ||
bne s1, t1, failure | ||
bne s11, t2, failure | ||
# If none of those branches were hit, print a message and exit normally | ||
li a0, 4 | ||
la a1, success_message | ||
ecall | ||
li a0, 10 | ||
ecall | ||
|
||
# Just a simple function. Returns 1. | ||
# | ||
# FIXME Fix the reported error in this function (you can delete lines | ||
# if necessary, as long as the function still returns 1 in a0). | ||
simple_fn: | ||
mv a0, t0 | ||
li a0, 1 | ||
ret | ||
|
||
# Computes a0 to the power of a1. | ||
# This is analogous to the following C pseudocode: | ||
# | ||
# uint32_t naive_pow(uint32_t a0, uint32_t a1) { | ||
# uint32_t s0 = 1; | ||
# while (a1 != 0) { | ||
# s0 *= a0; | ||
# a1 -= 1; | ||
# } | ||
# return s0; | ||
# } | ||
# | ||
# FIXME There's a CC error with this function! | ||
# The big all-caps comments should give you a hint about what's | ||
# missing. Another hint: what does the "s" in "s0" stand for? | ||
naive_pow: | ||
# BEGIN PROLOGUE | ||
# END PROLOGUE | ||
li s0, 1 | ||
naive_pow_loop: | ||
beq a1, zero, naive_pow_end | ||
mul s0, s0, a0 | ||
addi a1, a1, -1 | ||
j naive_pow_loop | ||
naive_pow_end: | ||
mv a0, s0 | ||
# BEGIN EPILOGUE | ||
# END EPILOGUE | ||
ret | ||
|
||
# Increments the elements of an array in-place. | ||
# a0 holds the address of the start of the array, and a1 holds | ||
# the number of elements it contains. | ||
# | ||
# This function calls the "helper_fn" function, which takes in an | ||
# address as argument and increments the 32-bit value stored there. | ||
inc_arr: | ||
# BEGIN PROLOGUE | ||
# | ||
# FIXME What other registers need to be saved? | ||
# | ||
addi sp, sp, -4 | ||
sw ra, 0(sp) | ||
# END PROLOGUE | ||
mv s0, a0 # Copy start of array to saved register | ||
mv s1, a1 # Copy length of array to saved register | ||
li t0, 0 # Initialize counter to 0 | ||
inc_arr_loop: | ||
beq t0, s1, inc_arr_end | ||
slli t1, t0, 2 # Convert array index to byte offset | ||
add a0, s0, t1 # Add offset to start of array | ||
# Prepare to call helper_fn | ||
# | ||
# FIXME Add code to preserve the value in t0 before we call helper_fn | ||
# Hint: What does the "t" in "t0" stand for? | ||
# Also ask yourself this: why don't we need to preserve t1? | ||
# | ||
jal helper_fn | ||
# Finished call for helper_fn | ||
addi t0, t0, 1 # Increment counter | ||
j inc_arr_loop | ||
inc_arr_end: | ||
# BEGIN EPILOGUE | ||
lw ra, 0(sp) | ||
addi sp, sp, 4 | ||
# END EPILOGUE | ||
ret | ||
|
||
# This helper function adds 1 to the value at the memory address in a0. | ||
# It doesn't return anything. | ||
# C pseudocode for what it does: "*a0 = *a0 + 1" | ||
# | ||
# FIXME This function also violates calling convention, but it might not | ||
# be reported by the Venus CC checker (try and figure out why). | ||
# You should fix the bug anyway by filling in the prologue and epilogue | ||
# as appropriate. | ||
helper_fn: | ||
# BEGIN PROLOGUE | ||
# END PROLOGUE | ||
lw t1, 0(a0) | ||
addi s0, t1, 1 | ||
sw s0, 0(a0) | ||
# BEGIN EPILOGUE | ||
# END EPILOGUE | ||
ret | ||
|
||
# YOU CAN IGNORE EVERYTHING BELOW THIS COMMENT | ||
|
||
# Checks the result of inc_arr, which should contain 2 3 4 5 6 after | ||
# one call. | ||
# You can safely ignore this function; it has no errors. | ||
check_arr: | ||
la t0, exp_inc_array_result | ||
la t1, array | ||
addi t2, t1, 20 # Last element is 5*4 bytes off | ||
check_arr_loop: | ||
beq t1, t2, check_arr_end | ||
lw t3, 0(t0) | ||
lw t4, 0(t1) | ||
bne t3, t4, failure | ||
addi t0, t0, 4 | ||
addi t1, t1, 4 | ||
j check_arr_loop | ||
check_arr_end: | ||
ret | ||
|
||
|
||
# This isn't really a function - it just prints a message, then | ||
# terminates the program on failure. Think of it like an exception. | ||
failure: | ||
li a0, 4 # String print ecall | ||
la a1, failure_message | ||
ecall | ||
li a0, 10 # Exit ecall | ||
ecall | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
.data | ||
.word 2, 4, 6, 8 | ||
n: .word 9 | ||
|
||
.text | ||
main: | ||
add t0, x0, x0 | ||
addi t1, x0, 1 | ||
la t3, n | ||
lw t3, 0(t3) | ||
fib: | ||
beq t3, x0, finish | ||
add t2, t1, t0 | ||
mv t0, t1 | ||
mv t1, t2 | ||
addi t3, t3, -1 | ||
j fib | ||
finish: | ||
addi a0, x0, 1 | ||
addi a1, t0, 0 | ||
ecall # print integer ecall | ||
addi a0, x0, 10 | ||
ecall # terminate ecall |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
int source[] = {3, 1, 4, 1, 5, 9, 0}; | ||
int dest[10]; | ||
|
||
int fun(int x) { | ||
return -x * (x + 1); | ||
} | ||
|
||
int main() { | ||
int k; | ||
int sum = 0; | ||
for (k = 0; source[k] != 0; k++) { | ||
dest[k] = fun(source[k]); | ||
sum += dest[k]; | ||
} | ||
return sum; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
.globl main | ||
|
||
.data | ||
source: | ||
.word 3 | ||
.word 1 | ||
.word 4 | ||
.word 1 | ||
.word 5 | ||
.word 9 | ||
.word 0 | ||
dest: | ||
.word 0 | ||
.word 0 | ||
.word 0 | ||
.word 0 | ||
.word 0 | ||
.word 0 | ||
.word 0 | ||
.word 0 | ||
.word 0 | ||
.word 0 | ||
|
||
.text | ||
fun: | ||
addi t0, a0, 1 | ||
sub t1, x0, a0 | ||
mul a0, t0, t1 | ||
jr ra | ||
|
||
main: | ||
# BEGIN PROLOGUE | ||
addi sp, sp, -16 | ||
sw s0, 0(sp) | ||
sw s1, 4(sp) | ||
sw s2, 4(sp) | ||
sw ra, 8(sp) | ||
# END PROLOGUE | ||
addi t0, x0, 0 | ||
addi s0, x0, 0 | ||
la s1, source | ||
la s2, dest | ||
loop: | ||
slli s3, t0, 2 | ||
add t1, s1, s3 | ||
lw t2, 0(t1) | ||
beq t2, x0, exit | ||
add a0, x0, t2 | ||
addi sp, sp, -8 | ||
sw t0, 0(sp) | ||
sw t2, 4(sp) | ||
jal fun | ||
lw t0, 0(sp) | ||
lw t2, 4(sp) | ||
addi sp, sp, 8 | ||
add t2, x0, a0 | ||
add t3, s2, s3 | ||
sw t2, 0(t3) | ||
add s0, s0, t2 | ||
addi t0, t0, 1 | ||
jal x0, loop | ||
exit: | ||
add a0, x0, s0 | ||
# BEGIN EPILOGUE | ||
lw s0, 0(sp) | ||
lw s1, 4(sp) | ||
lw s2, 4(sp) | ||
lw ra, 8(sp) | ||
addi sp, sp, 16 | ||
# END EPILOGUE | ||
jr ra |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
.globl factorial | ||
|
||
.data | ||
n: .word 8 | ||
|
||
.text | ||
main: | ||
la t0, n | ||
lw a0, 0(t0) | ||
jal ra, factorial | ||
|
||
addi a1, a0, 0 | ||
addi a0, x0, 1 | ||
ecall # Print Result | ||
|
||
addi a1, x0, '\n' | ||
addi a0, x0, 11 | ||
ecall # Print newline | ||
|
||
addi a0, x0, 10 | ||
ecall # Exit | ||
|
||
factorial: | ||
# YOUR CODE HERE |
Oops, something went wrong.