bcopy_page.S revision 139735
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> 42129198Scognet#include <machine/param.h> 43129198Scognet__FBSDID("$FreeBSD: head/sys/arm/arm/bcopy_page.S 139735 2005-01-05 21:58:49Z imp $"); 44129198Scognet#ifndef __XSCALE__ 45129198Scognet 46129198Scognet/* #define BIG_LOOPS */ 47129198Scognet 48129198Scognet/* 49129198Scognet * bcopy_page(src, dest) 50129198Scognet * 51129198Scognet * Optimised copy page routine. 52129198Scognet * 53129198Scognet * On entry: 54129198Scognet * r0 - src address 55129198Scognet * r1 - dest address 56129198Scognet * 57129198Scognet * Requires: 58129198Scognet * number of bytes per page (PAGE_SIZE) is a multiple of 512 (BIG_LOOPS), 128 59129198Scognet * otherwise. 60129198Scognet */ 61129198Scognet 62129198Scognet#define CHUNK_SIZE 32 63129198Scognet 64129198Scognet#define PREFETCH_FIRST_CHUNK /* nothing */ 65129198Scognet#define PREFETCH_NEXT_CHUNK /* nothing */ 66129198Scognet 67129198Scognet#ifndef COPY_CHUNK 68129198Scognet#define COPY_CHUNK \ 69129198Scognet PREFETCH_NEXT_CHUNK ; \ 70129198Scognet ldmia r0!, {r3-r8,ip,lr} ; \ 71129198Scognet stmia r1!, {r3-r8,ip,lr} 72129198Scognet#endif /* ! COPY_CHUNK */ 73129198Scognet 74129198Scognet#ifndef SAVE_REGS 75129198Scognet#define SAVE_REGS stmfd sp!, {r4-r8, lr} 76129198Scognet#define RESTORE_REGS ldmfd sp!, {r4-r8, pc} 77129198Scognet#endif 78129198Scognet 79129198ScognetENTRY(bcopy_page) 80129198Scognet PREFETCH_FIRST_CHUNK 81129198Scognet SAVE_REGS 82129198Scognet#ifdef BIG_LOOPS 83129198Scognet mov r2, #(PAGE_SIZE >> 9) 84129198Scognet#else 85129198Scognet mov r2, #(PAGE_SIZE >> 7) 86129198Scognet#endif 87129198Scognet 88129198Scognet1: 89129198Scognet COPY_CHUNK 90129198Scognet COPY_CHUNK 91129198Scognet COPY_CHUNK 92129198Scognet COPY_CHUNK 93129198Scognet 94129198Scognet#ifdef BIG_LOOPS 95129198Scognet /* There is little point making the loop any larger; unless we are 96129198Scognet running with the cache off, the load/store overheads will 97129198Scognet completely dominate this loop. */ 98129198Scognet COPY_CHUNK 99129198Scognet COPY_CHUNK 100129198Scognet COPY_CHUNK 101129198Scognet COPY_CHUNK 102129198Scognet 103129198Scognet COPY_CHUNK 104129198Scognet COPY_CHUNK 105129198Scognet COPY_CHUNK 106129198Scognet COPY_CHUNK 107129198Scognet 108129198Scognet COPY_CHUNK 109129198Scognet COPY_CHUNK 110129198Scognet COPY_CHUNK 111129198Scognet COPY_CHUNK 112129198Scognet#endif 113129198Scognet subs r2, r2, #1 114129198Scognet bne 1b 115129198Scognet 116129198Scognet RESTORE_REGS /* ...and return. */ 117129198Scognet 118129198Scognet/* 119129198Scognet * bzero_page(dest) 120129198Scognet * 121129198Scognet * Optimised zero page routine. 122129198Scognet * 123129198Scognet * On entry: 124129198Scognet * r0 - dest address 125129198Scognet * 126129198Scognet * Requires: 127129198Scognet * number of bytes per page (PAGE_SIZE) is a multiple of 512 (BIG_LOOPS), 128 128129198Scognet * otherwise 129129198Scognet */ 130129198Scognet 131129198ScognetENTRY(bzero_page) 132129198Scognet stmfd sp!, {r4-r8, lr} 133129198Scognet#ifdef BIG_LOOPS 134129198Scognet mov r2, #(PAGE_SIZE >> 9) 135129198Scognet#else 136129198Scognet mov r2, #(PAGE_SIZE >> 7) 137129198Scognet#endif 138129198Scognet mov r3, #0 139129198Scognet mov r4, #0 140129198Scognet mov r5, #0 141129198Scognet mov r6, #0 142129198Scognet mov r7, #0 143129198Scognet mov r8, #0 144129198Scognet mov ip, #0 145129198Scognet mov lr, #0 146129198Scognet 147129198Scognet1: 148129198Scognet stmia r0!, {r3-r8,ip,lr} 149129198Scognet stmia r0!, {r3-r8,ip,lr} 150129198Scognet stmia r0!, {r3-r8,ip,lr} 151129198Scognet stmia r0!, {r3-r8,ip,lr} 152129198Scognet 153129198Scognet#ifdef BIG_LOOPS 154129198Scognet /* There is little point making the loop any larger; unless we are 155129198Scognet running with the cache off, the load/store overheads will 156129198Scognet completely dominate this loop. */ 157129198Scognet stmia r0!, {r3-r8,ip,lr} 158129198Scognet stmia r0!, {r3-r8,ip,lr} 159129198Scognet stmia r0!, {r3-r8,ip,lr} 160129198Scognet stmia r0!, {r3-r8,ip,lr} 161129198Scognet 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#endif 173129198Scognet 174129198Scognet subs r2, r2, #1 175129198Scognet bne 1b 176129198Scognet 177129198Scognet ldmfd sp!, {r4-r8, pc} 178129198Scognet 179129198Scognet#else /* __XSCALE__ */ 180129198Scognet 181129198Scognet/* 182129198Scognet * XSCALE version of bcopy_page 183129198Scognet */ 184129198ScognetENTRY(bcopy_page) 185129198Scognet pld [r0] 186129198Scognet stmfd sp!, {r4, r5} 187129198Scognet mov ip, #32 188129198Scognet ldr r2, [r0], #0x04 /* 0x00 */ 189129198Scognet ldr r3, [r0], #0x04 /* 0x04 */ 190129198Scognet1: pld [r0, #0x18] /* Prefetch 0x20 */ 191129198Scognet ldr r4, [r0], #0x04 /* 0x08 */ 192129198Scognet ldr r5, [r0], #0x04 /* 0x0c */ 193129198Scognet strd r2, [r1], #0x08 194129198Scognet ldr r2, [r0], #0x04 /* 0x10 */ 195129198Scognet ldr r3, [r0], #0x04 /* 0x14 */ 196129198Scognet strd r4, [r1], #0x08 197129198Scognet ldr r4, [r0], #0x04 /* 0x18 */ 198129198Scognet ldr r5, [r0], #0x04 /* 0x1c */ 199129198Scognet strd r2, [r1], #0x08 200129198Scognet ldr r2, [r0], #0x04 /* 0x20 */ 201129198Scognet ldr r3, [r0], #0x04 /* 0x24 */ 202129198Scognet pld [r0, #0x18] /* Prefetch 0x40 */ 203129198Scognet strd r4, [r1], #0x08 204129198Scognet ldr r4, [r0], #0x04 /* 0x28 */ 205129198Scognet ldr r5, [r0], #0x04 /* 0x2c */ 206129198Scognet strd r2, [r1], #0x08 207129198Scognet ldr r2, [r0], #0x04 /* 0x30 */ 208129198Scognet ldr r3, [r0], #0x04 /* 0x34 */ 209129198Scognet strd r4, [r1], #0x08 210129198Scognet ldr r4, [r0], #0x04 /* 0x38 */ 211129198Scognet ldr r5, [r0], #0x04 /* 0x3c */ 212129198Scognet strd r2, [r1], #0x08 213129198Scognet ldr r2, [r0], #0x04 /* 0x40 */ 214129198Scognet ldr r3, [r0], #0x04 /* 0x44 */ 215129198Scognet pld [r0, #0x18] /* Prefetch 0x60 */ 216129198Scognet strd r4, [r1], #0x08 217129198Scognet ldr r4, [r0], #0x04 /* 0x48 */ 218129198Scognet ldr r5, [r0], #0x04 /* 0x4c */ 219129198Scognet strd r2, [r1], #0x08 220129198Scognet ldr r2, [r0], #0x04 /* 0x50 */ 221129198Scognet ldr r3, [r0], #0x04 /* 0x54 */ 222129198Scognet strd r4, [r1], #0x08 223129198Scognet ldr r4, [r0], #0x04 /* 0x58 */ 224129198Scognet ldr r5, [r0], #0x04 /* 0x5c */ 225129198Scognet strd r2, [r1], #0x08 226129198Scognet ldr r2, [r0], #0x04 /* 0x60 */ 227129198Scognet ldr r3, [r0], #0x04 /* 0x64 */ 228129198Scognet pld [r0, #0x18] /* Prefetch 0x80 */ 229129198Scognet strd r4, [r1], #0x08 230129198Scognet ldr r4, [r0], #0x04 /* 0x68 */ 231129198Scognet ldr r5, [r0], #0x04 /* 0x6c */ 232129198Scognet strd r2, [r1], #0x08 233129198Scognet ldr r2, [r0], #0x04 /* 0x70 */ 234129198Scognet ldr r3, [r0], #0x04 /* 0x74 */ 235129198Scognet strd r4, [r1], #0x08 236129198Scognet ldr r4, [r0], #0x04 /* 0x78 */ 237129198Scognet ldr r5, [r0], #0x04 /* 0x7c */ 238129198Scognet strd r2, [r1], #0x08 239129198Scognet subs ip, ip, #0x01 240129198Scognet ldrgt r2, [r0], #0x04 /* 0x80 */ 241129198Scognet ldrgt r3, [r0], #0x04 /* 0x84 */ 242129198Scognet strd r4, [r1], #0x08 243129198Scognet bgt 1b 244129198Scognet ldmfd sp!, {r4, r5} 245137463Scognet RET 246129198Scognet 247129198Scognet/* 248129198Scognet * XSCALE version of bzero_page 249129198Scognet */ 250129198ScognetENTRY(bzero_page) 251129198Scognet mov r1, #PAGE_SIZE 252129198Scognet mov r2, #0 253129198Scognet mov r3, #0 254129198Scognet1: strd r2, [r0], #8 /* 32 */ 255129198Scognet strd r2, [r0], #8 256129198Scognet strd r2, [r0], #8 257129198Scognet strd r2, [r0], #8 258129198Scognet strd r2, [r0], #8 /* 64 */ 259129198Scognet strd r2, [r0], #8 260129198Scognet strd r2, [r0], #8 261129198Scognet strd r2, [r0], #8 262129198Scognet strd r2, [r0], #8 /* 96 */ 263129198Scognet strd r2, [r0], #8 264129198Scognet strd r2, [r0], #8 265129198Scognet strd r2, [r0], #8 266129198Scognet strd r2, [r0], #8 /* 128 */ 267129198Scognet strd r2, [r0], #8 268129198Scognet strd r2, [r0], #8 269129198Scognet strd r2, [r0], #8 270129198Scognet subs r1, r1, #128 271129198Scognet bne 1b 272137463Scognet RET 273129198Scognet#endif /* __XSCALE__ */ 274