How to make my MIPS program more register efficient and readable

1

This is the C++ code I am trying to convert to MIPS with

  int count_painted(int *wall, int width, int radius, int coord) {
  int row = (coord & 0xffff0000) >> 16;
  int col = coord & 0x0000ffff;
  int value = 0;
  for (int row_offset = -radius; row_offset <= radius; row_offset++) {
    int temp_row = row + row_offset;
    if (width <= temp_row || temp_row < 0) {
      continue;
    }
    for (int col_offset = -radius; col_offset <= radius; col_offset++) {
      int temp_col = col + col_offset;
      if (width <= temp_col || temp_col < 0) {
        continue;
      }
      value += wall[temp_row*width + temp_col];
    }
  }
  return value;
}

and this is my code I wrote below. I want to know how to make sure my program is accurate, readable and efficient with usage of registers.

.globl count_painted
count_paint:
#think about moving variables initialized inside to within the for loop

    #initializes all variables

    li $v0, 0                                               # int value = 0

    li $t0, 0                                               # int row = 0
    li $t1, 0                                               # int col = 0
    li $t2, 0                                               # int i = 0
    li $t3, 0                                               # int row _offset = 0
    li $t4, -1                                              # negative one to multiply with row_offset
    li $t5, 0                                               # int temp_row = 0
    li $t6, 0                                               # int col_offset = 0
    li $t7, 0                                               # int temp_col = 0

    andi $t0, $a3, 0xffff0000
    srl $t0, $t0, 16                                                    # now int row = (coord & 0xffff0000) >> 16 (double check this...prob need a temp register to store before modifying both)

    andi $t1, $a3, 0x0000ffff                               # now int col = coord & 0x0000ffff

    mul $t3 , $a2, $t4.                                             # row_offsett = -1 *  radius
    mul $t6 , $a2, $t4.                                             # col_offsett = -1 *  radius

#for loop 1
count_paint_for_loop_one:
    bgt $t3, $a2, count_painted_end                     # if row_offset > radius (bgt since it can only be greater)
    add $t5, $t0, $t3                                               # int temp_row = row + row_offset;


    sle $t9, $a1, $t5 # returns 1 if width <= temp_row is true
    slt $s2, $t5, 0   # returns 1 if temp_row < 0 is true

    or $t9, $t9, $s2 # or the result of the 2 if statment functions

    bgt $t9, 0, count_paint_for_loop_one_iterator #if 1 > 0 then condition is true and we iterate and then loop

    j count_paint_for_loop_two

    #iterator
    add $t3, $t3, 1                                                     # adds 1 to row_offset i.e iterates for loop

    #dont forget to do the ++ for all iterators
count_paint_for_loop_two:
    bgt $t6, $a2, count_paint_for_loop_one                  # if col_offset > radius (bgt since it can only be greater)
    add $t7, $t1, $t6                                                           # int temp_col = col + col_offset;


    sle $s3, $a1, $t7 # returns 1 if width <= temp_colis true
    slt $s4, $t7, 0   # returns 1 if temp_col < 0 is true

    or $s3, $s3, $s4 # or the result of the 2 if statment functions

    bgt $s3, 0, count_paint_for_loop_two_iterator #if 1 > 0 then condition is true and we iterate and then loop

    #bgt $a1 $t7, count_paint_for_loop_one                      #if statement with or inside (for loop 2)
    #bge $t7, 0, count_paint_for_loop_one


    #
    mul $t8, $t5, $a1                                                               # multiplies temp_row and width and stores in $t8
    add $t8, $t8, $t7                                                               # adds the product of temp_row and width and adds it to temp_col and stores it in temp register $t9
    #t8 is index for wall array

    #ran out of temp registers use saved registers
    sll $s0, $t8, 2
    add $s0, $a0, $s0
    lw $s1, 0($s0)                                              # $s1 contains wall[temp_row*width + temp_col]


    add $v0, $v0, $s1

    add $t6. $t6, 1                                                             # adds 1 to col_offset i.e iterates for loop
    j count_paint_for_loop_two                                          # restarts inner for loop
count_paint_for_loop_one_iterator:
    add $t3, $t3, 1     #iterate through loop
    j count_paint_for_loop_one

count_paint_for_loop_two_iterator:
    add $t6, $t6, 1     #iterate through loop
    j count_paint_for_loop_two
count_painted_end:
    jr  $ra                                                                                 # returns value

I use up all the t registers and I was forced to use s registers to store temp variables and I was hoping to learn a more useful method of writing my MIPS code

c++
performance
assembly
mips
cpu-registers
asked on Stack Overflow Oct 6, 2019 by air bmx

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0