Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* GENbzero.S: Generic sparc64 memset/clear_user.
0003  *
0004  * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
0005  */
0006 #include <asm/asi.h>
0007 
0008 #define EX_ST(x,y)      \
0009 98: x,y;            \
0010     .section __ex_table,"a";\
0011     .align 4;       \
0012     .word 98b, __retl_o1_asi;\
0013     .text;          \
0014     .align 4;
0015 
0016     .align  32
0017     .text
0018 
0019     .globl      GENmemset
0020     .type       GENmemset, #function
0021 GENmemset:      /* %o0=buf, %o1=pat, %o2=len */
0022     and     %o1, 0xff, %o3
0023     mov     %o2, %o1
0024     sllx        %o3, 8, %g1
0025     or      %g1, %o3, %o2
0026     sllx        %o2, 16, %g1
0027     or      %g1, %o2, %o2
0028     sllx        %o2, 32, %g1
0029     ba,pt       %xcc, 1f
0030      or     %g1, %o2, %o2
0031 
0032     .globl      GENbzero
0033     .type       GENbzero, #function
0034 GENbzero:
0035     clr     %o2
0036 1:  brz,pn      %o1, GENbzero_return
0037      mov        %o0, %o3
0038 
0039     /* %o5: saved %asi, restored at GENbzero_done
0040      * %o4: store %asi to use
0041      */
0042     rd      %asi, %o5
0043     mov     ASI_P, %o4
0044     wr      %o4, 0x0, %asi
0045 
0046 GENbzero_from_clear_user:
0047     cmp     %o1, 15
0048     bl,pn       %icc, GENbzero_tiny
0049      andcc      %o0, 0x7, %g1
0050     be,pt       %xcc, 2f
0051      mov        8, %g2
0052     sub     %g2, %g1, %g1
0053     sub     %o1, %g1, %o1
0054 1:  EX_ST(stba %o2, [%o0 + 0x00] %asi)
0055     subcc       %g1, 1, %g1
0056     bne,pt      %xcc, 1b
0057      add        %o0, 1, %o0
0058 2:  cmp     %o1, 128
0059     bl,pn       %icc, GENbzero_medium
0060      andcc      %o0, (64 - 1), %g1
0061     be,pt       %xcc, GENbzero_pre_loop
0062      mov        64, %g2
0063     sub     %g2, %g1, %g1
0064     sub     %o1, %g1, %o1
0065 1:  EX_ST(stxa %o2, [%o0 + 0x00] %asi)
0066     subcc       %g1, 8, %g1
0067     bne,pt      %xcc, 1b
0068      add        %o0, 8, %o0
0069 
0070 GENbzero_pre_loop:
0071     andn        %o1, (64 - 1), %g1
0072     sub     %o1, %g1, %o1
0073 GENbzero_loop:
0074     EX_ST(stxa %o2, [%o0 + 0x00] %asi)
0075     EX_ST(stxa %o2, [%o0 + 0x08] %asi)
0076     EX_ST(stxa %o2, [%o0 + 0x10] %asi)
0077     EX_ST(stxa %o2, [%o0 + 0x18] %asi)
0078     EX_ST(stxa %o2, [%o0 + 0x20] %asi)
0079     EX_ST(stxa %o2, [%o0 + 0x28] %asi)
0080     EX_ST(stxa %o2, [%o0 + 0x30] %asi)
0081     EX_ST(stxa %o2, [%o0 + 0x38] %asi)
0082     subcc       %g1, 64, %g1
0083     bne,pt      %xcc, GENbzero_loop
0084      add        %o0, 64, %o0
0085 
0086     membar      #Sync
0087     wr      %o4, 0x0, %asi
0088     brz,pn      %o1, GENbzero_done
0089 GENbzero_medium:
0090      andncc     %o1, 0x7, %g1
0091     be,pn       %xcc, 2f
0092      sub        %o1, %g1, %o1
0093 1:  EX_ST(stxa %o2, [%o0 + 0x00] %asi)
0094     subcc       %g1, 8, %g1
0095     bne,pt      %xcc, 1b
0096      add        %o0, 8, %o0
0097 2:  brz,pt      %o1, GENbzero_done
0098      nop
0099 
0100 GENbzero_tiny:
0101 1:  EX_ST(stba %o2, [%o0 + 0x00] %asi)
0102     subcc       %o1, 1, %o1
0103     bne,pt      %icc, 1b
0104      add        %o0, 1, %o0
0105 
0106     /* fallthrough */
0107 
0108 GENbzero_done:
0109     wr      %o5, 0x0, %asi
0110 
0111 GENbzero_return:
0112     retl
0113      mov        %o3, %o0
0114     .size       GENbzero, .-GENbzero
0115     .size       GENmemset, .-GENmemset
0116 
0117     .globl      GENclear_user
0118     .type       GENclear_user, #function
0119 GENclear_user:      /* %o0=buf, %o1=len */
0120     rd      %asi, %o5
0121     brz,pn      %o1, GENbzero_done
0122      clr        %o3
0123     cmp     %o5, ASI_AIUS
0124     bne,pn      %icc, GENbzero
0125      clr        %o2
0126     ba,pt       %xcc, GENbzero_from_clear_user
0127      mov        ASI_AIUS, %o4
0128     .size       GENclear_user, .-GENclear_user
0129 
0130 #define BRANCH_ALWAYS   0x10680000
0131 #define NOP     0x01000000
0132 #define GEN_DO_PATCH(OLD, NEW)  \
0133     sethi   %hi(NEW), %g1; \
0134     or  %g1, %lo(NEW), %g1; \
0135     sethi   %hi(OLD), %g2; \
0136     or  %g2, %lo(OLD), %g2; \
0137     sub %g1, %g2, %g1; \
0138     sethi   %hi(BRANCH_ALWAYS), %g3; \
0139     sll %g1, 11, %g1; \
0140     srl %g1, 11 + 2, %g1; \
0141     or  %g3, %lo(BRANCH_ALWAYS), %g3; \
0142     or  %g3, %g1, %g3; \
0143     stw %g3, [%g2]; \
0144     sethi   %hi(NOP), %g3; \
0145     or  %g3, %lo(NOP), %g3; \
0146     stw %g3, [%g2 + 0x4]; \
0147     flush   %g2;
0148 
0149     .globl  generic_patch_bzero
0150     .type   generic_patch_bzero,#function
0151 generic_patch_bzero:
0152     GEN_DO_PATCH(memset, GENmemset)
0153     GEN_DO_PATCH(__bzero, GENbzero)
0154     GEN_DO_PATCH(__clear_user, GENclear_user)
0155     retl
0156      nop
0157     .size   generic_patch_bzero,.-generic_patch_bzero