-
Notifications
You must be signed in to change notification settings - Fork 0
/
lab5aYuvan.asm
221 lines (181 loc) · 5.63 KB
/
lab5aYuvan.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# Lab 5a CS 10
# Program by Yuvan Sharma
# multiplies two 4x4 matrices and prints the result
# This version of lab 5 has the inner loop of matrix multiply unrolled once.
# It uses the same number of registers as the rolled original version since
# I reused the same registers, but it is longer since it has the same segment
# of code written twice instead of once. Conceptually it is almost the same
# as this rolled version since it uses the loop twice and the original version uses
# the loop four times. However, its execution time will be very slightly faster
# because of the reduction in the loop overhead.
.data
.align 2
prompt: .asciiz "Enter Row "
.align 2
prompt2: .asciiz " : "
newline: .asciiz "\n"
space: .asciiz " "
.align 2
prompt3: .asciiz "Row "
.align 2
M: .space 64 # 4x4 integer array #1
.align 2
N: .space 64 # 4x4 integer array #2
.align 2
result: .space 64 # 4x4 integer array to store multiplication result
.align 2
input: .space 8
.align 2
inputsize: .word 8
mask: .word 15 # 15 is the mask to convert char digits to int
.text
# get first matrix
li $t0, 0 # counter for loop
li $t1, 1
lw $t6, mask
la $t4, M #address counter for M(+4 each time)
jal getmatriceloop
la $a0, newline
li $v0, 4
syscall
# get second matrix
li $t0, 0 # counter for loop
li $t1, 1
lw $t6, mask
la $t4, N
jal getmatriceloop
la $a1, result
la $a2, M
la $a3, N
jal matrixmultiply
la $a0, newline
li $v0, 4
syscall
li $t0, 1
la $t1, result
jal printloop
j exit # exit the program
exit:
li $v0, 10
syscall #exit the program
getrow:
li $v0, 4
la $a0, prompt
syscall
li $v0, 1
la $a0, ($t1)
syscall
li $v0, 4
la $a0, prompt2
syscall
li $v0, 8
la $a0, input
la $t2, inputsize
lw $a1, 0($t2)
syscall
li $v0, 4
la $a0, newline
syscall
jr $ra
fillrow:
lbu $a0, ($t3)
and $a0, $a0, $t6 #convert to ascii by masking with 0000 1111 (decimal number 15) which is stored in $t6
sw $a0, ($t4)
addi $t5, $t5, 1
addi $t3, $t3, 2
addi $t4, $t4, 4
li $t9, 4
bne $t5, $t9, fillrow
jr $ra
getmatriceloop:
addi $sp, $sp, -4
sw $ra, 0($sp)
insideloop:
jal getrow
la $t3, input #address counter for input (+2 each time, since each char is a byte and we need to skip the spaces)
li $t5, 0 # counter for fillrow loop
jal fillrow
addi $t0, $t0, 1
addi $t1, $t1, 1
li $t9, 4
bne $t0, $t9, insideloop
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
matrixmultiply:
addi $t0, $zero, 4 # $t0 holds the number of elements in each row
addi $t1, $zero, 0 # counter for first loop
L1:
addi $t2, $zero, 0 # counter for second loop
L2:
addi $t3, $zero, 0 # counter for third loop
sll $t4, $t1, 2 # multiply first counter by 4 to "skip" that many rows
add $t4, $t4, $t2 # add the second counter value to select the required element in the row
sll $t4, $t4, 2 # multiply our index by 4 to transform it into a byte index, since one int = 4 bytes
add $t4, $a1, $t4 # add the byte index to address of the result array, to tranform t4 into address of result[][] element
lw $s0, 0($t4)
L3: # loop unrolled once
sll $t5, $t3, 2 # multiply counter for third loop by 4 to skip that many rows
add $t5, $t5, $t2 # add second counter value to select the required element in the row
sll $t5, $t5, 2 # multiply index by 4 to transform into byte index, since one int = 4 bytes
add $t5, $a3, $t5 # add byte index to address of N array, to transform $t5 to address of N[][] element
lw $s1, 0($t5)
sll $t5, $t1, 2 # multiply counter of first loop by 4 to skip that many rows
add $t5, $t5, $t3 # add third counter value to select the required element in the row
sll $t5, $t5, 2 # multiply index by 4 to transform into byte index, since one int = 4 bytes
add $t5, $a2, $t5 # add byte index to address of M array, to transform $t5 to address of M[][] element
lw $s2, 0($t5)
# s0 has result element, s1 has N element, s2 has M element
mul $s1, $s2, $s1
add $s0, $s0, $s1
addi $t3, $t3, 1
sll $t5, $t3, 2 # multiply counter for third loop by 4 to skip that many rows
add $t5, $t5, $t2 # add second counter value to select the required element in the row
sll $t5, $t5, 2 # multiply index by 4 to transform into byte index, since one int = 4 bytes
add $t5, $a3, $t5 # add byte index to address of N array, to transform $t5 to address of N[][] element
lw $s1, 0($t5)
sll $t5, $t1, 2 # multiply counter of first loop by 4 to skip that many rows
add $t5, $t5, $t3 # add second counter value to select the required element in the row
sll $t5, $t5, 2 # multiply index by 4 to transform into byte index, since one int = 4 bytes
add $t5, $a2, $t5 # add byte index to address of M array, to transform $t5 to address of M[][] element
lw $s2, 0($t5)
# s0 has result element, s1 has N element, s2 has M element
mul $s1, $s1, $s2
add $s0, $s0, $s1
addi $t3, $t3, 1 # increment 3rd loop counter by 1
bltu $t3, $t0, L3 # if 3rd loop counter < 4, repeat addition
sw $s0, 0($t4) # otherwise store the computed value in the appropriate element
addi $t2, $t2, 1
bltu $t2, $t0, L2
addi $t1, $t1, 1
bltu $t1, $t0, L1
jr $ra
printloop:
la $a0, prompt3 # prompt3 = "Row "
li $v0, 4
syscall
addi $a0, $t0, 0 # to print row number
li $v0, 1
syscall
la $a0, prompt2 # prompt2 = ": "
li $v0, 4
syscall
li $t2, 1 # counter for printloop2
printloop2:
li $v0, 1 # print element
lw $a0, 0($t1)
syscall
li $v0, 4 # print space
la $a0, space
syscall
addi $t2, $t2, 1
addi $t1, $t1, 4
li $t9, 5
bne $t2, $t9, printloop2
la $a0, newline # go to next line
li $v0, 4
syscall
addi $t0, $t0, 1
li $t9, 5
bne $t0, $t9, printloop
jr $ra