^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * copy_page, __copy_user_page, __copy_user implementation of SuperH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2002 Toshinobu Sugioka
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2006 Paul Mundt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * copy_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * @to: P1 address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * @from: P1 address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * void copy_page(void *to, void *from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * r8 --- from + PAGE_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * r9 --- not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * r10 --- to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * r11 --- from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ENTRY(copy_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) mov.l r8,@-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) mov.l r10,@-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) mov.l r11,@-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) mov r4,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) mov r5,r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) mov r5,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) mov #(PAGE_SIZE >> 10), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) shll8 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) shll2 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) add r0,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 1: mov.l @r11+,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) mov.l @r11+,r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) mov.l @r11+,r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) mov.l @r11+,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) mov.l @r11+,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) mov.l @r11+,r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) mov.l @r11+,r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) mov.l @r11+,r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #if defined(CONFIG_CPU_SH4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) movca.l r0,@r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) mov.l r0,@r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) add #32,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) mov.l r7,@-r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) mov.l r6,@-r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) mov.l r5,@-r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) mov.l r4,@-r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mov.l r3,@-r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) mov.l r2,@-r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) mov.l r1,@-r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) cmp/eq r11,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) bf/s 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) add #28,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) mov.l @r15+,r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) mov.l @r15+,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) mov.l @r15+,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Return the number of bytes NOT copied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define EX(...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 9999: __VA_ARGS__ ; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .section __ex_table, "a"; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .long 9999b, 6000f ; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define EX_NO_POP(...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 9999: __VA_ARGS__ ; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .section __ex_table, "a"; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .long 9999b, 6005f ; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ENTRY(__copy_user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ! Check if small number of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mov #11,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mov r4,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) cmp/gt r0,r6 ! r6 (len) > r0 (11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) bf/s .L_cleanup_loop_no_pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) add r6,r3 ! last destination address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ! Calculate bytes needed to align to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) mov.l r11,@-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) neg r5,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) mov.l r10,@-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) add #4,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) mov.l r9,@-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) and #3,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) mov.l r8,@-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) tst r0,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) bt 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ! Copy bytes to long word align src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) EX( mov.b @r5+,r1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dt r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) add #-1,r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) EX( mov.b r1,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) bf/s 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) add #1,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ! Jump to appropriate routine depending on dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 2: mov #3,r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mov r6, r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) and r4,r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) shlr2 r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) shll2 r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mova .L_jump_tbl,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mov.l @(r0,r1),r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) jmp @r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .L_jump_tbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .long .L_dest00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .long .L_dest01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .long .L_dest10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .long .L_dest11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Come here if there are less than 12 bytes to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Keep the branch target close, so the bf/s callee doesn't overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * and result in a more expensive branch being inserted. This is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * fast-path for small copies, the jump via the jump table will hit the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * default slow-path cleanup. -PFM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .L_cleanup_loop_no_pop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) tst r6,r6 ! Check explicitly for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) bt 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) EX_NO_POP( mov.b @r5+,r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) dt r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) EX_NO_POP( mov.b r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) bf/s 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) add #1,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 1: mov #0,r0 ! normal return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 5000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) # Exception handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .section .fixup, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 6005:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mov.l 8000f,r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) mov r3,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) jmp @r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) sub r4,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 8000: .long 5000b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ! Destination = 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .L_dest00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ! Skip the large copy for small transfers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) mov #(32+32-4), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) cmp/gt r6, r0 ! r0 (60) > r6 (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) bt 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ! Align dest to a 32 byte boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) neg r4,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) add #0x20, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) and #0x1f, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) tst r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) bt 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) sub r0, r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) shlr2 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) EX( mov.l @r5+,r1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) dt r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) EX( mov.l r1,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) bf/s 3b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) add #4,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) EX( mov.l @r5+,r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) EX( mov.l @r5+,r1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) EX( mov.l @r5+,r2 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) EX( mov.l @r5+,r7 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) EX( mov.l @r5+,r8 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) EX( mov.l @r5+,r9 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) EX( mov.l @r5+,r10 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) EX( mov.l @r5+,r11 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #ifdef CONFIG_CPU_SH4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) EX( movca.l r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) EX( mov.l r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) add #-32, r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) EX( mov.l r1,@(4,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mov #32, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) EX( mov.l r2,@(8,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) cmp/gt r6, r0 ! r0 (32) > r6 (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) EX( mov.l r7,@(12,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) EX( mov.l r8,@(16,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) EX( mov.l r9,@(20,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) EX( mov.l r10,@(24,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) EX( mov.l r11,@(28,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) bf/s 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) add #32,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 1: mov r6, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) shlr2 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) tst r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) bt .L_cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) EX( mov.l @r5+,r1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dt r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) EX( mov.l r1,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) bf/s 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) add #4,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) bra .L_cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ! Destination = 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .L_dest10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) mov r2,r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) shlr2 r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) shlr r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) tst r7,r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) mov #7,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) bt/s 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) and r0,r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dt r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #ifdef CONFIG_CPU_LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) EX( mov.l @r5+,r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) EX( mov.l @r5+,r1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) EX( mov.l @r5+,r8 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) EX( mov.l @r5+,r9 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) EX( mov.l @r5+,r10 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) EX( mov.w r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) add #2,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) xtrct r1,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) xtrct r8,r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) xtrct r9,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) xtrct r10,r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) EX( mov.l r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) EX( mov.l r1,@(4,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) EX( mov.l r8,@(8,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) EX( mov.l r9,@(12,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) EX( mov.l @r5+,r1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) EX( mov.l @r5+,r8 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) EX( mov.l @r5+,r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) xtrct r1,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) xtrct r8,r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) xtrct r0,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) shlr16 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) EX( mov.l r10,@(16,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) EX( mov.l r1,@(20,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) EX( mov.l r8,@(24,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) EX( mov.w r0,@(28,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) bf/s 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) add #30,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) EX( mov.l @(28,r5),r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) EX( mov.l @(24,r5),r8 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) EX( mov.l @(20,r5),r9 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) EX( mov.l @(16,r5),r10 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) EX( mov.w r0,@(30,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) add #-2,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) xtrct r8,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) xtrct r9,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) xtrct r10,r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) EX( mov.l r0,@(28,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) EX( mov.l r8,@(24,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) EX( mov.l r9,@(20,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) EX( mov.l @(12,r5),r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) EX( mov.l @(8,r5),r8 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) xtrct r0,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) EX( mov.l @(4,r5),r9 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) mov.l r10,@(16,r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) EX( mov.l @r5,r10 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) xtrct r8,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) xtrct r9,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) xtrct r10,r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) EX( mov.l r0,@(12,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) EX( mov.l r8,@(8,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) swap.w r10,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) EX( mov.l r9,@(4,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) EX( mov.w r0,@(2,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) add #32,r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) bf/s 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) add #34,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) tst r2,r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) bt .L_cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 1: ! Read longword, write two words per iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) EX( mov.l @r5+,r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dt r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #ifdef CONFIG_CPU_LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) EX( mov.w r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) shlr16 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) EX( mov.w r0,@(2,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) EX( mov.w r0,@(2,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) shlr16 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) EX( mov.w r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) bf/s 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) add #4,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) bra .L_cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ! Destination = 01 or 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .L_dest01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .L_dest11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ! Read longword, write byte, word, byte per iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) EX( mov.l @r5+,r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dt r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #ifdef CONFIG_CPU_LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) EX( mov.b r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) shlr8 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) add #1,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) EX( mov.w r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) shlr16 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) EX( mov.b r0,@(2,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) bf/s .L_dest01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) add #3,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) EX( mov.b r0,@(3,r4) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) shlr8 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) swap.w r0,r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) EX( mov.b r7,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) add #1,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) EX( mov.w r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) bf/s .L_dest01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) add #3,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ! Cleanup last few bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .L_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) mov r6,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) and #3,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) tst r0,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) bt .L_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) mov r0,r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .L_cleanup_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) EX( mov.b @r5+,r0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dt r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) EX( mov.b r0,@r4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) bf/s .L_cleanup_loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) add #1,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .L_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) mov #0,r0 ! normal return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 5000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) # Exception handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .section .fixup, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 6000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) mov.l 8000f,r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mov r3,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) jmp @r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) sub r4,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 8000: .long 5000b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mov.l @r15+,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) mov.l @r15+,r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) mov.l @r15+,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) mov.l @r15+,r11