apratt@AMES.ARC.NASA.GOV (Allan Pratt) (09/26/89)
Here is C source and 68000 assembly output from GCC 1.35 with -O.
In the true part of the if, move.b ax@+,ay@+ would work and be
much better, but the compiler didn't notice that it could be used.
In the false part of the if, move.l ax@+,ay@+ is used correctly.
void
copy(src,dest,count)
long *src, *dest;
short count;
{
if ((((long)src) & 1) || (((long)dest) & 1)) {
do {
*((char *)dest)++ = *((char *)src)++;
} while (count--);
}
else {
count /= 4;
do {
*dest++ = *src++;
} while (count--);
}
}
****************************************
.even
.globl _copy
_copy:
link a6,#0
moveml #0x30,sp@-
movel a6@(8),a3
movel a6@(12),a2
movew a6@(18),d0
movel a3,d1
btst #0,d1
jne L3
movel a2,d1
btst #0,d1
jeq L2
L3:
L4:
movel a2,a0
addqw #1,a2
movel a3,a1
addqw #1,a3
moveb a1@,a0@
dbra d0,L4
jra L7
L2:
tstw d0
jge L8
addqw #3,d0
L8:
asrw #2,d0
L9:
movel a3@+,a2@+
dbra d0,L9
L7:
moveml a6@(-8),#0xc00
unlk a6
rts
I mentioned this to James Wilson; this was his reply:
> From: ames!ucbarpa.Berkeley.EDU!wilson (James E. Wilson)
>
> Gcc seems to generate some really terrible code here. I can see how this
> is happening in the optimization stages, but the real problem seems to
> be in the rtl generation phase. Well, this problem is too tough for me
> to solve in 10 minutes, so I suggest you send in a bug report.
>
> However, in the meantime, you can get the desired code by rewritting the
> loop like this:
> *((char *)dest) = *((char *)src); /**/
> ((char *)dest)++;
> ((char *)src)++;
>
> This is not a hard problem, gcc should be able to handle it. The mshort
> and m68000 options do not matter. The same problem happens on a VAX.
============================================
Opinions expressed above do not necessarily -- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else. ...ames!atari!apratt