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