^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * arch/xtensa/lib/usercopy.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copy to/from user space (derived from arch/xtensa/lib/hal/memcopy.S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * DO NOT COMBINE this function with <arch/xtensa/lib/hal/memcopy.S>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * It needs to remain separate and distinct. The hal files are part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * of the Xtensa link-time HAL, and those files may differ per
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * processor configuration. Patching the kernel for another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * processor configuration includes replacing the hal files, and we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * could lose the special functionality for accessing user-space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * memory during such a patch. We sacrifice a little code space here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * in favor to simplify code maintenance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * This file is subject to the terms and conditions of the GNU General
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Public License. See the file "COPYING" in the main directory of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * this archive for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Copyright (C) 2002 Tensilica Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * size_t __xtensa_copy_user (void *dst, const void *src, size_t len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * The returned value is the number of bytes not copied. Implies zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * is success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * The general case algorithm is as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * If the destination and source are both aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * do 16B chunks with a loop, and then finish up with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * 8B, 4B, 2B, and 1B copies conditional on the length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * If destination is aligned and source unaligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * do the same, but use SRC to align the source data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * If destination is unaligned, align it by conditionally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * copying 1B and 2B and then retest.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * This code tries to use fall-through braches for the common
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * case of aligned destinations (except for the branches to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * the alignment label).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Register use:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * a0/ return address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * a1/ stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * a2/ return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * a3/ src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * a4/ length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * a5/ dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * a6/ tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * a7/ tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * a8/ tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * a9/ tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * a10/ tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * a11/ original length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <asm/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ENTRY(__xtensa_copy_user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) abi_entry_default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) # a2/ dst, a3/ src, a4/ len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) mov a5, a2 # copy dst so that a2 is return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) mov a11, a4 # preserve original len for error case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .Lcommon:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) bbsi.l a2, 0, .Ldst1mod2 # if dst is 1 mod 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) bbsi.l a2, 1, .Ldst2mod4 # if dst is 2 mod 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .Ldstaligned: # return here from .Ldstunaligned when dst is aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) srli a7, a4, 4 # number of loop iterations with 16B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) # per iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) movi a8, 3 # if source is also aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) bnone a3, a8, .Laligned # then use word copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) __ssa8 a3 # set shift amount from byte offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) bnez a4, .Lsrcunaligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) movi a2, 0 # return success for len==0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) abi_ret_default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Destination is unaligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .Ldst1mod2: # dst is only byte aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) bltui a4, 7, .Lbytecopy # do short copies byte by byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) # copy 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) EX(10f) l8ui a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) addi a3, a3, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) EX(10f) s8i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) addi a5, a5, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) addi a4, a4, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) bbci.l a5, 1, .Ldstaligned # if dst is now aligned, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) # return to main algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .Ldst2mod4: # dst 16-bit aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) # copy 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) bltui a4, 6, .Lbytecopy # do short copies byte by byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EX(10f) l8ui a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) EX(10f) l8ui a7, a3, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) addi a3, a3, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) EX(10f) s8i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) EX(10f) s8i a7, a5, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) addi a5, a5, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) addi a4, a4, -2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) j .Ldstaligned # dst is now aligned, return to main algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Byte by byte copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .byte 0 # 1 mod 4 alignment for LOOPNEZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) # (0 mod 4 alignment for LBEG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .Lbytecopy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #if XCHAL_HAVE_LOOPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) loopnez a4, .Lbytecopydone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #else /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) beqz a4, .Lbytecopydone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) add a7, a3, a4 # a7 = end address for source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #endif /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .Lnextbyte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) EX(10f) l8ui a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) addi a3, a3, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) EX(10f) s8i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) addi a5, a5, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #if !XCHAL_HAVE_LOOPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) blt a3, a7, .Lnextbyte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #endif /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .Lbytecopydone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) movi a2, 0 # return success for len bytes copied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) abi_ret_default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Destination and source are word-aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) # copy 16 bytes per iteration for word-aligned dst and word-aligned src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .align 4 # 1 mod 4 alignment for LOOPNEZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .byte 0 # (0 mod 4 alignment for LBEG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .Laligned:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #if XCHAL_HAVE_LOOPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) loopnez a7, .Loop1done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #else /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) beqz a7, .Loop1done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) slli a8, a7, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) add a8, a8, a3 # a8 = end of last 16B source chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #endif /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .Loop1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) EX(10f) l32i a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) EX(10f) l32i a7, a3, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) EX(10f) s32i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) EX(10f) l32i a6, a3, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) EX(10f) s32i a7, a5, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) EX(10f) l32i a7, a3, 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) EX(10f) s32i a6, a5, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) addi a3, a3, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) EX(10f) s32i a7, a5, 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) addi a5, a5, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #if !XCHAL_HAVE_LOOPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) blt a3, a8, .Loop1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #endif /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .Loop1done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) bbci.l a4, 3, .L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) # copy 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) EX(10f) l32i a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) EX(10f) l32i a7, a3, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) addi a3, a3, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) EX(10f) s32i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) EX(10f) s32i a7, a5, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) addi a5, a5, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .L2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) bbci.l a4, 2, .L3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) # copy 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) EX(10f) l32i a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) addi a3, a3, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) EX(10f) s32i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) addi a5, a5, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .L3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) bbci.l a4, 1, .L4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) # copy 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) EX(10f) l16ui a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) addi a3, a3, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) EX(10f) s16i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) addi a5, a5, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .L4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) bbci.l a4, 0, .L5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) # copy 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) EX(10f) l8ui a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) EX(10f) s8i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .L5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) movi a2, 0 # return success for len bytes copied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) abi_ret_default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Destination is aligned, Source is unaligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .byte 0 # 1 mod 4 alignement for LOOPNEZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) # (0 mod 4 alignment for LBEG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .Lsrcunaligned:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) # copy 16 bytes per iteration for word-aligned dst and unaligned src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) and a10, a3, a8 # save unalignment offset for below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) sub a3, a3, a10 # align a3 (to avoid sim warnings only; not needed for hardware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) EX(10f) l32i a6, a3, 0 # load first word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #if XCHAL_HAVE_LOOPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) loopnez a7, .Loop2done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #else /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) beqz a7, .Loop2done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) slli a12, a7, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) add a12, a12, a3 # a12 = end of last 16B source chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #endif /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .Loop2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) EX(10f) l32i a7, a3, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) EX(10f) l32i a8, a3, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) __src_b a6, a6, a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) EX(10f) s32i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) EX(10f) l32i a9, a3, 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) __src_b a7, a7, a8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) EX(10f) s32i a7, a5, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) EX(10f) l32i a6, a3, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) __src_b a8, a8, a9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) EX(10f) s32i a8, a5, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) addi a3, a3, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) __src_b a9, a9, a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) EX(10f) s32i a9, a5, 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) addi a5, a5, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #if !XCHAL_HAVE_LOOPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) blt a3, a12, .Loop2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #endif /* !XCHAL_HAVE_LOOPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .Loop2done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) bbci.l a4, 3, .L12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) # copy 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) EX(10f) l32i a7, a3, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) EX(10f) l32i a8, a3, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) __src_b a6, a6, a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) EX(10f) s32i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) addi a3, a3, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) __src_b a7, a7, a8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) EX(10f) s32i a7, a5, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) addi a5, a5, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) mov a6, a8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .L12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) bbci.l a4, 2, .L13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) # copy 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) EX(10f) l32i a7, a3, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) addi a3, a3, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) __src_b a6, a6, a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) EX(10f) s32i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) addi a5, a5, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) mov a6, a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .L13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) add a3, a3, a10 # readjust a3 with correct misalignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) bbci.l a4, 1, .L14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) # copy 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) EX(10f) l8ui a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) EX(10f) l8ui a7, a3, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) addi a3, a3, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) EX(10f) s8i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) EX(10f) s8i a7, a5, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) addi a5, a5, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .L14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) bbci.l a4, 0, .L15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) # copy 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) EX(10f) l8ui a6, a3, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) EX(10f) s8i a6, a5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .L15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) movi a2, 0 # return success for len bytes copied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) abi_ret_default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ENDPROC(__xtensa_copy_user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .section .fixup, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* a2 = original dst; a5 = current dst; a11= original len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * bytes_copied = a5 - a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * retval = bytes_not_copied = original len - bytes_copied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * retval = a11 - (a5 - a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) sub a2, a5, a2 /* a2 <-- bytes copied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) sub a2, a11, a2 /* a2 <-- bytes not copied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) abi_ret_default