views:

71

answers:

1

MIPS32 ISA defines the following format for the sync instruction:

SYNC (stype = 0 implied)
SYNC stype

here, stype may be SYNC_WMB (SYNC 4), SYNC_MB (SYNC 16), etc. In inline assembler, I may use default sync: __asm__ volatile ("sync" ::);.

But, if I write something like __asm__ volatile ("sync 0x10" ::), it doesn't compile:

Error: illegal operands 'sync 0x10'

Same if pass -mips32r2 option to gcc.

So, the question is: how to use SYNC_* (WYNC_WMB, SYNC_MB, SYNC_ACQUIRE, ...) instructions from GCC inlined assembly?

+1  A: 

I suspect that your binutils are too old - it looks like support for this was only added in version 2.20.

As a workaround, if you can't upgrade your binutils easily, you could construct the opcode by hand.

sync is an opcode 0 instruction with a function code (bits 5..0) of 0xf, and this form of it encodes the sync type in the shift amount field (bits 10..6). So, e.g. for sync 0x10:

__asm__ volatile(".word (0x0000000f | (0x10 << 6))");
Matthew Slattery
Well, I'm afraid it's not that easy, my GCC is quite new:`mips-linux-gnu-gcc (Sourcery G++ Lite 4.2-85) 4.2.1`Btw, I also use manual instruction encoding for now:`#define EMIT_SYNC(stype) __asm__ volatile (".int (%0 << 6) | 0x0f " : : "n" (stype) : "memory");`But it's just an ugly workaround.
Andy
It's the version of the assembler that matters here, not the version of GCC. (If you know where the assembler is installed, and what it's called, you can find the version with e.g. `mips-linux-gnu-as --version`; if not, use the `-v` flag when compiling something with GCC, and look for a line in the output which says something like `GNU assembler version N.NN`.)
Matthew Slattery
Looks like you were right, my assembler version is 2.18.50.20070820. Thanks, I'll try to upgrade to 2.20.
Andy