Changeset 8a5a902 in mainline


Ignore:
Timestamp:
2013-03-29T16:26:39Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0ca441c
Parents:
2d1195c0
Message:

GCC 4.8 recognizes parts of our C implementation of memset() and memcpy() and actually emits a call to memset() and memcpy()
(which is of course futile and only causes an infinite recursion)
switch to a hand-written memset() and memcpy()

Files:
1 added
2 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • boot/generic/include/memstr.h

    r2d1195c0 r8a5a902  
    3535#include <typedefs.h>
    3636
    37 extern void *memcpy(void *, const void *, size_t);
    38 extern void *memset(void *, int, size_t);
    3937extern void *memmove(void *, const void *, size_t);
    4038
  • boot/generic/src/memstr.c

    r2d1195c0 r8a5a902  
    2929#include <memstr.h>
    3030#include <typedefs.h>
    31 
    32 /** Move memory block without overlapping.
    33  *
    34  * Copy cnt bytes from src address to dst address. The source
    35  * and destination memory areas cannot overlap.
    36  *
    37  * @param dst Destination address to copy to.
    38  * @param src Source address to copy from.
    39  * @param cnt Number of bytes to copy.
    40  *
    41  * @return Destination address.
    42  *
    43  */
    44 void *memcpy(void *dst, const void *src, size_t cnt)
    45 {
    46         uint8_t *dp = (uint8_t *) dst;
    47         const uint8_t *sp = (uint8_t *) src;
    48        
    49         while (cnt-- != 0)
    50                 *dp++ = *sp++;
    51        
    52         return dst;
    53 }
    54 
    55 /** Fill block of memory.
    56  *
    57  * Fill cnt bytes at dst address with the value val.
    58  *
    59  * @param dst Destination address to fill.
    60  * @param val Value to fill.
    61  * @param cnt Number of bytes to fill.
    62  *
    63  * @return Destination address.
    64  *
    65  */
    66 void *memset(void *dst, int val, size_t cnt)
    67 {
    68         uint8_t *dp = (uint8_t *) dst;
    69        
    70         while (cnt-- != 0)
    71                 *dp++ = val;
    72        
    73         return dst;
    74 }
    7531
    7632/** Move memory block with possible overlapping.
  • kernel/Makefile

    r2d1195c0 r8a5a902  
    228228        generic/src/lib/func.c \
    229229        generic/src/lib/memstr.c \
    230         generic/src/lib/memfnc.c \
    231230        generic/src/lib/sort.c \
    232231        generic/src/lib/str.c \
  • kernel/arch/ia32/src/asm.S

    r2d1195c0 r8a5a902  
    3838.global paging_on
    3939.global enable_l_apic_in_msr
     40.global memset
     41.global memcpy
    4042.global memcpy_from_uspace
    4143.global memcpy_from_uspace_failover_address
     
    4446.global early_putchar
    4547
     48#define MEMSET_DST   4
     49#define MEMSET_VAL   8
     50#define MEMSET_SIZE  12
     51
    4652#define MEMCPY_DST   4
    4753#define MEMCPY_SRC   8
    4854#define MEMCPY_SIZE  12
     55
     56/* Fill memory with byte pattern
     57 *
     58 * This is a conventional memset().
     59 *
     60 * @param MEMSET_DST(%esp)  Destination address.
     61 * @param MEMSET_VAL(%esp)  Value to fill.
     62 * @param MEMSET_SIZE(%esp) Size.
     63 *
     64 * @return MEMSET_DST(%esp).
     65 *
     66 */
     67memset:
     68        movl %edi, %edx  /* save %edi */
     69       
     70        movl MEMSET_DST(%esp), %edi
     71        movl MEMSET_VAL(%esp), %ecx
     72       
     73        /* Create byte pattern */
     74        movb %cl, %ch
     75        movw %cx, %ax
     76        shll $16, %eax
     77        orw %cx, %ax
     78       
     79        movl MEMSET_SIZE(%esp), %ecx
     80        shrl $2, %ecx  /* size / 4 */
     81       
     82        /* Write whole words */
     83        rep stosl
     84       
     85        movl MEMSET_SIZE(%esp), %ecx
     86        andl $3, %ecx  /* size % 4 */
     87        jz 0f
     88       
     89        /* Copy the rest byte by byte */
     90        rep stosb
     91       
     92        0:
     93       
     94                movl %edx, %edi
     95               
     96                /* MEMSET_DST(%esp), success */
     97                movl MEMSET_DST(%esp), %eax
     98                ret
    4999
    50100/** Copy memory to/from userspace.
     
    63113 *
    64114 */
     115memcpy:
    65116memcpy_from_uspace:
    66117memcpy_to_uspace:
  • uspace/lib/c/arch/ia32/Makefile.inc

    r2d1195c0 r8a5a902  
    2828
    2929ARCH_SOURCES = \
     30        arch/$(UARCH)/src/asm.S \
    3031        arch/$(UARCH)/src/entry.S \
    3132        arch/$(UARCH)/src/entryjmp.s \
  • uspace/lib/c/generic/mem.c

    r2d1195c0 r8a5a902  
    3737#include <stdlib.h>
    3838#include <sys/types.h>
    39 
    40 /** Fill memory block with a constant value. */
    41 void *memset(void *dest, int b, size_t n)
    42 {
    43         char *pb;
    44         unsigned long *pw;
    45         size_t word_size;
    46         size_t n_words;
    47 
    48         unsigned long pattern;
    49         size_t i;
    50         size_t fill;
    51 
    52         /* Fill initial segment. */
    53         word_size = sizeof(unsigned long);
    54         fill = word_size - ((uintptr_t) dest & (word_size - 1));
    55         if (fill > n) fill = n;
    56 
    57         pb = dest;
    58 
    59         i = fill;
    60         while (i-- != 0)
    61                 *pb++ = b;
    62 
    63         /* Compute remaining size. */
    64         n -= fill;
    65         if (n == 0) return dest;
    66 
    67         n_words = n / word_size;
    68         n = n % word_size;
    69         pw = (unsigned long *) pb;
    70 
    71         /* Create word-sized pattern for aligned segment. */
    72         pattern = 0;
    73         i = word_size;
    74         while (i-- != 0)
    75                 pattern = (pattern << 8) | (uint8_t) b;
    76 
    77         /* Fill aligned segment. */
    78         i = n_words;
    79         while (i-- != 0)
    80                 *pw++ = pattern;
    81 
    82         pb = (char *) pw;
    83 
    84         /* Fill final segment. */
    85         i = n;
    86         while (i-- != 0)
    87                 *pb++ = b;
    88 
    89         return dest;
    90 }
    91 
    92 struct along {
    93         unsigned long n;
    94 } __attribute__ ((packed));
    95 
    96 static void *unaligned_memcpy(void *dst, const void *src, size_t n)
    97 {
    98         size_t i, j;
    99         struct along *adst = dst;
    100         const struct along *asrc = src;
    101 
    102         for (i = 0; i < n / sizeof(unsigned long); i++)
    103                 adst[i].n = asrc[i].n;
    104                
    105         for (j = 0; j < n % sizeof(unsigned long); j++)
    106                 ((unsigned char *) (((unsigned long *) dst) + i))[j] =
    107                     ((unsigned char *) (((unsigned long *) src) + i))[j];
    108                
    109         return (char *) dst;
    110 }
    111 
    112 /** Copy memory block. */
    113 void *memcpy(void *dst, const void *src, size_t n)
    114 {
    115         size_t i;
    116         size_t mod, fill;
    117         size_t word_size;
    118         size_t n_words;
    119 
    120         const unsigned long *srcw;
    121         unsigned long *dstw;
    122         const uint8_t *srcb;
    123         uint8_t *dstb;
    124 
    125         word_size = sizeof(unsigned long);
    126 
    127         /*
    128          * Are source and destination addresses congruent modulo word_size?
    129          * If not, use unaligned_memcpy().
    130          */
    131 
    132         if (((uintptr_t) dst & (word_size - 1)) !=
    133             ((uintptr_t) src & (word_size - 1)))
    134                 return unaligned_memcpy(dst, src, n);
    135 
    136         /*
    137          * mod is the address modulo word size. fill is the length of the
    138          * initial buffer segment before the first word boundary.
    139          * If the buffer is very short, use unaligned_memcpy(), too.
    140          */
    141 
    142         mod = (uintptr_t) dst & (word_size - 1);
    143         fill = word_size - mod;
    144         if (fill > n) fill = n;
    145 
    146         /* Copy the initial segment. */
    147 
    148         srcb = src;
    149         dstb = dst;
    150 
    151         i = fill;
    152         while (i-- != 0)
    153                 *dstb++ = *srcb++;
    154 
    155         /* Compute remaining length. */
    156 
    157         n -= fill;
    158         if (n == 0) return dst;
    159 
    160         /* Pointers to aligned segment. */
    161 
    162         dstw = (unsigned long *) dstb;
    163         srcw = (const unsigned long *) srcb;
    164 
    165         n_words = n / word_size;        /* Number of whole words to copy. */
    166         n -= n_words * word_size;       /* Remaining bytes at the end. */
    167 
    168         /* "Fast" copy. */
    169         i = n_words;
    170         while (i-- != 0)
    171                 *dstw++ = *srcw++;
    172 
    173         /*
    174          * Copy the rest.
    175          */
    176 
    177         srcb = (const uint8_t *) srcw;
    178         dstb = (uint8_t *) dstw;
    179 
    180         i = n;
    181         while (i-- != 0)
    182                 *dstb++ = *srcb++;
    183 
    184         return dst;
    185 }
    18639
    18740/** Move memory block with possible overlapping. */
  • uspace/lib/c/include/mem.h

    r2d1195c0 r8a5a902  
    3838#include <sys/types.h>
    3939
     40#define memset(dst, val, cnt)  __builtin_memset((dst), (val), (cnt))
     41#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     42
    4043#define bzero(ptr, len)  memset((ptr), 0, (len))
    4144
    42 extern void *memset(void *, int, size_t);
    43 extern void *memcpy(void *, const void *, size_t);
    4445extern void *memmove(void *, const void *, size_t);
    45 
    4646extern int bcmp(const void *, const void *, size_t);
    4747
  • uspace/lib/posix/include/posix/string.h

    r2d1195c0 r8a5a902  
    6060 * forward declarations ought to be enough.
    6161 */
     62
    6263/* From str.h. */
    63 extern char * strtok_r(char *, const char *, char **);
    64 extern char * strtok(char *, const char *);
     64
     65extern char *strtok_r(char *, const char *, char **);
     66extern char *strtok(char *, const char *);
    6567
    6668/* From mem.h */
     69
     70#define memset(dst, val, cnt)  __builtin_memset((dst), (val), (cnt))
     71#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     72
    6773#define bzero(ptr, len)  memset((ptr), 0, (len))
    68 extern void *memset(void *, int, size_t);
    69 extern void *memcpy(void *, const void *, size_t);
     74
    7075extern void *memmove(void *, const void *, size_t);
    71 
     76extern int bcmp(const void *, const void *, size_t);
    7277
    7378/* Copying and Concatenation */
Note: See TracChangeset for help on using the changeset viewer.