1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds/* copy_user.S: Sparc optimized copy_from_user and copy_to_user code. 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright(C) 1995 Linus Torvalds 51da177e4SLinus Torvalds * Copyright(C) 1996 David S. Miller 61da177e4SLinus Torvalds * Copyright(C) 1996 Eddie C. Dost 71da177e4SLinus Torvalds * Copyright(C) 1996,1998 Jakub Jelinek 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * derived from: 101da177e4SLinus Torvalds * e-mail between David and Eddie. 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds * Returns 0 if successful, otherwise count of bytes not copied yet 131da177e4SLinus Torvalds */ 141da177e4SLinus Torvalds 15*4cdb71b6SMasahiro Yamada#include <linux/export.h> 161da177e4SLinus Torvalds#include <asm/ptrace.h> 171da177e4SLinus Torvalds#include <asm/asmmacro.h> 181da177e4SLinus Torvalds#include <asm/page.h> 193a1d5c84SDavid S. Miller#include <asm/thread_info.h> 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds/* Work around cpp -rob */ 221da177e4SLinus Torvalds#define ALLOC #alloc 231da177e4SLinus Torvalds#define EXECINSTR #execinstr 24c4da8e0dSAl Viro 25c4da8e0dSAl Viro#define EX_ENTRY(l1, l2) \ 26c4da8e0dSAl Viro .section __ex_table,ALLOC; \ 27c4da8e0dSAl Viro .align 4; \ 28c4da8e0dSAl Viro .word l1, l2; \ 29c4da8e0dSAl Viro .text; 30c4da8e0dSAl Viro 311da177e4SLinus Torvalds#define EX(x,y,a,b) \ 321da177e4SLinus Torvalds98: x,y; \ 331da177e4SLinus Torvalds .section .fixup,ALLOC,EXECINSTR; \ 341da177e4SLinus Torvalds .align 4; \ 35c4da8e0dSAl Viro99: retl; \ 36c4da8e0dSAl Viro a, b, %o0; \ 37c4da8e0dSAl Viro EX_ENTRY(98b, 99b) 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds#define EX2(x,y,c,d,e,a,b) \ 401da177e4SLinus Torvalds98: x,y; \ 411da177e4SLinus Torvalds .section .fixup,ALLOC,EXECINSTR; \ 421da177e4SLinus Torvalds .align 4; \ 431da177e4SLinus Torvalds99: c, d, e; \ 44c4da8e0dSAl Viro retl; \ 45c4da8e0dSAl Viro a, b, %o0; \ 46c4da8e0dSAl Viro EX_ENTRY(98b, 99b) 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds#define EXO2(x,y) \ 491da177e4SLinus Torvalds98: x, y; \ 50c4da8e0dSAl Viro EX_ENTRY(98b, 97f) 511da177e4SLinus Torvalds 52c4da8e0dSAl Viro#define LD(insn, src, offset, reg, label) \ 53c4da8e0dSAl Viro98: insn [%src + (offset)], %reg; \ 54c4da8e0dSAl Viro .section .fixup,ALLOC,EXECINSTR; \ 55c4da8e0dSAl Viro99: ba label; \ 56c4da8e0dSAl Viro mov offset, %g5; \ 57c4da8e0dSAl Viro EX_ENTRY(98b, 99b) 581da177e4SLinus Torvalds 59c4da8e0dSAl Viro#define ST(insn, dst, offset, reg, label) \ 60c4da8e0dSAl Viro98: insn %reg, [%dst + (offset)]; \ 61c4da8e0dSAl Viro .section .fixup,ALLOC,EXECINSTR; \ 62c4da8e0dSAl Viro99: ba label; \ 63c4da8e0dSAl Viro mov offset, %g5; \ 64c4da8e0dSAl Viro EX_ENTRY(98b, 99b) 651da177e4SLinus Torvalds 661da177e4SLinus Torvalds/* Both these macros have to start with exactly the same insn */ 67c4da8e0dSAl Viro/* left: g7 + (g1 % 128) - offset */ 681da177e4SLinus Torvalds#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ 69c4da8e0dSAl Viro LD(ldd, src, offset + 0x00, t0, bigchunk_fault) \ 70c4da8e0dSAl Viro LD(ldd, src, offset + 0x08, t2, bigchunk_fault) \ 71c4da8e0dSAl Viro LD(ldd, src, offset + 0x10, t4, bigchunk_fault) \ 72c4da8e0dSAl Viro LD(ldd, src, offset + 0x18, t6, bigchunk_fault) \ 73c4da8e0dSAl Viro ST(st, dst, offset + 0x00, t0, bigchunk_fault) \ 74c4da8e0dSAl Viro ST(st, dst, offset + 0x04, t1, bigchunk_fault) \ 75c4da8e0dSAl Viro ST(st, dst, offset + 0x08, t2, bigchunk_fault) \ 76c4da8e0dSAl Viro ST(st, dst, offset + 0x0c, t3, bigchunk_fault) \ 77c4da8e0dSAl Viro ST(st, dst, offset + 0x10, t4, bigchunk_fault) \ 78c4da8e0dSAl Viro ST(st, dst, offset + 0x14, t5, bigchunk_fault) \ 79c4da8e0dSAl Viro ST(st, dst, offset + 0x18, t6, bigchunk_fault) \ 80c4da8e0dSAl Viro ST(st, dst, offset + 0x1c, t7, bigchunk_fault) 811da177e4SLinus Torvalds 82c4da8e0dSAl Viro/* left: g7 + (g1 % 128) - offset */ 831da177e4SLinus Torvalds#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ 84c4da8e0dSAl Viro LD(ldd, src, offset + 0x00, t0, bigchunk_fault) \ 85c4da8e0dSAl Viro LD(ldd, src, offset + 0x08, t2, bigchunk_fault) \ 86c4da8e0dSAl Viro LD(ldd, src, offset + 0x10, t4, bigchunk_fault) \ 87c4da8e0dSAl Viro LD(ldd, src, offset + 0x18, t6, bigchunk_fault) \ 88c4da8e0dSAl Viro ST(std, dst, offset + 0x00, t0, bigchunk_fault) \ 89c4da8e0dSAl Viro ST(std, dst, offset + 0x08, t2, bigchunk_fault) \ 90c4da8e0dSAl Viro ST(std, dst, offset + 0x10, t4, bigchunk_fault) \ 91c4da8e0dSAl Viro ST(std, dst, offset + 0x18, t6, bigchunk_fault) 921da177e4SLinus Torvalds 93c4da8e0dSAl Viro .section .fixup,#alloc,#execinstr 94c4da8e0dSAl Virobigchunk_fault: 95c4da8e0dSAl Viro sub %g7, %g5, %o0 96c4da8e0dSAl Viro and %g1, 127, %g1 97c4da8e0dSAl Viro retl 98c4da8e0dSAl Viro add %o0, %g1, %o0 99c4da8e0dSAl Viro 100c4da8e0dSAl Viro/* left: offset + 16 + (g1 % 16) */ 1011da177e4SLinus Torvalds#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \ 102c4da8e0dSAl Viro LD(ldd, src, -(offset + 0x10), t0, lastchunk_fault) \ 103c4da8e0dSAl Viro LD(ldd, src, -(offset + 0x08), t2, lastchunk_fault) \ 104c4da8e0dSAl Viro ST(st, dst, -(offset + 0x10), t0, lastchunk_fault) \ 105c4da8e0dSAl Viro ST(st, dst, -(offset + 0x0c), t1, lastchunk_fault) \ 106c4da8e0dSAl Viro ST(st, dst, -(offset + 0x08), t2, lastchunk_fault) \ 107c4da8e0dSAl Viro ST(st, dst, -(offset + 0x04), t3, lastchunk_fault) 1081da177e4SLinus Torvalds 109c4da8e0dSAl Viro .section .fixup,#alloc,#execinstr 110c4da8e0dSAl Virolastchunk_fault: 111c4da8e0dSAl Viro and %g1, 15, %g1 112c4da8e0dSAl Viro retl 113c4da8e0dSAl Viro sub %g1, %g5, %o0 114c4da8e0dSAl Viro 115c4da8e0dSAl Viro/* left: o3 + (o2 % 16) - offset */ 1161da177e4SLinus Torvalds#define MOVE_HALFCHUNK(src, dst, offset, t0, t1, t2, t3) \ 117c4da8e0dSAl Viro LD(lduh, src, offset + 0x00, t0, halfchunk_fault) \ 118c4da8e0dSAl Viro LD(lduh, src, offset + 0x02, t1, halfchunk_fault) \ 119c4da8e0dSAl Viro LD(lduh, src, offset + 0x04, t2, halfchunk_fault) \ 120c4da8e0dSAl Viro LD(lduh, src, offset + 0x06, t3, halfchunk_fault) \ 121c4da8e0dSAl Viro ST(sth, dst, offset + 0x00, t0, halfchunk_fault) \ 122c4da8e0dSAl Viro ST(sth, dst, offset + 0x02, t1, halfchunk_fault) \ 123c4da8e0dSAl Viro ST(sth, dst, offset + 0x04, t2, halfchunk_fault) \ 124c4da8e0dSAl Viro ST(sth, dst, offset + 0x06, t3, halfchunk_fault) 1251da177e4SLinus Torvalds 126c4da8e0dSAl Viro/* left: o3 + (o2 % 16) + offset + 2 */ 1271da177e4SLinus Torvalds#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \ 128c4da8e0dSAl Viro LD(ldub, src, -(offset + 0x02), t0, halfchunk_fault) \ 129c4da8e0dSAl Viro LD(ldub, src, -(offset + 0x01), t1, halfchunk_fault) \ 130c4da8e0dSAl Viro ST(stb, dst, -(offset + 0x02), t0, halfchunk_fault) \ 131c4da8e0dSAl Viro ST(stb, dst, -(offset + 0x01), t1, halfchunk_fault) 132c4da8e0dSAl Viro 133c4da8e0dSAl Viro .section .fixup,#alloc,#execinstr 134c4da8e0dSAl Virohalfchunk_fault: 135c4da8e0dSAl Viro and %o2, 15, %o2 136c4da8e0dSAl Viro sub %o3, %g5, %o3 137c4da8e0dSAl Viro retl 138c4da8e0dSAl Viro add %o2, %o3, %o0 139c4da8e0dSAl Viro 140c4da8e0dSAl Viro/* left: offset + 2 + (o2 % 2) */ 141c4da8e0dSAl Viro#define MOVE_LAST_SHORTCHUNK(src, dst, offset, t0, t1) \ 142c4da8e0dSAl Viro LD(ldub, src, -(offset + 0x02), t0, last_shortchunk_fault) \ 143c4da8e0dSAl Viro LD(ldub, src, -(offset + 0x01), t1, last_shortchunk_fault) \ 144c4da8e0dSAl Viro ST(stb, dst, -(offset + 0x02), t0, last_shortchunk_fault) \ 145c4da8e0dSAl Viro ST(stb, dst, -(offset + 0x01), t1, last_shortchunk_fault) 146c4da8e0dSAl Viro 147c4da8e0dSAl Viro .section .fixup,#alloc,#execinstr 148c4da8e0dSAl Virolast_shortchunk_fault: 149c4da8e0dSAl Viro and %o2, 1, %o2 150c4da8e0dSAl Viro retl 151c4da8e0dSAl Viro sub %o2, %g5, %o0 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds .text 1541da177e4SLinus Torvalds .align 4 1551da177e4SLinus Torvalds 1561da177e4SLinus Torvalds .globl __copy_user_begin 1571da177e4SLinus Torvalds__copy_user_begin: 1581da177e4SLinus Torvalds 1591da177e4SLinus Torvalds .globl __copy_user 160d3867f04SAl Viro EXPORT_SYMBOL(__copy_user) 1611da177e4SLinus Torvaldsdword_align: 1621da177e4SLinus Torvalds andcc %o1, 1, %g0 1631da177e4SLinus Torvalds be 4f 1641da177e4SLinus Torvalds andcc %o1, 2, %g0 1651da177e4SLinus Torvalds 1661da177e4SLinus Torvalds EXO2(ldub [%o1], %g2) 1671da177e4SLinus Torvalds add %o1, 1, %o1 1681da177e4SLinus Torvalds EXO2(stb %g2, [%o0]) 1691da177e4SLinus Torvalds sub %o2, 1, %o2 1701da177e4SLinus Torvalds bne 3f 1711da177e4SLinus Torvalds add %o0, 1, %o0 1721da177e4SLinus Torvalds 1731da177e4SLinus Torvalds EXO2(lduh [%o1], %g2) 1741da177e4SLinus Torvalds add %o1, 2, %o1 1751da177e4SLinus Torvalds EXO2(sth %g2, [%o0]) 1761da177e4SLinus Torvalds sub %o2, 2, %o2 1771da177e4SLinus Torvalds b 3f 1781da177e4SLinus Torvalds add %o0, 2, %o0 1791da177e4SLinus Torvalds4: 1801da177e4SLinus Torvalds EXO2(lduh [%o1], %g2) 1811da177e4SLinus Torvalds add %o1, 2, %o1 1821da177e4SLinus Torvalds EXO2(sth %g2, [%o0]) 1831da177e4SLinus Torvalds sub %o2, 2, %o2 1841da177e4SLinus Torvalds b 3f 1851da177e4SLinus Torvalds add %o0, 2, %o0 1861da177e4SLinus Torvalds 1871da177e4SLinus Torvalds__copy_user: /* %o0=dst %o1=src %o2=len */ 1881da177e4SLinus Torvalds xor %o0, %o1, %o4 1891da177e4SLinus Torvalds1: 1901da177e4SLinus Torvalds andcc %o4, 3, %o5 1911da177e4SLinus Torvalds2: 1921da177e4SLinus Torvalds bne cannot_optimize 1931da177e4SLinus Torvalds cmp %o2, 15 1941da177e4SLinus Torvalds 1951da177e4SLinus Torvalds bleu short_aligned_end 1961da177e4SLinus Torvalds andcc %o1, 3, %g0 1971da177e4SLinus Torvalds 1981da177e4SLinus Torvalds bne dword_align 1991da177e4SLinus Torvalds3: 2001da177e4SLinus Torvalds andcc %o1, 4, %g0 2011da177e4SLinus Torvalds 2021da177e4SLinus Torvalds be 2f 2031da177e4SLinus Torvalds mov %o2, %g1 2041da177e4SLinus Torvalds 2051da177e4SLinus Torvalds EXO2(ld [%o1], %o4) 2061da177e4SLinus Torvalds sub %g1, 4, %g1 2071da177e4SLinus Torvalds EXO2(st %o4, [%o0]) 2081da177e4SLinus Torvalds add %o1, 4, %o1 2091da177e4SLinus Torvalds add %o0, 4, %o0 2101da177e4SLinus Torvalds2: 2111da177e4SLinus Torvalds andcc %g1, 0xffffff80, %g7 2121da177e4SLinus Torvalds be 3f 2131da177e4SLinus Torvalds andcc %o0, 4, %g0 2141da177e4SLinus Torvalds 2151da177e4SLinus Torvalds be ldd_std + 4 2161da177e4SLinus Torvalds5: 2171da177e4SLinus Torvalds MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 2181da177e4SLinus Torvalds MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 2191da177e4SLinus Torvalds MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 2201da177e4SLinus Torvalds MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 2211da177e4SLinus Torvalds subcc %g7, 128, %g7 2221da177e4SLinus Torvalds add %o1, 128, %o1 2231da177e4SLinus Torvalds bne 5b 2241da177e4SLinus Torvalds add %o0, 128, %o0 2251da177e4SLinus Torvalds3: 2261da177e4SLinus Torvalds andcc %g1, 0x70, %g7 2271da177e4SLinus Torvalds be copy_user_table_end 2281da177e4SLinus Torvalds andcc %g1, 8, %g0 2291da177e4SLinus Torvalds 2301da177e4SLinus Torvalds sethi %hi(copy_user_table_end), %o5 2311da177e4SLinus Torvalds srl %g7, 1, %o4 2321da177e4SLinus Torvalds add %g7, %o4, %o4 2331da177e4SLinus Torvalds add %o1, %g7, %o1 2341da177e4SLinus Torvalds sub %o5, %o4, %o5 2351da177e4SLinus Torvalds jmpl %o5 + %lo(copy_user_table_end), %g0 2361da177e4SLinus Torvalds add %o0, %g7, %o0 2371da177e4SLinus Torvalds 2381da177e4SLinus Torvalds MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5) 2391da177e4SLinus Torvalds MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5) 2401da177e4SLinus Torvalds MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5) 2411da177e4SLinus Torvalds MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5) 2421da177e4SLinus Torvalds MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5) 2431da177e4SLinus Torvalds MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5) 2441da177e4SLinus Torvalds MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 2451da177e4SLinus Torvaldscopy_user_table_end: 2461da177e4SLinus Torvalds be copy_user_last7 2471da177e4SLinus Torvalds andcc %g1, 4, %g0 2481da177e4SLinus Torvalds 2491da177e4SLinus Torvalds EX(ldd [%o1], %g2, and %g1, 0xf) 2501da177e4SLinus Torvalds add %o0, 8, %o0 2511da177e4SLinus Torvalds add %o1, 8, %o1 2521da177e4SLinus Torvalds EX(st %g2, [%o0 - 0x08], and %g1, 0xf) 2531da177e4SLinus Torvalds EX2(st %g3, [%o0 - 0x04], and %g1, 0xf, %g1, sub %g1, 4) 2541da177e4SLinus Torvaldscopy_user_last7: 2551da177e4SLinus Torvalds be 1f 2561da177e4SLinus Torvalds andcc %g1, 2, %g0 2571da177e4SLinus Torvalds 2581da177e4SLinus Torvalds EX(ld [%o1], %g2, and %g1, 7) 2591da177e4SLinus Torvalds add %o1, 4, %o1 2601da177e4SLinus Torvalds EX(st %g2, [%o0], and %g1, 7) 2611da177e4SLinus Torvalds add %o0, 4, %o0 2621da177e4SLinus Torvalds1: 2631da177e4SLinus Torvalds be 1f 2641da177e4SLinus Torvalds andcc %g1, 1, %g0 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds EX(lduh [%o1], %g2, and %g1, 3) 2671da177e4SLinus Torvalds add %o1, 2, %o1 2681da177e4SLinus Torvalds EX(sth %g2, [%o0], and %g1, 3) 2691da177e4SLinus Torvalds add %o0, 2, %o0 2701da177e4SLinus Torvalds1: 2711da177e4SLinus Torvalds be 1f 2721da177e4SLinus Torvalds nop 2731da177e4SLinus Torvalds 2741da177e4SLinus Torvalds EX(ldub [%o1], %g2, add %g0, 1) 2751da177e4SLinus Torvalds EX(stb %g2, [%o0], add %g0, 1) 2761da177e4SLinus Torvalds1: 2771da177e4SLinus Torvalds retl 2781da177e4SLinus Torvalds clr %o0 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvaldsldd_std: 2811da177e4SLinus Torvalds MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 2821da177e4SLinus Torvalds MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 2831da177e4SLinus Torvalds MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 2841da177e4SLinus Torvalds MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 2851da177e4SLinus Torvalds subcc %g7, 128, %g7 2861da177e4SLinus Torvalds add %o1, 128, %o1 2871da177e4SLinus Torvalds bne ldd_std 2881da177e4SLinus Torvalds add %o0, 128, %o0 2891da177e4SLinus Torvalds 2901da177e4SLinus Torvalds andcc %g1, 0x70, %g7 2911da177e4SLinus Torvalds be copy_user_table_end 2921da177e4SLinus Torvalds andcc %g1, 8, %g0 2931da177e4SLinus Torvalds 2941da177e4SLinus Torvalds sethi %hi(copy_user_table_end), %o5 2951da177e4SLinus Torvalds srl %g7, 1, %o4 2961da177e4SLinus Torvalds add %g7, %o4, %o4 2971da177e4SLinus Torvalds add %o1, %g7, %o1 2981da177e4SLinus Torvalds sub %o5, %o4, %o5 2991da177e4SLinus Torvalds jmpl %o5 + %lo(copy_user_table_end), %g0 3001da177e4SLinus Torvalds add %o0, %g7, %o0 3011da177e4SLinus Torvalds 3021da177e4SLinus Torvaldscannot_optimize: 3031da177e4SLinus Torvalds bleu short_end 3041da177e4SLinus Torvalds cmp %o5, 2 3051da177e4SLinus Torvalds 3061da177e4SLinus Torvalds bne byte_chunk 3071da177e4SLinus Torvalds and %o2, 0xfffffff0, %o3 3081da177e4SLinus Torvalds 3091da177e4SLinus Torvalds andcc %o1, 1, %g0 3101da177e4SLinus Torvalds be 10f 3111da177e4SLinus Torvalds nop 3121da177e4SLinus Torvalds 3131da177e4SLinus Torvalds EXO2(ldub [%o1], %g2) 3141da177e4SLinus Torvalds add %o1, 1, %o1 3151da177e4SLinus Torvalds EXO2(stb %g2, [%o0]) 3161da177e4SLinus Torvalds sub %o2, 1, %o2 3171da177e4SLinus Torvalds andcc %o2, 0xfffffff0, %o3 3181da177e4SLinus Torvalds be short_end 3191da177e4SLinus Torvalds add %o0, 1, %o0 3201da177e4SLinus Torvalds10: 3211da177e4SLinus Torvalds MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 3221da177e4SLinus Torvalds MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5) 3231da177e4SLinus Torvalds subcc %o3, 0x10, %o3 3241da177e4SLinus Torvalds add %o1, 0x10, %o1 3251da177e4SLinus Torvalds bne 10b 3261da177e4SLinus Torvalds add %o0, 0x10, %o0 3271da177e4SLinus Torvalds b 2f 3281da177e4SLinus Torvalds and %o2, 0xe, %o3 3291da177e4SLinus Torvalds 3301da177e4SLinus Torvaldsbyte_chunk: 3311da177e4SLinus Torvalds MOVE_SHORTCHUNK(o1, o0, -0x02, g2, g3) 3321da177e4SLinus Torvalds MOVE_SHORTCHUNK(o1, o0, -0x04, g2, g3) 3331da177e4SLinus Torvalds MOVE_SHORTCHUNK(o1, o0, -0x06, g2, g3) 3341da177e4SLinus Torvalds MOVE_SHORTCHUNK(o1, o0, -0x08, g2, g3) 3351da177e4SLinus Torvalds MOVE_SHORTCHUNK(o1, o0, -0x0a, g2, g3) 3361da177e4SLinus Torvalds MOVE_SHORTCHUNK(o1, o0, -0x0c, g2, g3) 3371da177e4SLinus Torvalds MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3) 3381da177e4SLinus Torvalds MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3) 3391da177e4SLinus Torvalds subcc %o3, 0x10, %o3 3401da177e4SLinus Torvalds add %o1, 0x10, %o1 3411da177e4SLinus Torvalds bne byte_chunk 3421da177e4SLinus Torvalds add %o0, 0x10, %o0 3431da177e4SLinus Torvalds 3441da177e4SLinus Torvaldsshort_end: 3451da177e4SLinus Torvalds and %o2, 0xe, %o3 3461da177e4SLinus Torvalds2: 3471da177e4SLinus Torvalds sethi %hi(short_table_end), %o5 3481da177e4SLinus Torvalds sll %o3, 3, %o4 3491da177e4SLinus Torvalds add %o0, %o3, %o0 3501da177e4SLinus Torvalds sub %o5, %o4, %o5 3511da177e4SLinus Torvalds add %o1, %o3, %o1 3521da177e4SLinus Torvalds jmpl %o5 + %lo(short_table_end), %g0 3531da177e4SLinus Torvalds andcc %o2, 1, %g0 354c4da8e0dSAl Viro MOVE_LAST_SHORTCHUNK(o1, o0, 0x0c, g2, g3) 355c4da8e0dSAl Viro MOVE_LAST_SHORTCHUNK(o1, o0, 0x0a, g2, g3) 356c4da8e0dSAl Viro MOVE_LAST_SHORTCHUNK(o1, o0, 0x08, g2, g3) 357c4da8e0dSAl Viro MOVE_LAST_SHORTCHUNK(o1, o0, 0x06, g2, g3) 358c4da8e0dSAl Viro MOVE_LAST_SHORTCHUNK(o1, o0, 0x04, g2, g3) 359c4da8e0dSAl Viro MOVE_LAST_SHORTCHUNK(o1, o0, 0x02, g2, g3) 360c4da8e0dSAl Viro MOVE_LAST_SHORTCHUNK(o1, o0, 0x00, g2, g3) 3611da177e4SLinus Torvaldsshort_table_end: 3621da177e4SLinus Torvalds be 1f 3631da177e4SLinus Torvalds nop 3641da177e4SLinus Torvalds EX(ldub [%o1], %g2, add %g0, 1) 3651da177e4SLinus Torvalds EX(stb %g2, [%o0], add %g0, 1) 3661da177e4SLinus Torvalds1: 3671da177e4SLinus Torvalds retl 3681da177e4SLinus Torvalds clr %o0 3691da177e4SLinus Torvalds 3701da177e4SLinus Torvaldsshort_aligned_end: 3711da177e4SLinus Torvalds bne short_end 3721da177e4SLinus Torvalds andcc %o2, 8, %g0 3731da177e4SLinus Torvalds 3741da177e4SLinus Torvalds be 1f 3751da177e4SLinus Torvalds andcc %o2, 4, %g0 3761da177e4SLinus Torvalds 3771da177e4SLinus Torvalds EXO2(ld [%o1 + 0x00], %g2) 3781da177e4SLinus Torvalds EXO2(ld [%o1 + 0x04], %g3) 3791da177e4SLinus Torvalds add %o1, 8, %o1 3801da177e4SLinus Torvalds EXO2(st %g2, [%o0 + 0x00]) 3811da177e4SLinus Torvalds EX(st %g3, [%o0 + 0x04], sub %o2, 4) 3821da177e4SLinus Torvalds add %o0, 8, %o0 3831da177e4SLinus Torvalds1: 3841da177e4SLinus Torvalds b copy_user_last7 3851da177e4SLinus Torvalds mov %o2, %g1 3861da177e4SLinus Torvalds 3871da177e4SLinus Torvalds .section .fixup,#alloc,#execinstr 3881da177e4SLinus Torvalds .align 4 3891da177e4SLinus Torvalds97: 39031af2f36SAl Viro retl 391c4da8e0dSAl Viro mov %o2, %o0 3921da177e4SLinus Torvalds 3931da177e4SLinus Torvalds .globl __copy_user_end 3941da177e4SLinus Torvalds__copy_user_end: 395