Folks,

After a little bit of research on the web and elsewhere,
I came to the conclusion that there is no easy way to
solve this problem, so I decided to fixedly use $2 as
the register to move values to/from cp0reg, in exchange
for some degree in loss of efficiency.

So, my solution is to implement
{read,write}_lxc0_{estatus,ecause,intvec} macros with
register constraints about $2 and in/out parameters, e.g.:

#define read_lxc0_estatus()                     \
({                                              \
        register int __res __asm__("$2");       \
        __asm__ __volatile__(                   \
                "# mflxc0 $2,ESTATUS\n\t"       \
                ".word\t0x40620000\n\t"         \
                : "=r" (__res));                \
        __res;                                  \
})

--- shinoda


On 2012/02/05, at 16:05, LEO Airwarosu Yoichi Shinoda wrote:

> 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

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

Reply via email to