RE: -nostdlib option!

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

 



Yes.

Memset and memcpy are standalone functions. My team (at Edisoft) has a
version for these files.

For memcpy we have the file:

/**
 * @brief check if either of the addresses are aligned
 *
 * Nonzero if either X or Y is not aligned on a "long" boundary.
 */
#define UNALIGNED(X, Y) \
  (((uint32)X & (sizeof (uint32) - 1U)) | ((uint32)Y & (sizeof (uint32) -
1U)))

/**
 * @brief determine how many bytes are copied each iteration of the 4X
unrolled
 * loop
 */
#define BIGBLOCKSIZE    ((uint32)sizeof (sint32) << 2U)

/**
 * @brief determine how many bytes are copied each iteration of the word
copy
 * loop
 */
#define LITTLEBLOCKSIZE ((uint32)sizeof (sint32))

/**
 * @brief Threshhold for punting to the byte copier  */ #define
TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)


void *memcpy(void *dst0 , const void *src0 , rtems_size len0) {

#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

    /* get destination address as a byte pointer */
    sint8 *dst = (sint8 *) dst0;

    /* get source address as a byte pointer */
    sint8 *src = (const sint8 *) src0;

    
    /* save the destination address */
    void * save = dst0;

    /* copy the source vector to destination for len0 bytes*/
    while(len0--)
    {
        /* copy the source to the destination */
        *dst++ = *src++;
    }

    /* return the saved destination address */
    return save;

#else

    /* get destination address as a byte pointer */
    sint8 *dst = (sint8 *) dst0;

    /* get source address as a byte pointer */
    const sint8 *src = src0;

    /* alligned destination pointer */
    sint32 *aligned_dst;

    /* aligned source pointer */
    const sint32 *aligned_src;

    /* lenght in integer */
    uint32 len = (uint32) len0;


    /* If the size is small, or either SRC or DST is unaligned,
     * then punt into the byte copy loop.  This should be rare.  */
    if(( ( TOO_SMALL(len) ) == 0U ) &&
       ( ( UNALIGNED((uint32) src0 , (uint32) dst0) ) == FALSE ))
    {
        /* get the destination */
        aligned_dst = (sint32*) dst;

        /* get the source */
        aligned_src = (sint32*) src;

        /* Copy 4X long words at a time if possible.  */
        while(len >= BIGBLOCKSIZE)
        {
            /* copy the first 4 bytes */
            *aligned_dst = *aligned_src;
            aligned_dst++;
            aligned_src++;

            /* copy the second 4 bytes */
            *aligned_dst = *aligned_src;
            aligned_dst++;
            aligned_src++;

            /* copy the third 4 bytes */
            *aligned_dst = *aligned_src;
            aligned_dst++;
            aligned_src++;

            /* copy the fourth 4 bytes */
            *aligned_dst = *aligned_src;
            aligned_dst++;
            aligned_src++;

            /* decrement the number of bytes left to copy */
            len -= BIGBLOCKSIZE;
        }

        /* Copy one long word at a time if possible.  */
        while(len >= LITTLEBLOCKSIZE)
        {
            /* copy 4 bytes */
            *aligned_dst = *aligned_src;
            aligned_dst++;
            aligned_src++;

            /* decrement the number of bytes left to copy */
            len -= LITTLEBLOCKSIZE;
        }

        /* Pick up any residual with a byte copier.  */
        dst = (sint8*) aligned_dst;
        src = (sint8*) aligned_src;
    }

    /* copy residual bytes (maximum of 3) */
    while(len > 0U)
    {
        /* copy each byte */
        *dst = *src;

        /* increment the pointer */
        dst++;
        src++;

        /* decrement number of bytes */
        len--;
    }

    /* return the destination address */
    return dst0;
    
#endif /* not PREFER_SIZE_OVER_SPEED */
}




For the file memset.c we have the file:


/**
 * @brief size of a block
 */
#define LBLOCKSIZE ((uint32) sizeof(uintptr))

/**
 * @brief check if the address is alligned  */ #define UNALIGNED(X)
((uintptr)X & (LBLOCKSIZE - 1))

/**
 * @brief check if the size is too small  */ #define TOO_SMALL(LEN) ((LEN) <
LBLOCKSIZE)


void *memset(void *m , sint32 c , rtems_size n) {

#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

    /* copy the destination address to another variable */
    sint8 *s = (sint8 *) m;


    /* while there are bytes left to copy */
    while(n != 0)
    {
        /* copy the byte */
        *s = (sint8) c;

        /* increment index on array */
        s++;

        /* decrement number of remaining bytes to copy */
        n--;
    }

    /* return the destination address */
    return m;

#else
    
    /* pointer to address where to write */
    sint8 *s = (sint8 *) m;

    /* iterator */
    uint32 i;

    /* buffer where to place small array */
    uint32 buffer;

    /* pointer to address aligned */
    uintptr *aligned_addr;

    /* To avoid sign extension, copy c to an unsigned variable.  */
    uint32 d = (uint32) c & 0xffU;


    /* check if the size is too small or the destination address in not
aligned */
    if(( TOO_SMALL(n) == 0U ) && ( UNALIGNED(m) == 0U ))
    {
        /* If we get this far, we know that n is large and m is
word-aligned. */
        aligned_addr = (uint32*) m;

        /* Store D into each char sized location in BUFFER so that
                we can set large blocks quickly.  */
        if(LBLOCKSIZE == 4U)
        {
            /* copy to the buffer */
            buffer = (uint32) ( ( d << 8U ) | d );
            buffer = buffer | ( buffer << 16U );
        }
        else
        {
            /* reset the buffer */
            buffer = 0U;

            /* copy to the buffer the char */
            for(i = 0U; i < LBLOCKSIZE; i++)
            {
                buffer = ( buffer << 8U ) | d;
            }
        }

        /* copy the aligned bytes */
        while(n >= LBLOCKSIZE * 4U)
        {
            /* copy the first four byte word */
            *aligned_addr = buffer;
            aligned_addr++;

            /* copy the second four byte word */
            *aligned_addr = buffer;
            aligned_addr++;

            /* copy the third four byte word */
            *aligned_addr = buffer;
            aligned_addr++;

            /* copy the fourth four byte word */
            *aligned_addr = buffer;
            aligned_addr++;

            /* decrement the number of bytes copied */
            n -= (rtems_size) ( 4U * LBLOCKSIZE );
        }

        /* copy the remaining bytes */
        while(n >= LBLOCKSIZE)
        {
            /* copy the first four byte word */
            *aligned_addr = buffer;
            aligned_addr++;

            /* decrement the number of bytes copied */
            n -= LBLOCKSIZE;
        }
        /* Pick up the remainder with a bytewise loop.  */
        s = (sint8*) aligned_addr;
    }

    /* copy the remaining bytes */
    while(n > 0U)
    {
        /* copy the byte */
        *s = (sint8) d;
        s++;
        /* decrement size */
        n--;
    }

    /* return the destination address */
    return m;

#endif /* not PREFER_SIZE_OVER_SPEED */
}





Hope this help ;)
Manuel Coutinho

-----Original Message-----
From: gcc-help-owner@xxxxxxxxxxx [mailto:gcc-help-owner@xxxxxxxxxxx] On
Behalf Of Kai Ruottu
Sent: 07 February 2011 14:43
To: gcc-help@xxxxxxxxxxx
Cc: ali hagigat
Subject: Re: -nostdlib option!

7.2.2011 14:44, ali hagigat kirjoitti:

> How will be memset, memcpy, etc. Can i copy them from the source code
> of gcc? But they are dependent to other functions in other libraries
> probably and some headers.

Most probably these functions are standalone and don't
call other functions... Does your program really call
them? What does 'nm' say anout undefined symbols in the
compiled object(s)?

> Are those functions available stand alone some where?

For instance in :
   newlib-1.18.0/newlib/libc/machine/i386
in the current newlib sources.




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux