Luka Rahne

Compiler bug on fast optimisation options?

Discussion created by Luka Rahne on Nov 20, 2008
Latest reply on Nov 21, 2008 by Luka Rahne
I am working on  pixel driven LCD driver and i amusing 2 buffers. Display is monocrome and 128*128 bit.
I am using coldwarrior 7.1 for coldfire MCP52235 
I  was working on display picture (display_image) function and found weird behaving on fast optimisation. I write 3 same functions (display_image) and all of them has same and desired on low optimisation options or on space optimisation options.
During copile I am not using any spacial flags just those automaticaly generated trough cw gui whit 5 step slider and radio buttons on either speed or space optimisation.

this function exept
*pixel_matrix is address of display buffer
*img is source of image which has pixels one by another and new line of pixels is not broken by empty pixel. (black squre of 3*3 is 111111111b
height is height
width is width
x0 is x position of left side of picture (left up)
y0 is y positon of upper side of picture(right up)
Code:

void draw_image(TDisplayBuffer* pixel_matrix,u8* img,s16 height,s16 width,s16 x0,s16 y0){ u8 c; s16 i, j; s32 img_iter=0; s32 index,step; TDisplayBuffer* img_0 = (TDisplayBuffer *) img; step=SIZE_OF_DISPLAY_Y-height; index=SIZE_OF_DISPLAY_Y*x0+y0;  //dont display pictures that doesent fit screen    if( (y0 > SIZE_OF_DISPLAY_Y) || (y0 + height < 0) || (x0 > SIZE_OF_DISPLAY_X)  || (x0 + width < 0) )        return;     for (i=0;i<width;i++)    {        for (j=0;j<height;j++)        {                         if ( ( (y0+j) < SIZE_OF_DISPLAY_Y ) && ( (y0+j)>=0 )  && ( (x0+i) < SIZE_OF_DISPLAY_X ) && ( (x0+i)>=0 ) )                    //check if pixel should be putted in buffer                {                    c=img_0[img_iter>>3] & (1<< (7 -(img_iter & 7))); // read img_iter bit from img[]                    if (c != 0) draw_dot_index(pixel_matrix,index,dsON);                    else draw_dot_index(pixel_matrix,index,dsOFF);                }                img_iter++;                index++;        }        index+=step;    }}
Problem whit this function is when picture is placed on upper edge of display for instance
x0=0,y0=-5(minus),width=10,height=10;
this picture is in case of fast optimisation not displayed



another function:
Code:
void draw_image(TDisplayBuffer* pixel_matrix,u8* img,s16 height,s16 width,s16 x0,s16 y0){    u8 c;    s16 i, j;    s32 img_iter=0;    s32 index,step;    TDisplayBuffer* img_0 = (TDisplayBuffer *) img;    step=SIZE_OF_DISPLAY_Y-height;    index=SIZE_OF_DISPLAY_Y*x0+y0;    if( (y0 > SIZE_OF_DISPLAY_Y) || (y0 + height < 0) )        return;    if( (x0 > SIZE_OF_DISPLAY_X) || (x0 + width < 0) )        return;    for (i=0;i<width;i++)    {        if(((x0+i) < SIZE_OF_DISPLAY_X) && ((x0+i)>=0 ))        {            for (j=0;j<height;j++)            {                if ( ((y0+j) < SIZE_OF_DISPLAY_Y) && ((y0+j)>=0 ) )                    //check if pixel should be putted in buffer                {                    c=img_0[img_iter>>3] & (1<< (7 -(img_iter & 7))); // read img_iter bit from img[]                    if (c != 0) draw_dot_index(pixel_matrix,index,dsON);                    else draw_dot_index(pixel_matrix,index,dsOFF);                }                img_iter++;                index++;            }        }        else        {            img_iter+=height;            index+=height;        }        index+=step;    }}
This function get stuck when is called whit
x0=0,y0=-5(minus),width=10,height=10; (memory owerflow or shomething like that)



third funcion which I wrote latest is functionaly same and works ok on speed optimisation level 4;
Code:
//3rd function whitout if-s in for loopsvoid draw_image(TDisplayBuffer* pixel_matrix,u8* img,s16 height,s16 width,s16 x0,s16 y0){    u8 c;    s16 i, j;    s32 img_iter=0;    s32 index,step;    s16 width_s,height_s;    TDisplayBuffer* img_0 = (TDisplayBuffer *) img;    s32 iter_step = 0;    //unsigned int dbg;    step=SIZE_OF_DISPLAY_Y-height;    index=SIZE_OF_DISPLAY_Y*x0+y0;    if( (y0 > SIZE_OF_DISPLAY_Y) || (y0 + height < 0) )        return;    if( (x0 > SIZE_OF_DISPLAY_X) || (x0 + width < 0) )        return;    if( y0 + height > SIZE_OF_DISPLAY_Y )    {        height_s = SIZE_OF_DISPLAY_Y - y0;        step=SIZE_OF_DISPLAY_Y-height_s;        iter_step+=y0 + height - SIZE_OF_DISPLAY_Y;    }    else if(y0 < 0 )    {        height_s = height + y0 ;        step=SIZE_OF_DISPLAY_Y-height_s;        img_iter=img_iter + y0 * (-1);        iter_step+=y0*(-1);        y0 = 0;    }    else    {        height_s = height;    }    if( x0 + width > SIZE_OF_DISPLAY_X )    {        width_s = SIZE_OF_DISPLAY_X - x0;    }    else if(x0 < 0 )    {        width_s = width + x0;        img_iter=height*x0*(-1);        x0 = 0;    }    else    {        width_s = width;    }    index=SIZE_OF_DISPLAY_Y*x0+y0;    for (i=0;i<width_s;i++)    {            for (j=0;j<height_s;j++)            {                c=img_0[img_iter>>3] & (1<< (7 -(img_iter & 7))); // read img_iter bit from img[]                if (c != 0) draw_dot_index(pixel_matrix,index,dsON);                else draw_dot_index(pixel_matrix,index,dsOFF);                img_iter++;                index++;            }            img_iter+=iter_step;            index+=step;    }}

 

extra function
Code:
void draw_dot_index(TDisplayBuffer * pixel_matrix,s32 index,TDispStatus status){ u8 * matrix = (u8 *) pixel_matrix; if(status == dsON)          matrix[index>>3] |= (0x01 << (index & 7)); else if(status == dsOFF)          matrix[index>>3] &= ~(0x01 << (index & 7)); else if(status == dsTOGGLE)          matrix[index>>3] ^= (0x01 << (index & 7));}

 


I also create display emulator on PC and copiled whit gcc -03 option. All functions get compiled ok and work as expected this way but differently on speed optimisaton options in CW.

.

Outcomes