Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* linux/arch/sparc/lib/memset.S: Sparc optimized memset, bzero and clear_user code
0003  * Copyright (C) 1991,1996 Free Software Foundation
0004  * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
0005  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
0006  *
0007  * Calls to memset returns initial %o0. Calls to bzero returns 0, if ok, and
0008  * number of bytes not yet set if exception occurs and we were called as
0009  * clear_user.
0010  */
0011 
0012 #include <asm/ptrace.h>
0013 #include <asm/export.h>
0014 
0015 /* Work around cpp -rob */
0016 #define ALLOC #alloc
0017 #define EXECINSTR #execinstr
0018 #define EX(x,y,a,b)                 \
0019 98:     x,y;                    \
0020     .section .fixup,ALLOC,EXECINSTR;    \
0021     .align  4;              \
0022 99: retl;                   \
0023      a, b, %o0;             \
0024     .section __ex_table,ALLOC;      \
0025     .align  4;              \
0026     .word   98b, 99b;           \
0027     .text;                  \
0028     .align  4
0029 
0030 #define STORE(source, base, offset, n)      \
0031 98:     std source, [base + offset + n];    \
0032     .section .fixup,ALLOC,EXECINSTR;    \
0033     .align  4;              \
0034 99: ba 30f;                 \
0035      sub %o3, n - offset, %o3;      \
0036     .section __ex_table,ALLOC;      \
0037     .align  4;              \
0038     .word   98b, 99b;           \
0039     .text;                  \
0040     .align  4;
0041 
0042 #define STORE_LAST(source, base, offset, n) \
0043     EX(std source, [base - offset - n], \
0044        add %o1, offset + n);
0045 
0046 /* Please don't change these macros, unless you change the logic
0047  * in the .fixup section below as well.
0048  * Store 64 bytes at (BASE + OFFSET) using value SOURCE. */
0049 #define ZERO_BIG_BLOCK(base, offset, source)    \
0050     STORE(source, base, offset, 0x00);  \
0051     STORE(source, base, offset, 0x08);  \
0052     STORE(source, base, offset, 0x10);  \
0053     STORE(source, base, offset, 0x18);  \
0054     STORE(source, base, offset, 0x20);  \
0055     STORE(source, base, offset, 0x28);  \
0056     STORE(source, base, offset, 0x30);  \
0057     STORE(source, base, offset, 0x38);
0058 
0059 #define ZERO_LAST_BLOCKS(base, offset, source)  \
0060     STORE_LAST(source, base, offset, 0x38); \
0061     STORE_LAST(source, base, offset, 0x30); \
0062     STORE_LAST(source, base, offset, 0x28); \
0063     STORE_LAST(source, base, offset, 0x20); \
0064     STORE_LAST(source, base, offset, 0x18); \
0065     STORE_LAST(source, base, offset, 0x10); \
0066     STORE_LAST(source, base, offset, 0x08); \
0067     STORE_LAST(source, base, offset, 0x00);
0068 
0069     .text
0070     .align 4
0071 
0072         .globl  __bzero_begin
0073 __bzero_begin:
0074 
0075     .globl  __bzero
0076     .type   __bzero,#function
0077     .globl  memset
0078     EXPORT_SYMBOL(__bzero)
0079     EXPORT_SYMBOL(memset)
0080 memset:
0081     mov %o0, %g1
0082     mov 1, %g4
0083     and %o1, 0xff, %g3
0084     sll %g3, 8, %g2
0085     or  %g3, %g2, %g3
0086     sll %g3, 16, %g2
0087     or  %g3, %g2, %g3
0088     b   1f
0089      mov    %o2, %o1
0090 3:
0091     cmp %o2, 3
0092     be  2f
0093      EX(stb %g3, [%o0], sub %o1, 0)
0094 
0095     cmp %o2, 2
0096     be  2f
0097      EX(stb %g3, [%o0 + 0x01], sub %o1, 1)
0098 
0099     EX(stb  %g3, [%o0 + 0x02], sub %o1, 2)
0100 2:
0101     sub %o2, 4, %o2
0102     add %o1, %o2, %o1
0103     b   4f
0104      sub    %o0, %o2, %o0
0105 
0106 __bzero:
0107     clr %g4
0108     mov %g0, %g3
0109 1:
0110     cmp %o1, 7
0111     bleu    7f
0112      andcc  %o0, 3, %o2
0113 
0114     bne 3b
0115 4:
0116      andcc  %o0, 4, %g0
0117 
0118     be  2f
0119      mov    %g3, %g2
0120 
0121     EX(st   %g3, [%o0], sub %o1, 0)
0122     sub %o1, 4, %o1
0123     add %o0, 4, %o0
0124 2:
0125     andcc   %o1, 0xffffff80, %o3    ! Now everything is 8 aligned and o1 is len to run
0126     be  9f
0127      andcc  %o1, 0x78, %o2
0128 10:
0129     ZERO_BIG_BLOCK(%o0, 0x00, %g2)
0130     subcc   %o3, 128, %o3
0131     ZERO_BIG_BLOCK(%o0, 0x40, %g2)
0132     bne 10b
0133      add    %o0, 128, %o0
0134 
0135     orcc    %o2, %g0, %g0
0136 9:
0137     be  13f
0138      andcc  %o1, 7, %o1
0139 
0140     srl %o2, 1, %o3
0141     set 13f, %o4
0142     sub %o4, %o3, %o4
0143     jmp %o4
0144      add    %o0, %o2, %o0
0145 
0146     ZERO_LAST_BLOCKS(%o0, 0x48, %g2)
0147     ZERO_LAST_BLOCKS(%o0, 0x08, %g2)
0148 13:
0149     be  8f
0150      andcc  %o1, 4, %g0
0151 
0152     be  1f
0153      andcc  %o1, 2, %g0
0154 
0155     EX(st   %g3, [%o0], and %o1, 7)
0156     add %o0, 4, %o0
0157 1:
0158     be  1f
0159      andcc  %o1, 1, %g0
0160 
0161     EX(sth  %g3, [%o0], and %o1, 3)
0162     add %o0, 2, %o0
0163 1:
0164     bne,a   8f
0165      EX(stb %g3, [%o0], and %o1, 1)
0166 8:
0167     b   0f
0168      nop
0169 7:
0170     be  13b
0171      orcc   %o1, 0, %g0
0172 
0173     be  0f
0174 8:
0175      add    %o0, 1, %o0
0176     subcc   %o1, 1, %o1
0177     bne 8b
0178      EX(stb %g3, [%o0 - 1], add %o1, 1)
0179 0:
0180     andcc   %g4, 1, %g0
0181     be  5f
0182      nop
0183     retl
0184      mov    %g1, %o0
0185 5:
0186     retl
0187      clr    %o0
0188 
0189     .section .fixup,#alloc,#execinstr
0190     .align  4
0191 30:
0192     and %o1, 0x7f, %o1
0193     retl
0194      add    %o3, %o1, %o0
0195 
0196     .globl __bzero_end
0197 __bzero_end: