Created
November 7, 2012 11:15
-
-
Save aji/4030908 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
; Alex Iadicicco | |
; CSE 230 Project 3 | |
.data | |
matA: .word 3,4,6,8,0,1,1,2,8,7,9,4,5,2 | |
matB: .word 4,2,3,2,4,7,3,6,5,1 | |
matC: .word 0,0,0,0,0,0,0,0 | |
.text | |
la $a0, matA ; load addresses of matrices | |
la $a1, matB | |
la $a2, matC | |
jal MATMUL ; multiply them | |
addi $v0, $zero, 10 ; exit | |
syscall | |
; Performs matrix multiplication, $a2 = $a0 x $a1 | |
MATMUL: | |
; First we store our arguments, $ra, and $s0-4 on the stack | |
addi $sp, $sp, -36 | |
sw $a0, 0($sp) | |
sw $a1, 4($sp) | |
sw $a2, 8($sp) | |
sw $ra, 12($sp) | |
sw $s0, 16($sp) | |
sw $s1, 20($sp) | |
sw $s2, 24($sp) | |
sw $s3, 28($sp) | |
sw $s4, 32($sp) | |
; The ; of rows from the first matrix and ; of columns from the second | |
; become the ; of rows and columns in the resultant matrix | |
lw $t0, 0($a0) ; rows from first matrix | |
lw $t1, 4($a1) ; cols from second matrix | |
sw $t0, 0($a2) ; -> rows in resultant | |
sw $t1, 4($a2) ; -> cols in resultant | |
; Transpose the second matrix so we can get at its columns as rows | |
lw $a0, 4($sp) | |
jal TRANSPOSE | |
; Now we perform the actual multiplication, which is just a series of | |
; dot products | |
; $s0 = row counter of first matrix | |
; $s1 = row counter of second matrix (transposed cols) | |
; $s2 = product pointer | |
; $s3 = size of row in first matrix | |
; $s4 = size of row in second matrix | |
lw $s2, 8($sp) ; load result argument | |
addi $s2, $s2, 8 ; skip dimensions | |
lw $t0, 0($sp) ; load addr of first matrix | |
lw $s3, 4($t0) ; load cols in first matrix | |
lw $t0, 4($sp) ; load addr of second matrix | |
lw $s4, 4($t0) ; load cols in second matrix | |
; Outer loop, iterates rows of A | |
addi $s0, $zero, 0 ; clear row counter of A | |
ML1: lw $t0, 0($sp) | |
lw $t0, 0($t0) ; load number of rows in A | |
beq $s0, $t0, ML1OUT ; exit if done here | |
addi $s1, $zero, 0 ; clear row counter of B | |
ML2: lw $t0, 4($sp) | |
lw $t0, 0($t0) ; load number of rows in B | |
beq $s1, $t0, ML2OUT ; exit if done here | |
lw $a0, 0($sp) ; calculate start of A row | |
addi $a0, $a0, 8 | |
mul $t0, $s0, $s3 | |
sll $t0, $t0, 2 | |
add $a0, $a0, $t0 | |
lw $a1, 4($sp) ; calculate start of B row | |
addi $a1, $a1, 8 | |
mul $t0, $s1, $s4 | |
sll $t0, $t0, 2 | |
add $a1, $a1, $t0 | |
lw $a2, 0($sp) ; load row length | |
lw $a2, 4($a2) | |
jal DOT_PRODUCT ; calculate dot product | |
sw $v0, 0($s2) ; store dot product in result | |
addi $s2, $s2, 4 ; increment result pointer | |
addi $s1, $s1, 1 ; increment B row counter | |
j ML2 | |
ML2OUT: | |
addi $s0, $s0, 1 ; increment A row counter | |
j ML1 | |
ML1OUT: | |
; Finally, un-transpose B, restore stack and $ra, and leave | |
lw $a0, 4($sp) ; un-transpose B | |
jal TRANSPOSE | |
lw $ra, 12($sp) ; get back $ra | |
lw $s0, 16($sp) | |
lw $s1, 20($sp) | |
lw $s2, 24($sp) | |
lw $s3, 28($sp) | |
lw $s4, 32($sp) | |
addi $sp, $sp, 36 ; restore stack | |
jr $ra ; adios! | |
; This DOT_PRODUCT code has been copied out of Task 1 with | |
; extra comments and spaces removed to reduce verbosity | |
DOT_PRODUCT: | |
add $t0, $zero, $a0 ; start at start of P | |
add $t1, $zero, $a1 ; start at start of Q | |
addi $t2, $zero, 0 ; start counter at zero | |
addi $v0, $zero, 0 ; start result at zero | |
DPL: beq $t2, $a2, DPLOUT ; test counter equals vector length | |
lw $t3, 0($t0) ; load in words | |
lw $t4, 0($t1) | |
mul $t3, $t3, $t4 ; multiply words together | |
add $v0, $v0, $t3 ; add to result | |
addi $t0, $t0, 4 ; increment P pointer one | |
addi $t1, $t1, 4 ; increment Q pointer one | |
addi $t2, $t2, 1 ; increment counter | |
j DPL ; jump back to condition | |
DPLOUT: jr $ra | |
; This TRANSPOSE code has been copied out of Task 2 with | |
; extra comments and spaces removed to reduce verbosity | |
TRANSPOSE: | |
lw $t0, 0($a0) ; obtain rows | |
lw $t1, 4($a0) ; and columns | |
mul $t6, $t0, $t1 ; calculate total length | |
sll $t6, $t6, 2 | |
sll $t0, $t0, 2 | |
sll $t1, $t1, 2 | |
addi $t2, $a0, 8 ; get read base | |
sub $sp, $sp, $t6 ; allocate space on stack for new array | |
add $t3, $zero, $sp ; set write pointer | |
addi $t5, $zero, 0 ; clear col counter | |
TL1: beq $t1, $t5, TL1OUT ; leave loop if all columns done | |
add $t7, $t2, $t5 ; start up read counter | |
addi $t4, $zero, 0 ; clear row counter | |
TL2: beq $t0, $t4, TL2OUT ; leave loop if all rows done | |
lw $t8, 0($t7) ; copy value | |
sw $t8, 0($t3) | |
add $t7, $t7, $t1 ; advance read pointer | |
addi $t3, $t3, 4 ; advance write pointer | |
addi $t4, $t4, 4 ; increment row counter | |
j TL2 | |
TL2OUT: addi $t5, $t5, 4 ; increment column counter | |
j TL1 | |
TL1OUT: addi $t4, $zero, 0 ; reset word counter | |
TL3: beq $t4, $t6, TL3OUT ; leave loop if done copying bytes | |
lw $t8, 0($sp) ; copy value | |
sw $t8, 0($t2) | |
addi $sp, $sp, 4 ; davance read pointer | |
addi $t2, $t2, 4 ; advance write pointer | |
addi $t4, $t4, 4 ; increment byte counter | |
j TL3 | |
TL3OUT: srl $t0, $t0, 2 | |
srl $t1, $t1, 2 | |
sw $t0, 4($a0) ; store rows as columns | |
sw $t1, 0($a0) ; and columns as rows | |
jr $ra |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment