andrewt0301 / hse-acos-course

Materials for the "Computer Architecture and Operating Systems" course taught at Faculty of Computer Science of Higher School of Economics
https://andrewt0301.github.io/hse-acos-course/
Apache License 2.0
32 stars 27 forks source link

Final Test Issue #15

Open andrewt0301 opened 2 years ago

andrewt0301 commented 2 years ago

Notes on Final Test Programming Task

Task

The programming task as specified here:

Write a RISC-V assembly program that inputs integer value x (assumed non-negative) and calculates the value of the f(x) mathematical function according to the specified equations. f(x) must be implemented as a function and must comply with RISC-V calling conventions.

The implemented function must use callee-saved registers (s0, s1, etc.) to store intermediate results of calculations. These registers must be saved to the stack and restored when the function returns.

Variant

Group 202, variant 7. Taken from here:

f(x) = 6 * x**5 + 4 * x**3 - 5 * x**2 + 7 * x if x < 5
f(x) = 4 if x >= 5
f(x) = 7**x + -2 if x == 6
f(x) = -1 * x + 10 if x > 9

This task means to create a RISC-V assembly program that does the same as this Python program:

def f(x):
    if x < 5:
        return 6 * x ** 5 + 4 * x ** 3 - 5 * x ** 2 + 7 * x
    if x > 9:
        return -1 * x + 10
    if x == 6:
        return 7 ** x + -2
    return 4  # if x >= 5

x = int(input())
print(f(x))

Expected results:

x = 1
f(x) = 12

x = 5
f(x) = 4

x = 6
f(x) = 117647

x = 7
f(x) = 4

x = 11
f(x) = -1

Solution

#попытка  f(x) = 6 * x**5 + 4 * x**3 - 5 * x**2 + 7 * x if x < 5
.text
li a7, 5 
ecall
mv t0, a0  

addi t1, zero, 6 
addi t2, zero, 4
addi t3, zero, 5
addi t4, zero, zero

    j compare
loop:
    mul t0, t0, t0
    addi t4, zero, 1
compare:
    blt t4, t2 loop

bge t0, t3, endif
mv a0, t4
li a7, 1
ecall 
endif:

# f(x) = 4 if x >= 5
.text
li a7, 5 
ecall
mv t0, a0  

addi t1, zero, 5
addi t2, zero, 4

blt t0, t1, endif
mv a0, t2
li a7, 1
ecall 
endif:

# f(x) = 7**x + -2 if x == 6
.text
li a7, 5 
ecall
mv t0, a0  

addi t1, zero, 7 
addi t2, zero, 2
addi t3, zero, 6

mul t4, t0, t0
mul t4, t4, t1
sub t4, t4, t2

bne t0, t3, endif
mv a0, t4
li a7, 1
ecall 
endif:

#  f(x) = -1 * x + 10 if x > 9
.text
li a7, 5 
ecall
mv t0, a0  

addi t1, zero, 9 
addi t2, zero, -1
mul t3, t0, t2
addi t3, t3, 10

bge t1, t0, endif
mv a0, t3
li a7, 1
ecall 
endif:

Notes

  1. There is no f(x) function: -2
  2. Callee-saved registers are not saved/loaded to stack: -1
  3. There are 4 programs:
    • f(x) = 6 * x**5 + 4 * x**3 - 5 * x**2 + 7 * x if x < 5 - does not work, -2
    • f(x) = 4 if x >= 5 - OK
    • f(x) = 7**x + -2 if x == 6 - wrong, 250 vs. 117647, -2
    • f(x) = -1 * x + 10 if x > 9 - OK

Result

10 - 2 - 1 - 2 - 2 = 3

andrewt0301 commented 2 years ago

Group 201, variant 12. Taken from here:

f(x) = 4 if x < 5
f(x) = 7 * x + 2 if x >= 5
f(x) = 2 * x**8 - 2 * x**4 + 3 * x**2 + 7 * x if x == 6
f(x) = -10**x + 9 if x > 9
#f(x) = 4 if x < 5
fx:
    li a7, 5
    ecall
    mv s1, a0
    addi t0, t0, 5
    blt s1, t0, f_1
f_1:
    addi t1, t1, 4
    mv s1, t1
    mv a0, s1
    li a7, 1
    ecall

#f(x) = 7 * x + 2 if x >= 5
fx:
    li a7, 5
    ecall
    mv s1, a0
    addi t0, t0, 5
    bge s1, t0, f_2

f_2:
    addi t1, t1, 2
    addi t2, t2, 7
    mul s1, s1, t2
    add s1, s1, t1
    mv a0, s1
    li a7, 1
    ecall

Notes

  1. There is no common f(x) function that would handle all cases. Instead, there are two separate programs that do not compile together.
  2. Callee-saved registers are not saved/loaded to stack.
  3. There are 4 cases:
    • f(x) = 4 if x < 5 - incorrect, always prints 4 (even when x is 10)
    • f(x) = 7 * x + 2 if x >= 5 - partially icorrect, calculates result even if x < 5 (e.g. {x=10, result=72} - correct, {x=1, result=9} - incorrect)
    • f(x) = 2 * x**8 - 2 * x**4 + 3 * x**2 + 7 * x if x == 6 - missing
    • f(x) = -10**x + 9 if x > 9 - missing