blob: a900b92cbe53930431d490473d1f98ef0f3e795b [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
2 * Copyright (C) 2004 Joakim Tjernlund
3 * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
4 *
5 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
6 */
7
8/* These are carefully optimized mem*() functions for PPC written in C.
9 * Don't muck around with these function without checking the generated
10 * assembler code.
11 * It is possible to optimize these significantly more by using specific
12 * data cache instructions(mainly dcbz). However that requires knownledge
13 * about the CPU's cache line size.
14 *
15 * BUG ALERT!
16 * The cache instructions on MPC8xx CPU's are buggy(they don't update
17 * the DAR register when causing a DTLB Miss/Error) and cannot be
18 * used on 8xx CPU's without a kernel patch to work around this
19 * problem.
20 */
21
22#include <string.h>
23
24
25static __inline__ int expand_byte_word(int c){
26 /* this does:
27 c = c << 8 | c;
28 c = c << 16 | c ;
29 */
30 __asm__("rlwimi %0,%0,8,16,23\n"
31 "\trlwimi %0,%0,16,0,15\n"
32 : "=r" (c) : "0" (c));
33 return c;
34}
35
36void *memset(void *to, int c, size_t n)
37{
38 unsigned long rem, chunks;
39 unsigned char *tmp_to;
40
41 chunks = n / 8;
42 tmp_to = to - 4;
43 c = expand_byte_word(c);
44 if (!chunks)
45 goto lessthan8;
46 rem = (unsigned long )tmp_to % 4;
47 if (rem)
48 goto align;
49 copy_chunks:
50 do {
51 *(unsigned long *)(tmp_to+4) = c;
52 tmp_to += 4;
53 *(unsigned long *)(tmp_to+4) = c;
54 tmp_to += 4;
55 } while (--chunks);
56 lessthan8:
57 n = n % 8;
58 if (n >= 4) {
59 *(unsigned long *)(tmp_to+4) = c;
60 tmp_to += 4;
61 n = n-4;
62 }
63 if (!n ) return to;
64 tmp_to += 3;
65 do {
66 *++tmp_to = c;
67 } while (--n);
68
69 return to;
70 align:
71 rem = 4 - rem;
72 n = n-rem;
73 do {
74 *(tmp_to+4) = c;
75 ++tmp_to;
76 } while (--rem);
77 chunks = n / 8;
78 if (chunks)
79 goto copy_chunks;
80 goto lessthan8;
81}
82libc_hidden_def(memset)