1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1998, 1999, 2000 by Ralf Baechle 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 */ 9#include <asm/asm.h> 10#include <asm/asm-offsets.h> 11#include <asm/regdef.h> 12 13#if LONGSIZE == 4 14#define LONG_S_L swl 15#define LONG_S_R swr 16#else 17#define LONG_S_L sdl 18#define LONG_S_R sdr 19#endif 20 21#define EX(insn,reg,addr,handler) \ 229: insn reg, addr; \ 23 .section __ex_table,"a"; \ 24 PTR 9b, handler; \ 25 .previous 26 27 .macro f_fill64 dst, offset, val, fixup 28 EX(LONG_S, \val, (\offset + 0 * LONGSIZE)(\dst), \fixup) 29 EX(LONG_S, \val, (\offset + 1 * LONGSIZE)(\dst), \fixup) 30 EX(LONG_S, \val, (\offset + 2 * LONGSIZE)(\dst), \fixup) 31 EX(LONG_S, \val, (\offset + 3 * LONGSIZE)(\dst), \fixup) 32 EX(LONG_S, \val, (\offset + 4 * LONGSIZE)(\dst), \fixup) 33 EX(LONG_S, \val, (\offset + 5 * LONGSIZE)(\dst), \fixup) 34 EX(LONG_S, \val, (\offset + 6 * LONGSIZE)(\dst), \fixup) 35 EX(LONG_S, \val, (\offset + 7 * LONGSIZE)(\dst), \fixup) 36#if LONGSIZE == 4 37 EX(LONG_S, \val, (\offset + 8 * LONGSIZE)(\dst), \fixup) 38 EX(LONG_S, \val, (\offset + 9 * LONGSIZE)(\dst), \fixup) 39 EX(LONG_S, \val, (\offset + 10 * LONGSIZE)(\dst), \fixup) 40 EX(LONG_S, \val, (\offset + 11 * LONGSIZE)(\dst), \fixup) 41 EX(LONG_S, \val, (\offset + 12 * LONGSIZE)(\dst), \fixup) 42 EX(LONG_S, \val, (\offset + 13 * LONGSIZE)(\dst), \fixup) 43 EX(LONG_S, \val, (\offset + 14 * LONGSIZE)(\dst), \fixup) 44 EX(LONG_S, \val, (\offset + 15 * LONGSIZE)(\dst), \fixup) 45#endif 46 .endm 47 48/* 49 * memset(void *s, int c, size_t n) 50 * 51 * a0: start of area to clear 52 * a1: char to fill with 53 * a2: size of area to clear 54 */ 55 .set noreorder 56 .align 5 57LEAF(memset) 58 beqz a1, 1f 59 move v0, a0 /* result */ 60 61 andi a1, 0xff /* spread fillword */ 62 LONG_SLL t1, a1, 8 63 or a1, t1 64 LONG_SLL t1, a1, 16 65#if LONGSIZE == 8 66 or a1, t1 67 LONG_SLL t1, a1, 32 68#endif 69 or a1, t1 701: 71 72FEXPORT(__bzero) 73 sltiu t0, a2, LONGSIZE /* very small region? */ 74 bnez t0, small_memset 75 andi t0, a0, LONGMASK /* aligned? */ 76 77 beqz t0, 1f 78 PTR_SUBU t0, LONGSIZE /* alignment in bytes */ 79 80#ifdef __MIPSEB__ 81 EX(LONG_S_L, a1, (a0), first_fixup) /* make word/dword aligned */ 82#endif 83#ifdef __MIPSEL__ 84 EX(LONG_S_R, a1, (a0), first_fixup) /* make word/dword aligned */ 85#endif 86 PTR_SUBU a0, t0 /* long align ptr */ 87 PTR_ADDU a2, t0 /* correct size */ 88 891: ori t1, a2, 0x3f /* # of full blocks */ 90 xori t1, 0x3f 91 beqz t1, memset_partial /* no block to fill */ 92 andi t0, a2, 0x40-LONGSIZE 93 94 PTR_ADDU t1, a0 /* end address */ 95 .set reorder 961: PTR_ADDIU a0, 64 97 f_fill64 a0, -64, a1, fwd_fixup 98 bne t1, a0, 1b 99 .set noreorder 100 101memset_partial: 102 PTR_LA t1, 2f /* where to start */ 103#if LONGSIZE == 4 104 PTR_SUBU t1, t0 105#else 106 .set noat 107 LONG_SRL AT, t0, 1 108 PTR_SUBU t1, AT 109 .set noat 110#endif 111 jr t1 112 PTR_ADDU a0, t0 /* dest ptr */ 113 114 .set push 115 .set noreorder 116 .set nomacro 117 f_fill64 a0, -64, a1, partial_fixup /* ... but first do longs ... */ 1182: .set pop 119 andi a2, LONGMASK /* At most one long to go */ 120 121 beqz a2, 1f 122 PTR_ADDU a0, a2 /* What's left */ 123#ifdef __MIPSEB__ 124 EX(LONG_S_R, a1, -1(a0), last_fixup) 125#endif 126#ifdef __MIPSEL__ 127 EX(LONG_S_L, a1, -1(a0), last_fixup) 128#endif 1291: jr ra 130 move a2, zero 131 132small_memset: 133 beqz a2, 2f 134 PTR_ADDU t1, a0, a2 135 1361: PTR_ADDIU a0, 1 /* fill bytewise */ 137 bne t1, a0, 1b 138 sb a1, -1(a0) 139 1402: jr ra /* done */ 141 move a2, zero 142 END(memset) 143 144first_fixup: 145 jr ra 146 nop 147 148fwd_fixup: 149 PTR_L t0, TI_TASK($28) 150 LONG_L t0, THREAD_BUADDR(t0) 151 andi a2, 0x3f 152 LONG_ADDU a2, t1 153 jr ra 154 LONG_SUBU a2, t0 155 156partial_fixup: 157 PTR_L t0, TI_TASK($28) 158 LONG_L t0, THREAD_BUADDR(t0) 159 andi a2, LONGMASK 160 LONG_ADDU a2, t1 161 jr ra 162 LONG_SUBU a2, t0 163 164last_fixup: 165 jr ra 166 andi v1, a2, LONGMASK 167