Gabriel Saragoca

Bug in generated Code CodeWarrior V7.1

Discussion created by Gabriel Saragoca on Jan 21, 2010
Latest reply on Jan 22, 2010 by CompilerGuru



First of all I am not sure if this is the correct forum to report this problem, or even if it has been detected already. Nevertheless I am posting it here in the hope that somebody might read it and take this problem into account.


In a project previously developed with CodeEarrior V6.4 wich for the following C code generated the following assembler:


// ----------------------------- 

unsigned short status ;


unsigned short  my_function (void) ;


status = my_function () ;


 if ((status == 0x2102) || (status == 0x210B) || (status == 0x210A)) {

    bla bla ;


  else {

    bla bla ;


// -------------- 


CodeWarrior V6.4 with "Faster Execution Speed" And "Level 4" Optimization:


0x00000076  0x7400             moveq#0,d2

0x00000078  0x3400             move.wd0,d2

0x0000007A  0x0C8200002102     cmpi.l#8450,d2                  ; '..!.'

0x00000080  0x670000B4         beq.w*+182                      ; 0x00000136

0x00000084  0x06800000DEF6     addi.l#57078,d0                 ; '....'

0x0000008A  0x7200             moveq#0,d1

0x0000008C  0x3200             move.wd0,d1

0x0000008E  0x0C8100000001     cmpi.l#1,d1                     ; '....'

0x00000094  0x630000A0         bls.w*+162                      ; 0x00000136


Status is in d0, and a special trick is made to test the two last consecutive values. By adding #57078 to the returned value in a 2 byte operation we will get a value of #0 or #1 depending on the value on d0 being 0x210B, or 0x210A. The we can check if the result value is less or equal to #1.


Under CodeWarrior V7.1 with "Faster Execution Speed" And "Level 4" Optimization:


0x00000076  0x7200              moveq      #0,d1

0x00000078  0x3200              move.w     d0,d1

0x0000007A  0x0C8100002102      cmpi.l    #8450,d1              ; '..!.'

0x00000080  0x670000AC          beq.w     *+174                 ; 0x0000012e

0x00000084  0x7200              moveq     #0,d1

0x00000086  0x3200              move.w    d0,d1

0x00000088  0x06810000DEF6      addi.l     #57078,d1             ; '....'

0x0000008E  0x0C8100000001      cmpi.l    #1,d1                 ; '....'

0x00000094  0x63000098          bls.w     *+154                 ; 0x0000012e


Here status is also in d0, and the same trick is attempted, but there is a catch.
With V6.4 the value of #57078 is added to d0 an then d0 is moved to d1 (just the two lower bytes) correctly truncating the value to two bytes.
But in V7.1 we get the value of #57078 added instead to d1 in a 4 byte long addition and then comparing it with #1 also in a 4 byte long operation. For the trick to work the result of the addition must pe truncated to 2 bytes. This code does not work!
Thank you