1129198Scognet/* $NetBSD: bcopy_page.S,v 1.7 2003/10/13 21:03:13 scw Exp $ */ 2129198Scognet 3139735Simp/*- 4129198Scognet * Copyright (c) 1995 Scott Stevens 5129198Scognet * All rights reserved. 6129198Scognet * 7129198Scognet * Redistribution and use in source and binary forms, with or without 8129198Scognet * modification, are permitted provided that the following conditions 9129198Scognet * are met: 10129198Scognet * 1. Redistributions of source code must retain the above copyright 11129198Scognet * notice, this list of conditions and the following disclaimer. 12129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 13129198Scognet * notice, this list of conditions and the following disclaimer in the 14129198Scognet * documentation and/or other materials provided with the distribution. 15129198Scognet * 3. All advertising materials mentioning features or use of this software 16129198Scognet * must display the following acknowledgement: 17129198Scognet * This product includes software developed by Scott Stevens. 18129198Scognet * 4. The name of the author may not be used to endorse or promote products 19129198Scognet * derived from this software without specific prior written permission. 20129198Scognet * 21129198Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22129198Scognet * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23129198Scognet * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24129198Scognet * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25129198Scognet * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26129198Scognet * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27129198Scognet * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28129198Scognet * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29129198Scognet * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30129198Scognet * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31129198Scognet * 32129198Scognet * RiscBSD kernel project 33129198Scognet * 34129198Scognet * bcopy_page.S 35129198Scognet * 36129198Scognet * page optimised bcopy and bzero routines 37129198Scognet * 38129198Scognet * Created : 08/04/95 39129198Scognet */ 40129198Scognet 41129198Scognet#include <machine/asm.h> 42150996Scognet 43129198Scognet__FBSDID("$FreeBSD$"); 44150996Scognet 45150996Scognet#include "assym.s" 46150996Scognet 47172614Scognet#ifndef _ARM_ARCH_5E 48129198Scognet 49129198Scognet/* #define BIG_LOOPS */ 50129198Scognet 51129198Scognet/* 52129198Scognet * bcopy_page(src, dest) 53129198Scognet * 54129198Scognet * Optimised copy page routine. 55129198Scognet * 56129198Scognet * On entry: 57129198Scognet * r0 - src address 58129198Scognet * r1 - dest address 59129198Scognet * 60129198Scognet * Requires: 61129198Scognet * number of bytes per page (PAGE_SIZE) is a multiple of 512 (BIG_LOOPS), 128 62129198Scognet * otherwise. 63129198Scognet */ 64129198Scognet 65129198Scognet#define CHUNK_SIZE 32 66129198Scognet 67129198Scognet#define PREFETCH_FIRST_CHUNK /* nothing */ 68129198Scognet#define PREFETCH_NEXT_CHUNK /* nothing */ 69129198Scognet 70129198Scognet#ifndef COPY_CHUNK 71129198Scognet#define COPY_CHUNK \ 72129198Scognet PREFETCH_NEXT_CHUNK ; \ 73129198Scognet ldmia r0!, {r3-r8,ip,lr} ; \ 74129198Scognet stmia r1!, {r3-r8,ip,lr} 75129198Scognet#endif /* ! COPY_CHUNK */ 76129198Scognet 77129198Scognet#ifndef SAVE_REGS 78288662Srwatson#define SAVE_REGS stmfd sp!, {r4-r8, lr}; _SAVE({r4-r8, lr}) 79129198Scognet#define RESTORE_REGS ldmfd sp!, {r4-r8, pc} 80129198Scognet#endif 81129198Scognet 82129198ScognetENTRY(bcopy_page) 83129198Scognet PREFETCH_FIRST_CHUNK 84129198Scognet SAVE_REGS 85129198Scognet#ifdef BIG_LOOPS 86129198Scognet mov r2, #(PAGE_SIZE >> 9) 87129198Scognet#else 88129198Scognet mov r2, #(PAGE_SIZE >> 7) 89129198Scognet#endif 90129198Scognet 91129198Scognet1: 92129198Scognet COPY_CHUNK 93129198Scognet COPY_CHUNK 94129198Scognet COPY_CHUNK 95129198Scognet COPY_CHUNK 96129198Scognet 97129198Scognet#ifdef BIG_LOOPS 98129198Scognet /* There is little point making the loop any larger; unless we are 99129198Scognet running with the cache off, the load/store overheads will 100129198Scognet completely dominate this loop. */ 101129198Scognet COPY_CHUNK 102129198Scognet COPY_CHUNK 103129198Scognet COPY_CHUNK 104129198Scognet COPY_CHUNK 105129198Scognet 106129198Scognet COPY_CHUNK 107129198Scognet COPY_CHUNK 108129198Scognet COPY_CHUNK 109129198Scognet COPY_CHUNK 110129198Scognet 111129198Scognet COPY_CHUNK 112129198Scognet COPY_CHUNK 113129198Scognet COPY_CHUNK 114129198Scognet COPY_CHUNK 115129198Scognet#endif 116129198Scognet subs r2, r2, #1 117129198Scognet bne 1b 118129198Scognet 119129198Scognet RESTORE_REGS /* ...and return. */ 120248361SandrewEND(bcopy_page) 121129198Scognet 122129198Scognet/* 123129198Scognet * bzero_page(dest) 124129198Scognet * 125129198Scognet * Optimised zero page routine. 126129198Scognet * 127129198Scognet * On entry: 128129198Scognet * r0 - dest address 129129198Scognet * 130129198Scognet * Requires: 131129198Scognet * number of bytes per page (PAGE_SIZE) is a multiple of 512 (BIG_LOOPS), 128 132129198Scognet * otherwise 133129198Scognet */ 134129198Scognet 135129198ScognetENTRY(bzero_page) 136129198Scognet stmfd sp!, {r4-r8, lr} 137288662Srwatson _SAVE({r4-r8, lr}) 138129198Scognet#ifdef BIG_LOOPS 139129198Scognet mov r2, #(PAGE_SIZE >> 9) 140129198Scognet#else 141129198Scognet mov r2, #(PAGE_SIZE >> 7) 142129198Scognet#endif 143129198Scognet mov r3, #0 144129198Scognet mov r4, #0 145129198Scognet mov r5, #0 146129198Scognet mov r6, #0 147129198Scognet mov r7, #0 148129198Scognet mov r8, #0 149129198Scognet mov ip, #0 150129198Scognet mov lr, #0 151129198Scognet 152129198Scognet1: 153129198Scognet stmia r0!, {r3-r8,ip,lr} 154129198Scognet stmia r0!, {r3-r8,ip,lr} 155129198Scognet stmia r0!, {r3-r8,ip,lr} 156129198Scognet stmia r0!, {r3-r8,ip,lr} 157129198Scognet 158129198Scognet#ifdef BIG_LOOPS 159129198Scognet /* There is little point making the loop any larger; unless we are 160129198Scognet running with the cache off, the load/store overheads will 161129198Scognet completely dominate this loop. */ 162129198Scognet stmia r0!, {r3-r8,ip,lr} 163129198Scognet stmia r0!, {r3-r8,ip,lr} 164129198Scognet stmia r0!, {r3-r8,ip,lr} 165129198Scognet stmia r0!, {r3-r8,ip,lr} 166129198Scognet 167129198Scognet stmia r0!, {r3-r8,ip,lr} 168129198Scognet stmia r0!, {r3-r8,ip,lr} 169129198Scognet stmia r0!, {r3-r8,ip,lr} 170129198Scognet stmia r0!, {r3-r8,ip,lr} 171129198Scognet 172129198Scognet stmia r0!, {r3-r8,ip,lr} 173129198Scognet stmia r0!, {r3-r8,ip,lr} 174129198Scognet stmia r0!, {r3-r8,ip,lr} 175129198Scognet stmia r0!, {r3-r8,ip,lr} 176129198Scognet 177129198Scognet#endif 178129198Scognet 179129198Scognet subs r2, r2, #1 180129198Scognet bne 1b 181129198Scognet 182129198Scognet ldmfd sp!, {r4-r8, pc} 183248361SandrewEND(bzero_page) 184129198Scognet 185172614Scognet#else /* _ARM_ARCH_5E */ 186129198Scognet 187129198Scognet/* 188172614Scognet * armv5e version of bcopy_page 189129198Scognet */ 190129198ScognetENTRY(bcopy_page) 191129198Scognet pld [r0] 192129198Scognet stmfd sp!, {r4, r5} 193288662Srwatson _SAVE({r4, r5}) 194129198Scognet mov ip, #32 195129198Scognet ldr r2, [r0], #0x04 /* 0x00 */ 196129198Scognet ldr r3, [r0], #0x04 /* 0x04 */ 197129198Scognet1: pld [r0, #0x18] /* Prefetch 0x20 */ 198129198Scognet ldr r4, [r0], #0x04 /* 0x08 */ 199129198Scognet ldr r5, [r0], #0x04 /* 0x0c */ 200129198Scognet strd r2, [r1], #0x08 201129198Scognet ldr r2, [r0], #0x04 /* 0x10 */ 202129198Scognet ldr r3, [r0], #0x04 /* 0x14 */ 203129198Scognet strd r4, [r1], #0x08 204129198Scognet ldr r4, [r0], #0x04 /* 0x18 */ 205129198Scognet ldr r5, [r0], #0x04 /* 0x1c */ 206129198Scognet strd r2, [r1], #0x08 207129198Scognet ldr r2, [r0], #0x04 /* 0x20 */ 208129198Scognet ldr r3, [r0], #0x04 /* 0x24 */ 209129198Scognet pld [r0, #0x18] /* Prefetch 0x40 */ 210129198Scognet strd r4, [r1], #0x08 211129198Scognet ldr r4, [r0], #0x04 /* 0x28 */ 212129198Scognet ldr r5, [r0], #0x04 /* 0x2c */ 213129198Scognet strd r2, [r1], #0x08 214129198Scognet ldr r2, [r0], #0x04 /* 0x30 */ 215129198Scognet ldr r3, [r0], #0x04 /* 0x34 */ 216129198Scognet strd r4, [r1], #0x08 217129198Scognet ldr r4, [r0], #0x04 /* 0x38 */ 218129198Scognet ldr r5, [r0], #0x04 /* 0x3c */ 219129198Scognet strd r2, [r1], #0x08 220129198Scognet ldr r2, [r0], #0x04 /* 0x40 */ 221129198Scognet ldr r3, [r0], #0x04 /* 0x44 */ 222129198Scognet pld [r0, #0x18] /* Prefetch 0x60 */ 223129198Scognet strd r4, [r1], #0x08 224129198Scognet ldr r4, [r0], #0x04 /* 0x48 */ 225129198Scognet ldr r5, [r0], #0x04 /* 0x4c */ 226129198Scognet strd r2, [r1], #0x08 227129198Scognet ldr r2, [r0], #0x04 /* 0x50 */ 228129198Scognet ldr r3, [r0], #0x04 /* 0x54 */ 229129198Scognet strd r4, [r1], #0x08 230129198Scognet ldr r4, [r0], #0x04 /* 0x58 */ 231129198Scognet ldr r5, [r0], #0x04 /* 0x5c */ 232129198Scognet strd r2, [r1], #0x08 233129198Scognet ldr r2, [r0], #0x04 /* 0x60 */ 234129198Scognet ldr r3, [r0], #0x04 /* 0x64 */ 235129198Scognet pld [r0, #0x18] /* Prefetch 0x80 */ 236129198Scognet strd r4, [r1], #0x08 237129198Scognet ldr r4, [r0], #0x04 /* 0x68 */ 238129198Scognet ldr r5, [r0], #0x04 /* 0x6c */ 239129198Scognet strd r2, [r1], #0x08 240129198Scognet ldr r2, [r0], #0x04 /* 0x70 */ 241129198Scognet ldr r3, [r0], #0x04 /* 0x74 */ 242129198Scognet strd r4, [r1], #0x08 243129198Scognet ldr r4, [r0], #0x04 /* 0x78 */ 244129198Scognet ldr r5, [r0], #0x04 /* 0x7c */ 245129198Scognet strd r2, [r1], #0x08 246129198Scognet subs ip, ip, #0x01 247129198Scognet ldrgt r2, [r0], #0x04 /* 0x80 */ 248129198Scognet ldrgt r3, [r0], #0x04 /* 0x84 */ 249129198Scognet strd r4, [r1], #0x08 250129198Scognet bgt 1b 251129198Scognet ldmfd sp!, {r4, r5} 252137463Scognet RET 253248361SandrewEND(bcopy_page) 254129198Scognet 255129198Scognet/* 256172614Scognet * armv5e version of bzero_page 257129198Scognet */ 258129198ScognetENTRY(bzero_page) 259129198Scognet mov r1, #PAGE_SIZE 260129198Scognet mov r2, #0 261129198Scognet mov r3, #0 262129198Scognet1: strd r2, [r0], #8 /* 32 */ 263129198Scognet strd r2, [r0], #8 264129198Scognet strd r2, [r0], #8 265129198Scognet strd r2, [r0], #8 266129198Scognet strd r2, [r0], #8 /* 64 */ 267129198Scognet strd r2, [r0], #8 268129198Scognet strd r2, [r0], #8 269129198Scognet strd r2, [r0], #8 270129198Scognet strd r2, [r0], #8 /* 96 */ 271129198Scognet strd r2, [r0], #8 272129198Scognet strd r2, [r0], #8 273129198Scognet strd r2, [r0], #8 274129198Scognet strd r2, [r0], #8 /* 128 */ 275129198Scognet strd r2, [r0], #8 276129198Scognet strd r2, [r0], #8 277129198Scognet strd r2, [r0], #8 278129198Scognet subs r1, r1, #128 279129198Scognet bne 1b 280137463Scognet RET 281248361SandrewEND(bzero_page) 282172614Scognet#endif /* _ARM_ARCH_5E */ 283