1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski 25*b1cdbd2cSJim Jagielski /* 26*b1cdbd2cSJim Jagielski * Implements osl_[increment|decrement]InterlockedCount in two ways: 27*b1cdbd2cSJim Jagielski * sparcv8 architecture: use the "swap" instruction 28*b1cdbd2cSJim Jagielski * sparcv9/sparcv8plus architecture: use the "cas" instruction 29*b1cdbd2cSJim Jagielski * 30*b1cdbd2cSJim Jagielski * 32 bit mode with v8 and v8plus support: 31*b1cdbd2cSJim Jagielski * Initialize once with osl_InterlockedCountSetV9(int bv9) if you want to 32*b1cdbd2cSJim Jagielski * use the "cas" instruction, which is faster (no spinlock needed) 33*b1cdbd2cSJim Jagielski * Default is to use the "swap" instruction, which works on all supported 34*b1cdbd2cSJim Jagielski * SPARC cpu's 35*b1cdbd2cSJim Jagielski * 36*b1cdbd2cSJim Jagielski * osl_InterlockedCountSetV9(int bv9) 37*b1cdbd2cSJim Jagielski * bv9 = 0 use sparcv8 "swap" (spinlock) 38*b1cdbd2cSJim Jagielski * bv9 = 1 use sparcv9/sparcv8plus "cas" (no spinlock) 39*b1cdbd2cSJim Jagielski * 40*b1cdbd2cSJim Jagielski * 32 bit mode without v8 support (implies v8plus) or 64 bit mode: 41*b1cdbd2cSJim Jagielski * No need (nor the possibilty) to call osl_InterlockedCountSetV9(), 42*b1cdbd2cSJim Jagielski * sparcv9 mode is implied. Assemble with -xarch=v8plus (32 bit) or 43*b1cdbd2cSJim Jagielski * -xarch=v9 (64 bit). 44*b1cdbd2cSJim Jagielski * 45*b1cdbd2cSJim Jagielski */ 46*b1cdbd2cSJim Jagielski 47*b1cdbd2cSJim Jagielski #if !defined(__sparcv8plus) && !defined(__sparcv9) && !defined(__sparc_v9__) 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski .section ".data" 50*b1cdbd2cSJim Jagielski .align 4 51*b1cdbd2cSJim Jagielski osl_incrementInterLockCountFuncPtr: 52*b1cdbd2cSJim Jagielski .word osl_incrementInterlockedCountV8 53*b1cdbd2cSJim Jagielski .type osl_incrementInterLockCountFuncPtr,#object 54*b1cdbd2cSJim Jagielski .size osl_incrementInterLockCountFuncPtr,4 55*b1cdbd2cSJim Jagielski 56*b1cdbd2cSJim Jagielski .align 4 57*b1cdbd2cSJim Jagielski osl_decrementInterLockCountFuncPtr: 58*b1cdbd2cSJim Jagielski .word osl_decrementInterlockedCountV8 59*b1cdbd2cSJim Jagielski .type osl_decrementInterLockCountFuncPtr,#object 60*b1cdbd2cSJim Jagielski .size osl_decrementInterLockCountFuncPtr,4 61*b1cdbd2cSJim Jagielski 62*b1cdbd2cSJim Jagielski .section ".text" 63*b1cdbd2cSJim Jagielski 64*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX) 65*b1cdbd2cSJim Jagielski /* add the address of the calling "call" instruction (stored in %o7) to 66*b1cdbd2cSJim Jagielski * %o5 which contains _GLOBAL_OFFSET_TABLE_ 67*b1cdbd2cSJim Jagielski */ 68*b1cdbd2cSJim Jagielski .Laddoseven: 69*b1cdbd2cSJim Jagielski retl 70*b1cdbd2cSJim Jagielski add %o7, %o5, %o5 71*b1cdbd2cSJim Jagielski #endif 72*b1cdbd2cSJim Jagielski 73*b1cdbd2cSJim Jagielski .global osl_incrementInterlockedCount 74*b1cdbd2cSJim Jagielski .align 4 75*b1cdbd2cSJim Jagielski 76*b1cdbd2cSJim Jagielski osl_incrementInterlockedCount: 77*b1cdbd2cSJim Jagielski 78*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX) 79*b1cdbd2cSJim Jagielski mov %o7, %g1 80*b1cdbd2cSJim Jagielski sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5 81*b1cdbd2cSJim Jagielski call .Laddoseven 82*b1cdbd2cSJim Jagielski add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5 83*b1cdbd2cSJim Jagielski mov %g1, %o7 84*b1cdbd2cSJim Jagielski #endif 85*b1cdbd2cSJim Jagielski set osl_incrementInterLockCountFuncPtr, %o1 86*b1cdbd2cSJim Jagielski #if defined(NETBSD) 87*b1cdbd2cSJim Jagielski ld [%o1 + %o5], %o1 88*b1cdbd2cSJim Jagielski #endif 89*b1cdbd2cSJim Jagielski ld [%o1], %o1 90*b1cdbd2cSJim Jagielski jmp %o1 91*b1cdbd2cSJim Jagielski nop ! delay slot 92*b1cdbd2cSJim Jagielski .type osl_incrementInterlockedCount,#function 93*b1cdbd2cSJim Jagielski .size osl_incrementInterlockedCount,.-osl_incrementInterlockedCount 94*b1cdbd2cSJim Jagielski 95*b1cdbd2cSJim Jagielski .section ".text" 96*b1cdbd2cSJim Jagielski .global osl_decrementInterlockedCount 97*b1cdbd2cSJim Jagielski .align 4 98*b1cdbd2cSJim Jagielski 99*b1cdbd2cSJim Jagielski osl_decrementInterlockedCount: 100*b1cdbd2cSJim Jagielski 101*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX) 102*b1cdbd2cSJim Jagielski mov %o7, %g1 103*b1cdbd2cSJim Jagielski sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5 104*b1cdbd2cSJim Jagielski call .Laddoseven 105*b1cdbd2cSJim Jagielski add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5 106*b1cdbd2cSJim Jagielski mov %g1, %o7 107*b1cdbd2cSJim Jagielski #endif 108*b1cdbd2cSJim Jagielski set osl_decrementInterLockCountFuncPtr, %o1 109*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX) 110*b1cdbd2cSJim Jagielski ld [%o1 + %o5], %o1 111*b1cdbd2cSJim Jagielski #endif 112*b1cdbd2cSJim Jagielski ld [%o1], %o1 113*b1cdbd2cSJim Jagielski jmp %o1 114*b1cdbd2cSJim Jagielski nop ! delay slot 115*b1cdbd2cSJim Jagielski .type osl_decrementInterlockedCount,#function 116*b1cdbd2cSJim Jagielski .size osl_decrementInterlockedCount,.-osl_decrementInterlockedCount 117*b1cdbd2cSJim Jagielski 118*b1cdbd2cSJim Jagielski .section ".text" 119*b1cdbd2cSJim Jagielski .global osl_InterlockedCountSetV9 120*b1cdbd2cSJim Jagielski .align 4 121*b1cdbd2cSJim Jagielski 122*b1cdbd2cSJim Jagielski osl_InterlockedCountSetV9: 123*b1cdbd2cSJim Jagielski 124*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX) 125*b1cdbd2cSJim Jagielski mov %o7, %g1 126*b1cdbd2cSJim Jagielski sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5 127*b1cdbd2cSJim Jagielski call .Laddoseven 128*b1cdbd2cSJim Jagielski add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5 129*b1cdbd2cSJim Jagielski mov %g1, %o7 130*b1cdbd2cSJim Jagielski #endif 131*b1cdbd2cSJim Jagielski set osl_incrementInterLockCountFuncPtr, %o1 132*b1cdbd2cSJim Jagielski set osl_decrementInterLockCountFuncPtr, %o2 133*b1cdbd2cSJim Jagielski cmp %o0, %g0 134*b1cdbd2cSJim Jagielski bnz 1f 135*b1cdbd2cSJim Jagielski nop ! delay slot 136*b1cdbd2cSJim Jagielski set osl_incrementInterlockedCountV8, %o0 137*b1cdbd2cSJim Jagielski set osl_decrementInterlockedCountV8, %o3 138*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX) 139*b1cdbd2cSJim Jagielski ld [%o0 + %o5], %o0 140*b1cdbd2cSJim Jagielski ld [%o1 + %o5], %o1 141*b1cdbd2cSJim Jagielski ld [%o2 + %o5], %o2 142*b1cdbd2cSJim Jagielski ld [%o3 + %o5], %o3 143*b1cdbd2cSJim Jagielski #endif 144*b1cdbd2cSJim Jagielski st %o3,[%o2] 145*b1cdbd2cSJim Jagielski retl 146*b1cdbd2cSJim Jagielski st %o0,[%o1] 147*b1cdbd2cSJim Jagielski 1: set osl_incrementInterlockedCountV9, %o0 148*b1cdbd2cSJim Jagielski set osl_decrementInterlockedCountV9, %o3 149*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX) 150*b1cdbd2cSJim Jagielski ld [%o0 + %o5], %o0 151*b1cdbd2cSJim Jagielski ld [%o1 + %o5], %o1 152*b1cdbd2cSJim Jagielski ld [%o2 + %o5], %o2 153*b1cdbd2cSJim Jagielski ld [%o3 + %o5], %o3 154*b1cdbd2cSJim Jagielski #endif 155*b1cdbd2cSJim Jagielski st %o3,[%o2] 156*b1cdbd2cSJim Jagielski retl 157*b1cdbd2cSJim Jagielski st %o0,[%o1] 158*b1cdbd2cSJim Jagielski 159*b1cdbd2cSJim Jagielski .type osl_InterlockedCountSetV9,#function 160*b1cdbd2cSJim Jagielski .size osl_InterlockedCountSetV9,.-osl_InterlockedCountSetV9 161*b1cdbd2cSJim Jagielski 162*b1cdbd2cSJim Jagielski 163*b1cdbd2cSJim Jagielski .section ".text" 164*b1cdbd2cSJim Jagielski .local osl_incrementInterlockedCountV8 165*b1cdbd2cSJim Jagielski .align 4 166*b1cdbd2cSJim Jagielski 167*b1cdbd2cSJim Jagielski ! Implements osl_[increment|decrement]InterlockedCount with sparcv8 "swap" instruction. 168*b1cdbd2cSJim Jagielski ! Uses -4096 as lock value for spinlock to allow for small negative counts. 169*b1cdbd2cSJim Jagielski 170*b1cdbd2cSJim Jagielski osl_incrementInterlockedCountV8: 171*b1cdbd2cSJim Jagielski 172*b1cdbd2cSJim Jagielski 1: ld [%o0], %o1 173*b1cdbd2cSJim Jagielski cmp %o1, -4096 ! test spinlock 174*b1cdbd2cSJim Jagielski be 1b 175*b1cdbd2cSJim Jagielski mov -4096, %o1 ! delay slot 176*b1cdbd2cSJim Jagielski swap [%o0], %o1 177*b1cdbd2cSJim Jagielski cmp %o1, -4096 178*b1cdbd2cSJim Jagielski be 1b 179*b1cdbd2cSJim Jagielski inc %o1 ! delay slot, if we got spinlock, increment count 180*b1cdbd2cSJim Jagielski st %o1, [%o0] 181*b1cdbd2cSJim Jagielski retl 182*b1cdbd2cSJim Jagielski mov %o1, %o0 ! delay slot 183*b1cdbd2cSJim Jagielski 184*b1cdbd2cSJim Jagielski .type osl_incrementInterlockedCountV8,#function 185*b1cdbd2cSJim Jagielski .size osl_incrementInterlockedCountV8,.-osl_incrementInterlockedCountV8 186*b1cdbd2cSJim Jagielski 187*b1cdbd2cSJim Jagielski 188*b1cdbd2cSJim Jagielski .section ".text" 189*b1cdbd2cSJim Jagielski .local osl_decrementInterlockedCountV8 190*b1cdbd2cSJim Jagielski .align 4 191*b1cdbd2cSJim Jagielski 192*b1cdbd2cSJim Jagielski osl_decrementInterlockedCountV8: 193*b1cdbd2cSJim Jagielski 194*b1cdbd2cSJim Jagielski 1: ld [%o0], %o1 195*b1cdbd2cSJim Jagielski cmp %o1, -4096 ! test spinlock 196*b1cdbd2cSJim Jagielski be 1b 197*b1cdbd2cSJim Jagielski mov -4096, %o1 ! delay slot 198*b1cdbd2cSJim Jagielski swap [%o0], %o1 199*b1cdbd2cSJim Jagielski cmp %o1, -4096 200*b1cdbd2cSJim Jagielski be 1b 201*b1cdbd2cSJim Jagielski dec %o1 ! delay slot, if we got spinlock, decrement count 202*b1cdbd2cSJim Jagielski st %o1, [%o0] ! delay slot 203*b1cdbd2cSJim Jagielski retl 204*b1cdbd2cSJim Jagielski mov %o1, %o0 ! delay slot 205*b1cdbd2cSJim Jagielski 206*b1cdbd2cSJim Jagielski .type osl_decrementInterlockedCountV8,#function 207*b1cdbd2cSJim Jagielski .size osl_decrementInterlockedCountV8,.-osl_decrementInterlockedCountV8 208*b1cdbd2cSJim Jagielski 209*b1cdbd2cSJim Jagielski #endif /* !__sparcv8plus && !__sparcv9 && !_sparcv9__ */ 210*b1cdbd2cSJim Jagielski 211*b1cdbd2cSJim Jagielski .section ".text" 212*b1cdbd2cSJim Jagielski #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__) 213*b1cdbd2cSJim Jagielski #define osl_incrementInterlockedCountV9 osl_incrementInterlockedCount 214*b1cdbd2cSJim Jagielski .global osl_incrementInterlockedCountV9 215*b1cdbd2cSJim Jagielski #else 216*b1cdbd2cSJim Jagielski .local osl_incrementInterlockedCountV9 217*b1cdbd2cSJim Jagielski #endif 218*b1cdbd2cSJim Jagielski .align 8 219*b1cdbd2cSJim Jagielski 220*b1cdbd2cSJim Jagielski ! Implements osl_[increment|decrement]InterlockedCount with sparcv9(sparcv8plus) "cas" 221*b1cdbd2cSJim Jagielski ! instruction. 222*b1cdbd2cSJim Jagielski 223*b1cdbd2cSJim Jagielski osl_incrementInterlockedCountV9: 224*b1cdbd2cSJim Jagielski 225*b1cdbd2cSJim Jagielski 1: ld [%o0], %o1 226*b1cdbd2cSJim Jagielski add %o1, 1, %o2 227*b1cdbd2cSJim Jagielski ! allow linux to build for v8 228*b1cdbd2cSJim Jagielski .word 0xD5E21009 229*b1cdbd2cSJim Jagielski ! cas [%o0], %o1, %o2 230*b1cdbd2cSJim Jagielski cmp %o1, %o2 231*b1cdbd2cSJim Jagielski bne 1b 232*b1cdbd2cSJim Jagielski nop ! delay slot 233*b1cdbd2cSJim Jagielski retl 234*b1cdbd2cSJim Jagielski add %o2, 1, %o0 ! delay slot 235*b1cdbd2cSJim Jagielski 236*b1cdbd2cSJim Jagielski .type osl_incrementInterlockedCountV9,#function 237*b1cdbd2cSJim Jagielski .size osl_incrementInterlockedCountV9,.-osl_incrementInterlockedCountV9 238*b1cdbd2cSJim Jagielski 239*b1cdbd2cSJim Jagielski 240*b1cdbd2cSJim Jagielski .section ".text" 241*b1cdbd2cSJim Jagielski #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__) 242*b1cdbd2cSJim Jagielski #define osl_decrementInterlockedCountV9 osl_decrementInterlockedCount 243*b1cdbd2cSJim Jagielski .global osl_decrementInterlockedCountV9 244*b1cdbd2cSJim Jagielski #else 245*b1cdbd2cSJim Jagielski .local osl_decrementInterlockedCountV9 246*b1cdbd2cSJim Jagielski #endif 247*b1cdbd2cSJim Jagielski .align 8 248*b1cdbd2cSJim Jagielski 249*b1cdbd2cSJim Jagielski osl_decrementInterlockedCountV9: 250*b1cdbd2cSJim Jagielski 251*b1cdbd2cSJim Jagielski 1: ld [%o0], %o1 252*b1cdbd2cSJim Jagielski sub %o1, 1, %o2 253*b1cdbd2cSJim Jagielski ! allow linux to build for v8 254*b1cdbd2cSJim Jagielski .word 0xD5E21009 255*b1cdbd2cSJim Jagielski ! cas [%o0], %o1, %o2 256*b1cdbd2cSJim Jagielski cmp %o1, %o2 257*b1cdbd2cSJim Jagielski bne 1b 258*b1cdbd2cSJim Jagielski nop ! delay slot 259*b1cdbd2cSJim Jagielski retl 260*b1cdbd2cSJim Jagielski sub %o2, 1, %o0 ! delay slot 261*b1cdbd2cSJim Jagielski 262*b1cdbd2cSJim Jagielski .type osl_decrementInterlockedCountV9,#function 263*b1cdbd2cSJim Jagielski .size osl_decrementInterlockedCountV9,.-osl_decrementInterlockedCountV9 264