(Fwd) Coldfire bug in GCC
Kai Ruottu
karuottu@freenet.hut.fi
Fri Jan 22 14:27:00 GMT 1999
Rolf.Fiedler@Ferrari.DE wrote:
> the following piece of code causes egcs gcc to emit illegal coldfire
> instructions:
----------- clip ---------------------------------------------
#define IO_BASE 0x10000000
typedef unsigned char BYTE;
/* page 1, read */
#define RTL_PAR0 (*(volatile unsigned char *)(IO_BASE + 0x00002301))
#define RTL_PAR1 (*(volatile unsigned char *)(IO_BASE + 0x00002302))
#define RTL_PAR2 (*(volatile unsigned char *)(IO_BASE + 0x00002303))
#define RTL_PAR3 (*(volatile unsigned char *)(IO_BASE + 0x00002304))
#define RTL_PAR4 (*(volatile unsigned char *)(IO_BASE + 0x00002305))
#define RTL_PAR5 (*(volatile unsigned char *)(IO_BASE + 0x00002306))
/* Get the actual MAC address out of the Ethernet chip */
long long EthGetMAC(void) {
long long temp;
EthSetPage(1);
temp = RTL_PAR0;
temp |= (long long)RTL_PAR1 << 8;
temp |= (long long)RTL_PAR2 << 16;
temp |= (long long)RTL_PAR3 << 24;
temp |= (long long)RTL_PAR4 << 32;
temp |= (long long)RTL_PAR5 << 40;
return temp;
}
----------- clip ---------------------------------------------
rol.l #8,%d3 <- this is ok for 68000, but not for coldfire
rol.l #8,%d2
move.b %d3,%d2
clr.b %d3
--------------------------------------------------------------
The fix can be easier than I first thought... After looking at the
'ColdFire@WildRice.com' mail-list archive (www.WildRice.com/ColdFire)
and not founding anything about this yet, I looked at the 'm68k.md'
for the second time...
It seems to optimize those 8, 16, 24, 32,.. special cases and use a
generic method for the others. So, let the 8-bit shift simply be just
a 'generic' case for 5200 :
----------- clip ---------------------------------------------
*** m68k.md.orig Wed Nov 18 15:18:56 1998
--- m68k.md Fri Jan 22 21:07:21 1999
***************
*** 4566,4572 ****
operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
if (INTVAL (operands[2]) == 1)
return \"add%.l %1,%1\;addx%.l %0,%0\";
! else if (INTVAL (operands[2]) == 8)
return \"rol%.l %#8,%1\;rol%.l %#8,%0\;move%.b %1,%0\;clr%.b %1\";
else if (INTVAL (operands[2]) == 16)
return \"swap %1\;swap %0\;move%.w %1,%0\;clr%.w %1\";
--- 4566,4572 ----
operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
if (INTVAL (operands[2]) == 1)
return \"add%.l %1,%1\;addx%.l %0,%0\";
! else if (!TARGET_5200 && (INTVAL (operands[2]) == 8))
return \"rol%.l %#8,%1\;rol%.l %#8,%0\;move%.b %1,%0\;clr%.b %1\";
else if (INTVAL (operands[2]) == 16)
return \"swap %1\;swap %0\;move%.w %1,%0\;clr%.w %1\";
----------- clip ---------------------------------------------
Then it generates the following:
---
> asl.l #-24,%d3
> mov.l %d3,%d2
> moveq #0,%d3
---
instead of the previous:
---
< rol.l #8,%d3
< rol.l #8,%d2
< move.b %d3,%d2
< clr.b %d3
---
for the 8-bit shift case...
Cheers, Kai
_______________________________________________
New CrossGCC FAQ: http://www.objsw.com/CrossGCC
_______________________________________________
To remove yourself from the crossgcc list, send
mail to crossgcc-request@cygnus.com with the
text 'unsubscribe' (without the quotes) in the
body of the message.
More information about the crossgcc
mailing list