This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

AMD64. sign extension correct?


Hi,

I'm not subscribed, so if you want to reach me directly you have to send an email directly to me; otherwise I'll pick up any answer via the web-archives.

I'm a little bit confused w.r.t. to signed/unsigned multiplication on x86_64:

Assume multiplying (signed <some integer type)-1 by (unsigned <same integer type)20 and cast that value to a larger integer. With gcc-3.4.3 (pretty sure head CVS is the same):

1.
(signed long) = (signed int) = (signed short) = (signed char) x (unsigned char)

This yields proper (?) sign extension to every integer type. In hex notation:

a = -1 * 20, then a = 0xffff ffff ffff ffec

2.
(signed long) = (signed int) = (signed short) x (unsigned short)

Dito.

a = -1 * 20, then a = 0xffff ffff ffff ffec

3.
(signed long) = (signed int) x (unsigned int)

Surprisingly the sign is not promoted in this case:

a = -1 * 20, then a = 0x0000 0000 ffff ffec


IMHO, this is a bug. Below is a short test program which tries to execute the three scenarios.


Regards

Claus

############################ snip ####################################
#include <stdio.h>

short char_mix(signed char sign, unsigned char val)
{
	return sign * val;
}

int short_mix(signed short sign, unsigned short val)
{
	return sign * val;
}

long int int_mix(int sign, unsigned int val)
{
	return sign * val;
}

int main(int argc, const char *argv[])
{
	short    short_res;
	int      int_res;
	long int long_int_res;

	short_res     = char_mix(-1, 20);
	int_res      = short_mix(-1, 20);
	long_int_res = int_mix(-1, 20);

	printf("Char : 0x%016lx | 0x%08x | 0x%04x\n",
	       (unsigned long)short_res, (unsigned int)short_res, (unsigned short)short_res);
	printf("Short: 0x%016lx | 0x%08x\n",
	       (unsigned long)int_res, (unsigned int)int_res);
	printf("Int  : 0x%016lx\n", (unsigned long)long_int_res);
}
############################ snap ####################################


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]