Monday, June 09, 2008

    Invoking MADD instruction from C

    Generally, C programmers don't have to worry about the assembly instructions that their C compiler generates. We have, however, received a few messages asking if the MPLAB C Compiler for PIC32 (aka MPLAB C32) supports the MADD instruction. Yes, it does. The compiler tries to avoid using the HI/LO registers, but the code below shows a sequence that invokes the MADD instruction (as of C32 1.02).

    EDIT1: You'll need to build with at least the -O1 level of optimization.
    int dp (int a[], int b[], int n);

    int ary1[] = {1,2,3,4,5};
    int ary2[] = {6,7,8,9,10};
    volatile int testval;

    int main(void)
    {
    testval = dp (ary1, ary2, 5);
    while(1);
    }

    int dp (int a[], int b[], int n)
    {
    /*
    * move a3,a0
    */

    int i;
    long long acc = (long long) a[0] * b[0];
    /*
    * lw v1,0(a1)
    * lw a0,0(a0)
    */

    for (i = 1; i < n; i++)
    /*
    * li t0,1
    * slt v0,t0,a2
    * beqz v0,9d00005c
    * mult a0,v1
    * addiu a1,a1,4
    * addiu a0,a3,4
    * addiu a2,a2,-1
    */

    acc += (long long) a[i] * b[i];
    /*
    * lw t1,0(a0)
    * lw a3,0(a1)
    * addiu a2,a2,-1
    * madd t1,a3 <--- MADD instruction
    * addiu a0,a0,4
    * bnez a2,9d000040
    * addiu a1,a1,4
    */

    return (acc >> 31);
    /*
    * mflo t3
    * mfhi t2
    * srl a1,t3,0x1f
    * sll a2,t2,0x1
    */
    }
    /*
    * jr ra
    * or v0,a1,a2
    */

    3 comments:

    zappBrannigan said...
    This comment has been removed by the author.
    Anonymous said...

    You have a # include on the first line, but it's blank.
    It looks like it's unnecessary, so I removed it.

    Is a specific optimization required to see the MADD instruction?
    I tried -O0 and didn't get this, but did if I used -Os.

    BTW, pretty cool!

    Anonymous said...

    Thanks for the comment. I think I was including p32xxxx.h. It probably got lost when I posted the HTML.

    Also, thanks for pointing out that you need at least -O1 optimization enabled. Actually, you might want to leave -O1 on all the time because it has only a slightly negative impact on the debugging experience, which it significantly improves the compiler-generated code.

    I'll edit the original post.