compiler.h revision 4202a189
1/*
2 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Thomas Roell not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Thomas Roell makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 */
23/*
24 * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
25 *
26 * Permission is hereby granted, free of charge, to any person obtaining a
27 * copy of this software and associated documentation files (the "Software"),
28 * to deal in the Software without restriction, including without limitation
29 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
30 * and/or sell copies of the Software, and to permit persons to whom the
31 * Software is furnished to do so, subject to the following conditions:
32 *
33 * The above copyright notice and this permission notice shall be included in
34 * all copies or substantial portions of the Software.
35 *
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
39 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
40 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
41 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
42 * OTHER DEALINGS IN THE SOFTWARE.
43 *
44 * Except as contained in this notice, the name of the copyright holder(s)
45 * and author(s) shall not be used in advertising or otherwise to promote
46 * the sale, use or other dealings in this Software without prior written
47 * authorization from the copyright holder(s) and author(s).
48 */
49
50#ifndef _COMPILER_H
51
52# define _COMPILER_H
53
54#if defined(__SUNPRO_C)
55# define DO_PROTOTYPES
56#endif
57
58/* Map Sun compiler platform defines to gcc-style used in the code */
59#if defined(__amd64) && !defined(__amd64__)
60# define __amd64__
61#endif
62#if defined(__i386) && !defined(__i386__)
63# define __i386__
64#endif
65#if defined(__sparc) && !defined(__sparc__)
66# define __sparc__
67#endif
68#if defined(__sparcv9) && !defined(__sparc64__)
69# define __sparc64__
70#endif
71
72#ifndef _X_EXPORT
73# include <X11/Xfuncproto.h>
74#endif
75
76# include <pixman.h> /* for uint*_t types */
77
78/* Allow drivers to use the GCC-supported __inline__ and/or __inline. */
79# ifndef __inline__
80#  if defined(__GNUC__)
81    /* gcc has __inline__ */
82#  elif defined(__HIGHC__)
83#   define __inline__ _Inline
84#  else
85#   define __inline__ /**/
86#  endif
87# endif /* __inline__ */
88# ifndef __inline
89#  if defined(__GNUC__)
90    /* gcc has __inline */
91#  elif defined(__HIGHC__)
92#   define __inline _Inline
93#  else
94#   define __inline /**/
95#  endif
96# endif /* __inline */
97
98/* Support gcc's __FUNCTION__ for people using other compilers */
99#if !defined(__GNUC__) && !defined(__FUNCTION__)
100# define __FUNCTION__ __func__ /* C99 */
101#endif
102
103# if defined(NO_INLINE) || defined(DO_PROTOTYPES)
104
105#  if !defined(__arm__)
106#   if !defined(__sparc__) && !defined(__sparc) && !defined(__arm32__) && !defined(__nds32__) \
107      && !(defined(__alpha__) && defined(linux)) \
108      && !(defined(__ia64__) && defined(linux)) \
109
110extern _X_EXPORT void outb(unsigned short, unsigned char);
111extern _X_EXPORT void outw(unsigned short, unsigned short);
112extern _X_EXPORT void outl(unsigned short, unsigned int);
113extern _X_EXPORT unsigned int inb(unsigned short);
114extern _X_EXPORT unsigned int inw(unsigned short);
115extern _X_EXPORT unsigned int inl(unsigned short);
116
117#   else /* __sparc__,  __arm32__, __alpha__, __nds32__ */
118
119extern _X_EXPORT void outb(unsigned long, unsigned char);
120extern _X_EXPORT void outw(unsigned long, unsigned short);
121extern _X_EXPORT void outl(unsigned long, unsigned int);
122extern _X_EXPORT unsigned int inb(unsigned long);
123extern _X_EXPORT unsigned int inw(unsigned long);
124extern _X_EXPORT unsigned int inl(unsigned long);
125
126#   endif /* __sparc__,  __arm32__, __alpha__, __nds32__ */
127#  endif /* __arm__ */
128
129#  if defined(__powerpc__) && !defined(__OpenBSD__)
130extern unsigned long ldq_u(unsigned long *);
131extern unsigned long ldl_u(unsigned int *);
132extern unsigned long ldw_u(unsigned short *);
133extern void stq_u(unsigned long, unsigned long *);
134extern void stl_u(unsigned long, unsigned int *);
135extern void stw_u(unsigned long, unsigned short *);
136extern void mem_barrier(void);
137extern void write_mem_barrier(void);
138extern void stl_brx(unsigned long, volatile unsigned char *, int);
139extern void stw_brx(unsigned short, volatile unsigned char *, int);
140extern unsigned long ldl_brx(volatile unsigned char *, int);
141extern unsigned short ldw_brx(volatile unsigned char *, int);
142#  endif /* __powerpc__ && !__OpenBSD */
143
144# endif /* NO_INLINE || DO_PROTOTYPES */
145
146# ifndef NO_INLINE
147#  ifdef __GNUC__
148#   ifdef __i386__
149
150#    ifdef __SSE__
151#     define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory")
152#    else
153#     define write_mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory")
154#    endif
155
156#    ifdef __SSE2__
157#     define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory")
158#    else
159#     define mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory")
160#    endif
161
162#   elif defined __alpha__
163
164#    define mem_barrier() __asm__ __volatile__ ("mb" : : : "memory")
165#    define write_mem_barrier() __asm__ __volatile__ ("wmb" : : : "memory")
166
167#   elif defined __amd64__
168
169#    define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory")
170#    define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory")
171
172#   elif defined __ia64__
173
174#    ifndef __INTEL_COMPILER
175#     define mem_barrier()        __asm__ __volatile__ ("mf" : : : "memory")
176#     define write_mem_barrier()  __asm__ __volatile__ ("mf" : : : "memory")
177#    else
178#     include "ia64intrin.h"
179#     define mem_barrier() __mf()
180#     define write_mem_barrier() __mf()
181#    endif
182
183#   elif defined __mips__
184     /* Note: sync instruction requires MIPS II instruction set */
185#    define mem_barrier()		\
186	__asm__ __volatile__(		\
187		".set   push\n\t"	\
188		".set   noreorder\n\t"	\
189		".set   mips2\n\t"	\
190		"sync\n\t"		\
191		".set   pop"		\
192		: /* no output */	\
193		: /* no input */	\
194		: "memory")
195#    define write_mem_barrier() mem_barrier()
196
197#   elif defined __powerpc__
198
199#    if defined(linux) && defined(__powerpc64__)
200#     include <linux/version.h>
201#     if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
202#      include <asm/memory.h>
203#     endif
204#    endif /* defined(linux) && defined(__powerpc64__) */
205
206#    ifndef eieio /* We deal with arch-specific eieio() routines above... */
207#     define eieio() __asm__ __volatile__ ("eieio" ::: "memory")
208#    endif /* eieio */
209#    define mem_barrier()	eieio()
210#    define write_mem_barrier()	eieio()
211
212#   elif defined __sparc__
213
214#    define barrier() __asm__ __volatile__ (".word 0x8143e00a" : : : "memory")
215#    define mem_barrier()         /* XXX: nop for now */
216#    define write_mem_barrier()   /* XXX: nop for now */
217#   endif
218#  endif /* __GNUC__ */
219# endif /* NO_INLINE */
220
221# ifndef mem_barrier
222#  define mem_barrier() /* NOP */
223# endif
224
225# ifndef write_mem_barrier
226#  define write_mem_barrier() /* NOP */
227# endif
228
229
230# ifndef NO_INLINE
231#  ifdef __GNUC__
232
233/* Define some packed structures to use with unaligned accesses */
234
235struct __una_u64 { uint64_t x __attribute__((packed)); };
236struct __una_u32 { uint32_t x __attribute__((packed)); };
237struct __una_u16 { uint16_t x __attribute__((packed)); };
238
239/* Elemental unaligned loads */
240
241static __inline__ uint64_t ldq_u(uint64_t *p)
242{
243	const struct __una_u64 *ptr = (const struct __una_u64 *) p;
244	return ptr->x;
245}
246
247static __inline__ uint32_t ldl_u(uint32_t *p)
248{
249	const struct __una_u32 *ptr = (const struct __una_u32 *) p;
250	return ptr->x;
251}
252
253static __inline__ uint16_t ldw_u(uint16_t *p)
254{
255	const struct __una_u16 *ptr = (const struct __una_u16 *) p;
256	return ptr->x;
257}
258
259/* Elemental unaligned stores */
260
261static __inline__ void stq_u(uint64_t val, uint64_t *p)
262{
263	struct __una_u64 *ptr = (struct __una_u64 *) p;
264	ptr->x = val;
265}
266
267static __inline__ void stl_u(uint32_t val, uint32_t *p)
268{
269	struct __una_u32 *ptr = (struct __una_u32 *) p;
270	ptr->x = val;
271}
272
273static __inline__ void stw_u(uint16_t val, uint16_t *p)
274{
275	struct __una_u16 *ptr = (struct __una_u16 *) p;
276	ptr->x = val;
277}
278#  else /* !__GNUC__ */
279
280#include <string.h> /* needed for memmove */
281
282static __inline__ uint64_t ldq_u(uint64_t *p)
283{
284	uint64_t ret;
285	memmove(&ret, p, sizeof(*p));
286	return ret;
287}
288
289static __inline__ uint32_t ldl_u(uint32_t *p)
290{
291	uint32_t ret;
292	memmove(&ret, p, sizeof(*p));
293	return ret;
294}
295
296static __inline__ uint16_t ldw_u(uint16_t *p)
297{
298	uint16_t ret;
299	memmove(&ret, p, sizeof(*p));
300	return ret;
301}
302
303static __inline__ void stq_u(uint64_t val, uint64_t *p)
304{
305	uint64_t tmp = val;
306	memmove(p, &tmp, sizeof(*p));
307}
308
309static __inline__ void stl_u(uint32_t val, uint32_t *p)
310{
311	uint32_t tmp = val;
312	memmove(p, &tmp, sizeof(*p));
313}
314
315static __inline__ void stw_u(uint16_t val, uint16_t *p)
316{
317	uint16_t tmp = val;
318	memmove(p, &tmp, sizeof(*p));
319}
320
321#  endif /* __GNUC__ */
322# endif /* NO_INLINE */
323
324# ifndef NO_INLINE
325#  ifdef __GNUC__
326#   if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && (defined(__alpha__))
327
328#    ifdef linux
329/* for Linux on Alpha, we use the LIBC _inx/_outx routines */
330/* note that the appropriate setup via "ioperm" needs to be done */
331/*  *before* any inx/outx is done. */
332
333extern _X_EXPORT void _outb(unsigned char val, unsigned long port);
334extern _X_EXPORT void _outw(unsigned short val, unsigned long port);
335extern _X_EXPORT void _outl(unsigned int val, unsigned long port);
336extern _X_EXPORT unsigned int _inb(unsigned long port);
337extern _X_EXPORT unsigned int _inw(unsigned long port);
338extern _X_EXPORT unsigned int _inl(unsigned long port);
339
340static __inline__ void
341outb(unsigned long port, unsigned char val)
342{
343    _outb(val, port);
344}
345
346static __inline__ void
347outw(unsigned long port, unsigned short val)
348{
349    _outw(val, port);
350}
351
352static __inline__ void
353outl(unsigned long port, unsigned int val)
354{
355    _outl(val, port);
356}
357
358static __inline__ unsigned int
359inb(unsigned long port)
360{
361  return _inb(port);
362}
363
364static __inline__ unsigned int
365inw(unsigned long port)
366{
367  return _inw(port);
368}
369
370static __inline__ unsigned int
371inl(unsigned long port)
372{
373  return _inl(port);
374}
375
376#    endif /* linux */
377
378#    if (defined(__FreeBSD__) || defined(__OpenBSD__)) \
379      && !defined(DO_PROTOTYPES)
380
381/* for FreeBSD and OpenBSD on Alpha, we use the libio (resp. libalpha) */
382/*  inx/outx routines */
383/* note that the appropriate setup via "ioperm" needs to be done */
384/*  *before* any inx/outx is done. */
385
386extern _X_EXPORT void outb(unsigned int port, unsigned char val);
387extern _X_EXPORT void outw(unsigned int port, unsigned short val);
388extern _X_EXPORT void outl(unsigned int port, unsigned int val);
389extern _X_EXPORT unsigned char inb(unsigned int port);
390extern _X_EXPORT unsigned short inw(unsigned int port);
391extern _X_EXPORT unsigned int inl(unsigned int port);
392
393#    endif /* (__FreeBSD__ || __OpenBSD__ ) && !DO_PROTOTYPES */
394
395
396#if defined(__NetBSD__)
397#include <machine/pio.h>
398#endif /* __NetBSD__ */
399
400#   elif defined(linux) && defined(__ia64__)
401
402#    include <inttypes.h>
403
404#    include <sys/io.h>
405
406#    undef outb
407#    undef outw
408#    undef outl
409#    undef inb
410#    undef inw
411#    undef inl
412extern _X_EXPORT void outb(unsigned long port, unsigned char val);
413extern _X_EXPORT void outw(unsigned long port, unsigned short val);
414extern _X_EXPORT void outl(unsigned long port, unsigned int val);
415extern _X_EXPORT unsigned int inb(unsigned long port);
416extern _X_EXPORT unsigned int inw(unsigned long port);
417extern _X_EXPORT unsigned int inl(unsigned long port);
418
419#   elif (defined(linux) || defined(__FreeBSD__)) && defined(__amd64__)
420
421#    include <inttypes.h>
422
423static __inline__ void
424outb(unsigned short port, unsigned char val)
425{
426   __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
427}
428
429
430static __inline__ void
431outw(unsigned short port, unsigned short val)
432{
433   __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
434}
435
436static __inline__ void
437outl(unsigned short port, unsigned int val)
438{
439   __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
440}
441
442static __inline__ unsigned int
443inb(unsigned short port)
444{
445   unsigned char ret;
446   __asm__ __volatile__("inb %1,%0" :
447       "=a" (ret) :
448       "d" (port));
449   return ret;
450}
451
452static __inline__ unsigned int
453inw(unsigned short port)
454{
455   unsigned short ret;
456   __asm__ __volatile__("inw %1,%0" :
457       "=a" (ret) :
458       "d" (port));
459   return ret;
460}
461
462static __inline__ unsigned int
463inl(unsigned short port)
464{
465   unsigned int ret;
466   __asm__ __volatile__("inl %1,%0" :
467       "=a" (ret) :
468       "d" (port));
469   return ret;
470}
471
472#   elif (defined(linux) || defined(sun) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)) && defined(__sparc__)
473
474#     ifndef ASI_PL
475#      define ASI_PL 0x88
476#     endif
477
478static __inline__ void
479outb(unsigned long port, unsigned char val)
480{
481	__asm__ __volatile__("stba %0, [%1] %2"
482			     : /* No outputs */
483			     : "r" (val), "r" (port), "i" (ASI_PL));
484	barrier();
485}
486
487static __inline__ void
488outw(unsigned long port, unsigned short val)
489{
490	__asm__ __volatile__("stha %0, [%1] %2"
491			     : /* No outputs */
492			     : "r" (val), "r" (port), "i" (ASI_PL));
493	barrier();
494}
495
496static __inline__ void
497outl(unsigned long port, unsigned int val)
498{
499	__asm__ __volatile__("sta %0, [%1] %2"
500			     : /* No outputs */
501			     : "r" (val), "r" (port), "i" (ASI_PL));
502	barrier();
503}
504
505static __inline__ unsigned int
506inb(unsigned long port)
507{
508	unsigned int ret;
509	__asm__ __volatile__("lduba [%1] %2, %0"
510			     : "=r" (ret)
511			     : "r" (port), "i" (ASI_PL));
512	return ret;
513}
514
515static __inline__ unsigned int
516inw(unsigned long port)
517{
518	unsigned int ret;
519	__asm__ __volatile__("lduha [%1] %2, %0"
520			     : "=r" (ret)
521			     : "r" (port), "i" (ASI_PL));
522	return ret;
523}
524
525static __inline__ unsigned int
526inl(unsigned long port)
527{
528	unsigned int ret;
529	__asm__ __volatile__("lda [%1] %2, %0"
530			     : "=r" (ret)
531			     : "r" (port), "i" (ASI_PL));
532	return ret;
533}
534
535static __inline__ unsigned char
536xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
537{
538	unsigned long addr = ((unsigned long)base) + offset;
539	unsigned char ret;
540
541	__asm__ __volatile__("lduba [%1] %2, %0"
542			     : "=r" (ret)
543			     : "r" (addr), "i" (ASI_PL));
544	return ret;
545}
546
547static __inline__ unsigned short
548xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset)
549{
550	unsigned long addr = ((unsigned long)base) + offset;
551	unsigned short ret;
552
553	__asm__ __volatile__("lduh [%1], %0"
554			     : "=r" (ret)
555			     : "r" (addr));
556	return ret;
557}
558
559static __inline__ unsigned short
560xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset)
561{
562	unsigned long addr = ((unsigned long)base) + offset;
563	unsigned short ret;
564
565	__asm__ __volatile__("lduha [%1] %2, %0"
566			     : "=r" (ret)
567			     : "r" (addr), "i" (ASI_PL));
568	return ret;
569}
570
571static __inline__ unsigned int
572xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
573{
574	unsigned long addr = ((unsigned long)base) + offset;
575	unsigned int ret;
576
577	__asm__ __volatile__("ld [%1], %0"
578			     : "=r" (ret)
579			     : "r" (addr));
580	return ret;
581}
582
583static __inline__ unsigned int
584xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset)
585{
586	unsigned long addr = ((unsigned long)base) + offset;
587	unsigned int ret;
588
589	__asm__ __volatile__("lda [%1] %2, %0"
590			     : "=r" (ret)
591			     : "r" (addr), "i" (ASI_PL));
592	return ret;
593}
594
595static __inline__ void
596xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
597	       const unsigned int val)
598{
599	unsigned long addr = ((unsigned long)base) + offset;
600
601	__asm__ __volatile__("stba %0, [%1] %2"
602			     : /* No outputs */
603			     : "r" (val), "r" (addr), "i" (ASI_PL));
604	barrier();
605}
606
607static __inline__ void
608xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset,
609		  const unsigned int val)
610{
611	unsigned long addr = ((unsigned long)base) + offset;
612
613	__asm__ __volatile__("sth %0, [%1]"
614			     : /* No outputs */
615			     : "r" (val), "r" (addr));
616	barrier();
617}
618
619static __inline__ void
620xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset,
621		  const unsigned int val)
622{
623	unsigned long addr = ((unsigned long)base) + offset;
624
625	__asm__ __volatile__("stha %0, [%1] %2"
626			     : /* No outputs */
627			     : "r" (val), "r" (addr), "i" (ASI_PL));
628	barrier();
629}
630
631static __inline__ void
632xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
633		  const unsigned int val)
634{
635	unsigned long addr = ((unsigned long)base) + offset;
636
637	__asm__ __volatile__("st %0, [%1]"
638			     : /* No outputs */
639			     : "r" (val), "r" (addr));
640	barrier();
641}
642
643static __inline__ void
644xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset,
645		  const unsigned int val)
646{
647	unsigned long addr = ((unsigned long)base) + offset;
648
649	__asm__ __volatile__("sta %0, [%1] %2"
650			     : /* No outputs */
651			     : "r" (val), "r" (addr), "i" (ASI_PL));
652	barrier();
653}
654
655static __inline__ void
656xf86WriteMmio8NB(__volatile__ void *base, const unsigned long offset,
657		 const unsigned int val)
658{
659	unsigned long addr = ((unsigned long)base) + offset;
660
661	__asm__ __volatile__("stba %0, [%1] %2"
662			     : /* No outputs */
663			     : "r" (val), "r" (addr), "i" (ASI_PL));
664}
665
666static __inline__ void
667xf86WriteMmio16BeNB(__volatile__ void *base, const unsigned long offset,
668		    const unsigned int val)
669{
670	unsigned long addr = ((unsigned long)base) + offset;
671
672	__asm__ __volatile__("sth %0, [%1]"
673			     : /* No outputs */
674			     : "r" (val), "r" (addr));
675}
676
677static __inline__ void
678xf86WriteMmio16LeNB(__volatile__ void *base, const unsigned long offset,
679		    const unsigned int val)
680{
681	unsigned long addr = ((unsigned long)base) + offset;
682
683	__asm__ __volatile__("stha %0, [%1] %2"
684			     : /* No outputs */
685			     : "r" (val), "r" (addr), "i" (ASI_PL));
686}
687
688static __inline__ void
689xf86WriteMmio32BeNB(__volatile__ void *base, const unsigned long offset,
690		    const unsigned int val)
691{
692	unsigned long addr = ((unsigned long)base) + offset;
693
694	__asm__ __volatile__("st %0, [%1]"
695			     : /* No outputs */
696			     : "r" (val), "r" (addr));
697}
698
699static __inline__ void
700xf86WriteMmio32LeNB(__volatile__ void *base, const unsigned long offset,
701		    const unsigned int val)
702{
703	unsigned long addr = ((unsigned long)base) + offset;
704
705	__asm__ __volatile__("sta %0, [%1] %2"
706			     : /* No outputs */
707			     : "r" (val), "r" (addr), "i" (ASI_PL));
708}
709
710#   elif defined(__mips__) || (defined(__arm32__) && !defined(__linux__))
711#    ifdef __arm32__
712#     define PORT_SIZE long
713#    else
714#     define PORT_SIZE short
715#    endif
716
717_X_EXPORT unsigned int IOPortBase;  /* Memory mapped I/O port area */
718
719static __inline__ void
720outb(unsigned PORT_SIZE port, unsigned char val)
721{
722	*(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
723}
724
725static __inline__ void
726outw(unsigned PORT_SIZE port, unsigned short val)
727{
728	*(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
729}
730
731static __inline__ void
732outl(unsigned PORT_SIZE port, unsigned int val)
733{
734	*(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
735}
736
737static __inline__ unsigned int
738inb(unsigned PORT_SIZE port)
739{
740	return *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase);
741}
742
743static __inline__ unsigned int
744inw(unsigned PORT_SIZE port)
745{
746	return *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase);
747}
748
749#if 0
750static __inline__ void stw_u(unsigned long val, unsigned short *p)
751{
752#    if defined(__GNUC__)
753	struct __una_u16 *ptr = (struct __una_u16 *) p;
754	ptr->x = val;
755#    else
756	unsigned short tmp = val;
757	memmove(p, &tmp, sizeof(*p));
758#    endif
759}
760
761#    define mem_barrier()         /* XXX: nop for now */
762#    define write_mem_barrier()   /* XXX: nop for now */
763
764#   elif defined(__mips__) || ((defined(__arm32__) || defined(__arm__)) && !defined(__linux__))
765#    if defined(__arm32__) || defined(__arm__)
766#     define PORT_SIZE long
767#    else
768#     define PORT_SIZE short
769#    endif
770
771unsigned int IOPortBase;  /* Memory mapped I/O port area */
772
773static __inline__ void
774outb(unsigned PORT_SIZE port, unsigned char val)
775{
776	*(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
777}
778
779static __inline__ void
780outw(unsigned PORT_SIZE port, unsigned short val)
781{
782	*(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
783}
784
785static __inline__ void
786outl(unsigned PORT_SIZE port, unsigned int val)
787{
788	*(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
789}
790
791static __inline__ unsigned int
792inb(unsigned PORT_SIZE port)
793{
794	return *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase);
795}
796
797static __inline__ unsigned int
798inw(unsigned PORT_SIZE port)
799{
800	return *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase);
801}
802#enif
803
804static __inline__ unsigned int
805inl(unsigned PORT_SIZE port)
806{
807	return *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase);
808}
809
810
811#    if defined(__mips__)
812#     ifdef linux	/* don't mess with other OSs */
813#       if X_BYTE_ORDER == X_BIG_ENDIAN
814static __inline__ unsigned int
815xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
816{
817	unsigned long addr = ((unsigned long)base) + offset;
818	unsigned int ret;
819
820	__asm__ __volatile__("lw %0, 0(%1)"
821			     : "=r" (ret)
822			     : "r" (addr));
823	return ret;
824}
825
826static __inline__ void
827xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
828		  const unsigned int val)
829{
830	unsigned long addr = ((unsigned long)base) + offset;
831
832	__asm__ __volatile__("sw %0, 0(%1)"
833			     : /* No outputs */
834			     : "r" (val), "r" (addr));
835}
836#      endif
837#     endif /* !linux */
838#    endif /* __mips__ */
839
840#if 0
841#    if defined(__arm32__) || defined(__arm__)
842#     define ldq_u(p)	(*((unsigned long  *)(p)))
843#     define ldl_u(p)	(*((unsigned int   *)(p)))
844#     define ldw_u(p)	(*((unsigned short *)(p)))
845#     define stq_u(v,p)	(*(unsigned long  *)(p)) = (v)
846#     define stl_u(v,p)	(*(unsigned int   *)(p)) = (v)
847#     define stw_u(v,p)	(*(unsigned short *)(p)) = (v)
848#     define mem_barrier()	/* NOP */
849#     define write_mem_barrier()	/* NOP */
850#    endif /* __arm32__ || __arm__ */
851#endif
852
853#   elif (defined(linux) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)) && defined(__powerpc__)
854
855#    ifndef MAP_FAILED
856#     define MAP_FAILED ((void *)-1)
857#    endif
858
859extern _X_EXPORT volatile unsigned char *ioBase;
860
861static __inline__ unsigned char
862xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
863{
864        register unsigned char val;
865        __asm__ __volatile__(
866                        "lbzx %0,%1,%2\n\t"
867                        "eieio"
868                        : "=r" (val)
869                        : "b" (base), "r" (offset),
870                        "m" (*((volatile unsigned char *)base+offset)));
871        return val;
872}
873
874static __inline__ unsigned short
875xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset)
876{
877        register unsigned short val;
878        __asm__ __volatile__(
879                        "lhzx %0,%1,%2\n\t"
880                        "eieio"
881                        : "=r" (val)
882                        : "b" (base), "r" (offset),
883                        "m" (*((volatile unsigned char *)base+offset)));
884        return val;
885}
886
887static __inline__ unsigned short
888xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset)
889{
890        register unsigned short val;
891        __asm__ __volatile__(
892                        "lhbrx %0,%1,%2\n\t"
893                        "eieio"
894                        : "=r" (val)
895                        : "b" (base), "r" (offset),
896                        "m" (*((volatile unsigned char *)base+offset)));
897        return val;
898}
899
900static __inline__ unsigned int
901xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
902{
903        register unsigned int val;
904        __asm__ __volatile__(
905                        "lwzx %0,%1,%2\n\t"
906                        "eieio"
907                        : "=r" (val)
908                        : "b" (base), "r" (offset),
909                        "m" (*((volatile unsigned char *)base+offset)));
910        return val;
911}
912
913static __inline__ unsigned int
914xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset)
915{
916        register unsigned int val;
917        __asm__ __volatile__(
918                        "lwbrx %0,%1,%2\n\t"
919                        "eieio"
920                        : "=r" (val)
921                        : "b" (base), "r" (offset),
922                        "m" (*((volatile unsigned char *)base+offset)));
923        return val;
924}
925
926static __inline__ void
927xf86WriteMmioNB8(__volatile__ void *base, const unsigned long offset,
928		 const unsigned char val)
929{
930        __asm__ __volatile__(
931                        "stbx %1,%2,%3\n\t"
932                        : "=m" (*((volatile unsigned char *)base+offset))
933                        : "r" (val), "b" (base), "r" (offset));
934}
935
936static __inline__ void
937xf86WriteMmioNB16Le(__volatile__ void *base, const unsigned long offset,
938		    const unsigned short val)
939{
940        __asm__ __volatile__(
941                        "sthbrx %1,%2,%3\n\t"
942                        : "=m" (*((volatile unsigned char *)base+offset))
943                        : "r" (val), "b" (base), "r" (offset));
944}
945
946static __inline__ void
947xf86WriteMmioNB16Be(__volatile__ void *base, const unsigned long offset,
948		    const unsigned short val)
949{
950        __asm__ __volatile__(
951                        "sthx %1,%2,%3\n\t"
952                        : "=m" (*((volatile unsigned char *)base+offset))
953                        : "r" (val), "b" (base), "r" (offset));
954}
955
956static __inline__ void
957xf86WriteMmioNB32Le(__volatile__ void *base, const unsigned long offset,
958		    const unsigned int val)
959{
960        __asm__ __volatile__(
961                        "stwbrx %1,%2,%3\n\t"
962                        : "=m" (*((volatile unsigned char *)base+offset))
963                        : "r" (val), "b" (base), "r" (offset));
964}
965
966static __inline__ void
967xf86WriteMmioNB32Be(__volatile__ void *base, const unsigned long offset,
968		    const unsigned int val)
969{
970        __asm__ __volatile__(
971                        "stwx %1,%2,%3\n\t"
972                        : "=m" (*((volatile unsigned char *)base+offset))
973                        : "r" (val), "b" (base), "r" (offset));
974}
975
976static __inline__ void
977xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
978               const unsigned char val)
979{
980        xf86WriteMmioNB8(base, offset, val);
981        eieio();
982}
983
984static __inline__ void
985xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset,
986                  const unsigned short val)
987{
988        xf86WriteMmioNB16Le(base, offset, val);
989        eieio();
990}
991
992static __inline__ void
993xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset,
994                  const unsigned short val)
995{
996        xf86WriteMmioNB16Be(base, offset, val);
997        eieio();
998}
999
1000static __inline__ void
1001xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset,
1002                  const unsigned int val)
1003{
1004        xf86WriteMmioNB32Le(base, offset, val);
1005        eieio();
1006}
1007
1008static __inline__ void
1009xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
1010                  const unsigned int val)
1011{
1012        xf86WriteMmioNB32Be(base, offset, val);
1013        eieio();
1014}
1015
1016
1017static __inline__ void
1018outb(unsigned short port, unsigned char value)
1019{
1020        if(ioBase == MAP_FAILED) return;
1021        xf86WriteMmio8((void *)ioBase, port, value);
1022}
1023
1024static __inline__ void
1025outw(unsigned short port, unsigned short value)
1026{
1027        if(ioBase == MAP_FAILED) return;
1028        xf86WriteMmio16Le((void *)ioBase, port, value);
1029}
1030
1031static __inline__ void
1032outl(unsigned short port, unsigned int value)
1033{
1034        if(ioBase == MAP_FAILED) return;
1035        xf86WriteMmio32Le((void *)ioBase, port, value);
1036}
1037
1038static __inline__ unsigned int
1039inb(unsigned short port)
1040{
1041        if(ioBase == MAP_FAILED) return 0;
1042        return xf86ReadMmio8((void *)ioBase, port);
1043}
1044
1045static __inline__ unsigned int
1046inw(unsigned short port)
1047{
1048        if(ioBase == MAP_FAILED) return 0;
1049        return xf86ReadMmio16Le((void *)ioBase, port);
1050}
1051
1052static __inline__ unsigned int
1053inl(unsigned short port)
1054{
1055        if(ioBase == MAP_FAILED) return 0;
1056        return xf86ReadMmio32Le((void *)ioBase, port);
1057}
1058
1059#elif defined(__arm__) && defined(__linux__)
1060
1061/* for Linux on ARM, we use the LIBC inx/outx routines */
1062/* note that the appropriate setup via "ioperm" needs to be done */
1063/*  *before* any inx/outx is done. */
1064
1065#include <sys/io.h>
1066
1067static __inline__ void
1068xf_outb(unsigned short port, unsigned char val)
1069{
1070    outb(val, port);
1071}
1072
1073static __inline__ void
1074xf_outw(unsigned short port, unsigned short val)
1075{
1076    outw(val, port);
1077}
1078
1079static __inline__ void
1080xf_outl(unsigned short port, unsigned int val)
1081{
1082    outl(val, port);
1083}
1084
1085#define outb xf_outb
1086#define outw xf_outw
1087#define outl xf_outl
1088
1089#   elif defined(__nds32__)
1090
1091/*
1092 * Assume all port access are aligned.  We need to revise this implementation
1093 * if there is unaligned port access.  For ldq_u, ldl_u, ldw_u, stq_u, stl_u and
1094 * stw_u, they are assumed unaligned.
1095 */
1096
1097#define barrier()		/* no barrier */
1098
1099#define PORT_SIZE long
1100
1101static __inline__ unsigned char
1102xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
1103{
1104	return *(volatile unsigned char *)((unsigned char *)base + offset) ;
1105}
1106
1107static __inline__ void
1108xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
1109	       const unsigned int val)
1110{
1111	*(volatile unsigned char *)((unsigned char *)base + offset) = val ;
1112	barrier();
1113}
1114
1115static __inline__ void
1116xf86WriteMmio8NB(__volatile__ void *base, const unsigned long offset,
1117		 const unsigned int val)
1118{
1119	*(volatile unsigned char *)((unsigned char *)base + offset) = val ;
1120}
1121
1122static __inline__ unsigned short
1123xf86ReadMmio16Swap(__volatile__ void *base, const unsigned long offset)
1124{
1125	unsigned long addr = ((unsigned long)base) + offset;
1126	unsigned short ret;
1127
1128	__asm__ __volatile__(
1129	           "lhi %0, [%1];\n\t"
1130	           "wsbh %0, %0;\n\t"
1131			     : "=r" (ret)
1132			     : "r" (addr));
1133	return ret;
1134}
1135
1136static __inline__ unsigned short
1137xf86ReadMmio16(__volatile__ void *base, const unsigned long offset)
1138{
1139	return *(volatile unsigned short *)((char *)base + offset) ;
1140}
1141
1142static __inline__ void
1143xf86WriteMmio16Swap(__volatile__ void *base, const unsigned long offset,
1144		  const unsigned int val)
1145{
1146	unsigned long addr = ((unsigned long)base) + offset;
1147
1148	__asm__ __volatile__(
1149	           "wsbh %0, %0;\n\t"
1150	           "shi %0, [%1];\n\t"
1151			     : /* No outputs */
1152			     : "r" (val), "r" (addr));
1153	barrier();
1154}
1155
1156static __inline__ void
1157xf86WriteMmio16(__volatile__ void *base, const unsigned long offset,
1158		  const unsigned int val)
1159{
1160	*(volatile unsigned short *)((unsigned char *)base + offset) = val ;
1161	barrier();
1162}
1163
1164static __inline__ void
1165xf86WriteMmio16SwapNB(__volatile__ void *base, const unsigned long offset,
1166		    const unsigned int val)
1167{
1168	unsigned long addr = ((unsigned long)base) + offset;
1169
1170	__asm__ __volatile__(
1171	           "wsbh %0, %0;\n\t"
1172	           "shi %0, [%1];\n\t"
1173			     : /* No outputs */
1174			     : "r" (val), "r" (addr));
1175}
1176
1177static __inline__ void
1178xf86WriteMmio16NB(__volatile__ void *base, const unsigned long offset,
1179		    const unsigned int val)
1180{
1181	*(volatile unsigned short *)((unsigned char *)base + offset) = val ;
1182}
1183
1184static __inline__ unsigned int
1185xf86ReadMmio32Swap(__volatile__ void *base, const unsigned long offset)
1186{
1187	unsigned long addr = ((unsigned long)base) + offset;
1188	unsigned int ret;
1189
1190	__asm__ __volatile__(
1191	           "lwi %0, [%1];\n\t"
1192	           "wsbh %0, %0;\n\t"
1193				  "rotri %0, %0, 16;\n\t"
1194			     : "=r" (ret)
1195			     : "r" (addr));
1196	return ret;
1197}
1198
1199static __inline__ unsigned int
1200xf86ReadMmio32(__volatile__ void *base, const unsigned long offset)
1201{
1202	return *(volatile unsigned int *)((unsigned char *)base + offset) ;
1203}
1204
1205static __inline__ void
1206xf86WriteMmio32Swap(__volatile__ void *base, const unsigned long offset,
1207		  const unsigned int val)
1208{
1209	unsigned long addr = ((unsigned long)base) + offset;
1210
1211	__asm__ __volatile__(
1212	           "wsbh %0, %0;\n\t"
1213	           "rotri %0, %0, 16;\n\t"
1214				  "swi %0, [%1];\n\t"
1215			     : /* No outputs */
1216			     : "r" (val), "r" (addr));
1217	barrier();
1218}
1219
1220static __inline__ void
1221xf86WriteMmio32(__volatile__ void *base, const unsigned long offset,
1222		  const unsigned int val)
1223{
1224	*(volatile unsigned int *)((unsigned char *)base + offset) = val ;
1225	barrier();
1226}
1227
1228static __inline__ void
1229xf86WriteMmio32SwapNB(__volatile__ void *base, const unsigned long offset,
1230		    const unsigned int val)
1231{
1232	unsigned long addr = ((unsigned long)base) + offset;
1233
1234	__asm__ __volatile__(
1235	           "wsbh %0, %0;\n\t"
1236				  "rotri %0, %0, 16;\n\t"
1237				  "swi %0, [%1];\n\t"
1238			     : /* No outputs */
1239			     : "r" (val), "r" (addr));
1240}
1241
1242static __inline__ void
1243xf86WriteMmio32NB(__volatile__ void *base, const unsigned long offset,
1244		    const unsigned int val)
1245{
1246	*(volatile unsigned int *)((unsigned char *)base + offset) = val ;
1247}
1248
1249#    if defined(NDS32_MMIO_SWAP)
1250static __inline__ void
1251outb(unsigned PORT_SIZE port, unsigned char val)
1252{
1253   xf86WriteMmio8(IOPortBase, port, val);
1254}
1255
1256static __inline__ void
1257outw(unsigned PORT_SIZE port, unsigned short val)
1258{
1259   xf86WriteMmio16Swap(IOPortBase, port, val);
1260}
1261
1262static __inline__ void
1263outl(unsigned PORT_SIZE port, unsigned int val)
1264{
1265   xf86WriteMmio32Swap(IOPortBase, port, val);
1266}
1267
1268static __inline__ unsigned int
1269inb(unsigned PORT_SIZE port)
1270{
1271   return xf86ReadMmio8(IOPortBase, port);
1272}
1273
1274static __inline__ unsigned int
1275inw(unsigned PORT_SIZE port)
1276{
1277   return xf86ReadMmio16Swap(IOPortBase, port);
1278}
1279
1280static __inline__ unsigned int
1281inl(unsigned PORT_SIZE port)
1282{
1283   return xf86ReadMmio32Swap(IOPortBase, port);
1284}
1285
1286static __inline__ unsigned long ldq_u(unsigned long *p)
1287{
1288	unsigned long addr = (unsigned long)p;
1289	unsigned int ret;
1290
1291	__asm__ __volatile__(
1292				  "lmw.bi %0, [%1], %0, 0;\n\t"
1293	           "wsbh %0, %0;\n\t"
1294				  "rotri %0, %0, 16;\n\t"
1295			     : "=r" (ret)
1296			     : "r" (addr));
1297	return ret;
1298}
1299
1300static __inline__ unsigned long ldl_u(unsigned int *p)
1301{
1302	unsigned long addr = (unsigned long)p;
1303	unsigned int ret;
1304
1305	__asm__ __volatile__(
1306				  "lmw.bi %0, [%1], %0, 0;\n\t"
1307	           "wsbh %0, %0;\n\t"
1308				  "rotri %0, %0, 16;\n\t"
1309			     : "=r" (ret)
1310			     : "r" (addr));
1311	return ret;
1312}
1313
1314static __inline__ void stq_u(unsigned long val, unsigned long *p)
1315{
1316	unsigned long addr = (unsigned long)p;
1317
1318	__asm__ __volatile__(
1319	           "wsbh %0, %0;\n\t"
1320				  "rotri %0, %0, 16;\n\t"
1321				  "smw.bi %0, [%1], %0, 0;\n\t"
1322			     : /* No outputs */
1323			     : "r" (val), "r" (addr));
1324}
1325
1326static __inline__ void stl_u(unsigned long val, unsigned int *p)
1327{
1328	unsigned long addr = (unsigned long)p;
1329
1330	__asm__ __volatile__(
1331	           "wsbh %0, %0;\n\t"
1332				  "rotri %0, %0, 16;\n\t"
1333				  "smw.bi %0, [%1], %0, 0;\n\t"
1334			     : /* No outputs */
1335			     : "r" (val), "r" (addr));
1336}
1337
1338#    else /* !NDS32_MMIO_SWAP */
1339static __inline__ void
1340outb(unsigned PORT_SIZE port, unsigned char val)
1341{
1342	*(volatile unsigned char*)(((unsigned PORT_SIZE)(port))) = val;
1343	barrier();
1344}
1345
1346static __inline__ void
1347outw(unsigned PORT_SIZE port, unsigned short val)
1348{
1349	*(volatile unsigned short*)(((unsigned PORT_SIZE)(port))) = val;
1350	barrier();
1351}
1352
1353static __inline__ void
1354outl(unsigned PORT_SIZE port, unsigned int val)
1355{
1356	*(volatile unsigned int*)(((unsigned PORT_SIZE)(port))) = val;
1357	barrier();
1358}
1359static __inline__ unsigned int
1360inb(unsigned PORT_SIZE port)
1361{
1362	return *(volatile unsigned char*)(((unsigned PORT_SIZE)(port)));
1363}
1364
1365static __inline__ unsigned int
1366inw(unsigned PORT_SIZE port)
1367{
1368	return *(volatile unsigned short*)(((unsigned PORT_SIZE)(port)));
1369}
1370
1371static __inline__ unsigned int
1372inl(unsigned PORT_SIZE port)
1373{
1374	return *(volatile unsigned int*)(((unsigned PORT_SIZE)(port)));
1375}
1376
1377static __inline__ unsigned long ldq_u(unsigned long *p)
1378{
1379	unsigned long addr = (unsigned long)p;
1380	unsigned int ret;
1381
1382	__asm__ __volatile__(
1383				  "lmw.bi %0, [%1], %0, 0;\n\t"
1384			     : "=r" (ret)
1385			     : "r" (addr));
1386	return ret;
1387}
1388
1389static __inline__ unsigned long ldl_u(unsigned int *p)
1390{
1391	unsigned long addr = (unsigned long)p;
1392	unsigned int ret;
1393
1394	__asm__ __volatile__(
1395				  "lmw.bi %0, [%1], %0, 0;\n\t"
1396			     : "=r" (ret)
1397			     : "r" (addr));
1398	return ret;
1399}
1400
1401
1402static __inline__ void stq_u(unsigned long val, unsigned long *p)
1403{
1404	unsigned long addr = (unsigned long)p;
1405
1406	__asm__ __volatile__(
1407				  "smw.bi %0, [%1], %0, 0;\n\t"
1408			     : /* No outputs */
1409			     : "r" (val), "r" (addr));
1410}
1411
1412static __inline__ void stl_u(unsigned long val, unsigned int *p)
1413{
1414	unsigned long addr = (unsigned long)p;
1415
1416	__asm__ __volatile__(
1417				  "smw.bi %0, [%1], %0, 0;\n\t"
1418			     : /* No outputs */
1419			     : "r" (val), "r" (addr));
1420}
1421#    endif /* NDS32_MMIO_SWAP */
1422
1423#    if (((X_BYTE_ORDER == X_BIG_ENDIAN) && !defined(NDS32_MMIO_SWAP)) || ((X_BYTE_ORDER != X_BIG_ENDIAN) && defined(NDS32_MMIO_SWAP)))
1424#    define ldw_u(p)	((*(unsigned char *)(p)) << 8 | \
1425			(*((unsigned char *)(p)+1)))
1426#    define stw_u(v,p)	(*(unsigned char *)(p)) = ((v) >> 8); \
1427				(*((unsigned char *)(p)+1)) = (v)
1428#    else
1429#    define ldw_u(p)	((*(unsigned char *)(p)) | \
1430			(*((unsigned char *)(p)+1)<<8))
1431#    define stw_u(v,p)	(*(unsigned char *)(p)) = (v); \
1432				(*((unsigned char *)(p)+1)) = ((v) >> 8)
1433#    endif
1434
1435#    define mem_barrier()         /* XXX: nop for now */
1436#    define write_mem_barrier()   /* XXX: nop for now */
1437
1438#   else /* ix86 */
1439
1440#    if !defined(__SUNPRO_C)
1441#    if !defined(FAKEIT) && !defined(__mc68000__) && !defined(__arm__) && !defined(__sh__) && !defined(__hppa__) && !defined(__s390__) && !defined(__m32r__)
1442#     ifdef GCCUSESGAS
1443
1444/*
1445 * If gcc uses gas rather than the native assembler, the syntax of these
1446 * inlines has to be different.		DHD
1447 */
1448
1449static __inline__ void
1450outb(unsigned short port, unsigned char val)
1451{
1452   __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
1453}
1454
1455
1456static __inline__ void
1457outw(unsigned short port, unsigned short val)
1458{
1459   __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
1460}
1461
1462static __inline__ void
1463outl(unsigned short port, unsigned int val)
1464{
1465   __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
1466}
1467
1468static __inline__ unsigned int
1469inb(unsigned short port)
1470{
1471   unsigned char ret;
1472   __asm__ __volatile__("inb %1,%0" :
1473       "=a" (ret) :
1474       "d" (port));
1475   return ret;
1476}
1477
1478static __inline__ unsigned int
1479inw(unsigned short port)
1480{
1481   unsigned short ret;
1482   __asm__ __volatile__("inw %1,%0" :
1483       "=a" (ret) :
1484       "d" (port));
1485   return ret;
1486}
1487
1488static __inline__ unsigned int
1489inl(unsigned short port)
1490{
1491   unsigned int ret;
1492   __asm__ __volatile__("inl %1,%0" :
1493       "=a" (ret) :
1494       "d" (port));
1495   return ret;
1496}
1497
1498#     else	/* GCCUSESGAS */
1499
1500static __inline__ void
1501outb(unsigned short port, unsigned char val)
1502{
1503  __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port));
1504}
1505
1506static __inline__ void
1507outw(unsigned short port, unsigned short val)
1508{
1509  __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port));
1510}
1511
1512static __inline__ void
1513outl(unsigned short port, unsigned int val)
1514{
1515  __asm__ __volatile__("out%L0 (%1)" : :"a" (val), "d" (port));
1516}
1517
1518static __inline__ unsigned int
1519inb(unsigned short port)
1520{
1521  unsigned char ret;
1522  __asm__ __volatile__("in%B0 (%1)" :
1523		   "=a" (ret) :
1524		   "d" (port));
1525  return ret;
1526}
1527
1528static __inline__ unsigned int
1529inw(unsigned short port)
1530{
1531  unsigned short ret;
1532  __asm__ __volatile__("in%W0 (%1)" :
1533		   "=a" (ret) :
1534		   "d" (port));
1535  return ret;
1536}
1537
1538static __inline__ unsigned int
1539inl(unsigned short port)
1540{
1541  unsigned int ret;
1542  __asm__ __volatile__("in%L0 (%1)" :
1543                   "=a" (ret) :
1544                   "d" (port));
1545  return ret;
1546}
1547
1548#     endif /* GCCUSESGAS */
1549
1550#    else /* !defined(FAKEIT) && !defined(__mc68000__)  && !defined(__arm__) && !defined(__sh__) && !defined(__hppa__) && !defined(__m32r__) */
1551
1552static __inline__ void
1553outb(unsigned short port, unsigned char val)
1554{
1555}
1556
1557static __inline__ void
1558outw(unsigned short port, unsigned short val)
1559{
1560}
1561
1562static __inline__ void
1563outl(unsigned short port, unsigned int val)
1564{
1565}
1566
1567static __inline__ unsigned int
1568inb(unsigned short port)
1569{
1570  return 0;
1571}
1572
1573static __inline__ unsigned int
1574inw(unsigned short port)
1575{
1576  return 0;
1577}
1578
1579static __inline__ unsigned int
1580inl(unsigned short port)
1581{
1582  return 0;
1583}
1584
1585#    endif /* FAKEIT */
1586#    endif /* __SUNPRO_C */
1587
1588#   endif /* ix86 */
1589
1590#  else /* !GNUC */
1591#    if defined(__STDC__) && (__STDC__ == 1)
1592#     ifndef asm
1593#      define asm __asm
1594#     endif
1595#    endif
1596#    ifndef SCO325
1597#     if defined(__UNIXWARE__)
1598#     /* avoid including <sys/types.h> for <sys/inline.h> on UnixWare */
1599#      define ushort unsigned short
1600#      define ushort_t unsigned short
1601#      define ulong unsigned long
1602#      define ulong_t unsigned long
1603#      define uint_t unsigned int
1604#      define uchar_t unsigned char
1605#     endif /* __UNIXWARE__ */
1606#     if !defined(__SUNPRO_C)
1607#      include <sys/inline.h>
1608#     endif
1609#    else
1610#     include "scoasm.h"
1611#    endif
1612#    if !defined(__HIGHC__) && !defined(__SUNPRO_C) || \
1613	defined(__USLC__)
1614#     pragma asm partial_optimization outl
1615#     pragma asm partial_optimization outw
1616#     pragma asm partial_optimization outb
1617#     pragma asm partial_optimization inl
1618#     pragma asm partial_optimization inw
1619#     pragma asm partial_optimization inb
1620#    endif
1621#  endif /* __GNUC__ */
1622
1623# endif /* NO_INLINE */
1624
1625# ifdef __alpha__
1626/* entry points for Mmio memory access routines */
1627extern _X_EXPORT int (*xf86ReadMmio8)(void *, unsigned long);
1628extern _X_EXPORT int (*xf86ReadMmio16)(void *, unsigned long);
1629#  ifndef STANDALONE_MMIO
1630extern _X_EXPORT int (*xf86ReadMmio32)(void *, unsigned long);
1631#  else
1632/* Some DRI 3D drivers need MMIO_IN32. */
1633static __inline__ int
1634xf86ReadMmio32(void *Base, unsigned long Offset)
1635{
1636	mem_barrier();
1637	return *(volatile unsigned int*)((unsigned long)Base+(Offset));
1638}
1639#  endif
1640extern _X_EXPORT void (*xf86WriteMmio8)(int, void *, unsigned long);
1641extern _X_EXPORT void (*xf86WriteMmio16)(int, void *, unsigned long);
1642extern _X_EXPORT void (*xf86WriteMmio32)(int, void *, unsigned long);
1643extern _X_EXPORT void (*xf86WriteMmioNB8)(int, void *, unsigned long);
1644extern _X_EXPORT void (*xf86WriteMmioNB16)(int, void *, unsigned long);
1645extern _X_EXPORT void (*xf86WriteMmioNB32)(int, void *, unsigned long);
1646extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, int);
1647extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int);
1648
1649/* Some macros to hide the system dependencies for MMIO accesses */
1650/* Changed to kill noise generated by gcc's -Wcast-align */
1651#  define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset)
1652#  define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset)
1653#  ifndef STANDALONE_MMIO
1654#   define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset)
1655#  else
1656#   define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset)
1657#  endif
1658
1659#  define MMIO_OUT32(base, offset, val) \
1660    do { \
1661	write_mem_barrier(); \
1662	*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \
1663    } while (0)
1664#  define MMIO_ONB32(base, offset, val) \
1665	*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
1666
1667#  define MMIO_OUT8(base, offset, val) \
1668    (*xf86WriteMmio8)((CARD8)(val), base, offset)
1669#  define MMIO_OUT16(base, offset, val) \
1670    (*xf86WriteMmio16)((CARD16)(val), base, offset)
1671#  define MMIO_ONB8(base, offset, val) \
1672    (*xf86WriteMmioNB8)((CARD8)(val), base, offset)
1673#  define MMIO_ONB16(base, offset, val) \
1674    (*xf86WriteMmioNB16)((CARD16)(val), base, offset)
1675#  define MMIO_MOVE32(base, offset, val) \
1676    MMIO_OUT32(base, offset, val)
1677
1678# elif defined(__powerpc__)
1679 /*
1680  * we provide byteswapping and no byteswapping functions here
1681  * with byteswapping as default,
1682  * drivers that don't need byteswapping should define PPC_MMIO_IS_BE
1683  */
1684#  define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
1685#  define MMIO_OUT8(base, offset, val) \
1686    xf86WriteMmio8(base, offset, (CARD8)(val))
1687#  define MMIO_ONB8(base, offset, val) \
1688    xf86WriteMmioNB8(base, offset, (CARD8)(val))
1689
1690#  if defined(PPC_MMIO_IS_BE) /* No byteswapping */
1691#   define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset)
1692#   define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset)
1693#   define MMIO_OUT16(base, offset, val) \
1694    xf86WriteMmio16Be(base, offset, (CARD16)(val))
1695#   define MMIO_OUT32(base, offset, val) \
1696    xf86WriteMmio32Be(base, offset, (CARD32)(val))
1697#   define MMIO_ONB16(base, offset, val) \
1698    xf86WriteMmioNB16Be(base, offset, (CARD16)(val))
1699#   define MMIO_ONB32(base, offset, val) \
1700    xf86WriteMmioNB32Be(base, offset, (CARD32)(val))
1701#  else /* byteswapping is the default */
1702#   define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset)
1703#   define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset)
1704#   define MMIO_OUT16(base, offset, val) \
1705     xf86WriteMmio16Le(base, offset, (CARD16)(val))
1706#   define MMIO_OUT32(base, offset, val) \
1707     xf86WriteMmio32Le(base, offset, (CARD32)(val))
1708#   define MMIO_ONB16(base, offset, val) \
1709     xf86WriteMmioNB16Le(base, offset, (CARD16)(val))
1710#   define MMIO_ONB32(base, offset, val) \
1711     xf86WriteMmioNB32Le(base, offset, (CARD32)(val))
1712#  endif
1713
1714#  define MMIO_MOVE32(base, offset, val) \
1715       xf86WriteMmio32Be(base, offset, (CARD32)(val))
1716
1717# elif defined(__sparc__) || defined(sparc) || defined(__sparc)
1718 /*
1719  * Like powerpc, we provide byteswapping and no byteswapping functions
1720  * here with byteswapping as default, drivers that don't need byteswapping
1721  * should define SPARC_MMIO_IS_BE (perhaps create a generic macro so that we
1722  * do not need to use PPC_MMIO_IS_BE and the sparc one in all the same places
1723  * of drivers?).
1724  */
1725#  define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
1726#  define MMIO_OUT8(base, offset, val) \
1727    xf86WriteMmio8(base, offset, (CARD8)(val))
1728#  define MMIO_ONB8(base, offset, val) \
1729    xf86WriteMmio8NB(base, offset, (CARD8)(val))
1730
1731#  if defined(SPARC_MMIO_IS_BE) /* No byteswapping */
1732#   define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset)
1733#   define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset)
1734#   define MMIO_OUT16(base, offset, val) \
1735     xf86WriteMmio16Be(base, offset, (CARD16)(val))
1736#   define MMIO_OUT32(base, offset, val) \
1737     xf86WriteMmio32Be(base, offset, (CARD32)(val))
1738#   define MMIO_ONB16(base, offset, val) \
1739     xf86WriteMmio16BeNB(base, offset, (CARD16)(val))
1740#   define MMIO_ONB32(base, offset, val) \
1741     xf86WriteMmio32BeNB(base, offset, (CARD32)(val))
1742#  else /* byteswapping is the default */
1743#   define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset)
1744#   define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset)
1745#   define MMIO_OUT16(base, offset, val) \
1746     xf86WriteMmio16Le(base, offset, (CARD16)(val))
1747#   define MMIO_OUT32(base, offset, val) \
1748     xf86WriteMmio32Le(base, offset, (CARD32)(val))
1749#   define MMIO_ONB16(base, offset, val) \
1750     xf86WriteMmio16LeNB(base, offset, (CARD16)(val))
1751#   define MMIO_ONB32(base, offset, val) \
1752     xf86WriteMmio32LeNB(base, offset, (CARD32)(val))
1753#  endif
1754
1755#  define MMIO_MOVE32(base, offset, val) \
1756       xf86WriteMmio32Be(base, offset, (CARD32)(val))
1757
1758# elif defined(__nds32__)
1759 /*
1760  * we provide byteswapping and no byteswapping functions here
1761  * with no byteswapping as default; when endianness of CPU core
1762  * and I/O devices don't match, byte swapping is necessary
1763  * drivers that need byteswapping should define NDS32_MMIO_SWAP
1764  */
1765#  define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
1766#  define MMIO_OUT8(base, offset, val) \
1767    xf86WriteMmio8(base, offset, (CARD8)(val))
1768#  define MMIO_ONB8(base, offset, val) \
1769    xf86WriteMmioNB8(base, offset, (CARD8)(val))
1770
1771#  if defined(NDS32_MMIO_SWAP) /* byteswapping */
1772#   define MMIO_IN16(base, offset) xf86ReadMmio16Swap(base, offset)
1773#   define MMIO_IN32(base, offset) xf86ReadMmio32Swap(base, offset)
1774#   define MMIO_OUT16(base, offset, val) \
1775    xf86WriteMmio16Swap(base, offset, (CARD16)(val))
1776#   define MMIO_OUT32(base, offset, val) \
1777    xf86WriteMmio32Swap(base, offset, (CARD32)(val))
1778#   define MMIO_ONB16(base, offset, val) \
1779    xf86WriteMmioNB16Swap(base, offset, (CARD16)(val))
1780#   define MMIO_ONB32(base, offset, val) \
1781    xf86WriteMmioNB32Swap(base, offset, (CARD32)(val))
1782#  else /* no byteswapping is the default */
1783#   define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset)
1784#   define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset)
1785#   define MMIO_OUT16(base, offset, val) \
1786     xf86WriteMmio16(base, offset, (CARD16)(val))
1787#   define MMIO_OUT32(base, offset, val) \
1788     xf86WriteMmio32(base, offset, (CARD32)(val))
1789#   define MMIO_ONB16(base, offset, val) \
1790     xf86WriteMmioNB16(base, offset, (CARD16)(val))
1791#   define MMIO_ONB32(base, offset, val) \
1792     xf86WriteMmioNB32(base, offset, (CARD32)(val))
1793#  endif
1794
1795#  define MMIO_MOVE32(base, offset, val) \
1796       xf86WriteMmio32(base, offset, (CARD32)(val))
1797
1798#ifdef N1213_HC /* for NDS32 N1213 hardcore */
1799static __inline__ void nds32_flush_icache(char *addr)
1800{
1801	__asm__ volatile (
1802		"isync %0;"
1803		"msync;"
1804		"isb;"
1805		"cctl %0,L1I_VA_INVAL;"
1806		"isb;"
1807		: : "r"(addr) : "memory");
1808}
1809#else
1810static __inline__ void nds32_flush_icache(char *addr)
1811{
1812	__asm__ volatile (
1813		"isync %0;"
1814		"isb;"
1815		: : "r"(addr) : "memory");
1816}
1817#endif
1818
1819# else /* !__alpha__ && !__powerpc__ && !__sparc__ */
1820
1821#  define MMIO_IN8(base, offset) \
1822	*(volatile CARD8 *)(((CARD8*)(base)) + (offset))
1823#  define MMIO_IN16(base, offset) \
1824	*(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset))
1825#  define MMIO_IN32(base, offset) \
1826	*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
1827#  define MMIO_OUT8(base, offset, val) \
1828	*(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val)
1829#  define MMIO_OUT16(base, offset, val) \
1830	*(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
1831#  define MMIO_OUT32(base, offset, val) \
1832	*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
1833#  define MMIO_ONB8(base, offset, val) MMIO_OUT8(base, offset, val)
1834#  define MMIO_ONB16(base, offset, val) MMIO_OUT16(base, offset, val)
1835#  define MMIO_ONB32(base, offset, val) MMIO_OUT32(base, offset, val)
1836
1837#  define MMIO_MOVE32(base, offset, val) MMIO_OUT32(base, offset, val)
1838
1839# endif /* __alpha__ */
1840
1841/*
1842 * With Intel, the version in os-support/misc/SlowBcopy.s is used.
1843 * This avoids port I/O during the copy (which causes problems with
1844 * some hardware).
1845 */
1846# ifdef __alpha__
1847#  define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count)
1848#  define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count)
1849# else /* __alpha__ */
1850#  define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count)
1851#  define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count)
1852# endif /* __alpha__ */
1853
1854#endif /* _COMPILER_H */
1855