|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_FREE_COPYRIGHT@ ! 24: */ ! 25: ! 26: #include <ppc/asm.h> ! 27: #include <ppc/proc_reg.h> /* For CACHE_LINE_SIZE */ ! 28: ! 29: /* ! 30: * void bzero(char *addr, unsigned int length) ! 31: * ! 32: * bzero implementation for PowerPC ! 33: * - assumes cacheable memory (i.e. uses DCBZ) ! 34: * - assumes non-pic code ! 35: * ! 36: * returns start address in r3, as per memset (called by memset) ! 37: */ ! 38: ! 39: ENTRY(bzero, TAG_NO_FRAME_USED) ! 40: ! 41: cmpwi cr0, r4, 0 /* no bytes to zero? */ ! 42: mr r7, r3 ! 43: mr r8, r3 /* use r8 as counter to where we are */ ! 44: beqlr- ! 45: cmpwi cr0, r4, CACHE_LINE_SIZE /* clear less than a block? */ ! 46: li r0, 0 /* use r0 as source of zeros */ ! 47: blt .L_bzeroEndWord ! 48: ! 49: /* first, clear bytes up to the next word boundary */ ! 50: addis r6, 0, HIGH_CADDR(.L_bzeroBeginWord) ! 51: addi r6, r6, LOW_ADDR(.L_bzeroBeginWord) ! 52: /* extract byte offset as word offset */ ! 53: rlwinm. r5, r8, 2, 28, 29 ! 54: addi r8, r8, -1 /* adjust for update */ ! 55: beq .L_bzeroBeginWord /* no bytes to zero */ ! 56: subfic r5, r5, 16 /* compute the number of instructions */ ! 57: sub r6, r6, r5 /* back from word clear to execute */ ! 58: mtctr r6 ! 59: bctr ! 60: ! 61: stbu r0, 1(r8) ! 62: stbu r0, 1(r8) ! 63: stbu r0, 1(r8) ! 64: ! 65: /* clear words up to the next block boundary */ ! 66: .L_bzeroBeginWord: ! 67: addis r6, 0, HIGH_CADDR(.L_bzeroBlock) ! 68: addi r6, r6, LOW_ADDR(.L_bzeroBlock) ! 69: addi r8, r8, 1 ! 70: rlwinm. r5, r8, 0, 27, 29 /* extract word offset */ ! 71: addi r8, r8, -4 /* adjust for update */ ! 72: beq .L_bzeroBlock /* no words to zero */ ! 73: /* compute the number of instructions */ ! 74: subfic r5, r5, CACHE_LINE_SIZE ! 75: sub r6, r6, r5 /* back from word clear to execute */ ! 76: mtctr r6 ! 77: bctr ! 78: ! 79: stwu r0, 4(r8) ! 80: stwu r0, 4(r8) ! 81: stwu r0, 4(r8) ! 82: stwu r0, 4(r8) ! 83: stwu r0, 4(r8) ! 84: stwu r0, 4(r8) ! 85: stwu r0, 4(r8) ! 86: ! 87: /* clear cache blocks */ ! 88: .L_bzeroBlock: ! 89: addi r8, r8, 4 /* remove update adjust */ ! 90: sub r5, r8, r7 /* bytes zeroed */ ! 91: sub r4, r4, r5 ! 92: srwi. r5, r4, CACHE_LINE_POW2 /* blocks to zero */ ! 93: beq .L_bzeroEndWord ! 94: mtctr r5 ! 95: ! 96: .L_bzeroBlock1: ! 97: dcbz 0, r8 ! 98: addi r8, r8, CACHE_LINE_SIZE ! 99: bdnz .L_bzeroBlock1 ! 100: ! 101: /* clear remaining words */ ! 102: .L_bzeroEndWord: ! 103: addis r6, 0, HIGH_CADDR(.L_bzeroEndByte) ! 104: addi r6, r6, LOW_ADDR(.L_bzeroEndByte) ! 105: rlwinm. r5, r4, 0, 27, 29 /* extract word offset */ ! 106: addi r8, r8, -4 /* adjust for update */ ! 107: beq .L_bzeroEndByte /* no words to zero */ ! 108: sub r6, r6, r5 /* back from word clear to execute */ ! 109: mtctr r6 ! 110: bctr ! 111: ! 112: stwu r0, 4(r8) ! 113: stwu r0, 4(r8) ! 114: stwu r0, 4(r8) ! 115: stwu r0, 4(r8) ! 116: stwu r0, 4(r8) ! 117: stwu r0, 4(r8) ! 118: stwu r0, 4(r8) ! 119: ! 120: /* clear remaining bytes */ ! 121: .L_bzeroEndByte: ! 122: addis r6, 0, HIGH_CADDR(.L_bzeroEnd) ! 123: addi r6, r6, LOW_ADDR(.L_bzeroEnd) ! 124: /* extract byte offset as word offset */ ! 125: rlwinm. r5, r4, 2, 28, 29 ! 126: addi r8, r8, 3 /* adjust for update */ ! 127: beqlr ! 128: sub r6, r6, r5 /* back from word clear to execute */ ! 129: mtctr r6 ! 130: bctr ! 131: ! 132: stbu r0, 1(r8) ! 133: stbu r0, 1(r8) ! 134: stbu r0, 1(r8) ! 135: ! 136: .L_bzeroEnd: ! 137: blr ! 138: ! 139: /* ! 140: * void *memset(void *from, int c, vm_size_t nbytes) ! 141: * ! 142: * almost everywhere in the kernel ! 143: * this appears to be called with argument c==0. We optimise for those ! 144: * cases and call bzero if we can. ! 145: * ! 146: */ ! 147: ! 148: ENTRY(memset, TAG_NO_FRAME_USED) ! 149: ! 150: mr. ARG3, ARG1 ! 151: mr ARG1, ARG2 ! 152: /* optimised case - do a bzero */ ! 153: beq+ EXT(bzero) ! 154: ! 155: /* If count is zero, return straight away */ ! 156: cmpi cr0, ARG1, 0 ! 157: beqlr- ! 158: ! 159: /* Now, ARG0 = addr, ARG1=len, ARG3=value */ ! 160: ! 161: subi ARG2, ARG0, 1 /* use ARG2 as our counter */ ! 162: ! 163: 0: ! 164: subi ARG1, ARG1, 1 ! 165: cmpi cr0, ARG1, 0 ! 166: stbu ARG3, 1(ARG2) ! 167: bne+ 0b ! 168: ! 169: /* Return original address in ARG0 */ ! 170: ! 171: blr
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.