assemblymips64

(mips64) lw and sw not adding value to registers


I am new to mips and for a homework project we have to convert a C code into mips64 assembly and run it with winmips64. The C code is this:

void fir(int X[], int H[], int Y[], int n, int m)
{
    int i, j;
    int y0;

    for (j=0; j<m; j++){
        y0=0;
        for (i=0; i<n; i++){
            y0+=X[i+j]*H[i];
        }
        Y[j]=y0;
    }
}

The lines I am having a problem with are y0+=X[i+j]*H[i] and Y[j]=y0, this is my attempt at doing them:

for2:
    beq r7,r3, afterfor2                        # for(i=0, i<n, i++)

    #making X[i+j]
    dadd r8,r5,r7                               # i+j stored in r8
    dmul r9,r8,r18                              #(i+j)*8 to find address stored in r8r9
    lw r10, r9(r0)                               #load x[i+j] to r10

    #making H[i]
    dmul r11,r18,r7                             # 8*i
    lw r12,r11(r1)                              #load h[i] to r12

    dmul r13,r10,r12                            #x[i+j] * h[i]
    dadd r6,r6,r13                              #y0 = y0 + x[i+j]*h[i]
    daddi r7,r7,1                               # i++
    j for2                                      # repeat loop

afterfor2: 
        
    dmul r14,r5,r18                             #8*j stored to r14
    sw r6, r14(r2)                              #Y[j] = y0
    daddi r5,r5,1                               #j++
    
    j for1                                      #go back to start of loop for1

More specifically these lines because no values are added to registers r10,r6, and r12:

lw r10, r9(r0)                               #load x[i+j] to r10
lw r12,r11(r1)                               #load h[i] to r12
sw r6, r14(r2)                               #Y[j] = y0

The winmips64 documentation mentions that I need to use an immediate to store/load to and from the arrays but how am I supposed to do it when I don't know the immediate and instead the values are based on adding and multiplying the indexes? don't they have to be stored in a register?

Thank you for your help in advance

edit: the code in total

.data                                           #data segment
    X: .word 1,1,1,2,2,3,4,2,1,1,2,3,2,4,8,1    #X[]
    H: .word 1,5,1,4,2,1,1,1                    #H[]
    Y: .space 64                                #n*8 = 8*8 = 64 bytes reserved for the y0 results = R2

    n: .word 8                                  #n = 8
    m: .word 8                                  #m = 8

   

.text
fir:                                            #void fir
    
    ori r15, r0, X                             #address of X[]
    ori r1, r0, H                              #address of H[]
    ori r2, r0, Y                              #address of Y[]

    daddi r3,r3,8                               # n = r3 = 8
    daddi r4,r4,8                               # m = r4 = 8

    dadd r5,r0,r0                              #set j counter to 0
    daddi r18,r0,8                                  

    j for1                                      #go to for1 loop

for1:   
    beq r5,r4,exit                              #when j is equal to m loop stops and goes to the exit function
    dadd r6,r0,r0                               #y0 = r6 = 0
    dadd r7,r0,r0                               #set i counter to 0 for every loop

    bne r5,r4,for2                              #go to the nested loop for2

for2:
    beq r7,r3, afterfor2                        # for(i=0, i<n, i++)

    #making X[i+j]
    dadd r8,r5,r7                               #i+j stored in r8
    dmul r9,r8,r18                              #(i+j)*8 to find address stored in r9
    daddu r9,r9,r15
    ld r10,(r9)                                 #load x[i+j] to r10

    #making H[i]
    dmul r11,r18,r7                             #8*i
    daddu r11,r11,r1                            #adding 8*i to the base address
    ld r12,(r11)                                #load h[i] to r12

    dmul r13,r10,r12                            #x[i+j] * h[i]
    dadd r6,r6,r13                              #y0 = y0 + x[i+j]*h[i]
    daddi r7,r7,1                               # i++
    j for2                                      # repeat loop

afterfor2: 
        
    dmul r14,r5,r18                             #8*j stored to r14
    daddu r14,r14,r2
    sd r6,(r14)                                 #Y[j] = y0
    daddi r5,r5,1                               #j++
    
    j for1                                      #go back to start of loop for1


exit:
    halt                                        #exit program

Solution

  • There's no such addressing mode as register(register). You'll have to add the two registers together first.

    For example, instead of lw r12,r11(r1), do:

    daddu r11,r11,r1
    lw r12,(r11)
    

    Note that in the case of lw r10, r9(r0), you can simply replace that with lw r10, (r9), since the value of r0 is hardwired to 0.