This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Weird optimisation compiler bug?

Hi there,

Included below is a sample disassembly output of some code I just discovered not behaving the way I think it should. Basically, it seems the compiler has determined that there is no need to return from the current function and instead can safely jump into the next function and return from that. Unfortunately, it cocks up the argument registers before it jumps!!!

The call to InitE888Receive from CANStr_GetSpecialChannelSetup mucks up the registers. See the note in the middle of the disassembly below to see how!

Code is:

UCAN_SPECIAL_CHAN_SETUP * InitE888Receive(uint32 ACANID)
{
    // Malloc a struct and then initialise it...
    UCAN_SPECIAL_CHAN_SETUP * specialSetup = UCAN_AllocSpecialSetup(2);
    if(specialSetup != NULL)
    {
        specialSetup->fptrRxCallBack = E888Receive;
        specialSetup->CANIDs[0] = ACANID;
        specialSetup->CANIDs[1] = ACANID + 1;
    }
    return specialSetup;
}

UCAN_SPECIAL_CHAN_SETUP * CANStr_GetSpecialChannelSetup(uint8 AMode, uint32 ACANID)
{
    if(AMode == 138)
    {
        return InitE888Receive(ACANID);
    }
    else
    {
        return NULL;
    }

    /*switch(AMode)  <-- This has the same problem as above too!
    {
        case 138:   return InitE888Receive(ACANID);
        default:    return NULL;
    }*/
}



   182: UCAN_SPECIAL_CHAN_SETUP * InitE888Receive(uint32 ACANID)
00046D86 ECFE      PUSH     R14
00046D88 ECFF      PUSH     R15
00046D8A F0E8      MOV      R14,R8
00046D8C F0F9      MOV      R15,R9
   183: {
   184:     // Malloc a struct and then initialise it...
   185:     UCAN_SPECIAL_CHAN_SETUP * specialSetup = UCAN_AllocSpecialSetup(2);
00046D8E E028      MOV      R8,#0x02
00046D90 DA0368AF  CALLS    UCAN_AllocSpecialSetup(0x3AF68)
00046D94 F0A4      MOV      R10,R4
00046D96 F0B5      MOV      R11,R5
   186:     if(specialSetup != NULL)
   187:     {
00046D98 7045      OR       R4,R5
00046D9A 2D1F      JMPR     CC_Z,0x046DDA
   188:         specialSetup->fptrRxCallBack = E888Receive;
00046D9C E6F6726D  MOV      R6,#0x6D72
00046DA0 E6F70400  MOV      R7,#0x0004
00046DA4 DC7B      EXTP     R11,#4
00046DA6 C46A0400  MOV      [R10+#0x0004],R6
00046DAA C47A0600  MOV      [R10+#0x0006],R7
   189:         specialSetup->CANIDs[0] = ACANID;
00046DAE D45A0C00  MOV      R5,[R10+#0x000C]
00046DB2 D44A0A00  MOV      R4,[R10+#0x000A]
00046DB6 DC55      EXTP     R5,#2
00046DB8 B8E4      MOV      [R4],R14
00046DBA C4F40200  MOV      [R4+#0x0002],R15
   190:         specialSetup->CANIDs[1] = ACANID + 1;
00046DBE F08E      MOV      R8,R14
00046DC0 F09F      MOV      R9,R15
00046DC2 0881      ADD      R8,#1
00046DC4 1890      ADDC     R9,#0
00046DC6 DC5B      EXTP     R11,#2
00046DC8 D45A0C00  MOV      R5,[R10+#0x000C]
00046DCC D44A0A00  MOV      R4,[R10+#0x000A]
00046DD0 DC55      EXTP     R5,#2
00046DD2 C4840400  MOV      [R4+#0x0004],R8
00046DD6 C4940600  MOV      [R4+#0x0006],R9
   191:     }
   192:     return specialSetup;
00046DDA F05B      MOV      R5,R11
00046DDC F04A      MOV      R4,R10
   193: }
   194:
00046DDE FCFF      POP      R15
00046DE0 FCFE      POP      R14
00046DE2 DB00      RETS
   195: UCAN_SPECIAL_CHAN_SETUP * CANStr_GetSpecialChannelSetup(uint8 AMode, uint32 ACANID)
   196: {
   197:     if(AMode == 138)
   198:     {
00046DE4 F048      MOV      R4,R8
00046DE6 47F88A00  CMPB     RL4,#0x008A
00046DEA 3D04      JMPR     CC_NZ,0x046DF4
   199:         return InitE888Receive(ACANID);


*********  GOES WRONG HERE *********
This should be putting R14/R15 into R8/R9
Instead it copies R10 into R8/R9 which weird as it should actually be a 32 bit copy anyways!!!


00046DEC F09A      MOV      R9,R10
00046DEE F08A      MOV      R8,R10
00046DF0 FA04866D  JMPS     InitE888Receive(0x46D86)
   200:     }
   201:     else
   202:     {
   203:         return NULL;
00046DF4 E004      MOV      R4,#0x00
00046DF6 E005      MOV      R5,#0x00
   204:     }
00046DF8 DB00      RETS

0