root/arch/unicore32/lib/copy_template.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * linux/arch/unicore32/lib/copy_template.S
   4  *
   5  * Code specific to PKUnity SoC and UniCore ISA
   6  *
   7  * Copyright (C) 2001-2010 GUAN Xue-tao
   8  */
   9 
  10 /*
  11  * Theory of operation
  12  * -------------------
  13  *
  14  * This file provides the core code for a forward memory copy used in
  15  * the implementation of memcopy(), copy_to_user() and copy_from_user().
  16  *
  17  * The including file must define the following accessor macros
  18  * according to the need of the given function:
  19  *
  20  * ldr1w ptr reg abort
  21  *
  22  *      This loads one word from 'ptr', stores it in 'reg' and increments
  23  *      'ptr' to the next word. The 'abort' argument is used for fixup tables.
  24  *
  25  * ldr4w ptr reg1 reg2 reg3 reg4 abort
  26  * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
  27  *
  28  *      This loads four or eight words starting from 'ptr', stores them
  29  *      in provided registers and increments 'ptr' past those words.
  30  *      The'abort' argument is used for fixup tables.
  31  *
  32  * ldr1b ptr reg cond abort
  33  *
  34  *      Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
  35  *      It also must apply the condition code if provided, otherwise the
  36  *      "al" condition is assumed by default.
  37  *
  38  * str1w ptr reg abort
  39  * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
  40  * str1b ptr reg cond abort
  41  *
  42  *      Same as their ldr* counterparts, but data is stored to 'ptr' location
  43  *      rather than being loaded.
  44  *
  45  * enter
  46  *
  47  *      Preserve the provided registers on the stack plus any additional
  48  *      data as needed by the implementation including this code. Called
  49  *      upon code entry.
  50  *
  51  * exit
  52  *
  53  *      Restore registers with the values previously saved with the
  54  *      'preserv' macro. Called upon code termination.
  55  */
  56 
  57 
  58                 enter
  59 
  60                 sub.a   r2, r2, #4
  61                 bsl     8f
  62                 and.a   ip, r0, #3
  63                 bne     9f
  64                 and.a   ip, r1, #3
  65                 bne     10f
  66 
  67 1:              sub.a   r2, r2, #(28)
  68                 stm.w   (r5 - r8), [sp-]
  69                 bsl     5f
  70 
  71 3:
  72 4:              ldr8w   r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
  73                 sub.a   r2, r2, #32
  74                 str8w   r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
  75                 beg     3b
  76 
  77 5:              and.a   ip, r2, #28
  78                 rsub    ip, ip, #32
  79                 beq     7f
  80                 add     pc, pc, ip              @ C is always clear here
  81                 nop
  82 
  83                 ldr1w   r1, r3, abort=20f
  84                 ldr1w   r1, r4, abort=20f
  85                 ldr1w   r1, r5, abort=20f
  86                 ldr1w   r1, r6, abort=20f
  87                 ldr1w   r1, r7, abort=20f
  88                 ldr1w   r1, r8, abort=20f
  89                 ldr1w   r1, r11, abort=20f
  90 
  91                 add     pc, pc, ip
  92                 nop
  93 
  94                 str1w   r0, r3, abort=20f
  95                 str1w   r0, r4, abort=20f
  96                 str1w   r0, r5, abort=20f
  97                 str1w   r0, r6, abort=20f
  98                 str1w   r0, r7, abort=20f
  99                 str1w   r0, r8, abort=20f
 100                 str1w   r0, r11, abort=20f
 101 
 102 7:              ldm.w   (r5 - r8), [sp]+
 103 
 104 8:              mov.a   r2, r2 << #31
 105                 ldr1b   r1, r3, ne, abort=21f
 106                 ldr1b   r1, r4, ea, abort=21f
 107                 ldr1b   r1, r10, ea, abort=21f
 108                 str1b   r0, r3, ne, abort=21f
 109                 str1b   r0, r4, ea, abort=21f
 110                 str1b   r0, r10, ea, abort=21f
 111 
 112                 exit
 113 
 114 9:              rsub    ip, ip, #4
 115                 csub.a  ip, #2
 116                 ldr1b   r1, r3, sg, abort=21f
 117                 ldr1b   r1, r4, eg, abort=21f
 118                 ldr1b   r1, r11, abort=21f
 119                 str1b   r0, r3, sg, abort=21f
 120                 str1b   r0, r4, eg, abort=21f
 121                 sub.a   r2, r2, ip
 122                 str1b   r0, r11, abort=21f
 123                 bsl     8b
 124                 and.a   ip, r1, #3
 125                 beq     1b
 126 
 127 10:             andn    r1, r1, #3
 128                 csub.a  ip, #2
 129                 ldr1w   r1, r11, abort=21f
 130                 beq     17f
 131                 bsg     18f
 132 
 133 
 134                 .macro  forward_copy_shift a b
 135 
 136                 sub.a   r2, r2, #28
 137                 bsl     14f
 138 
 139 11:             stm.w   (r5 - r9), [sp-]
 140 
 141 12:
 142                 ldr4w   r1, r4, r5, r6, r7, abort=19f
 143                 mov     r3, r11 pull #\a
 144                 sub.a   r2, r2, #32
 145                 ldr4w   r1, r8, r9, r10, r11, abort=19f
 146                 or      r3, r3, r4 push #\b
 147                 mov     r4, r4 pull #\a
 148                 or      r4, r4, r5 push #\b
 149                 mov     r5, r5 pull #\a
 150                 or      r5, r5, r6 push #\b
 151                 mov     r6, r6 pull #\a
 152                 or      r6, r6, r7 push #\b
 153                 mov     r7, r7 pull #\a
 154                 or      r7, r7, r8 push #\b
 155                 mov     r8, r8 pull #\a
 156                 or      r8, r8, r9 push #\b
 157                 mov     r9, r9 pull #\a
 158                 or      r9, r9, r10 push #\b
 159                 mov     r10, r10 pull #\a
 160                 or      r10, r10, r11 push #\b
 161                 str8w   r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f
 162                 beg     12b
 163 
 164                 ldm.w   (r5 - r9), [sp]+
 165 
 166 14:             and.a   ip, r2, #28
 167                 beq     16f
 168 
 169 15:             mov     r3, r11 pull #\a
 170                 ldr1w   r1, r11, abort=21f
 171                 sub.a   ip, ip, #4
 172                 or      r3, r3, r11 push #\b
 173                 str1w   r0, r3, abort=21f
 174                 bsg     15b
 175 
 176 16:             sub     r1, r1, #(\b / 8)
 177                 b       8b
 178 
 179                 .endm
 180 
 181 
 182                 forward_copy_shift      a=8     b=24
 183 
 184 17:             forward_copy_shift      a=16    b=16
 185 
 186 18:             forward_copy_shift      a=24    b=8
 187 
 188 
 189 /*
 190  * Abort preamble and completion macros.
 191  * If a fixup handler is required then those macros must surround it.
 192  * It is assumed that the fixup code will handle the private part of
 193  * the exit macro.
 194  */
 195 
 196         .macro  copy_abort_preamble
 197 19:     ldm.w   (r5 - r9), [sp]+
 198         b       21f
 199 299:    .word   0                       @ store lr
 200                                         @ to avoid function call in fixup
 201 20:     ldm.w   (r5 - r8), [sp]+
 202 21:
 203         adr     r1, 299b
 204         stw     lr, [r1]
 205         .endm
 206 
 207         .macro  copy_abort_end
 208         adr     lr, 299b
 209         ldw     pc, [lr]
 210         .endm
 211 

/* [<][>][^][v][top][bottom][index][help] */