Skip to content

Instantly share code, notes, and snippets.

@aji
Created November 7, 2012 11:15
Show Gist options
  • Save aji/4030908 to your computer and use it in GitHub Desktop.
Save aji/4030908 to your computer and use it in GitHub Desktop.
; 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