linux/arch/sparc/lib/NGbzero.S
<<
>>
Prefs
   1/* NGbzero.S: Niagara optimized memset/clear_user.
   2 *
   3 * Copyright (C) 2006 David S. Miller (davem@davemloft.net)
   4 */
   5#include <asm/asi.h>
   6
   7#define EX_ST(x,y)              \
   898:     x,y;                    \
   9        .section __ex_table,"a";\
  10        .align 4;               \
  11        .word 98b, __retl_o1;   \
  12        .text;                  \
  13        .align 4;
  14
  15        .text
  16
  17        .globl          NGmemset
  18        .type           NGmemset, #function
  19NGmemset:               /* %o0=buf, %o1=pat, %o2=len */
  20        and             %o1, 0xff, %o3
  21        mov             %o2, %o1
  22        sllx            %o3, 8, %g1
  23        or              %g1, %o3, %o2
  24        sllx            %o2, 16, %g1
  25        or              %g1, %o2, %o2
  26        sllx            %o2, 32, %g1
  27        ba,pt           %xcc, 1f
  28         or             %g1, %o2, %o2
  29
  30        .globl          NGbzero
  31        .type           NGbzero, #function
  32NGbzero:
  33        clr             %o2
  341:      brz,pn          %o1, NGbzero_return
  35         mov            %o0, %o3
  36
  37        /* %o5: saved %asi, restored at NGbzero_done
  38         * %g7: store-init %asi to use
  39         * %o4: non-store-init %asi to use
  40         */
  41        rd              %asi, %o5
  42        mov             ASI_BLK_INIT_QUAD_LDD_P, %g7
  43        mov             ASI_P, %o4
  44        wr              %o4, 0x0, %asi
  45
  46NGbzero_from_clear_user:
  47        cmp             %o1, 15
  48        bl,pn           %icc, NGbzero_tiny
  49         andcc          %o0, 0x7, %g1
  50        be,pt           %xcc, 2f
  51         mov            8, %g2
  52        sub             %g2, %g1, %g1
  53        sub             %o1, %g1, %o1
  541:      EX_ST(stba %o2, [%o0 + 0x00] %asi)
  55        subcc           %g1, 1, %g1
  56        bne,pt          %xcc, 1b
  57         add            %o0, 1, %o0
  582:      cmp             %o1, 128
  59        bl,pn           %icc, NGbzero_medium
  60         andcc          %o0, (64 - 1), %g1
  61        be,pt           %xcc, NGbzero_pre_loop
  62         mov            64, %g2
  63        sub             %g2, %g1, %g1
  64        sub             %o1, %g1, %o1
  651:      EX_ST(stxa %o2, [%o0 + 0x00] %asi)
  66        subcc           %g1, 8, %g1
  67        bne,pt          %xcc, 1b
  68         add            %o0, 8, %o0
  69
  70NGbzero_pre_loop:
  71        wr              %g7, 0x0, %asi
  72        andn            %o1, (64 - 1), %g1
  73        sub             %o1, %g1, %o1
  74NGbzero_loop:
  75        EX_ST(stxa %o2, [%o0 + 0x00] %asi)
  76        EX_ST(stxa %o2, [%o0 + 0x08] %asi)
  77        EX_ST(stxa %o2, [%o0 + 0x10] %asi)
  78        EX_ST(stxa %o2, [%o0 + 0x18] %asi)
  79        EX_ST(stxa %o2, [%o0 + 0x20] %asi)
  80        EX_ST(stxa %o2, [%o0 + 0x28] %asi)
  81        EX_ST(stxa %o2, [%o0 + 0x30] %asi)
  82        EX_ST(stxa %o2, [%o0 + 0x38] %asi)
  83        subcc           %g1, 64, %g1
  84        bne,pt          %xcc, NGbzero_loop
  85         add            %o0, 64, %o0
  86
  87        membar          #Sync
  88        wr              %o4, 0x0, %asi
  89        brz,pn          %o1, NGbzero_done
  90NGbzero_medium:
  91         andncc         %o1, 0x7, %g1
  92        be,pn           %xcc, 2f
  93         sub            %o1, %g1, %o1
  941:      EX_ST(stxa %o2, [%o0 + 0x00] %asi)
  95        subcc           %g1, 8, %g1
  96        bne,pt          %xcc, 1b
  97         add            %o0, 8, %o0
  982:      brz,pt          %o1, NGbzero_done
  99         nop
 100
 101NGbzero_tiny:
 1021:      EX_ST(stba %o2, [%o0 + 0x00] %asi)
 103        subcc           %o1, 1, %o1
 104        bne,pt          %icc, 1b
 105         add            %o0, 1, %o0
 106
 107        /* fallthrough */
 108
 109NGbzero_done:
 110        wr              %o5, 0x0, %asi
 111
 112NGbzero_return:
 113        retl
 114         mov            %o3, %o0
 115        .size           NGbzero, .-NGbzero
 116        .size           NGmemset, .-NGmemset
 117
 118        .globl          NGclear_user
 119        .type           NGclear_user, #function
 120NGclear_user:           /* %o0=buf, %o1=len */
 121        rd              %asi, %o5
 122        brz,pn          %o1, NGbzero_done
 123         clr            %o3
 124        cmp             %o5, ASI_AIUS
 125        bne,pn          %icc, NGbzero
 126         clr            %o2
 127        mov             ASI_BLK_INIT_QUAD_LDD_AIUS, %g7
 128        ba,pt           %xcc, NGbzero_from_clear_user
 129         mov            ASI_AIUS, %o4
 130        .size           NGclear_user, .-NGclear_user
 131
 132#define BRANCH_ALWAYS   0x10680000
 133#define NOP             0x01000000
 134#define NG_DO_PATCH(OLD, NEW)   \
 135        sethi   %hi(NEW), %g1; \
 136        or      %g1, %lo(NEW), %g1; \
 137        sethi   %hi(OLD), %g2; \
 138        or      %g2, %lo(OLD), %g2; \
 139        sub     %g1, %g2, %g1; \
 140        sethi   %hi(BRANCH_ALWAYS), %g3; \
 141        sll     %g1, 11, %g1; \
 142        srl     %g1, 11 + 2, %g1; \
 143        or      %g3, %lo(BRANCH_ALWAYS), %g3; \
 144        or      %g3, %g1, %g3; \
 145        stw     %g3, [%g2]; \
 146        sethi   %hi(NOP), %g3; \
 147        or      %g3, %lo(NOP), %g3; \
 148        stw     %g3, [%g2 + 0x4]; \
 149        flush   %g2;
 150
 151        .globl  niagara_patch_bzero
 152        .type   niagara_patch_bzero,#function
 153niagara_patch_bzero:
 154        NG_DO_PATCH(memset, NGmemset)
 155        NG_DO_PATCH(__bzero, NGbzero)
 156        NG_DO_PATCH(__clear_user, NGclear_user)
 157        NG_DO_PATCH(tsb_init, NGtsb_init)
 158        retl
 159         nop
 160        .size   niagara_patch_bzero,.-niagara_patch_bzero
 161