Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* NGbzero.S: Niagara optimized memset/clear_user.
0003  *
0004  * Copyright (C) 2006 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     .text
0017 
0018     .globl      NGmemset
0019     .type       NGmemset, #function
0020 NGmemset:       /* %o0=buf, %o1=pat, %o2=len */
0021     and     %o1, 0xff, %o3
0022     mov     %o2, %o1
0023     sllx        %o3, 8, %g1
0024     or      %g1, %o3, %o2
0025     sllx        %o2, 16, %g1
0026     or      %g1, %o2, %o2
0027     sllx        %o2, 32, %g1
0028     ba,pt       %xcc, 1f
0029      or     %g1, %o2, %o2
0030 
0031     .globl      NGbzero
0032     .type       NGbzero, #function
0033 NGbzero:
0034     clr     %o2
0035 1:  brz,pn      %o1, NGbzero_return
0036      mov        %o0, %o3
0037 
0038     /* %o5: saved %asi, restored at NGbzero_done
0039      * %g7: store-init %asi to use
0040      * %o4: non-store-init %asi to use
0041      */
0042     rd      %asi, %o5
0043     mov     ASI_BLK_INIT_QUAD_LDD_P, %g7
0044     mov     ASI_P, %o4
0045     wr      %o4, 0x0, %asi
0046 
0047 NGbzero_from_clear_user:
0048     cmp     %o1, 15
0049     bl,pn       %icc, NGbzero_tiny
0050      andcc      %o0, 0x7, %g1
0051     be,pt       %xcc, 2f
0052      mov        8, %g2
0053     sub     %g2, %g1, %g1
0054     sub     %o1, %g1, %o1
0055 1:  EX_ST(stba %o2, [%o0 + 0x00] %asi)
0056     subcc       %g1, 1, %g1
0057     bne,pt      %xcc, 1b
0058      add        %o0, 1, %o0
0059 2:  cmp     %o1, 128
0060     bl,pn       %icc, NGbzero_medium
0061      andcc      %o0, (64 - 1), %g1
0062     be,pt       %xcc, NGbzero_pre_loop
0063      mov        64, %g2
0064     sub     %g2, %g1, %g1
0065     sub     %o1, %g1, %o1
0066 1:  EX_ST(stxa %o2, [%o0 + 0x00] %asi)
0067     subcc       %g1, 8, %g1
0068     bne,pt      %xcc, 1b
0069      add        %o0, 8, %o0
0070 
0071 NGbzero_pre_loop:
0072     wr      %g7, 0x0, %asi
0073     andn        %o1, (64 - 1), %g1
0074     sub     %o1, %g1, %o1
0075 NGbzero_loop:
0076     EX_ST(stxa %o2, [%o0 + 0x00] %asi)
0077     EX_ST(stxa %o2, [%o0 + 0x08] %asi)
0078     EX_ST(stxa %o2, [%o0 + 0x10] %asi)
0079     EX_ST(stxa %o2, [%o0 + 0x18] %asi)
0080     EX_ST(stxa %o2, [%o0 + 0x20] %asi)
0081     EX_ST(stxa %o2, [%o0 + 0x28] %asi)
0082     EX_ST(stxa %o2, [%o0 + 0x30] %asi)
0083     EX_ST(stxa %o2, [%o0 + 0x38] %asi)
0084     subcc       %g1, 64, %g1
0085     bne,pt      %xcc, NGbzero_loop
0086      add        %o0, 64, %o0
0087 
0088     membar      #Sync
0089     wr      %o4, 0x0, %asi
0090     brz,pn      %o1, NGbzero_done
0091 NGbzero_medium:
0092      andncc     %o1, 0x7, %g1
0093     be,pn       %xcc, 2f
0094      sub        %o1, %g1, %o1
0095 1:  EX_ST(stxa %o2, [%o0 + 0x00] %asi)
0096     subcc       %g1, 8, %g1
0097     bne,pt      %xcc, 1b
0098      add        %o0, 8, %o0
0099 2:  brz,pt      %o1, NGbzero_done
0100      nop
0101 
0102 NGbzero_tiny:
0103 1:  EX_ST(stba %o2, [%o0 + 0x00] %asi)
0104     subcc       %o1, 1, %o1
0105     bne,pt      %icc, 1b
0106      add        %o0, 1, %o0
0107 
0108     /* fallthrough */
0109 
0110 NGbzero_done:
0111     wr      %o5, 0x0, %asi
0112 
0113 NGbzero_return:
0114     retl
0115      mov        %o3, %o0
0116     .size       NGbzero, .-NGbzero
0117     .size       NGmemset, .-NGmemset
0118 
0119     .globl      NGclear_user
0120     .type       NGclear_user, #function
0121 NGclear_user:       /* %o0=buf, %o1=len */
0122     rd      %asi, %o5
0123     brz,pn      %o1, NGbzero_done
0124      clr        %o3
0125     cmp     %o5, ASI_AIUS
0126     bne,pn      %icc, NGbzero
0127      clr        %o2
0128     mov     ASI_BLK_INIT_QUAD_LDD_AIUS, %g7
0129     ba,pt       %xcc, NGbzero_from_clear_user
0130      mov        ASI_AIUS, %o4
0131     .size       NGclear_user, .-NGclear_user
0132 
0133 #define BRANCH_ALWAYS   0x10680000
0134 #define NOP     0x01000000
0135 #define NG_DO_PATCH(OLD, NEW)   \
0136     sethi   %hi(NEW), %g1; \
0137     or  %g1, %lo(NEW), %g1; \
0138     sethi   %hi(OLD), %g2; \
0139     or  %g2, %lo(OLD), %g2; \
0140     sub %g1, %g2, %g1; \
0141     sethi   %hi(BRANCH_ALWAYS), %g3; \
0142     sll %g1, 11, %g1; \
0143     srl %g1, 11 + 2, %g1; \
0144     or  %g3, %lo(BRANCH_ALWAYS), %g3; \
0145     or  %g3, %g1, %g3; \
0146     stw %g3, [%g2]; \
0147     sethi   %hi(NOP), %g3; \
0148     or  %g3, %lo(NOP), %g3; \
0149     stw %g3, [%g2 + 0x4]; \
0150     flush   %g2;
0151 
0152     .globl  niagara_patch_bzero
0153     .type   niagara_patch_bzero,#function
0154 niagara_patch_bzero:
0155     NG_DO_PATCH(memset, NGmemset)
0156     NG_DO_PATCH(__bzero, NGbzero)
0157     NG_DO_PATCH(__clear_user, NGclear_user)
0158     NG_DO_PATCH(tsb_init, NGtsb_init)
0159     retl
0160      nop
0161     .size   niagara_patch_bzero,.-niagara_patch_bzero