Hi.

While porting Realtek's 8196c code to OpenWrt,
I came up with a need for an inline asm macro that mimics
instructions that manipulate lexra's CP0 registers.

The instructions are

    MFLXC0 reg,cp0reg

where cp0reg = 0 (ESTATUS), 1 (ECAUSE) or 2 (INTVEC),
to read ESTATUS, ECAUSE or INTVEC into reg, and

    MTLXC0 reg,cp0reg

where cp0reg = 0 (ESTATUS) or 2 (INTVEC),
to write reg into ESTATUS or INTVEC.

For MFLXC0, the base opcode is 0x40600000, and the
reg and cp0reg are encoded as 0x40600000 | (reg << 16) | (cp0reg << 11).
For MTLXC0, the base opcode is 0x40e00000.

Let's say I want an inline macro that read the ECAUSE register.
I came up with the following.

#define read_lxc0_ecause()                              \
({ int __res;                                           \
        __asm__ __volatile__(                           \
                ".word  0x40600800 | (%0 << 16)\n\t"    \
                : "=r" (__res));                        \
        __res;                                          \
})

If I just write "read_lxc0_ecause();", and assume $2 is
assigned to %0 by gcc, then I have

#APP
  .word  0x40600800 | ($2 << 16)
#NOAPP
  sw      $2,8($fp)

which clearly will not survive through an as stage.

I would want

  .word  0x40600800 | (2 << 16)

instead of

  .word  0x40600800 | ($2 << 16)

Is there anyway to convert the assigned $2 into 2
(or equivalent integer constant) before it is pass to the as stage?

Any help would be appreciated, including a pointer to proper ML
that this question should be redirected to.

Thanks in advance.

--- shinoda


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to