MIPS 32 examples

Example 1 — multi-dimenstional arrays

Multi-dimensional C

extern int twoD[5][5] ;

void diagonalCopy(int oneD[], int i) {
    twoD[i][i] = oneD[i] ;
}

Multi-dimensional MIPS32

diagonalCopy:
         sll     $t3,$a1,2        # i*4
         add     $t6,$t3,$a0      # $t6 = &A[i]
         sll     $t3,$a1,3        # i * 8
         sll     $t4,$a1,4        # i * 16
         add     $t3,$t4,$t3      # i * 24
         la      $t0,twoD         # $t0 = twoD
         lw      $t2,0($t6)       # $t2 = A[i]
         add     $t7,$t0,$t3      # $t7 = &twoD[i][i]
         sw      $t2,0($t7)       # twoD[i][i]=A[i]
         jr      $ra
         nop

Example 2 — Array iteration

Iteration in C

/* normal */
int positiveAdditude(int V[], int n) {
    int sum = 0 ;
    for (int i=0; i<n; ++i) {
        if (V[i] > 0) {
            sum = sum + V[i] ;
        }
    }
    return sum;
}

Iteration in MIPS

	addi	$v0,$zero,0	    # $v0 is sum
        addi    $t0,$zero,0         # $t0 is i
        j       loopTest
loopStart:
        sll     $t4,$t0,2           # $t4 is offset
	add     $t3,$a0,$t4         # $t3 is address of V[i]
	lw      $t2,0($t3)          # $t2 is V[i]
        slt     $t1,$zero,$t2       # $t2 is 0 < V[0]
	beq     $t1,$zero,incrSkip
	nop                         # Can move ++t0 to here
        add     $v0,$v0,$t2
incrSkip:
        addi    $t0,$t0,1
loopTest:
        slt     $t5,$t0,$a1
	bne     $t5,$zero,loopStart
	nop                         # can move sll to here
        jr      $ra
        nop

Example 3 — Array iteration with pointers

Pointer arithmetic in C

/* pointer */
int positiveAdditude(const int V[], int n) {
    int *Vstart = &V[0] ;
    int *Vend = &V[n] ;
    int sum = 0 ;
    for (int *p=Vstart; p<Vend; ++p) {
        if (*p > 0) {
            sum = sum + *p ;
        }
    }
    return sum;
}

Pointer arithemetic in MIPS32

	addi	$v0,$zero,0	    # $v0 is sum
                                    # $a0 is p       (&V[0])
        sll     $t0,$a1,2
        add     $t0,$a0,$t0         # $t0 is Vend    (&V[n])
        j       loopTest
loopStart:
	lw      $t2,0($t0)          # $t2 is *p
        slt     $t1,$zero,$t2       # $t1 is 0 < *p
	beq     $t1,$zero,incrSum
        nop
        addi    $v0,$v0,$t2         # sum = sum + *p
incrSum:
        addi    $t0,$t0,4           # ++p
loopTest:
        slt     $t5,$a0,$t0         # $t1 is Vstart < Vend
	bne     $t5,$zero,loopStart
	nop
        jr      $ra
        nop

MIPS32 assembly using delay slot

	addi	$v0,$zero,0	    # $v0 is sum
                                    # $a0 is p       (&V[0])
        sll     $t0,$a1,2
        add     $t0,$a0,$t0         # $t0 is Vend    (&V[n])
        j       loopTest
loopStart:
        slt     $t1,$zero,$t2       # $t1 is 0 < *p
	beq     $t1,$zero,incrSum
        addi    $t0,$t0,4           # ++p in delay slot
        addi    $v0,$v0,$t2         # sum = sum + *p
incrSum:
loopTest:
        slt     $t5,$a0,$t0         # $t1 is Vstart < Vend
	bne     $t5,$zero,loopStart
	lw      $t2,0($t0)          # $t2 is *p (in delay slot)
        jr      $ra
        nop

Example 4 — Loop unrolling

/* pointer */
int positiveAdditude(const int V[], int n) {
    if (n<=0) {
        return 0 ;
    }
    int sum = 0 ;
    int *Vpos = &V[0] ;
    int *Vend = &V[n] ;
    if (n&1) {
        vSum = *Vpos ;
        ++Vpos ;
    }
    while (; Vpos!=Vend; Vpos+=2) {
        int V0 = Vpos[0] ;
        int V1 = Vpos[1] ;
        if (V1 > 0) {
            sum = sum + V1 ;
        }
        if (V2 > 0) {
            sum = sum + V2 ;
        }
    }
    return sum;
}