Attempting to port pthreads to the ColdFire (was: RE: [uClibc]Status of POSIX Thread Support in uClibc)

David Chan dchan at controlproductsinc.com
Sat Aug 24 23:38:44 UTC 2002


> Looks like it supports m68k but not the Coldfire and needs to be
ported.
> The missing instructions and addressing modes in the coldfire mean a 
> little bit of work is needed here :-)

touche Davidm. 

I spent all morning trying to do just that and I was wondering if I
could get a hand with it. I'm a bit new to the m68k platform, but I
decided to give it the old college try. I did some poking around and
decided that I wanted to edit
libpthread/linuxthreads/sysdeps/m68k/pt-machine.h. (And when we have the
bloody thing working, make a new arch called m68knommu or something.) 

So, from examining the errors and source: 

/* Spinlock implementation; required.  */
PT_EI int
testandset (int *spinlock)
{
  char ret;

  __asm__ __volatile__("tas %1; sne %0"
       : "=dm"(ret), "=m"(*spinlock)
       : "m"(*spinlock) 
       : "cc");
	   
  return ret;
}


Error: invalid instruction for this architecture;
needs 68000 or higher -- statement `tas (%a0)' ignored

- The tas instruction was eliminated from all ColdFire cores except for
v4 cores. This 'test and set' routine is intended to guarantee an atomic
read, modify, set behavior. This statement is intended to compare the
operand (%a0) to zero and set the CC flags as necessary (N, Z), and then
set the most significant bit of the byte to 1. This is supposed to be
performed without interruption. Theoretically, we could replace this
statement with a series of tst and andi instructions. But doesn't this
lose the no-interruption behavior we want from the tas instruction?
Could we suspend interrupts surrounding a replacement block to ensure
its atomic behavior, since we're really not going to be running on
multiple processors?


Error: operands mismatch -- statement `sne -1(%a6)' ignored

- So, some documentation I found said that a few addressing modes were
omitted from the ColdFire. However, this "Address Register Indirect with
Displacement Mode" should still be there. However, the syntax has
changed from x(An) to (x,An). I have no idea where to change this
behavior.



/* Compare-and-swap for semaphores. */

#define HAS_COMPARE_AND_SWAP
PT_EI int
__compare_and_swap (long int *p, long int oldval, long int newval)
{
  char ret;
  long int readval;

  __asm__ __volatile__ ("casl %2, %3, %1; seq %0"
			: "=dm" (ret), "=m" (*p), "=d" (readval)
/* output */
			: "d" (newval), "m" (*p), "2" (oldval));
/* input */

  return ret;
}


Error: invalid instruction for this architecture;
needs 68020 or higher -- statement `casl %d2,%d0,(%a0)' ignored

- The cas instruction has been completely omitted from the ColdFire
instruction set. This 'compare and swap' instruction's behavior can
essentially be summed up by this pseudo-code: 

[CAS d0,d1,(a0)] 

if (d0 == (a0)) {
	(a0) = d1;
} else {
	d0 = (a0);
}

So, this instruction could be replaced with something like:

	cmp.l	(a0), d0
	bne.b	other
	move	d1, (a0)
	jmp	end
other:
	move	(a0), d0
end:

or... it looks like there's #define there. I wonder if the surrounding
code would allow us to omit that #define and the associated function and
take care of compare-and-swap by itself.
	

Error: operands mismatch -- statement `seq -1(%a6)' ignored

- See above.


Any help or advice on why this hasn't been done before would be nice.

Cheers,
David Chan




More information about the uClibc mailing list