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;
}
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;
}
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; }