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]

Re: m68k bootstrapping broken


Andreas Schwab wrote:
Bernardo Innocenti <bernie@develer.com> writes:


Another thing.  I'm playing with libffi to see if I can get it to work
on plain 68000.   Do you know a simple instruction sequence to replace
this bit-field operation?

bfins %d0,(%a1){#0,%d2}


I was thinking of something like this (in pseudo-C):


  mask = (1 << (d2 & 0x1f)) - 1;
  *a1 = (*a2 & ~mask) | (d0 & mask);


The mask is wrong. The bitfield insns number the bits from MSB to LSB, not
the other way round, as the single bit insns do.  Also, a width of 0 is
replaced by 32.
^^^^^^^^^^^^^^

This does only happen for immediate modes, to fit the valid range within the
available 5 bits.  When using a data register, the width and offest are just
wrapped around like my old code did.

     shift = 32 - (d2 & 0x1f);
     if (shift == 32) mask = 0, shift = 0;
     else mask = (1 << shift) - 1;
     *a1 = (*a2 & mask) | (d0 << shift);

So the correct code should be:


  mask = (1 << (32 - (d2 & 0x1f))) - 1;
  *a1 = (*a2 & ~mask) | (d0 & mask);

--
 // Bernardo Innocenti - Develer S.r.l., R&D dept.
\X/  http://www.develer.com/



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