Porting code to gcc, replacement for SFR?

Ola Liljedahl olli@enea.se
Fri Nov 7 10:54:00 GMT 1997

Roy Leonard wrote:
> The code makes use of an IAR specific type called sfr - special function
> register.  Does anyone know of a similar type in gcc, or an easy way to
> implement a similar type?
> A special function register is something like a UART control register, which
> is at a predetermined address and can read/written to as a byte or as
> individual bits.
> Example:
> sfr UART_CONTROL = 0xff20;   /* The address of UART_CONTROL */
> UART_CONTROL = 0xff   /* set the contents of the register to 0xff */
> UART_CONTROL.1 = 0;   /* set bit 1 to 0 */
> Any ideas, comments....

union UartControl
	unsigned char all; /* Hopefully byte-sized. */
		/* Beware unknown ordering of bits within byte. */
		unsigned bit7:1;
		unsigned bit6:1;
		unsigned bit5:1;
		unsigned bit4:1;
		unsigned bit3:1;
		unsigned bit2:1;
		unsigned bit1:1;
		unsigned bit0:1;
	} bits;

/* Some shortcuts to make programming simpler. */
#define bit0 bits.bit0
#define bit1 bits.bit1
#define bit2 bits.bit2
#define bit3 bits.bit3
#define bit4 bits.bit4
#define bit5 bits.bit5
#define bit6 bits.bit6
#define bit7 bits.bit7

/* The variable declaration (sort of). */
#define UART_CONTROL (*(volatile union UartControl*)0xff20)

int test(void)
	UART_CONTROL.all = 0xff;
	UART_CONTROL.bit1 = 0;
	return sizeof(union UartControl); /* Just to check the size of UartControl. */

Excerpt from the generated assembly code (gcc for 68K Amiga):
	link a5,#0
	movel #65312,a0			;cache the register address
	moveb #255,a0@			;write 0xff to register
	moveb a0@,d0			;bit setting implemented with non-atomic
	andb #-3,d0				;read/write, -3 == 253 => clearing bit 1
	moveb d0,a0@
	moveq #1,d0				;return size of register which is expected one
	unlk a5

Hopefully this will also work for your version of gcc and your target CPU.
	Ola Liljedahl
	Enea OSE Systems AB
	"OSE - Advanced but not alien"

More information about the crossgcc mailing list