18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* copy_user.S: Sparc optimized copy_from_user and copy_to_user code. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright(C) 1995 Linus Torvalds 58c2ecf20Sopenharmony_ci * Copyright(C) 1996 David S. Miller 68c2ecf20Sopenharmony_ci * Copyright(C) 1996 Eddie C. Dost 78c2ecf20Sopenharmony_ci * Copyright(C) 1996,1998 Jakub Jelinek 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * derived from: 108c2ecf20Sopenharmony_ci * e-mail between David and Eddie. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * Returns 0 if successful, otherwise count of bytes not copied yet 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <asm/ptrace.h> 168c2ecf20Sopenharmony_ci#include <asm/asmmacro.h> 178c2ecf20Sopenharmony_ci#include <asm/page.h> 188c2ecf20Sopenharmony_ci#include <asm/thread_info.h> 198c2ecf20Sopenharmony_ci#include <asm/export.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/* Work around cpp -rob */ 228c2ecf20Sopenharmony_ci#define ALLOC #alloc 238c2ecf20Sopenharmony_ci#define EXECINSTR #execinstr 248c2ecf20Sopenharmony_ci#define EX(x,y,a,b) \ 258c2ecf20Sopenharmony_ci98: x,y; \ 268c2ecf20Sopenharmony_ci .section .fixup,ALLOC,EXECINSTR; \ 278c2ecf20Sopenharmony_ci .align 4; \ 288c2ecf20Sopenharmony_ci99: ba fixupretl; \ 298c2ecf20Sopenharmony_ci a, b, %g3; \ 308c2ecf20Sopenharmony_ci .section __ex_table,ALLOC; \ 318c2ecf20Sopenharmony_ci .align 4; \ 328c2ecf20Sopenharmony_ci .word 98b, 99b; \ 338c2ecf20Sopenharmony_ci .text; \ 348c2ecf20Sopenharmony_ci .align 4 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define EX2(x,y,c,d,e,a,b) \ 378c2ecf20Sopenharmony_ci98: x,y; \ 388c2ecf20Sopenharmony_ci .section .fixup,ALLOC,EXECINSTR; \ 398c2ecf20Sopenharmony_ci .align 4; \ 408c2ecf20Sopenharmony_ci99: c, d, e; \ 418c2ecf20Sopenharmony_ci ba fixupretl; \ 428c2ecf20Sopenharmony_ci a, b, %g3; \ 438c2ecf20Sopenharmony_ci .section __ex_table,ALLOC; \ 448c2ecf20Sopenharmony_ci .align 4; \ 458c2ecf20Sopenharmony_ci .word 98b, 99b; \ 468c2ecf20Sopenharmony_ci .text; \ 478c2ecf20Sopenharmony_ci .align 4 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define EXO2(x,y) \ 508c2ecf20Sopenharmony_ci98: x, y; \ 518c2ecf20Sopenharmony_ci .section __ex_table,ALLOC; \ 528c2ecf20Sopenharmony_ci .align 4; \ 538c2ecf20Sopenharmony_ci .word 98b, 97f; \ 548c2ecf20Sopenharmony_ci .text; \ 558c2ecf20Sopenharmony_ci .align 4 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#define EXT(start,end,handler) \ 588c2ecf20Sopenharmony_ci .section __ex_table,ALLOC; \ 598c2ecf20Sopenharmony_ci .align 4; \ 608c2ecf20Sopenharmony_ci .word start, 0, end, handler; \ 618c2ecf20Sopenharmony_ci .text; \ 628c2ecf20Sopenharmony_ci .align 4 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/* Please do not change following macros unless you change logic used 658c2ecf20Sopenharmony_ci * in .fixup at the end of this file as well 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* Both these macros have to start with exactly the same insn */ 698c2ecf20Sopenharmony_ci#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ 708c2ecf20Sopenharmony_ci ldd [%src + (offset) + 0x00], %t0; \ 718c2ecf20Sopenharmony_ci ldd [%src + (offset) + 0x08], %t2; \ 728c2ecf20Sopenharmony_ci ldd [%src + (offset) + 0x10], %t4; \ 738c2ecf20Sopenharmony_ci ldd [%src + (offset) + 0x18], %t6; \ 748c2ecf20Sopenharmony_ci st %t0, [%dst + (offset) + 0x00]; \ 758c2ecf20Sopenharmony_ci st %t1, [%dst + (offset) + 0x04]; \ 768c2ecf20Sopenharmony_ci st %t2, [%dst + (offset) + 0x08]; \ 778c2ecf20Sopenharmony_ci st %t3, [%dst + (offset) + 0x0c]; \ 788c2ecf20Sopenharmony_ci st %t4, [%dst + (offset) + 0x10]; \ 798c2ecf20Sopenharmony_ci st %t5, [%dst + (offset) + 0x14]; \ 808c2ecf20Sopenharmony_ci st %t6, [%dst + (offset) + 0x18]; \ 818c2ecf20Sopenharmony_ci st %t7, [%dst + (offset) + 0x1c]; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ 848c2ecf20Sopenharmony_ci ldd [%src + (offset) + 0x00], %t0; \ 858c2ecf20Sopenharmony_ci ldd [%src + (offset) + 0x08], %t2; \ 868c2ecf20Sopenharmony_ci ldd [%src + (offset) + 0x10], %t4; \ 878c2ecf20Sopenharmony_ci ldd [%src + (offset) + 0x18], %t6; \ 888c2ecf20Sopenharmony_ci std %t0, [%dst + (offset) + 0x00]; \ 898c2ecf20Sopenharmony_ci std %t2, [%dst + (offset) + 0x08]; \ 908c2ecf20Sopenharmony_ci std %t4, [%dst + (offset) + 0x10]; \ 918c2ecf20Sopenharmony_ci std %t6, [%dst + (offset) + 0x18]; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \ 948c2ecf20Sopenharmony_ci ldd [%src - (offset) - 0x10], %t0; \ 958c2ecf20Sopenharmony_ci ldd [%src - (offset) - 0x08], %t2; \ 968c2ecf20Sopenharmony_ci st %t0, [%dst - (offset) - 0x10]; \ 978c2ecf20Sopenharmony_ci st %t1, [%dst - (offset) - 0x0c]; \ 988c2ecf20Sopenharmony_ci st %t2, [%dst - (offset) - 0x08]; \ 998c2ecf20Sopenharmony_ci st %t3, [%dst - (offset) - 0x04]; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci#define MOVE_HALFCHUNK(src, dst, offset, t0, t1, t2, t3) \ 1028c2ecf20Sopenharmony_ci lduh [%src + (offset) + 0x00], %t0; \ 1038c2ecf20Sopenharmony_ci lduh [%src + (offset) + 0x02], %t1; \ 1048c2ecf20Sopenharmony_ci lduh [%src + (offset) + 0x04], %t2; \ 1058c2ecf20Sopenharmony_ci lduh [%src + (offset) + 0x06], %t3; \ 1068c2ecf20Sopenharmony_ci sth %t0, [%dst + (offset) + 0x00]; \ 1078c2ecf20Sopenharmony_ci sth %t1, [%dst + (offset) + 0x02]; \ 1088c2ecf20Sopenharmony_ci sth %t2, [%dst + (offset) + 0x04]; \ 1098c2ecf20Sopenharmony_ci sth %t3, [%dst + (offset) + 0x06]; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \ 1128c2ecf20Sopenharmony_ci ldub [%src - (offset) - 0x02], %t0; \ 1138c2ecf20Sopenharmony_ci ldub [%src - (offset) - 0x01], %t1; \ 1148c2ecf20Sopenharmony_ci stb %t0, [%dst - (offset) - 0x02]; \ 1158c2ecf20Sopenharmony_ci stb %t1, [%dst - (offset) - 0x01]; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci .text 1188c2ecf20Sopenharmony_ci .align 4 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci .globl __copy_user_begin 1218c2ecf20Sopenharmony_ci__copy_user_begin: 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci .globl __copy_user 1248c2ecf20Sopenharmony_ci EXPORT_SYMBOL(__copy_user) 1258c2ecf20Sopenharmony_cidword_align: 1268c2ecf20Sopenharmony_ci andcc %o1, 1, %g0 1278c2ecf20Sopenharmony_ci be 4f 1288c2ecf20Sopenharmony_ci andcc %o1, 2, %g0 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci EXO2(ldub [%o1], %g2) 1318c2ecf20Sopenharmony_ci add %o1, 1, %o1 1328c2ecf20Sopenharmony_ci EXO2(stb %g2, [%o0]) 1338c2ecf20Sopenharmony_ci sub %o2, 1, %o2 1348c2ecf20Sopenharmony_ci bne 3f 1358c2ecf20Sopenharmony_ci add %o0, 1, %o0 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci EXO2(lduh [%o1], %g2) 1388c2ecf20Sopenharmony_ci add %o1, 2, %o1 1398c2ecf20Sopenharmony_ci EXO2(sth %g2, [%o0]) 1408c2ecf20Sopenharmony_ci sub %o2, 2, %o2 1418c2ecf20Sopenharmony_ci b 3f 1428c2ecf20Sopenharmony_ci add %o0, 2, %o0 1438c2ecf20Sopenharmony_ci4: 1448c2ecf20Sopenharmony_ci EXO2(lduh [%o1], %g2) 1458c2ecf20Sopenharmony_ci add %o1, 2, %o1 1468c2ecf20Sopenharmony_ci EXO2(sth %g2, [%o0]) 1478c2ecf20Sopenharmony_ci sub %o2, 2, %o2 1488c2ecf20Sopenharmony_ci b 3f 1498c2ecf20Sopenharmony_ci add %o0, 2, %o0 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci__copy_user: /* %o0=dst %o1=src %o2=len */ 1528c2ecf20Sopenharmony_ci xor %o0, %o1, %o4 1538c2ecf20Sopenharmony_ci1: 1548c2ecf20Sopenharmony_ci andcc %o4, 3, %o5 1558c2ecf20Sopenharmony_ci2: 1568c2ecf20Sopenharmony_ci bne cannot_optimize 1578c2ecf20Sopenharmony_ci cmp %o2, 15 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci bleu short_aligned_end 1608c2ecf20Sopenharmony_ci andcc %o1, 3, %g0 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci bne dword_align 1638c2ecf20Sopenharmony_ci3: 1648c2ecf20Sopenharmony_ci andcc %o1, 4, %g0 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci be 2f 1678c2ecf20Sopenharmony_ci mov %o2, %g1 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci EXO2(ld [%o1], %o4) 1708c2ecf20Sopenharmony_ci sub %g1, 4, %g1 1718c2ecf20Sopenharmony_ci EXO2(st %o4, [%o0]) 1728c2ecf20Sopenharmony_ci add %o1, 4, %o1 1738c2ecf20Sopenharmony_ci add %o0, 4, %o0 1748c2ecf20Sopenharmony_ci2: 1758c2ecf20Sopenharmony_ci andcc %g1, 0xffffff80, %g7 1768c2ecf20Sopenharmony_ci be 3f 1778c2ecf20Sopenharmony_ci andcc %o0, 4, %g0 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci be ldd_std + 4 1808c2ecf20Sopenharmony_ci5: 1818c2ecf20Sopenharmony_ci MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 1828c2ecf20Sopenharmony_ci MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 1838c2ecf20Sopenharmony_ci MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 1848c2ecf20Sopenharmony_ci MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 1858c2ecf20Sopenharmony_ci80: 1868c2ecf20Sopenharmony_ci EXT(5b, 80b, 50f) 1878c2ecf20Sopenharmony_ci subcc %g7, 128, %g7 1888c2ecf20Sopenharmony_ci add %o1, 128, %o1 1898c2ecf20Sopenharmony_ci bne 5b 1908c2ecf20Sopenharmony_ci add %o0, 128, %o0 1918c2ecf20Sopenharmony_ci3: 1928c2ecf20Sopenharmony_ci andcc %g1, 0x70, %g7 1938c2ecf20Sopenharmony_ci be copy_user_table_end 1948c2ecf20Sopenharmony_ci andcc %g1, 8, %g0 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci sethi %hi(copy_user_table_end), %o5 1978c2ecf20Sopenharmony_ci srl %g7, 1, %o4 1988c2ecf20Sopenharmony_ci add %g7, %o4, %o4 1998c2ecf20Sopenharmony_ci add %o1, %g7, %o1 2008c2ecf20Sopenharmony_ci sub %o5, %o4, %o5 2018c2ecf20Sopenharmony_ci jmpl %o5 + %lo(copy_user_table_end), %g0 2028c2ecf20Sopenharmony_ci add %o0, %g7, %o0 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cicopy_user_table: 2058c2ecf20Sopenharmony_ci MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5) 2068c2ecf20Sopenharmony_ci MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5) 2078c2ecf20Sopenharmony_ci MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5) 2088c2ecf20Sopenharmony_ci MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5) 2098c2ecf20Sopenharmony_ci MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5) 2108c2ecf20Sopenharmony_ci MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5) 2118c2ecf20Sopenharmony_ci MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 2128c2ecf20Sopenharmony_cicopy_user_table_end: 2138c2ecf20Sopenharmony_ci EXT(copy_user_table, copy_user_table_end, 51f) 2148c2ecf20Sopenharmony_ci be copy_user_last7 2158c2ecf20Sopenharmony_ci andcc %g1, 4, %g0 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci EX(ldd [%o1], %g2, and %g1, 0xf) 2188c2ecf20Sopenharmony_ci add %o0, 8, %o0 2198c2ecf20Sopenharmony_ci add %o1, 8, %o1 2208c2ecf20Sopenharmony_ci EX(st %g2, [%o0 - 0x08], and %g1, 0xf) 2218c2ecf20Sopenharmony_ci EX2(st %g3, [%o0 - 0x04], and %g1, 0xf, %g1, sub %g1, 4) 2228c2ecf20Sopenharmony_cicopy_user_last7: 2238c2ecf20Sopenharmony_ci be 1f 2248c2ecf20Sopenharmony_ci andcc %g1, 2, %g0 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci EX(ld [%o1], %g2, and %g1, 7) 2278c2ecf20Sopenharmony_ci add %o1, 4, %o1 2288c2ecf20Sopenharmony_ci EX(st %g2, [%o0], and %g1, 7) 2298c2ecf20Sopenharmony_ci add %o0, 4, %o0 2308c2ecf20Sopenharmony_ci1: 2318c2ecf20Sopenharmony_ci be 1f 2328c2ecf20Sopenharmony_ci andcc %g1, 1, %g0 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci EX(lduh [%o1], %g2, and %g1, 3) 2358c2ecf20Sopenharmony_ci add %o1, 2, %o1 2368c2ecf20Sopenharmony_ci EX(sth %g2, [%o0], and %g1, 3) 2378c2ecf20Sopenharmony_ci add %o0, 2, %o0 2388c2ecf20Sopenharmony_ci1: 2398c2ecf20Sopenharmony_ci be 1f 2408c2ecf20Sopenharmony_ci nop 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci EX(ldub [%o1], %g2, add %g0, 1) 2438c2ecf20Sopenharmony_ci EX(stb %g2, [%o0], add %g0, 1) 2448c2ecf20Sopenharmony_ci1: 2458c2ecf20Sopenharmony_ci retl 2468c2ecf20Sopenharmony_ci clr %o0 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_cildd_std: 2498c2ecf20Sopenharmony_ci MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 2508c2ecf20Sopenharmony_ci MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 2518c2ecf20Sopenharmony_ci MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 2528c2ecf20Sopenharmony_ci MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 2538c2ecf20Sopenharmony_ci81: 2548c2ecf20Sopenharmony_ci EXT(ldd_std, 81b, 52f) 2558c2ecf20Sopenharmony_ci subcc %g7, 128, %g7 2568c2ecf20Sopenharmony_ci add %o1, 128, %o1 2578c2ecf20Sopenharmony_ci bne ldd_std 2588c2ecf20Sopenharmony_ci add %o0, 128, %o0 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci andcc %g1, 0x70, %g7 2618c2ecf20Sopenharmony_ci be copy_user_table_end 2628c2ecf20Sopenharmony_ci andcc %g1, 8, %g0 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci sethi %hi(copy_user_table_end), %o5 2658c2ecf20Sopenharmony_ci srl %g7, 1, %o4 2668c2ecf20Sopenharmony_ci add %g7, %o4, %o4 2678c2ecf20Sopenharmony_ci add %o1, %g7, %o1 2688c2ecf20Sopenharmony_ci sub %o5, %o4, %o5 2698c2ecf20Sopenharmony_ci jmpl %o5 + %lo(copy_user_table_end), %g0 2708c2ecf20Sopenharmony_ci add %o0, %g7, %o0 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cicannot_optimize: 2738c2ecf20Sopenharmony_ci bleu short_end 2748c2ecf20Sopenharmony_ci cmp %o5, 2 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci bne byte_chunk 2778c2ecf20Sopenharmony_ci and %o2, 0xfffffff0, %o3 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci andcc %o1, 1, %g0 2808c2ecf20Sopenharmony_ci be 10f 2818c2ecf20Sopenharmony_ci nop 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci EXO2(ldub [%o1], %g2) 2848c2ecf20Sopenharmony_ci add %o1, 1, %o1 2858c2ecf20Sopenharmony_ci EXO2(stb %g2, [%o0]) 2868c2ecf20Sopenharmony_ci sub %o2, 1, %o2 2878c2ecf20Sopenharmony_ci andcc %o2, 0xfffffff0, %o3 2888c2ecf20Sopenharmony_ci be short_end 2898c2ecf20Sopenharmony_ci add %o0, 1, %o0 2908c2ecf20Sopenharmony_ci10: 2918c2ecf20Sopenharmony_ci MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 2928c2ecf20Sopenharmony_ci MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5) 2938c2ecf20Sopenharmony_ci82: 2948c2ecf20Sopenharmony_ci EXT(10b, 82b, 53f) 2958c2ecf20Sopenharmony_ci subcc %o3, 0x10, %o3 2968c2ecf20Sopenharmony_ci add %o1, 0x10, %o1 2978c2ecf20Sopenharmony_ci bne 10b 2988c2ecf20Sopenharmony_ci add %o0, 0x10, %o0 2998c2ecf20Sopenharmony_ci b 2f 3008c2ecf20Sopenharmony_ci and %o2, 0xe, %o3 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cibyte_chunk: 3038c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, -0x02, g2, g3) 3048c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, -0x04, g2, g3) 3058c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, -0x06, g2, g3) 3068c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, -0x08, g2, g3) 3078c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, -0x0a, g2, g3) 3088c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, -0x0c, g2, g3) 3098c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3) 3108c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3) 3118c2ecf20Sopenharmony_ci83: 3128c2ecf20Sopenharmony_ci EXT(byte_chunk, 83b, 54f) 3138c2ecf20Sopenharmony_ci subcc %o3, 0x10, %o3 3148c2ecf20Sopenharmony_ci add %o1, 0x10, %o1 3158c2ecf20Sopenharmony_ci bne byte_chunk 3168c2ecf20Sopenharmony_ci add %o0, 0x10, %o0 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_cishort_end: 3198c2ecf20Sopenharmony_ci and %o2, 0xe, %o3 3208c2ecf20Sopenharmony_ci2: 3218c2ecf20Sopenharmony_ci sethi %hi(short_table_end), %o5 3228c2ecf20Sopenharmony_ci sll %o3, 3, %o4 3238c2ecf20Sopenharmony_ci add %o0, %o3, %o0 3248c2ecf20Sopenharmony_ci sub %o5, %o4, %o5 3258c2ecf20Sopenharmony_ci add %o1, %o3, %o1 3268c2ecf20Sopenharmony_ci jmpl %o5 + %lo(short_table_end), %g0 3278c2ecf20Sopenharmony_ci andcc %o2, 1, %g0 3288c2ecf20Sopenharmony_ci84: 3298c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3) 3308c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3) 3318c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3) 3328c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3) 3338c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3) 3348c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3) 3358c2ecf20Sopenharmony_ci MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3) 3368c2ecf20Sopenharmony_cishort_table_end: 3378c2ecf20Sopenharmony_ci EXT(84b, short_table_end, 55f) 3388c2ecf20Sopenharmony_ci be 1f 3398c2ecf20Sopenharmony_ci nop 3408c2ecf20Sopenharmony_ci EX(ldub [%o1], %g2, add %g0, 1) 3418c2ecf20Sopenharmony_ci EX(stb %g2, [%o0], add %g0, 1) 3428c2ecf20Sopenharmony_ci1: 3438c2ecf20Sopenharmony_ci retl 3448c2ecf20Sopenharmony_ci clr %o0 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_cishort_aligned_end: 3478c2ecf20Sopenharmony_ci bne short_end 3488c2ecf20Sopenharmony_ci andcc %o2, 8, %g0 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci be 1f 3518c2ecf20Sopenharmony_ci andcc %o2, 4, %g0 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci EXO2(ld [%o1 + 0x00], %g2) 3548c2ecf20Sopenharmony_ci EXO2(ld [%o1 + 0x04], %g3) 3558c2ecf20Sopenharmony_ci add %o1, 8, %o1 3568c2ecf20Sopenharmony_ci EXO2(st %g2, [%o0 + 0x00]) 3578c2ecf20Sopenharmony_ci EX(st %g3, [%o0 + 0x04], sub %o2, 4) 3588c2ecf20Sopenharmony_ci add %o0, 8, %o0 3598c2ecf20Sopenharmony_ci1: 3608c2ecf20Sopenharmony_ci b copy_user_last7 3618c2ecf20Sopenharmony_ci mov %o2, %g1 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci .section .fixup,#alloc,#execinstr 3648c2ecf20Sopenharmony_ci .align 4 3658c2ecf20Sopenharmony_ci97: 3668c2ecf20Sopenharmony_ci mov %o2, %g3 3678c2ecf20Sopenharmony_cifixupretl: 3688c2ecf20Sopenharmony_ci retl 3698c2ecf20Sopenharmony_ci mov %g3, %o0 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci/* exception routine sets %g2 to (broken_insn - first_insn)>>2 */ 3728c2ecf20Sopenharmony_ci50: 3738c2ecf20Sopenharmony_ci/* This magic counts how many bytes are left when crash in MOVE_BIGCHUNK 3748c2ecf20Sopenharmony_ci * happens. This is derived from the amount ldd reads, st stores, etc. 3758c2ecf20Sopenharmony_ci * x = g2 % 12; 3768c2ecf20Sopenharmony_ci * g3 = g1 + g7 - ((g2 / 12) * 32 + (x < 4) ? 0 : (x - 4) * 4); 3778c2ecf20Sopenharmony_ci * o0 += (g2 / 12) * 32; 3788c2ecf20Sopenharmony_ci */ 3798c2ecf20Sopenharmony_ci cmp %g2, 12 3808c2ecf20Sopenharmony_ci add %o0, %g7, %o0 3818c2ecf20Sopenharmony_ci bcs 1f 3828c2ecf20Sopenharmony_ci cmp %g2, 24 3838c2ecf20Sopenharmony_ci bcs 2f 3848c2ecf20Sopenharmony_ci cmp %g2, 36 3858c2ecf20Sopenharmony_ci bcs 3f 3868c2ecf20Sopenharmony_ci nop 3878c2ecf20Sopenharmony_ci sub %g2, 12, %g2 3888c2ecf20Sopenharmony_ci sub %g7, 32, %g7 3898c2ecf20Sopenharmony_ci3: sub %g2, 12, %g2 3908c2ecf20Sopenharmony_ci sub %g7, 32, %g7 3918c2ecf20Sopenharmony_ci2: sub %g2, 12, %g2 3928c2ecf20Sopenharmony_ci sub %g7, 32, %g7 3938c2ecf20Sopenharmony_ci1: cmp %g2, 4 3948c2ecf20Sopenharmony_ci bcs,a 60f 3958c2ecf20Sopenharmony_ci clr %g2 3968c2ecf20Sopenharmony_ci sub %g2, 4, %g2 3978c2ecf20Sopenharmony_ci sll %g2, 2, %g2 3988c2ecf20Sopenharmony_ci60: and %g1, 0x7f, %g3 3998c2ecf20Sopenharmony_ci sub %o0, %g7, %o0 4008c2ecf20Sopenharmony_ci add %g3, %g7, %g3 4018c2ecf20Sopenharmony_ci ba fixupretl 4028c2ecf20Sopenharmony_ci sub %g3, %g2, %g3 4038c2ecf20Sopenharmony_ci51: 4048c2ecf20Sopenharmony_ci/* i = 41 - g2; j = i % 6; 4058c2ecf20Sopenharmony_ci * g3 = (g1 & 15) + (i / 6) * 16 + (j < 4) ? (j + 1) * 4 : 16; 4068c2ecf20Sopenharmony_ci * o0 -= (i / 6) * 16 + 16; 4078c2ecf20Sopenharmony_ci */ 4088c2ecf20Sopenharmony_ci neg %g2 4098c2ecf20Sopenharmony_ci and %g1, 0xf, %g1 4108c2ecf20Sopenharmony_ci add %g2, 41, %g2 4118c2ecf20Sopenharmony_ci add %o0, %g1, %o0 4128c2ecf20Sopenharmony_ci1: cmp %g2, 6 4138c2ecf20Sopenharmony_ci bcs,a 2f 4148c2ecf20Sopenharmony_ci cmp %g2, 4 4158c2ecf20Sopenharmony_ci add %g1, 16, %g1 4168c2ecf20Sopenharmony_ci b 1b 4178c2ecf20Sopenharmony_ci sub %g2, 6, %g2 4188c2ecf20Sopenharmony_ci2: bcc,a 2f 4198c2ecf20Sopenharmony_ci mov 16, %g2 4208c2ecf20Sopenharmony_ci inc %g2 4218c2ecf20Sopenharmony_ci sll %g2, 2, %g2 4228c2ecf20Sopenharmony_ci2: add %g1, %g2, %g3 4238c2ecf20Sopenharmony_ci ba fixupretl 4248c2ecf20Sopenharmony_ci sub %o0, %g3, %o0 4258c2ecf20Sopenharmony_ci52: 4268c2ecf20Sopenharmony_ci/* g3 = g1 + g7 - (g2 / 8) * 32 + (g2 & 4) ? (g2 & 3) * 8 : 0; 4278c2ecf20Sopenharmony_ci o0 += (g2 / 8) * 32 */ 4288c2ecf20Sopenharmony_ci andn %g2, 7, %g4 4298c2ecf20Sopenharmony_ci add %o0, %g7, %o0 4308c2ecf20Sopenharmony_ci andcc %g2, 4, %g0 4318c2ecf20Sopenharmony_ci and %g2, 3, %g2 4328c2ecf20Sopenharmony_ci sll %g4, 2, %g4 4338c2ecf20Sopenharmony_ci sll %g2, 3, %g2 4348c2ecf20Sopenharmony_ci bne 60b 4358c2ecf20Sopenharmony_ci sub %g7, %g4, %g7 4368c2ecf20Sopenharmony_ci ba 60b 4378c2ecf20Sopenharmony_ci clr %g2 4388c2ecf20Sopenharmony_ci53: 4398c2ecf20Sopenharmony_ci/* g3 = o3 + (o2 & 15) - (g2 & 8) - (g2 & 4) ? (g2 & 3) * 2 : 0; 4408c2ecf20Sopenharmony_ci o0 += (g2 & 8) */ 4418c2ecf20Sopenharmony_ci and %g2, 3, %g4 4428c2ecf20Sopenharmony_ci andcc %g2, 4, %g0 4438c2ecf20Sopenharmony_ci and %g2, 8, %g2 4448c2ecf20Sopenharmony_ci sll %g4, 1, %g4 4458c2ecf20Sopenharmony_ci be 1f 4468c2ecf20Sopenharmony_ci add %o0, %g2, %o0 4478c2ecf20Sopenharmony_ci add %g2, %g4, %g2 4488c2ecf20Sopenharmony_ci1: and %o2, 0xf, %g3 4498c2ecf20Sopenharmony_ci add %g3, %o3, %g3 4508c2ecf20Sopenharmony_ci ba fixupretl 4518c2ecf20Sopenharmony_ci sub %g3, %g2, %g3 4528c2ecf20Sopenharmony_ci54: 4538c2ecf20Sopenharmony_ci/* g3 = o3 + (o2 & 15) - (g2 / 4) * 2 - (g2 & 2) ? (g2 & 1) : 0; 4548c2ecf20Sopenharmony_ci o0 += (g2 / 4) * 2 */ 4558c2ecf20Sopenharmony_ci srl %g2, 2, %o4 4568c2ecf20Sopenharmony_ci and %g2, 1, %o5 4578c2ecf20Sopenharmony_ci srl %g2, 1, %g2 4588c2ecf20Sopenharmony_ci add %o4, %o4, %o4 4598c2ecf20Sopenharmony_ci and %o5, %g2, %o5 4608c2ecf20Sopenharmony_ci and %o2, 0xf, %o2 4618c2ecf20Sopenharmony_ci add %o0, %o4, %o0 4628c2ecf20Sopenharmony_ci sub %o3, %o5, %o3 4638c2ecf20Sopenharmony_ci sub %o2, %o4, %o2 4648c2ecf20Sopenharmony_ci ba fixupretl 4658c2ecf20Sopenharmony_ci add %o2, %o3, %g3 4668c2ecf20Sopenharmony_ci55: 4678c2ecf20Sopenharmony_ci/* i = 27 - g2; 4688c2ecf20Sopenharmony_ci g3 = (o2 & 1) + i / 4 * 2 + !(i & 3); 4698c2ecf20Sopenharmony_ci o0 -= i / 4 * 2 + 1 */ 4708c2ecf20Sopenharmony_ci neg %g2 4718c2ecf20Sopenharmony_ci and %o2, 1, %o2 4728c2ecf20Sopenharmony_ci add %g2, 27, %g2 4738c2ecf20Sopenharmony_ci srl %g2, 2, %o5 4748c2ecf20Sopenharmony_ci andcc %g2, 3, %g0 4758c2ecf20Sopenharmony_ci mov 1, %g2 4768c2ecf20Sopenharmony_ci add %o5, %o5, %o5 4778c2ecf20Sopenharmony_ci be,a 1f 4788c2ecf20Sopenharmony_ci clr %g2 4798c2ecf20Sopenharmony_ci1: add %g2, %o5, %g3 4808c2ecf20Sopenharmony_ci sub %o0, %g3, %o0 4818c2ecf20Sopenharmony_ci ba fixupretl 4828c2ecf20Sopenharmony_ci add %g3, %o2, %g3 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci .globl __copy_user_end 4858c2ecf20Sopenharmony_ci__copy_user_end: 486