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

Re: [microblaze-uclinux] [patch] errno corruption



Hi John,

At Thu, 18 Mar 2004 12:17:36 +1000,
John Williams wrote:

> I think it should probably be done like in David's m68knommu example. 
> Declare the variable __res, then inline asm to make the syscall, being 
> explicit about the register allocations.  Here's a quick hack:
> 
> #define _syscall2(type, name, atype, a, btype, b)   \
>   type name(atype a, btype b)                         \
>      {                                                   \
>        long __res;                                       \
>        __asm__ __volatile__ ("addk  SYSCALL_ARG0, %2, r0  \n\t"     \
>                              "addk  SYSCALL_ARG1, %3, r0  \n\t"     \
>                              "bralid r17, 0x08            \n\t"	   \
>                              "addik SYSCALL_NUM, r0, %1   \n\t"     \
>                              "addk   %0, SYSCALL_RET, r0  \n\t"     \
>                  :"=r" (__res)                          \
>                  : "i" (__NR_##name),                    \
>                    "r" ((long)a),                        \
>                    "r" ((long)b)                         \
>                  : "cc", "SYSCALL_RET", "SYSCALL_ARG0", "SYSCALL_ARG1", \
>                          "SYSCALL_NUM");\
>        if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
>          errno = -__res;                                 \
>          __res = -1;                                     \
>        }                                                 \
>        return (type)__res;                               \
>      }
> 
> Or something like it.  Note with this explicit approach we also get to 
> use the delayslot on the bralid instruction, which is nice.  Also the 
> syscall params should be mapped into exactly the same registers as for 
> the function call that's making it, so it should produce some pretty 
> streamlined assembly.
> 
>   > if you can tell me how you want, i can generate a patch. ;)
> 
> Great, well see if you can get my example above going, then map it into 
> the syscall0 -> syscall5 macros

ok, here is my version of _sycall2

#define SYSCALL_CLOBBERS	"r3", "r4", "r11", "r12", "r17"

#define _syscall2(type, name, type1, arg1, type2, arg2)                 \
type name (type1 arg1, type2 arg2)                                      \
{                                                                       \
        register long __r5 __asm__ ("r5") = arg1;                       \
        register long __r6 __asm__ ("r6") = arg2;                       \
        long __ret;                                                     \
        __asm__ __volatile__ ("bralid	r17, 0x8	\n\t"           \
                              "addik	r12, r0, %1	\n\t"           \
                              "addk	%0, r3, r0	\n\t"           \
                              : "=r" (__ret)                            \
                              : "i" (__NR_##name),                      \
                                "r" (__r5),                             \
                                "r" (__r6)                              \
                              : SYSCALL_CLOBBERS);                      \
        __syscall_return (type, __ret);                                 \
}

the difference from John's are:

- keep using C declarations for syscall arguments.
- keey using __syscall_return
- no mention of SYSCALL_ARG# in clobbers. they are listed in input operand
- all volatile registers, except r5-r10, are in clobbers
- use type# and arg# instead of a b c.

this code generates some this like this with -Os:

   2ef98:       3021ffd8        addik   r1, r1, -40
   2ef9c:       fac10024        swi     r22, r1, 36
   2efa0:       d9e00800        sw      r15, r0, r1
   2efa4:       ba3c0008        bralid  r17, 8
   2efa8:       3180003f        addik   r12, r0, 63
   2efac:       12c30000        addk    r22, r3, r0
   2efb0:       aa56ff82        xori    r18, r22, -126
   2efb4:       bcb2000c        bgei    r18, 12         // 2efc0
   2efb8:       bcb60028        bgei    r22, 40         // 2efe0
   2efbc:       b800000c        bri     12              // 2efc8
   2efc0:       3656ff82        rsubik  r18, r22, -126
   2efc4:       bcb2001c        bgei    r18, 28         // 2efe0
   2efc8:       b000ffff        imm     -1
   2efcc:       b9f45d00        brlid   r15, 23808      // 24ccc <__errno_location>
   2efd0:       80000000        or      r0, r0, r0
   2efd4:       14960000        rsubk   r4, r22, r0
   2efd8:       d8801800        sw      r4, r0, r3
   2efdc:       32c0ffff        addik   r22, r0, -1
   2efe0:       10760000        addk    r3, r22, r0
   2efe4:       eac10024        lwi     r22, r1, 36
   2efe8:       c9e00800        lw      r15, r0, r1
   2efec:       b60f0008        rtsd    r15, 8
   2eff0:       30210028        addik   r1, r1, 40

the patch for unistd.h is attached.

regards,
--
         yashi

Attachment: unistd.h-1.3-explicit.patch
Description: Binary data