powerpc gcc strange assembler for bitfields

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I have been working for some months using the powerpc variant of the gcc
compiler, and am experiencing strange behaviour when compiling
structures with bitfields.

The structure is as follows:

typedef volatile unsigned short VUINT16;

union {
	VUINT16 R;
	struct {
		VUINT16	STOP:1;
		VUINT16 TCR1P:2;
		VUINT16 TCR2P:2;
		VUINT16 EMU:1;
		VUINT16 T2CG:1;
		VUINT16 STF:1;
		VUINT16 SUPV:1;
		VUINT16 PSCK:1;
		VUINT16 TPU3:1;
		VUINT16 T2CSL:1;
		VUINT16:4;
	} B;
} TPUMCR;

TPUMCR is a register in a 16bit bus peripheral. Some bits of the
register are read only, some are write once and others read write. From
power on reset TPUMCR is 0x00A0.

In my code I have

TPUMCR.B.TCR1P = 2;

Thus making TPUMCR = 0x40A0, but this doesn't happen when compiling with
GCC (it does with another powerpc compiler) GCC results in TPUMCR =
0x4000.

The assembler GCC has produced for this is:
lbz 	0,0(9)
andi.	0,0,159
ori	0,0,64
stb	0,0(9)

This is actually correct, but only for 8bits, i.e. the CPU will only be
loading, changing and storing half the word, and due to the memory bus
operating in a certain way the other half of the word will be zeroed
when the store occurs. Which is why the 0xA0 disappears as shown above.

So my questions are:
How can I force GCC to create code that works on the whole 16bit word?
Or is there another way of doing it?

Incidentally the other compiler uses the instruction
rlwimi	r0,r30,13,17,18 which works on the whole word and looks like
would be more efficient.

Any help would be very much appreciated.

Many thanks
Pete


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux