PRB: _fastcall Code Generation Error with Shifted Operands

ID Number: Q66923

6.00 6.00a 6.00ax | 6.00 6.00a

MS-DOS | OS/2

buglist6.00 buglist6.00a buglist6.00ax

Summary:

SYMPTOMS

When using _fastcall in Microsoft C versions 6.0, 6.0a, and 6.0ax,

shifted immediate operands may be passed incorrectly. The sample

program below demonstrates this problem. The two parameters to be

passed to the sub1() function are stored in ax and dx (per

_fastcall convention), but the correct values are not used in this

case.

RESOLUTION

To work around this problem, you can either use the /Os

optimization or assign the value to a temporary variable and pass

that variable instead.

STATUS

Microsoft has confirmed this to be a problem in C versions 6.0,

6.0a, and 6.0ax. We are researching this problem and will post new

information here as it becomes available.

More Information:

In all optimizations except /Os and /Od, the compiler calculates the

right-shift value correctly but passes the high-order 2 bytes of the

result instead of the low-order 2 bytes. When compiled with /Od, the

generated code correctly passes one variable but not the other.

Finally, with the /Os optimization, a helper function performs the

shift calculation and the correct values are passed in both cases.

Sample Code

-----------

#include <stdio.h>

int _fastcall sub1(int i, int j);

long a=0x12345678;

void main(void)

{

int llama;

printf("%x\n",(int)(a>>15));

llama = sub1( (int)(a>>15), (int)(a>>15) );

printf("%x\n",llama);

}

int _fastcall sub1(int i, int j)

{

printf("%x \t %x\n",i,j);

return(i);

}

Additional reference words: 6.00 6.00a 6.00ax fastcall