Re: sparc implementation

From: Paul H. Hargrove (PHHargrove_at_lbl_dot_gov)
Date: Wed Sep 03 2008 - 13:31:04 PDT

  • Next message: Paul H. Hargrove: "Re: sparc implementation"
    The syscall macros you wrote may have taken my suggestion too literally, 
    or perhaps I was not as clear as I intended.  I sometimes take for 
    granted how much of the non-obvious stuff I already know.
    
    1) The macros from glibc are gcc-specific "expression statements" (or 
    something like that), which is why they are bracketed as ({ body }).  
    Such an compound expression evaluates to its last statement, which is 
    __o0 in the case of the glibc syscall macros.
    
    2) BLCR needs a macro that expands to define entire function, with a 
    returned value, not just an expression which evaluates to the desired 
    value.  So, we need to pass __o0 into the cri_syscall_cleanup() macro, 
    and then return it.
    
    3) BLCR want's to look at the value and if it is bigger than 0xFFFFF000 
    (or 0xFFFFFFFFFFFFF000 on 64-bit) put its negative into *errno_p (if 
    non-NULL) and change the return value to -1.  That is the purpose of 
    cri_syscall_cleanup().  This differs just slightly from the normal 
    kernel return ABI.
    
    4) The "memory", "cc", "cx", "dx" stuff is x86-specific register 
    clobbers which you should remove.
    
    5) The "string" is supplied by one of the ALL_CAPS macros earlier in 
    .../sparc/sysdep.h, which in turn use values that are defined in 
    .../sparc/sparc32/sysdep.h or .../sparc/sparc64/sysdep.h (same files 
    which provide the value for __SYSCALL_CLOBBERS.  I believe you want 
    "string" to be __INTERNAL_SYSCALL_STRING, being sure to get the correct 
    32-bit or 64-bit version.  However, the __INTERNAL_SYSCALL_STRING 
    appears to handle the errno-related stuff a little bit on its own, so we 
    don't want to use it exactly.  In fact, I think that we can discard 
    attempts as being optimal and just strip the error handing out of 
    __INTERNAL_SYSCALL_STRING and leave it all in cri_syscall_cleanup().
    
    So changes needed:
    a) remove the x86-specific asm() from cri_syscall_cleanup()
    b) remove lone "__o0;" line
    c) pass __o0 in place of __g1 to cri_syscall_cleanup()
    d) return __o0 (with an explicit cast to "type" to avoid gcc warnings)
    e) insert the proper value in place of "string" and __SYSCALL_CLOBBERS
    
    So,  I think you want the following:
    
    #if (SIZEOF_VOID_P == 4)
      #define CRI_SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6",   \
           "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",         \
           "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",   \
           "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
           "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
           "cc", "memory"
      #define CRI_SYSCALL_STRING "ta     0x10;"
    #elif (SIZEOF_VOID_P == 8)
      #define CRI_SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6",   \
           "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",         \
           "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",   \
           "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
           "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
           "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
           "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
           "cc", "memory"
      #define CRI_SYSCALL_STRING "ta     0x6d;"
    #else
      #error "Unknown SIZEOF_VOID_P"
    #endif
    
    #define cri_syscall_cleanup(res,errno_p) \
        if ((unsigned long)res >= (unsigned long)(-4096)) { \
            if (errno_p != NULL) { *errno_p = -res; }       \
            res = -1;                                       \
        }
    
    #define cri_syscall0(type,name,nr)                                      \
    type name(int *errno_p)                                                 \
    {                                                                       \
            register long __o0 __asm__ ("o0");                              \
            register long __g1 __asm__ ("g1") = name;                       \
            __asm __volatile (CRI_SYSCALL_STRING :                          \
                              "=r" (__g1), "=r" (__o0) :                    \
                              "0" (__g1) :                                  \
                              CRI_SYSCALL_CLOBBERS);                        \
            cri_syscall_cleanup(__o0, errno_p);                             \
            return (type)__o0;                                              \
    }
    
    #define cri_syscall1(type,name,nr,arg1)                                 \
    type name(type1 arg1,int *errno_p)                                      \
    {                                                                       \
            register long __o0 __asm__ ("o0") = (long)(arg1);               \
            register long __g1 __asm__ ("g1") = name;                       \
            __asm __volatile (CRI_SYSCALL_STRING :                          \
                              "=r" (__g1), "=r" (__o0) :                    \
                              "0" (__g1), "1" (__o0) :                      \
                              _CRI_SYSCALL_CLOBBERS);                       \
            cri_syscall_cleanup(__o0, errno_p);                             \
            return (type)__o0;                                              \
    }
    
    Just to be 100% proper about this code I've included here:
    Signed-off-by: Paul H. Hargrove <PHHargrove_at_lbl_dot_gov>
    
    -Paul
    
    Vincentius Robby wrote:
    > Hello Paul,
    >
    > Apologies, regarding the directory I forgot to add the CR_ARCH32 
    > option because I was working on a 64-bit sparc machine for testing this.
    > While my question regarding the fetch and add still stands, I am 
    > playing around with the syscall handlers now. Currently the errors I 
    > am encountering are:
    >         then mv -f ".deps/libcr_la-cr_syscall.Tpo" 
    > ".deps/libcr_la-cr_syscall.Plo"; else rm -f 
    > ".deps/libcr_la-cr_syscall.Tpo"; exit 1; fi
    >  gcc -DHAVE_CONFIG_H -I. -I../../libcr -I.. -D_GNU_SOURCE -D_REENTRANT 
    > -I../include -I../../include -I../../libcr/arch/sparc/ -Wall 
    > -Wno-unused-function -fno-stack-protector -g -O2 -MT 
    > libcr_la-cr_syscall.lo -MD -MP -MF .deps/libcr_la-cr_syscall.Tpo -c 
    > ../../libcr/cr_syscall.c  -fPIC -DPIC -o .libs/libcr_la-cr_syscall.o
    > ../../libcr/cr_syscall.c:169: error: expected ')' before 'int'
    > ../../libcr/cr_syscall.c:170: error: expected ')' before 'const'
    > ../../libcr/cr_syscall.c:171: error: expected ')' before 'int'
    > ../../libcr/cr_syscall.c: In function '__cri_sched_yield':
    > ../../libcr/cr_syscall.c:172: warning: initialization makes integer 
    > from pointer without a cast
    > ../../libcr/cr_syscall.c:172: error: expected string literal before 
    > 'string'
    > ../../libcr/cr_syscall.c:172: warning: statement with no effect
    > ../../libcr/cr_syscall.c: At top level:
    > ../../libcr/cr_syscall.c:173: error: expected ')' before 'const'
    > ../../libcr/cr_syscall.c:174: error: expected ')' before 'int'
    > ../../libcr/cr_syscall.c:176: error: expected ')' before 'int'
    > ../../libcr/cr_syscall.c:183: error: expected ')' before 'int'
    > ../../libcr/cr_syscall.c:189: error: expected ')' before 'int'
    > make[2]: *** [libcr_la-cr_syscall.lo] Error 1
    > make[2]: Leaving directory `/opt/blcr-0.7.3_vincent/builddir/libcr'
    >
    > and this is what the beginning of libcr/arch/sparc/cr_arch.h looks like:
    > #define cri_syscall_cleanup(res,errno_p) \
    >     __asm__ volatile ("" ::: "memory", "cc", "cx", "dx");\
    >     if ((unsigned long)res >= (unsigned long)(-4096)) { \
    >         if (errno_p != NULL) { *errno_p = -res; }       \
    >         res = -1;                                       \
    >     }
    >
    > #define cri_syscall0(type,name,nr)                                      \
    > type name(int *errno_p)                                                 \
    > {                                                                       \
    >         register long __o0 __asm__ ("o0");                              \
    >         register long __g1 __asm__ ("g1") = name;                       \
    >         __asm __volatile (string : "=r" (__g1), "=r" (__o0) :           \
    >                           "0" (__g1) :                                  \
    >                           __SYSCALL_CLOBBERS);                          \
    >         __o0;                                                           \
    >         cri_syscall_cleanup(__g1, errno_p);                             \
    > }
    >
    > #define cri_syscall1(type,name,nr,arg1)                                 \
    > type name(type1 arg1,int *errno_p)                                      \
    > {                                                                       \
    >         register long __o0 __asm__ ("o0") = (long)(arg1);               \
    >         register long __g1 __asm__ ("g1") = name;                       \
    >         __asm __volatile (string : "=r" (__g1), "=r" (__o0) :           \
    >                           "0" (__g1), "1" (__o0) :                      \
    >                           __SYSCALL_CLOBBERS);                          \
    >         __o0;                                                           \
    >         cri_syscall_cleanup(__g1, errno_p);                             \
    > }
    >
    > One question I have is where it is written __asm __volatile (string :, 
    > is the string to be replaced by 'type'? Originally the inline_syscall 
    > has arguments (string,name) so I assumed I had to change the 'string' 
    > to 'type' in the __asm __volatile arguments but after these errors I 
    > changed it back, but either way it was not a solution to the errors. 
    > Is this what you mentioned for the inclusion syscall_cleanup routine 
    > as well?
    >
    > Thank you.
    >
    
    
    -- 
    Paul H. Hargrove                          PHHargrove_at_lbl_dot_gov
    Future Technologies Group                 
    HPC Research Department                   Tel: +1-510-495-2352
    Lawrence Berkeley National Laboratory     Fax: +1-510-486-6900
    

  • Next message: Paul H. Hargrove: "Re: sparc implementation"