11da177e4SLinus Torvalds/* linux/arch/sparc/lib/memset.S: Sparc optimized memset, bzero and clear_user code 21da177e4SLinus Torvalds * Copyright (C) 1991,1996 Free Software Foundation 31da177e4SLinus Torvalds * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 41da177e4SLinus Torvalds * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Returns 0, if ok, and number of bytes not yet set if exception 71da177e4SLinus Torvalds * occurs and we were called as clear_user. 81da177e4SLinus Torvalds */ 91da177e4SLinus Torvalds 101da177e4SLinus Torvalds#include <asm/ptrace.h> 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds/* Work around cpp -rob */ 131da177e4SLinus Torvalds#define ALLOC #alloc 141da177e4SLinus Torvalds#define EXECINSTR #execinstr 151da177e4SLinus Torvalds#define EX(x,y,a,b) \ 161da177e4SLinus Torvalds98: x,y; \ 171da177e4SLinus Torvalds .section .fixup,ALLOC,EXECINSTR; \ 181da177e4SLinus Torvalds .align 4; \ 191da177e4SLinus Torvalds99: ba 30f; \ 201da177e4SLinus Torvalds a, b, %o0; \ 211da177e4SLinus Torvalds .section __ex_table,ALLOC; \ 221da177e4SLinus Torvalds .align 4; \ 231da177e4SLinus Torvalds .word 98b, 99b; \ 241da177e4SLinus Torvalds .text; \ 251da177e4SLinus Torvalds .align 4 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds#define EXT(start,end,handler) \ 281da177e4SLinus Torvalds .section __ex_table,ALLOC; \ 291da177e4SLinus Torvalds .align 4; \ 301da177e4SLinus Torvalds .word start, 0, end, handler; \ 311da177e4SLinus Torvalds .text; \ 321da177e4SLinus Torvalds .align 4 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds/* Please don't change these macros, unless you change the logic 351da177e4SLinus Torvalds * in the .fixup section below as well. 361da177e4SLinus Torvalds * Store 64 bytes at (BASE + OFFSET) using value SOURCE. */ 371da177e4SLinus Torvalds#define ZERO_BIG_BLOCK(base, offset, source) \ 381da177e4SLinus Torvalds std source, [base + offset + 0x00]; \ 391da177e4SLinus Torvalds std source, [base + offset + 0x08]; \ 401da177e4SLinus Torvalds std source, [base + offset + 0x10]; \ 411da177e4SLinus Torvalds std source, [base + offset + 0x18]; \ 421da177e4SLinus Torvalds std source, [base + offset + 0x20]; \ 431da177e4SLinus Torvalds std source, [base + offset + 0x28]; \ 441da177e4SLinus Torvalds std source, [base + offset + 0x30]; \ 451da177e4SLinus Torvalds std source, [base + offset + 0x38]; 461da177e4SLinus Torvalds 471da177e4SLinus Torvalds#define ZERO_LAST_BLOCKS(base, offset, source) \ 481da177e4SLinus Torvalds std source, [base - offset - 0x38]; \ 491da177e4SLinus Torvalds std source, [base - offset - 0x30]; \ 501da177e4SLinus Torvalds std source, [base - offset - 0x28]; \ 511da177e4SLinus Torvalds std source, [base - offset - 0x20]; \ 521da177e4SLinus Torvalds std source, [base - offset - 0x18]; \ 531da177e4SLinus Torvalds std source, [base - offset - 0x10]; \ 541da177e4SLinus Torvalds std source, [base - offset - 0x08]; \ 551da177e4SLinus Torvalds std source, [base - offset - 0x00]; 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds .text 581da177e4SLinus Torvalds .align 4 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds .globl __bzero_begin 611da177e4SLinus Torvalds__bzero_begin: 621da177e4SLinus Torvalds 63*4d14a459SDavid S. Miller .globl __bzero 641da177e4SLinus Torvalds .globl memset 651da177e4SLinus Torvalds .globl __memset_start, __memset_end 661da177e4SLinus Torvalds__memset_start: 671da177e4SLinus Torvaldsmemset: 681da177e4SLinus Torvalds and %o1, 0xff, %g3 691da177e4SLinus Torvalds sll %g3, 8, %g2 701da177e4SLinus Torvalds or %g3, %g2, %g3 711da177e4SLinus Torvalds sll %g3, 16, %g2 721da177e4SLinus Torvalds or %g3, %g2, %g3 731da177e4SLinus Torvalds b 1f 741da177e4SLinus Torvalds mov %o2, %o1 751da177e4SLinus Torvalds3: 761da177e4SLinus Torvalds cmp %o2, 3 771da177e4SLinus Torvalds be 2f 781da177e4SLinus Torvalds EX(stb %g3, [%o0], sub %o1, 0) 791da177e4SLinus Torvalds 801da177e4SLinus Torvalds cmp %o2, 2 811da177e4SLinus Torvalds be 2f 821da177e4SLinus Torvalds EX(stb %g3, [%o0 + 0x01], sub %o1, 1) 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds EX(stb %g3, [%o0 + 0x02], sub %o1, 2) 851da177e4SLinus Torvalds2: 861da177e4SLinus Torvalds sub %o2, 4, %o2 871da177e4SLinus Torvalds add %o1, %o2, %o1 881da177e4SLinus Torvalds b 4f 891da177e4SLinus Torvalds sub %o0, %o2, %o0 901da177e4SLinus Torvalds 911da177e4SLinus Torvalds__bzero: 921da177e4SLinus Torvalds mov %g0, %g3 931da177e4SLinus Torvalds1: 941da177e4SLinus Torvalds cmp %o1, 7 951da177e4SLinus Torvalds bleu 7f 961da177e4SLinus Torvalds andcc %o0, 3, %o2 971da177e4SLinus Torvalds 981da177e4SLinus Torvalds bne 3b 991da177e4SLinus Torvalds4: 1001da177e4SLinus Torvalds andcc %o0, 4, %g0 1011da177e4SLinus Torvalds 1021da177e4SLinus Torvalds be 2f 1031da177e4SLinus Torvalds mov %g3, %g2 1041da177e4SLinus Torvalds 1051da177e4SLinus Torvalds EX(st %g3, [%o0], sub %o1, 0) 1061da177e4SLinus Torvalds sub %o1, 4, %o1 1071da177e4SLinus Torvalds add %o0, 4, %o0 1081da177e4SLinus Torvalds2: 1091da177e4SLinus Torvalds andcc %o1, 0xffffff80, %o3 ! Now everything is 8 aligned and o1 is len to run 1101da177e4SLinus Torvalds be 9f 1111da177e4SLinus Torvalds andcc %o1, 0x78, %o2 1121da177e4SLinus Torvalds10: 1131da177e4SLinus Torvalds ZERO_BIG_BLOCK(%o0, 0x00, %g2) 1141da177e4SLinus Torvalds subcc %o3, 128, %o3 1151da177e4SLinus Torvalds ZERO_BIG_BLOCK(%o0, 0x40, %g2) 1161da177e4SLinus Torvalds11: 1171da177e4SLinus Torvalds EXT(10b, 11b, 20f) 1181da177e4SLinus Torvalds bne 10b 1191da177e4SLinus Torvalds add %o0, 128, %o0 1201da177e4SLinus Torvalds 1211da177e4SLinus Torvalds orcc %o2, %g0, %g0 1221da177e4SLinus Torvalds9: 1231da177e4SLinus Torvalds be 13f 1241da177e4SLinus Torvalds andcc %o1, 7, %o1 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds srl %o2, 1, %o3 1271da177e4SLinus Torvalds set 13f, %o4 1281da177e4SLinus Torvalds sub %o4, %o3, %o4 1291da177e4SLinus Torvalds jmp %o4 1301da177e4SLinus Torvalds add %o0, %o2, %o0 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds12: 1331da177e4SLinus Torvalds ZERO_LAST_BLOCKS(%o0, 0x48, %g2) 1341da177e4SLinus Torvalds ZERO_LAST_BLOCKS(%o0, 0x08, %g2) 1351da177e4SLinus Torvalds13: 1361da177e4SLinus Torvalds be 8f 1371da177e4SLinus Torvalds andcc %o1, 4, %g0 1381da177e4SLinus Torvalds 1391da177e4SLinus Torvalds be 1f 1401da177e4SLinus Torvalds andcc %o1, 2, %g0 1411da177e4SLinus Torvalds 1421da177e4SLinus Torvalds EX(st %g3, [%o0], and %o1, 7) 1431da177e4SLinus Torvalds add %o0, 4, %o0 1441da177e4SLinus Torvalds1: 1451da177e4SLinus Torvalds be 1f 1461da177e4SLinus Torvalds andcc %o1, 1, %g0 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds EX(sth %g3, [%o0], and %o1, 3) 1491da177e4SLinus Torvalds add %o0, 2, %o0 1501da177e4SLinus Torvalds1: 1511da177e4SLinus Torvalds bne,a 8f 1521da177e4SLinus Torvalds EX(stb %g3, [%o0], and %o1, 1) 1531da177e4SLinus Torvalds8: 1541da177e4SLinus Torvalds retl 1551da177e4SLinus Torvalds clr %o0 1561da177e4SLinus Torvalds7: 1571da177e4SLinus Torvalds be 13b 1581da177e4SLinus Torvalds orcc %o1, 0, %g0 1591da177e4SLinus Torvalds 1601da177e4SLinus Torvalds be 0f 1611da177e4SLinus Torvalds8: 1621da177e4SLinus Torvalds add %o0, 1, %o0 1631da177e4SLinus Torvalds subcc %o1, 1, %o1 164f61698e6SAlexander Shmelev bne 8b 1651da177e4SLinus Torvalds EX(stb %g3, [%o0 - 1], add %o1, 1) 1661da177e4SLinus Torvalds0: 1671da177e4SLinus Torvalds retl 1681da177e4SLinus Torvalds clr %o0 1691da177e4SLinus Torvalds__memset_end: 1701da177e4SLinus Torvalds 1711da177e4SLinus Torvalds .section .fixup,#alloc,#execinstr 1721da177e4SLinus Torvalds .align 4 1731da177e4SLinus Torvalds20: 1741da177e4SLinus Torvalds cmp %g2, 8 1751da177e4SLinus Torvalds bleu 1f 1761da177e4SLinus Torvalds and %o1, 0x7f, %o1 1771da177e4SLinus Torvalds sub %g2, 9, %g2 1781da177e4SLinus Torvalds add %o3, 64, %o3 1791da177e4SLinus Torvalds1: 1801da177e4SLinus Torvalds sll %g2, 3, %g2 1811da177e4SLinus Torvalds add %o3, %o1, %o0 1821da177e4SLinus Torvalds b 30f 1831da177e4SLinus Torvalds sub %o0, %g2, %o0 1841da177e4SLinus Torvalds21: 1851da177e4SLinus Torvalds mov 8, %o0 1861da177e4SLinus Torvalds and %o1, 7, %o1 1871da177e4SLinus Torvalds sub %o0, %g2, %o0 1881da177e4SLinus Torvalds sll %o0, 3, %o0 1891da177e4SLinus Torvalds b 30f 1901da177e4SLinus Torvalds add %o0, %o1, %o0 1911da177e4SLinus Torvalds30: 1921da177e4SLinus Torvalds/* %o4 is faulting address, %o5 is %pc where fault occurred */ 1931da177e4SLinus Torvalds save %sp, -104, %sp 1941da177e4SLinus Torvalds mov %i5, %o0 1951da177e4SLinus Torvalds mov %i7, %o1 1961da177e4SLinus Torvalds call lookup_fault 1971da177e4SLinus Torvalds mov %i4, %o2 1981da177e4SLinus Torvalds ret 1991da177e4SLinus Torvalds restore 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds .globl __bzero_end 2021da177e4SLinus Torvalds__bzero_end: 203