Working with romcc here, you can drop this block of code into the auto.c/raminit portion of any board using romcc and reproduce the error (it compiles fine with CAR, but that's not an option with the c7 cpu, at least not yet):
u8 reg8, spd_data;
reg8 = pci_read_config8(PCI_DEV(0, 0, 3), 0x62); spd_data = smbus_read_byte(0x50, 30); spd_data = spd_data / 10; if(spd_data < 5) spd_data = 5; else if(spd_data > 20) spd_data = 20;
if(spd_data > (reg8 >> 4)) { reg8 &= 0xf; reg8 |= (spd_data << 4); }
The error is confirmed on ubuntu 8.04 alpha/beta/? and debian unstable, both with gcc 4.2.3, and also gentoo with gcc 4.1.2:
dst type: auto unsigned char dst: %edx:%eax auto.c:35.1: raminit.c:436.33: raminit.c:615.36: auto.c:218.32: 0x83cbe70 convert Internal compiler error: failed to trunc value: mask ff make[1]: *** [auto.inc] Aborted (core dumped)
Commenting out either spd_data/10 or the if/else portion gets rid of the error, it only happens when all of these statements are in. I also have half a dozen blocks like this which compile fine:
reg8 = pci_read_config8(ctrl->d0f3, 0x63); j = spd_read_byte(ctrl->channel0[i], SPD_tRRD);//ctrl->channel0[0] = 0x50 spd_data = ((j >> 2) * 100); spd_data |= ((j & 0x3) * 25); spd_data = spd_data / (ram_cycle * 100); //ram_cycle in this case = 10 if(spd_data < 2) spd_data = 2; else if(spd_data > 5) spd_data = 5;
if((spd_data - 2) > (reg8 >> 6)) { reg8 &= 0x3f; reg8 |= (spd_data - 2) << 6; }
It's just that one instance that fails to compile. I've tried moving it around, changing the variables, changing the types, modifying the math, etc, etc, and nothing seems to help. Any suggestions?