Re: sparc implementation

From: Vincentius Robby (vincentius_at_umich_dot_edu)
Date: Wed Sep 03 2008 - 20:59:00 PDT

  • Next message: Paul H. Hargrove: "Re: sparc implementation"
    Hello Paul,
    
    Ah, I'm learning a lot here..
    The next step that I haven't been able to figure out is the errors  
    which I referenced in the previous e-mail:
    
             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: 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'
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/opt/blcr-0.7.3_vincent/builddir'
    make: *** [all] Error 2
    
    Here is the snippet from cr_syscall.c
    169:cri_syscall3(int, __cri_ioctl, __NR_ioctl, int, int, void*)
    170:cri_syscall3(int, __cri_open, __NR_open, const char*, int, int)
    171:cri_syscall1(int, __cri_close, __NR_close, int);
    172:cri_syscall0(int, __cri_sched_yield, __NR_sched_yield)
    173:cri_syscall2(int, __cri_nanosleep, __NR_nanosleep, const struct  
    timespec*, struct timespec*)
    174:cri_syscall1(int, __cri_exit, __NR_exit, int)
    
    It appears to be the result of a badly written macro. I attempted to  
    check for any missing or extra brackets but was unable to spot any.  
    Here is the code for cri_syscall3:
    #define cri_syscall3(type,name,nr,arg1,arg2,arg3)			\
    type name(type1 arg1,type2 arg2,type3 arg3,int *errno_p)		\
    {									\
    	register long __o0 __asm__ ("o0") = (long)(arg1);		\
    	register long __o1 __asm__ ("o1") = (long)(arg2);		\
    	register long __o2 __asm__ ("o2") = (long)(arg3);		\
    	register long __g1 __asm__ ("g1") = name;			\
    	__asm __volatile (CRI_SYSCALL_STRING :				\
    			  "=r" (__g1), "=r" (__o0) :			\
    			  "0" (__g1), "1" (__o0), "r" (__o1),		\
    			  "r" (__o2) :					\
    			  _CRI_SYSCALL_CLOBBERS);			\
    	cri_syscall_cleanup(__o0, errno_p);                             \
    	return (type)__o0;                                              \
    }
    
    If you have some time, would you check whether this is written  
    correctly? Hopefully this is the last step of porting to sparc.
    
    Thank you.
    
    -- 
    Vincentius Robby
    
    
    Quoting "Paul H. Hargrove" <PHHargrove_at_lbl_dot_gov>:
    
    > 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
    >
    >
    > -- 
    > 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"