1*e415d488SLionel Sambuc/* $NetBSD: bzero.S,v 1.11 2011/01/29 02:21:20 matt Exp $ */ 22fe8fb19SBen Gras 32fe8fb19SBen Gras/*- 42fe8fb19SBen Gras * Copyright (C) 2001 Martin J. Laubach <mjl@NetBSD.org> 52fe8fb19SBen Gras * All rights reserved. 62fe8fb19SBen Gras * 72fe8fb19SBen Gras * Redistribution and use in source and binary forms, with or without 82fe8fb19SBen Gras * modification, are permitted provided that the following conditions 92fe8fb19SBen Gras * are met: 102fe8fb19SBen Gras * 1. Redistributions of source code must retain the above copyright 112fe8fb19SBen Gras * notice, this list of conditions and the following disclaimer. 122fe8fb19SBen Gras * 2. Redistributions in binary form must reproduce the above copyright 132fe8fb19SBen Gras * notice, this list of conditions and the following disclaimer in the 142fe8fb19SBen Gras * documentation and/or other materials provided with the distribution. 152fe8fb19SBen Gras * 3. The name of the author may not be used to endorse or promote products 162fe8fb19SBen Gras * derived from this software without specific prior written permission. 172fe8fb19SBen Gras * 182fe8fb19SBen Gras * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 192fe8fb19SBen Gras * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 202fe8fb19SBen Gras * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 212fe8fb19SBen Gras * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 222fe8fb19SBen Gras * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 232fe8fb19SBen Gras * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242fe8fb19SBen Gras * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252fe8fb19SBen Gras * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262fe8fb19SBen Gras * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272fe8fb19SBen Gras * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282fe8fb19SBen Gras */ 292fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 302fe8fb19SBen Gras 312fe8fb19SBen Gras#include <machine/asm.h> 322fe8fb19SBen Gras 332fe8fb19SBen Gras 342fe8fb19SBen Gras#if defined(LIBC_SCCS) && !defined(lint) 35*e415d488SLionel Sambuc__RCSID("$NetBSD: bzero.S,v 1.11 2011/01/29 02:21:20 matt Exp $") 362fe8fb19SBen Gras#endif /* LIBC_SCCS && !lint */ 372fe8fb19SBen Gras 382fe8fb19SBen Gras#ifdef _KERNEL 392fe8fb19SBen Gras#include <assym.h> 402fe8fb19SBen Gras#endif 412fe8fb19SBen Gras 422fe8fb19SBen Gras#define USE_STSWX 0 /* don't. slower than trivial copy loop */ 432fe8fb19SBen Gras 442fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 452fe8fb19SBen Gras/* 462fe8fb19SBen Gras void bzero(void *b %r3, size_t len %r4); 472fe8fb19SBen Gras void * memset(void *b %r3, int c %r4, size_t len %r5); 482fe8fb19SBen Gras*/ 492fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 502fe8fb19SBen Gras 512fe8fb19SBen Gras#define r_dst %r3 522fe8fb19SBen Gras#define r_len %r4 532fe8fb19SBen Gras#define r_val %r0 542fe8fb19SBen Gras 552fe8fb19SBen Gras .text 562fe8fb19SBen Gras .align 4 572fe8fb19SBen GrasENTRY(bzero) 582fe8fb19SBen Gras li r_val, 0 /* Value to stuff in */ 592fe8fb19SBen Gras b cb_memset 602fe8fb19SBen GrasEND(bzero) 612fe8fb19SBen Gras 622fe8fb19SBen GrasENTRY(memset) 63*e415d488SLionel Sambuc cmplwi %cr1, %r5, 0 642fe8fb19SBen Gras mr. %r0, %r4 652fe8fb19SBen Gras mr %r8, %r3 66*e415d488SLionel Sambuc beqlr- %cr1 /* Nothing to do */ 672fe8fb19SBen Gras 682fe8fb19SBen Gras rlwimi %r0, %r4, 8, 16, 23 /* word extend fill value */ 692fe8fb19SBen Gras rlwimi %r0, %r0, 16, 0, 15 702fe8fb19SBen Gras mr %r4, %r5 712fe8fb19SBen Gras bne- simple_fill /* =! 0, use trivial fill */ 722fe8fb19SBen Grascb_memset: 732fe8fb19SBen Gras 742fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 752fe8fb19SBen Gras#ifndef _KERNEL 762fe8fb19SBen Gras /* First find out cache line size */ 772fe8fb19SBen Gras mflr %r9 782fe8fb19SBen Gras#ifdef PIC 792fe8fb19SBen Gras PIC_GOTSETUP(%r10) 802fe8fb19SBen Gras mtlr %r9 812fe8fb19SBen Gras lwz %r5,cache_info@got(%r10) 822fe8fb19SBen Gras#else 832fe8fb19SBen Gras lis %r5,cache_info@h 842fe8fb19SBen Gras ori %r5,%r5,cache_info@l 852fe8fb19SBen Gras#endif 862fe8fb19SBen Gras lwz %r6, 4(%r5) 872fe8fb19SBen Gras cmpwi %r6, -1 882fe8fb19SBen Gras bne+ cb_cacheline_known 892fe8fb19SBen Gras 902fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 912fe8fb19SBen Gras#define CTL_MACHDEP 7 922fe8fb19SBen Gras#define CPU_CACHELINE 1 932fe8fb19SBen Gras#define CPU_CACHEINFO 5 942fe8fb19SBen Gras 952fe8fb19SBen Gras#define STKFRAME_SZ 64 962fe8fb19SBen Gras#define MIB 8 972fe8fb19SBen Gras#define OLDPLEN 16 982fe8fb19SBen Gras#define R3_SAVE 20 992fe8fb19SBen Gras#define R4_SAVE 24 1002fe8fb19SBen Gras#define R0_SAVE 28 1012fe8fb19SBen Gras#define R8_SAVE 32 1022fe8fb19SBen Gras#define R31_SAVE 36 1032fe8fb19SBen Gras#ifdef PIC 1042fe8fb19SBen Gras#define R30_SAVE 40 1052fe8fb19SBen Gras#endif 1062fe8fb19SBen Gras 1072fe8fb19SBen Gras stw %r9, 4(%r1) 1082fe8fb19SBen Gras stwu %r1, -STKFRAME_SZ(%r1) 1092fe8fb19SBen Gras 1102fe8fb19SBen Gras stw %r31, R31_SAVE(%r1) 1112fe8fb19SBen Gras mr %r31, %r5 /* cache info */ 1122fe8fb19SBen Gras 1132fe8fb19SBen Gras#ifdef PIC 1142fe8fb19SBen Gras stw %r30, R30_SAVE(%r1) 1152fe8fb19SBen Gras PIC_TOCSETUP(cb_memset,%r30) 1162fe8fb19SBen Gras#endif 1172fe8fb19SBen Gras 1182fe8fb19SBen Gras stw %r8, R8_SAVE(%r1) 1192fe8fb19SBen Gras stw %r3, R3_SAVE(%r1) 1202fe8fb19SBen Gras stw %r4, R4_SAVE(%r1) 1212fe8fb19SBen Gras stw %r0, R0_SAVE(%r1) 1222fe8fb19SBen Gras 1232fe8fb19SBen Gras li %r0, CTL_MACHDEP /* Construct MIB */ 1242fe8fb19SBen Gras stw %r0, MIB(%r1) 1252fe8fb19SBen Gras li %r0, CPU_CACHEINFO 1262fe8fb19SBen Gras stw %r0, MIB+4(%r1) 1272fe8fb19SBen Gras 1282fe8fb19SBen Gras li %r0, 4*4 /* Oldlenp := 4*4 */ 1292fe8fb19SBen Gras stw %r0, OLDPLEN(%r1) 1302fe8fb19SBen Gras 1312fe8fb19SBen Gras addi %r3, %r1, MIB 1322fe8fb19SBen Gras li %r4, 2 /* namelen */ 1332fe8fb19SBen Gras /* %r5 already contains &cache_info */ 1342fe8fb19SBen Gras addi %r6, %r1, OLDPLEN 1352fe8fb19SBen Gras li %r7, 0 1362fe8fb19SBen Gras li %r8, 0 1372fe8fb19SBen Gras bl PIC_PLT(_C_LABEL(sysctl)) 1382fe8fb19SBen Gras 1392fe8fb19SBen Gras cmpwi %r3, 0 /* Check result */ 1402fe8fb19SBen Gras beq 1f 1412fe8fb19SBen Gras 1422fe8fb19SBen Gras /* Failure, try older sysctl */ 1432fe8fb19SBen Gras 1442fe8fb19SBen Gras li %r0, CTL_MACHDEP /* Construct MIB */ 1452fe8fb19SBen Gras stw %r0, MIB(%r1) 1462fe8fb19SBen Gras li %r0, CPU_CACHELINE 1472fe8fb19SBen Gras stw %r0, MIB+4(%r1) 1482fe8fb19SBen Gras 1492fe8fb19SBen Gras li %r0, 4 /* Oldlenp := 4 */ 1502fe8fb19SBen Gras stw %r0, OLDPLEN(%r1) 1512fe8fb19SBen Gras 1522fe8fb19SBen Gras addi %r3, %r1, MIB 1532fe8fb19SBen Gras li %r4, 2 /* namelen */ 1542fe8fb19SBen Gras addi %r5, %r31, 4 1552fe8fb19SBen Gras addi %r6, %r1, OLDPLEN 1562fe8fb19SBen Gras li %r7, 0 1572fe8fb19SBen Gras li %r8, 0 1582fe8fb19SBen Gras bl PIC_PLT(_C_LABEL(sysctl)) 1592fe8fb19SBen Gras1: 1602fe8fb19SBen Gras lwz %r3, R3_SAVE(%r1) 1612fe8fb19SBen Gras lwz %r4, R4_SAVE(%r1) 1622fe8fb19SBen Gras lwz %r8, R8_SAVE(%r1) 1632fe8fb19SBen Gras lwz %r0, R0_SAVE(%r1) 1642fe8fb19SBen Gras lwz %r9, 4(%r31) 1652fe8fb19SBen Gras lwz %r31, R31_SAVE(%r1) 1662fe8fb19SBen Gras#ifdef PIC 1672fe8fb19SBen Gras lwz %r30, R30_SAVE(%r1) 1682fe8fb19SBen Gras#endif 1692fe8fb19SBen Gras addi %r1, %r1, STKFRAME_SZ 170*e415d488SLionel Sambuc lwz %r7, 4(%r1) 171*e415d488SLionel Sambuc mtlr %r7 1722fe8fb19SBen Gras 1732fe8fb19SBen Gras cntlzw %r6, %r9 /* compute shift value */ 1742fe8fb19SBen Gras li %r5, 31 1752fe8fb19SBen Gras subf %r5, %r6, %r5 1762fe8fb19SBen Gras 1772fe8fb19SBen Gras#ifdef PIC 1782fe8fb19SBen Gras mflr %r9 1792fe8fb19SBen Gras PIC_GOTSETUP(%r10) 1802fe8fb19SBen Gras mtlr %r9 1812fe8fb19SBen Gras lwz %r6, cache_sh@got(%r10) 1822fe8fb19SBen Gras stw %r5, 0(%r6) 1832fe8fb19SBen Gras#else 1842fe8fb19SBen Gras lis %r6, cache_sh@ha 1852fe8fb19SBen Gras stw %r5, cache_sh@l(%r6) 1862fe8fb19SBen Gras#endif 1872fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 1882fe8fb19SBen Gras/* Okay, we know the cache line size (%r9) and shift value (%r10) */ 1892fe8fb19SBen Grascb_cacheline_known: 1902fe8fb19SBen Gras#ifdef PIC 1912fe8fb19SBen Gras lwz %r5, cache_info@got(%r10) 1922fe8fb19SBen Gras lwz %r9, 4(%r5) 1932fe8fb19SBen Gras lwz %r5, cache_sh@got(%r10) 1942fe8fb19SBen Gras lwz %r10, 0(%r5) 1952fe8fb19SBen Gras#else 1962fe8fb19SBen Gras lis %r9, cache_info+4@ha 1972fe8fb19SBen Gras lwz %r9, cache_info+4@l(%r9) 1982fe8fb19SBen Gras lis %r10, cache_sh@ha 1992fe8fb19SBen Gras lwz %r10, cache_sh@l(%r10) 2002fe8fb19SBen Gras#endif 2012fe8fb19SBen Gras 2022fe8fb19SBen Gras#else /* _KERNEL */ 2032fe8fb19SBen Gras#ifdef MULTIPROCESSOR 2042fe8fb19SBen Gras mfsprg %r10, 0 /* Get cpu_info pointer */ 2052fe8fb19SBen Gras#else 2062fe8fb19SBen Gras lis %r10, cpu_info_store@ha 2072fe8fb19SBen Gras addi %r10, %r10, cpu_info_store@l 2082fe8fb19SBen Gras#endif 2092fe8fb19SBen Gras lwz %r9, CPU_CI+4(%r10) /* Load D$ line size */ 2102fe8fb19SBen Gras cntlzw %r10, %r9 /* Calculate shift.. */ 2112fe8fb19SBen Gras li %r6, 31 2122fe8fb19SBen Gras subf %r10, %r10, %r6 2132fe8fb19SBen Gras#endif /* _KERNEL */ 2142fe8fb19SBen Gras /* Back in memory filling business */ 2152fe8fb19SBen Gras 216*e415d488SLionel Sambuc cmplwi %cr1, r_len, 0 /* Nothing to do? */ 2172fe8fb19SBen Gras add %r5, %r9, %r9 2182fe8fb19SBen Gras cmplw r_len, %r5 /* <= 2*CL bytes to move? */ 219*e415d488SLionel Sambuc beqlr- %cr1 /* then do nothing */ 2202fe8fb19SBen Gras 2212fe8fb19SBen Gras blt+ simple_fill /* a trivial fill routine */ 2222fe8fb19SBen Gras 2232fe8fb19SBen Gras /* Word align the block, fill bytewise until dst even*/ 2242fe8fb19SBen Gras 2252fe8fb19SBen Gras andi. %r5, r_dst, 0x03 2262fe8fb19SBen Gras li %r6, 4 2272fe8fb19SBen Gras beq+ cb_aligned_w /* already aligned to word? */ 2282fe8fb19SBen Gras 2292fe8fb19SBen Gras subf %r5, %r5, %r6 /* bytes to fill to align4 */ 2302fe8fb19SBen Gras#if USE_STSWX 2312fe8fb19SBen Gras mtxer %r5 2322fe8fb19SBen Gras stswx %r0, 0, r_dst 2332fe8fb19SBen Gras add r_dst, %r5, r_dst 2342fe8fb19SBen Gras#else 2352fe8fb19SBen Gras mtctr %r5 2362fe8fb19SBen Gras 2372fe8fb19SBen Gras subi r_dst, r_dst, 1 2382fe8fb19SBen Gras1: stbu r_val, 1(r_dst) /* Fill bytewise */ 2392fe8fb19SBen Gras bdnz 1b 2402fe8fb19SBen Gras 2412fe8fb19SBen Gras addi r_dst, r_dst, 1 2422fe8fb19SBen Gras#endif 2432fe8fb19SBen Gras subf r_len, %r5, r_len 2442fe8fb19SBen Gras 2452fe8fb19SBen Grascb_aligned_w: /* Cache block align, fill wordwise until dst aligned */ 2462fe8fb19SBen Gras 2472fe8fb19SBen Gras /* I know I have something to do since we had > 2*CL initially */ 2482fe8fb19SBen Gras /* so no need to check for r_len = 0 */ 2492fe8fb19SBen Gras 2502fe8fb19SBen Gras subi %r6, %r9, 1 /* CL mask */ 2512fe8fb19SBen Gras and. %r5, r_dst, %r6 2522fe8fb19SBen Gras srwi %r5, %r5, 2 2532fe8fb19SBen Gras srwi %r6, %r9, 2 2542fe8fb19SBen Gras beq cb_aligned_cb /* already on CL boundary? */ 2552fe8fb19SBen Gras 2562fe8fb19SBen Gras subf %r5, %r5, %r6 /* words to fill to alignment */ 2572fe8fb19SBen Gras mtctr %r5 2582fe8fb19SBen Gras slwi %r5, %r5, 2 2592fe8fb19SBen Gras subf r_len, %r5, r_len 2602fe8fb19SBen Gras 2612fe8fb19SBen Gras subi r_dst, r_dst, 4 2622fe8fb19SBen Gras1: stwu r_val, 4(r_dst) /* Fill wordwise */ 2632fe8fb19SBen Gras bdnz 1b 2642fe8fb19SBen Gras addi r_dst, r_dst, 4 2652fe8fb19SBen Gras 2662fe8fb19SBen Grascb_aligned_cb: /* no need to check r_len, see above */ 2672fe8fb19SBen Gras 2682fe8fb19SBen Gras srw. %r5, r_len, %r10 /* Number of cache blocks */ 2692fe8fb19SBen Gras mtctr %r5 2702fe8fb19SBen Gras beq cblocks_done 2712fe8fb19SBen Gras 2722fe8fb19SBen Gras slw %r5, %r5, %r10 2732fe8fb19SBen Gras subf r_len, %r5, r_len 2742fe8fb19SBen Gras 2752fe8fb19SBen Gras1: dcbz 0, r_dst /* Clear blockwise */ 2762fe8fb19SBen Gras add r_dst, r_dst, %r9 2772fe8fb19SBen Gras bdnz 1b 2782fe8fb19SBen Gras 2792fe8fb19SBen Grascblocks_done: /* still CL aligned, but less than CL bytes left */ 280*e415d488SLionel Sambuc cmplwi %cr1, r_len, 0 2812fe8fb19SBen Gras cmplwi r_len, 8 282*e415d488SLionel Sambuc beq- %cr1, sf_return 2832fe8fb19SBen Gras 2842fe8fb19SBen Gras blt- sf_bytewise /* <8 remaining? */ 2852fe8fb19SBen Gras b sf_aligned_w 2862fe8fb19SBen Gras 2872fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 2882fe8fb19SBen Graswbzero: li r_val, 0 2892fe8fb19SBen Gras 2902fe8fb19SBen Gras cmplwi r_len, 0 2912fe8fb19SBen Gras beqlr- /* Nothing to do */ 2922fe8fb19SBen Gras 2932fe8fb19SBen Grassimple_fill: 2942fe8fb19SBen Gras#if USE_STSWX 295*e415d488SLionel Sambuc cmplwi %cr1, r_len, 12 /* < 12 bytes to move? */ 2962fe8fb19SBen Gras#else 297*e415d488SLionel Sambuc cmplwi %cr1, r_len, 8 /* < 8 bytes to move? */ 2982fe8fb19SBen Gras#endif 2992fe8fb19SBen Gras andi. %r5, r_dst, 0x03 /* bytes to fill to align4 */ 300*e415d488SLionel Sambuc blt %cr1, sf_bytewise /* trivial byte mover */ 3012fe8fb19SBen Gras 3022fe8fb19SBen Gras li %r6, 4 3032fe8fb19SBen Gras subf %r5, %r5, %r6 3042fe8fb19SBen Gras beq+ sf_aligned_w /* dest is word aligned */ 3052fe8fb19SBen Gras 3062fe8fb19SBen Gras#if USE_STSWX 3072fe8fb19SBen Gras mtxer %r5 3082fe8fb19SBen Gras stswx %r0, 0, r_dst 3092fe8fb19SBen Gras add r_dst, %r5, r_dst 3102fe8fb19SBen Gras#else 3112fe8fb19SBen Gras mtctr %r5 /* nope, then fill bytewise */ 3122fe8fb19SBen Gras subi r_dst, r_dst, 1 /* until it is */ 3132fe8fb19SBen Gras1: stbu r_val, 1(r_dst) 3142fe8fb19SBen Gras bdnz 1b 3152fe8fb19SBen Gras 3162fe8fb19SBen Gras addi r_dst, r_dst, 1 3172fe8fb19SBen Gras#endif 3182fe8fb19SBen Gras subf r_len, %r5, r_len 3192fe8fb19SBen Gras 3202fe8fb19SBen Grassf_aligned_w: /* no need to check r_len since it were >= 8 bytes initially */ 3212fe8fb19SBen Gras#if USE_STSWX 3222fe8fb19SBen Gras mr %r6, %r0 3232fe8fb19SBen Gras mr %r7, %r0 3242fe8fb19SBen Gras 3252fe8fb19SBen Gras srwi %r5, r_len, 3 3262fe8fb19SBen Gras mtctr %r5 3272fe8fb19SBen Gras 3282fe8fb19SBen Gras slwi %r5, %r5, 3 /* adjust len */ 3292fe8fb19SBen Gras subf. r_len, %r5, r_len 3302fe8fb19SBen Gras 3312fe8fb19SBen Gras1: stswi %r6, r_dst, 8 3322fe8fb19SBen Gras addi r_dst, r_dst, 8 3332fe8fb19SBen Gras bdnz 1b 3342fe8fb19SBen Gras#else 3352fe8fb19SBen Gras srwi %r5, r_len, 2 /* words to fill */ 3362fe8fb19SBen Gras mtctr %r5 3372fe8fb19SBen Gras 3382fe8fb19SBen Gras slwi %r5, %r5, 2 3392fe8fb19SBen Gras subf. r_len, %r5, r_len /* adjust len for fill */ 3402fe8fb19SBen Gras 3412fe8fb19SBen Gras subi r_dst, r_dst, 4 3422fe8fb19SBen Gras1: stwu r_val, 4(r_dst) 3432fe8fb19SBen Gras bdnz 1b 3442fe8fb19SBen Gras addi r_dst, r_dst, 4 3452fe8fb19SBen Gras#endif 3462fe8fb19SBen Gras 3472fe8fb19SBen Grassf_word_done: bne- sf_bytewise 3482fe8fb19SBen Gras 3492fe8fb19SBen Grassf_return: mr %r3, %r8 /* restore orig ptr */ 3502fe8fb19SBen Gras blr /* for memset functionality */ 3512fe8fb19SBen Gras 3522fe8fb19SBen Grassf_bytewise: 3532fe8fb19SBen Gras#if USE_STSWX 3542fe8fb19SBen Gras mr %r5, %r0 3552fe8fb19SBen Gras mr %r6, %r0 3562fe8fb19SBen Gras mr %r7, %r0 3572fe8fb19SBen Gras 3582fe8fb19SBen Gras mtxer r_len 3592fe8fb19SBen Gras stswx %r5, 0, r_dst 3602fe8fb19SBen Gras#else 3612fe8fb19SBen Gras mtctr r_len 3622fe8fb19SBen Gras 3632fe8fb19SBen Gras subi r_dst, r_dst, 1 3642fe8fb19SBen Gras1: stbu r_val, 1(r_dst) 3652fe8fb19SBen Gras bdnz 1b 3662fe8fb19SBen Gras#endif 3672fe8fb19SBen Gras mr %r3, %r8 /* restore orig ptr */ 3682fe8fb19SBen Gras blr /* for memset functionality */ 3692fe8fb19SBen GrasEND(memset) 3702fe8fb19SBen Gras 3712fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 3722fe8fb19SBen Gras#ifndef _KERNEL 3732fe8fb19SBen Gras .data 3742fe8fb19SBen Grascache_info: .long -1, -1, -1, -1 3752fe8fb19SBen Grascache_sh: .long 0 3762fe8fb19SBen Gras 3772fe8fb19SBen Gras#endif 3782fe8fb19SBen Gras/*----------------------------------------------------------------------*/ 379