http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50281

             Bug #: 50281
           Summary: result registers are overwritten giving incorrect
                    result
    Classification: Unclassified
           Product: gcc
           Version: 4.3.3
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: nickpar...@eaton.com


Application code

bool8_t testMaths(void)
{
  uint32_t result1_u4;
  uint32_t result2_u4;
  int32_t result1_s4;
  int32_t result2_s4;
  //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  // Multiplying U3s
  //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  result1_u4 = MulU3U3S3(16777215L,100L);  // should be around 100

  PutImmediateString(ECU_COMMS,"\r\nmulu3u3s3 : [ ");
  PrintINT4(ECU_COMMS, 16777215L, 'D',0);
  PutImmediateString(ECU_COMMS," ] x [");
  PrintINT4(ECU_COMMS, 100L, 'D',0);
  PutImmediateString(ECU_COMMS," ] = [");
  PrintINT4(ECU_COMMS, result1_u4, 'D',0);
  PutImmediateString(ECU_COMMS," ]");
.
.
.
.
}


/***************************************************************************
* MulU3U3S3()
* ------------
* Function:     Multiplies two unsigned 24bit max values, 
*               then shifts left by 2^24
***************************************************************************/
uint32_t MulU3U3S3(uint32_t a_u4, uint32_t b_u4)
{
    uint32_t answer;

    asm volatile
    (

        "push r0"                   "\n\t"
        "push r1"                   "\n\t"

        "clr r20"                   "\n\t"      // zero register

        // 0 byte shifts
        "mul %A1,%A2"               "\n\t"      // a1a2
        "mov r2,r0"                 "\n\t"
        "mov r3,r1"                 "\n\t"

        // 1 byte shifts
        "mul %A1,%B2"              "\n\t"
        "add r3,r0"                "\n\t"
        "adc r4,r1"                "\n\t"
        "adc r5,r20"               "\n\t"

        "mul %A2,%B1"              "\n\t"
        "add r3,r0"                "\n\t"
        "adc r4,r1"                "\n\t"
        "adc r5,r20"               "\n\t"

        // 2 byte shifts
        "mul %A1,%C2"               "\n\t"
        "add r4,r0"                "\n\t"
        "adc r5,r1"                "\n\t"
        "adc r6,r20"               "\n\t"

        "mul %A2,%C1"               "\n\t"
        "add r4,r0"                "\n\t"
        "adc r5,r1"                "\n\t"
        "adc r6,r20"               "\n\t"

        "mul %B2,%B1"               "\n\t"
        "add r4,r0"                "\n\t"
        "adc r5,r1"                "\n\t"
        "adc r6,r20"               "\n\t"

        // 3 byte shifts
        "mul %B1,%C2"               "\n\t"
        "add r5,r0"                "\n\t"
        "adc r6,r1"                "\n\t"
        "adc r7,r20"               "\n\t"

        "mul %B2,%C1"               "\n\t"
        "add r5,r0"                "\n\t"
        "adc r6,r1"                "\n\t"
        "adc r7,r20"               "\n\t"

        // 4 byte shifts
        "mul %C2,%C1"               "\n\t"
        "add r6,r0"                "\n\t"
        "adc r7,r1"                "\n\t"

        "mov %A0,r5"               "\n\t"
        "mov %B0,r6"               "\n\t"
        "mov %C0,r7"               "\n\t"
        "clr %D0"                  "\n\t"

        //"adc %G0,r20"               "\n\t"
        "pop r1"                    "\n\t"
        "pop r0"                    "\n\t"

    : "=&r" (answer)
    : "r" (a_u4), "r" (b_u4)
    : "r2","r3","r4","r5","r6","r7","r20"
    );

    return (answer);
}

Reply via email to