mips-extns.h revision 224110
1/*- 2 * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights 3 * reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $FreeBSD: head/sys/mips/nlm/hal/mips-extns.h 224110 2011-07-16 19:35:44Z jchandra $ 29 * NETLOGIC_BSD */ 30 31#ifndef __NLM_MIPS_EXTNS_H__ 32#define __NLM_MIPS_EXTNS_H__ 33 34#if !defined(LOCORE) && !defined(__ASSEMBLY__) 35static __inline__ int32_t nlm_swapw(int32_t *loc, int32_t val) 36{ 37 int32_t oldval = 0; 38 39 __asm__ __volatile__ ( 40 ".set push\n" 41 ".set noreorder\n" 42 "move $9, %2\n" 43 "move $8, %3\n" 44 ".word 0x71280014\n" /* "swapw $8, $9\n" */ 45 "move %1, $8\n" 46 ".set pop\n" 47 : "+m" (*loc), "=r" (oldval) 48 : "r" (loc), "r" (val) 49 : "$8", "$9" ); 50 51 return oldval; 52} 53 54static __inline__ uint32_t nlm_swapwu(int32_t *loc, uint32_t val) 55{ 56 uint32_t oldval; 57 58 __asm__ __volatile__ ( 59 ".set push\n" 60 ".set noreorder\n" 61 "move $9, %2\n" 62 "move $8, %3\n" 63 ".word 0x71280015\n" /* "swapwu $8, $9\n" */ 64 "move %1, $8\n" 65 ".set pop\n" 66 : "+m" (*loc), "=r" (oldval) 67 : "r" (loc), "r" (val) 68 : "$8", "$9" ); 69 70 return oldval; 71} 72 73#if (__mips == 64) 74static __inline__ uint64_t nlm_swapd(int32_t *loc, uint64_t val) 75{ 76 uint64_t oldval; 77 78 __asm__ __volatile__ ( 79 ".set push\n" 80 ".set noreorder\n" 81 "move $9, %2\n" 82 "move $8, %3\n" 83 ".word 0x71280014\n" /* "swapw $8, $9\n" */ 84 "move %1, $8\n" 85 ".set pop\n" 86 : "+m" (*loc), "=r" (oldval) 87 : "r" (loc), "r" (val) 88 : "$8", "$9" ); 89 90 return oldval; 91} 92#endif 93 94#if defined(__mips_n64) || defined(__mips_n32) 95static __inline uint64_t 96nlm_mfcr(uint32_t reg) 97{ 98 uint64_t res; 99 100 __asm__ __volatile__( 101 ".set push\n\t" 102 ".set noreorder\n\t" 103 "move $9, %1\n\t" 104 ".word 0x71280018\n\t" /* mfcr $8, $9 */ 105 "move %0, $8\n\t" 106 ".set pop\n" 107 : "=r" (res) : "r"(reg) 108 : "$8", "$9" 109 ); 110 return (res); 111} 112 113static __inline void 114nlm_mtcr(uint32_t reg, uint64_t value) 115{ 116 __asm__ __volatile__( 117 ".set push\n\t" 118 ".set noreorder\n\t" 119 "move $8, %0\n" 120 "move $9, %1\n" 121 ".word 0x71280019\n" /* mtcr $8, $9 */ 122 ".set pop\n" 123 : 124 : "r" (value), "r" (reg) 125 : "$8", "$9" 126 ); 127} 128 129#else /* !(defined(__mips_n64) || defined(__mips_n32)) */ 130 131static __inline__ uint64_t 132nlm_mfcr(uint32_t reg) 133{ 134 uint64_t hi; 135 uint64_t lo; 136 137 __asm__ __volatile__ ( 138 ".set push\n" 139 ".set mips64\n" 140 "move $8, %2\n" 141 ".word 0x71090018\n" 142 "nop \n" 143 "dsra32 %0, $9, 0\n" 144 "sll %1, $9, 0\n" 145 ".set pop\n" 146 : "=r"(hi), "=r"(lo) 147 : "r"(reg) : "$8", "$9"); 148 149 return (((uint64_t)hi) << 32) | lo; 150} 151 152static __inline__ void 153nlm_mtcr(uint32_t reg, uint64_t val) 154{ 155 uint32_t hi, lo; 156 hi = val >> 32; 157 lo = val & 0xffffffff; 158 159 __asm__ __volatile__ ( 160 ".set push\n" 161 ".set mips64\n" 162 "move $9, %0\n" 163 "dsll32 $9, %1, 0\n" 164 "dsll32 $8, %0, 0\n" 165 "dsrl32 $9, $9, 0\n" 166 "or $9, $9, $8\n" 167 "move $8, %2\n" 168 ".word 0x71090019\n" 169 "nop \n" 170 ".set pop\n" 171 ::"r"(hi), "r"(lo), "r"(reg) 172 : "$8", "$9"); 173} 174#endif /* (defined(__mips_n64) || defined(__mips_n32)) */ 175 176/* dcrc2 */ 177/* XLP additional instructions */ 178 179/* 180 * Atomic increment a unsigned int 181 */ 182static __inline unsigned int 183nlm_ldaddwu(unsigned int value, unsigned int *addr) 184{ 185 __asm__ __volatile__( 186 ".set push\n" 187 ".set noreorder\n" 188 "move $8, %2\n" 189 "move $9, %3\n" 190 ".word 0x71280011\n" /* ldaddwu $8, $9 */ 191 "move %0, $8\n" 192 ".set pop\n" 193 : "=&r"(value), "+m"(*addr) 194 : "0"(value), "r" ((unsigned long)addr) 195 : "$8", "$9"); 196 197 return (value); 198} 199#endif 200#endif 201