mips-extns.h revision 224110
1224110Sjchandra/*- 2224110Sjchandra * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights 3224110Sjchandra * reserved. 4224110Sjchandra * 5224110Sjchandra * Redistribution and use in source and binary forms, with or without 6224110Sjchandra * modification, are permitted provided that the following conditions are 7224110Sjchandra * met: 8224110Sjchandra * 9224110Sjchandra * 1. Redistributions of source code must retain the above copyright 10224110Sjchandra * notice, this list of conditions and the following disclaimer. 11224110Sjchandra * 2. Redistributions in binary form must reproduce the above copyright 12224110Sjchandra * notice, this list of conditions and the following disclaimer in 13224110Sjchandra * the documentation and/or other materials provided with the 14224110Sjchandra * distribution. 15224110Sjchandra * 16224110Sjchandra * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND 17224110Sjchandra * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18224110Sjchandra * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19224110Sjchandra * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE 20224110Sjchandra * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21224110Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22224110Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23224110Sjchandra * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24224110Sjchandra * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25224110Sjchandra * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26224110Sjchandra * THE POSSIBILITY OF SUCH DAMAGE. 27224110Sjchandra * 28224110Sjchandra * $FreeBSD: head/sys/mips/nlm/hal/mips-extns.h 224110 2011-07-16 19:35:44Z jchandra $ 29224110Sjchandra * NETLOGIC_BSD */ 30224110Sjchandra 31224110Sjchandra#ifndef __NLM_MIPS_EXTNS_H__ 32224110Sjchandra#define __NLM_MIPS_EXTNS_H__ 33224110Sjchandra 34224110Sjchandra#if !defined(LOCORE) && !defined(__ASSEMBLY__) 35224110Sjchandrastatic __inline__ int32_t nlm_swapw(int32_t *loc, int32_t val) 36224110Sjchandra{ 37224110Sjchandra int32_t oldval = 0; 38224110Sjchandra 39224110Sjchandra __asm__ __volatile__ ( 40224110Sjchandra ".set push\n" 41224110Sjchandra ".set noreorder\n" 42224110Sjchandra "move $9, %2\n" 43224110Sjchandra "move $8, %3\n" 44224110Sjchandra ".word 0x71280014\n" /* "swapw $8, $9\n" */ 45224110Sjchandra "move %1, $8\n" 46224110Sjchandra ".set pop\n" 47224110Sjchandra : "+m" (*loc), "=r" (oldval) 48224110Sjchandra : "r" (loc), "r" (val) 49224110Sjchandra : "$8", "$9" ); 50224110Sjchandra 51224110Sjchandra return oldval; 52224110Sjchandra} 53224110Sjchandra 54224110Sjchandrastatic __inline__ uint32_t nlm_swapwu(int32_t *loc, uint32_t val) 55224110Sjchandra{ 56224110Sjchandra uint32_t oldval; 57224110Sjchandra 58224110Sjchandra __asm__ __volatile__ ( 59224110Sjchandra ".set push\n" 60224110Sjchandra ".set noreorder\n" 61224110Sjchandra "move $9, %2\n" 62224110Sjchandra "move $8, %3\n" 63224110Sjchandra ".word 0x71280015\n" /* "swapwu $8, $9\n" */ 64224110Sjchandra "move %1, $8\n" 65224110Sjchandra ".set pop\n" 66224110Sjchandra : "+m" (*loc), "=r" (oldval) 67224110Sjchandra : "r" (loc), "r" (val) 68224110Sjchandra : "$8", "$9" ); 69224110Sjchandra 70224110Sjchandra return oldval; 71224110Sjchandra} 72224110Sjchandra 73224110Sjchandra#if (__mips == 64) 74224110Sjchandrastatic __inline__ uint64_t nlm_swapd(int32_t *loc, uint64_t val) 75224110Sjchandra{ 76224110Sjchandra uint64_t oldval; 77224110Sjchandra 78224110Sjchandra __asm__ __volatile__ ( 79224110Sjchandra ".set push\n" 80224110Sjchandra ".set noreorder\n" 81224110Sjchandra "move $9, %2\n" 82224110Sjchandra "move $8, %3\n" 83224110Sjchandra ".word 0x71280014\n" /* "swapw $8, $9\n" */ 84224110Sjchandra "move %1, $8\n" 85224110Sjchandra ".set pop\n" 86224110Sjchandra : "+m" (*loc), "=r" (oldval) 87224110Sjchandra : "r" (loc), "r" (val) 88224110Sjchandra : "$8", "$9" ); 89224110Sjchandra 90224110Sjchandra return oldval; 91224110Sjchandra} 92224110Sjchandra#endif 93224110Sjchandra 94224110Sjchandra#if defined(__mips_n64) || defined(__mips_n32) 95224110Sjchandrastatic __inline uint64_t 96224110Sjchandranlm_mfcr(uint32_t reg) 97224110Sjchandra{ 98224110Sjchandra uint64_t res; 99224110Sjchandra 100224110Sjchandra __asm__ __volatile__( 101224110Sjchandra ".set push\n\t" 102224110Sjchandra ".set noreorder\n\t" 103224110Sjchandra "move $9, %1\n\t" 104224110Sjchandra ".word 0x71280018\n\t" /* mfcr $8, $9 */ 105224110Sjchandra "move %0, $8\n\t" 106224110Sjchandra ".set pop\n" 107224110Sjchandra : "=r" (res) : "r"(reg) 108224110Sjchandra : "$8", "$9" 109224110Sjchandra ); 110224110Sjchandra return (res); 111224110Sjchandra} 112224110Sjchandra 113224110Sjchandrastatic __inline void 114224110Sjchandranlm_mtcr(uint32_t reg, uint64_t value) 115224110Sjchandra{ 116224110Sjchandra __asm__ __volatile__( 117224110Sjchandra ".set push\n\t" 118224110Sjchandra ".set noreorder\n\t" 119224110Sjchandra "move $8, %0\n" 120224110Sjchandra "move $9, %1\n" 121224110Sjchandra ".word 0x71280019\n" /* mtcr $8, $9 */ 122224110Sjchandra ".set pop\n" 123224110Sjchandra : 124224110Sjchandra : "r" (value), "r" (reg) 125224110Sjchandra : "$8", "$9" 126224110Sjchandra ); 127224110Sjchandra} 128224110Sjchandra 129224110Sjchandra#else /* !(defined(__mips_n64) || defined(__mips_n32)) */ 130224110Sjchandra 131224110Sjchandrastatic __inline__ uint64_t 132224110Sjchandranlm_mfcr(uint32_t reg) 133224110Sjchandra{ 134224110Sjchandra uint64_t hi; 135224110Sjchandra uint64_t lo; 136224110Sjchandra 137224110Sjchandra __asm__ __volatile__ ( 138224110Sjchandra ".set push\n" 139224110Sjchandra ".set mips64\n" 140224110Sjchandra "move $8, %2\n" 141224110Sjchandra ".word 0x71090018\n" 142224110Sjchandra "nop \n" 143224110Sjchandra "dsra32 %0, $9, 0\n" 144224110Sjchandra "sll %1, $9, 0\n" 145224110Sjchandra ".set pop\n" 146224110Sjchandra : "=r"(hi), "=r"(lo) 147224110Sjchandra : "r"(reg) : "$8", "$9"); 148224110Sjchandra 149224110Sjchandra return (((uint64_t)hi) << 32) | lo; 150224110Sjchandra} 151224110Sjchandra 152224110Sjchandrastatic __inline__ void 153224110Sjchandranlm_mtcr(uint32_t reg, uint64_t val) 154224110Sjchandra{ 155224110Sjchandra uint32_t hi, lo; 156224110Sjchandra hi = val >> 32; 157224110Sjchandra lo = val & 0xffffffff; 158224110Sjchandra 159224110Sjchandra __asm__ __volatile__ ( 160224110Sjchandra ".set push\n" 161224110Sjchandra ".set mips64\n" 162224110Sjchandra "move $9, %0\n" 163224110Sjchandra "dsll32 $9, %1, 0\n" 164224110Sjchandra "dsll32 $8, %0, 0\n" 165224110Sjchandra "dsrl32 $9, $9, 0\n" 166224110Sjchandra "or $9, $9, $8\n" 167224110Sjchandra "move $8, %2\n" 168224110Sjchandra ".word 0x71090019\n" 169224110Sjchandra "nop \n" 170224110Sjchandra ".set pop\n" 171224110Sjchandra ::"r"(hi), "r"(lo), "r"(reg) 172224110Sjchandra : "$8", "$9"); 173224110Sjchandra} 174224110Sjchandra#endif /* (defined(__mips_n64) || defined(__mips_n32)) */ 175224110Sjchandra 176224110Sjchandra/* dcrc2 */ 177224110Sjchandra/* XLP additional instructions */ 178224110Sjchandra 179224110Sjchandra/* 180224110Sjchandra * Atomic increment a unsigned int 181224110Sjchandra */ 182224110Sjchandrastatic __inline unsigned int 183224110Sjchandranlm_ldaddwu(unsigned int value, unsigned int *addr) 184224110Sjchandra{ 185224110Sjchandra __asm__ __volatile__( 186224110Sjchandra ".set push\n" 187224110Sjchandra ".set noreorder\n" 188224110Sjchandra "move $8, %2\n" 189224110Sjchandra "move $9, %3\n" 190224110Sjchandra ".word 0x71280011\n" /* ldaddwu $8, $9 */ 191224110Sjchandra "move %0, $8\n" 192224110Sjchandra ".set pop\n" 193224110Sjchandra : "=&r"(value), "+m"(*addr) 194224110Sjchandra : "0"(value), "r" ((unsigned long)addr) 195224110Sjchandra : "$8", "$9"); 196224110Sjchandra 197224110Sjchandra return (value); 198224110Sjchandra} 199224110Sjchandra#endif 200224110Sjchandra#endif 201