I'm writing inline assembly statements using a GNU-based toolchain, and there are three instructions within the inline assembly to update a single bit of a system register. The steps will be:
in the instruction set I'm using, the inline assembly syntax is like this:
unsigned int OV_TMP = 0xffefffff;
asm volatile ( "mfsr %0, $PSW\n\t"
"and %0, %0, %1\n\t"
"mtsr %0, $PSW"
: : "r"(OV_TMP) : );
%1 is the register which I want to forward the value of OV_TMP into.
%0 is the problem for me, and my problem is : How to write the inline assembly code once there is a register used internally and is not assigned from nor copy to the C variables in the C code?
The thing to consider here is that, from the compiler's perspective, the register is assigned-to by the inline assembly, even if you don't use it again later. That is, you're generating the equivalent of:
register unsigned int OV_TMP = 0xffefffff, scratch;
scratch = magic() & OV_TMP;
more_magic(scratch);
/* and then don't re-use scratch for anything from here on */
The magic and/or more_magic steps cannot be moved or combined away because of the volatile
, so the compiler cannot simply delete the written-but-unused register.
The mfsr
and mtsr
look like powerpc instructions to me, and I would probably do the and
step in C code (see footnote); but the following should generally work:
unsigned int OV_TMP = 0xffefffff, scratch;
asm volatile("mfsr %0, $PSW\n\t"
"and %0, %0, %1\n\t"
"mtsr %0, $PSW"
: "=&r"(scratch) : "r"(OV_TMP));
Here the "=&r" constraint says that the output operand ( %0
) is written before the input operand ( %1
) is read.
mfsr
and mtsr
instructions a specific distance apart, unlike certain lock-step sequences on other processors.
If so, I would write something more like this:
static inline unsigned int read_psw() { unsigned int result; asm volatile("mfsr %0, $PSW" : "=r"(result)); return result; } static inline void write_psw(unsigned int value) { asm volatile("mtsr %0, $PSW" :: "r"(value)); } #define PSW_FE0 0x00100000 /* this looks like it's FE0 anyway */ ... write_psw(read_psw() & ~PSW_FE0); /* some appropriate comment here */
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.