master
  1/*	$NetBSD: byte_swap.h,v 1.16 2017/01/17 11:08:50 rin Exp $	*/
  2
  3/*-
  4 * Copyright (c) 1997, 1999, 2002 The NetBSD Foundation, Inc.
  5 * All rights reserved.
  6 *
  7 * This code is derived from software contributed to The NetBSD Foundation
  8 * by Charles M. Hannum, Neil A. Carson, and Jason R. Thorpe.
  9 *
 10 * Redistribution and use in source and binary forms, with or without
 11 * modification, are permitted provided that the following conditions
 12 * are met:
 13 * 1. Redistributions of source code must retain the above copyright
 14 *    notice, this list of conditions and the following disclaimer.
 15 * 2. Redistributions in binary form must reproduce the above copyright
 16 *    notice, this list of conditions and the following disclaimer in the
 17 *    documentation and/or other materials provided with the distribution.
 18 *
 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 29 * POSSIBILITY OF SUCH DAMAGE.
 30 */
 31
 32#ifndef _ARM_BYTE_SWAP_H_
 33#define	_ARM_BYTE_SWAP_H_
 34
 35#ifdef _LOCORE
 36
 37#if defined(_ARM_ARCH_6) || defined(_ARM_ARCH_7)
 38
 39#define	BSWAP16(_src, _dst, _tmp)		\
 40	rev16	_dst, _src
 41#define	BSWAP32(_src, _dst, _tmp)		\
 42	rev	_dst, _src
 43
 44#else
 45
 46#define	BSWAP16(_src, _dst, _tmp)		\
 47	mov	_tmp, _src, ror #8		;\
 48	orr	_tmp, _tmp, _tmp, lsr #16	;\
 49	bic	_dst, _tmp, _tmp, lsl #16
 50
 51#define	BSWAP32(_src, _dst, _tmp)		\
 52	eor	_tmp, _src, _src, ror #16	;\
 53	bic	_tmp, _tmp, #0x00FF0000		;\
 54	mov	_dst, _src, ror #8		;\
 55	eor	_dst, _dst, _tmp, lsr #8
 56
 57#endif
 58
 59
 60#else
 61
 62#ifdef __GNUC__
 63#include <sys/types.h>
 64__BEGIN_DECLS
 65
 66#define	__BYTE_SWAP_U32_VARIABLE __byte_swap_u32_variable
 67static __inline uint32_t
 68__byte_swap_u32_variable(uint32_t v)
 69{
 70	uint32_t t1;
 71
 72#ifdef _ARM_ARCH_6
 73	if (!__builtin_constant_p(v)) {
 74		__asm("rev\t%0, %1" : "=r" (v) : "0" (v));
 75		return v;
 76	}
 77#endif
 78
 79	t1 = v ^ ((v << 16) | (v >> 16));
 80	t1 &= 0xff00ffffU;
 81	v = (v >> 8) | (v << 24);
 82	v ^= (t1 >> 8);
 83
 84	return v;
 85}
 86
 87#define	__BYTE_SWAP_U16_VARIABLE __byte_swap_u16_variable
 88static __inline uint16_t
 89__byte_swap_u16_variable(uint16_t v)
 90{
 91
 92#ifdef _ARM_ARCH_6
 93	if (!__builtin_constant_p(v)) {
 94		uint32_t v32 = v;
 95		__asm("rev16\t%0, %1" : "=r" (v32) : "0" (v32));
 96		return (uint16_t)v32;
 97	}
 98#elif !defined(__thumb__) && 0	/* gcc produces decent code for this */
 99	if (!__builtin_constant_p(v)) {
100		uint32_t v0 = v;
101		__asm volatile(
102			"mov	%0, %1, ror #8\n"
103			"orr	%0, %0, %0, lsr #16\n"
104			"bic	%0, %0, %0, lsl #16"
105		: "=&r" (v0)
106		: "0" (v0));
107		return (uint16_t)v0;
108	}
109#endif
110	v &= 0xffff;
111	v = (uint16_t)((v >> 8) | (v << 8));
112
113	return v;
114}
115
116__END_DECLS
117#endif
118
119#endif	/* _LOCORE */
120
121#endif /* _ARM_BYTE_SWAP_H_ */