1*b31d312cSrin /* $NetBSD: byte_swap.h,v 1.16 2017/01/17 11:08:50 rin Exp $ */
2da5ef20bSthorpej
3da5ef20bSthorpej /*-
4da5ef20bSthorpej * Copyright (c) 1997, 1999, 2002 The NetBSD Foundation, Inc.
5da5ef20bSthorpej * All rights reserved.
6da5ef20bSthorpej *
7da5ef20bSthorpej * This code is derived from software contributed to The NetBSD Foundation
8da5ef20bSthorpej * by Charles M. Hannum, Neil A. Carson, and Jason R. Thorpe.
9da5ef20bSthorpej *
10da5ef20bSthorpej * Redistribution and use in source and binary forms, with or without
11da5ef20bSthorpej * modification, are permitted provided that the following conditions
12da5ef20bSthorpej * are met:
13da5ef20bSthorpej * 1. Redistributions of source code must retain the above copyright
14da5ef20bSthorpej * notice, this list of conditions and the following disclaimer.
15da5ef20bSthorpej * 2. Redistributions in binary form must reproduce the above copyright
16da5ef20bSthorpej * notice, this list of conditions and the following disclaimer in the
17da5ef20bSthorpej * documentation and/or other materials provided with the distribution.
18da5ef20bSthorpej *
19da5ef20bSthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20da5ef20bSthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21da5ef20bSthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22da5ef20bSthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23da5ef20bSthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24da5ef20bSthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25da5ef20bSthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26da5ef20bSthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27da5ef20bSthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28da5ef20bSthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29da5ef20bSthorpej * POSSIBILITY OF SUCH DAMAGE.
30da5ef20bSthorpej */
31da5ef20bSthorpej
32da5ef20bSthorpej #ifndef _ARM_BYTE_SWAP_H_
33da5ef20bSthorpej #define _ARM_BYTE_SWAP_H_
34da5ef20bSthorpej
3567e5bbcbSmatt #ifdef _LOCORE
3667e5bbcbSmatt
374777b0bfSmatt #if defined(_ARM_ARCH_6) || defined(_ARM_ARCH_7)
3867e5bbcbSmatt
3967e5bbcbSmatt #define BSWAP16(_src, _dst, _tmp) \
4067e5bbcbSmatt rev16 _dst, _src
4167e5bbcbSmatt #define BSWAP32(_src, _dst, _tmp) \
4267e5bbcbSmatt rev _dst, _src
4367e5bbcbSmatt
4467e5bbcbSmatt #else
4567e5bbcbSmatt
4667e5bbcbSmatt #define BSWAP16(_src, _dst, _tmp) \
4767e5bbcbSmatt mov _tmp, _src, ror #8 ;\
4867e5bbcbSmatt orr _tmp, _tmp, _tmp, lsr #16 ;\
4967e5bbcbSmatt bic _dst, _tmp, _tmp, lsl #16
5067e5bbcbSmatt
5167e5bbcbSmatt #define BSWAP32(_src, _dst, _tmp) \
5267e5bbcbSmatt eor _tmp, _src, _src, ror #16 ;\
5367e5bbcbSmatt bic _tmp, _tmp, #0x00FF0000 ;\
5467e5bbcbSmatt mov _dst, _src, ror #8 ;\
5567e5bbcbSmatt eor _dst, _dst, _tmp, lsr #8
5667e5bbcbSmatt
5767e5bbcbSmatt #endif
5867e5bbcbSmatt
5967e5bbcbSmatt
6067e5bbcbSmatt #else
6167e5bbcbSmatt
62c88ae1f9Sdsl #ifdef __GNUC__
63da5ef20bSthorpej #include <sys/types.h>
64c88ae1f9Sdsl __BEGIN_DECLS
65da5ef20bSthorpej
66c88ae1f9Sdsl #define __BYTE_SWAP_U32_VARIABLE __byte_swap_u32_variable
67c88ae1f9Sdsl static __inline uint32_t
__byte_swap_u32_variable(uint32_t v)68c88ae1f9Sdsl __byte_swap_u32_variable(uint32_t v)
69da5ef20bSthorpej {
70c88ae1f9Sdsl uint32_t t1;
71da5ef20bSthorpej
72dd02d63dSmatt #ifdef _ARM_ARCH_6
73dd02d63dSmatt if (!__builtin_constant_p(v)) {
74dd02d63dSmatt __asm("rev\t%0, %1" : "=r" (v) : "0" (v));
75dd02d63dSmatt return v;
76dd02d63dSmatt }
77dd02d63dSmatt #endif
78dd02d63dSmatt
79201e41fcSthorpej t1 = v ^ ((v << 16) | (v >> 16));
80c05e648eSthorpej t1 &= 0xff00ffffU;
81201e41fcSthorpej v = (v >> 8) | (v << 24);
82201e41fcSthorpej v ^= (t1 >> 8);
83dd02d63dSmatt
84*b31d312cSrin return v;
85da5ef20bSthorpej }
86da5ef20bSthorpej
87c88ae1f9Sdsl #define __BYTE_SWAP_U16_VARIABLE __byte_swap_u16_variable
88c88ae1f9Sdsl static __inline uint16_t
__byte_swap_u16_variable(uint16_t v)89c88ae1f9Sdsl __byte_swap_u16_variable(uint16_t v)
90da5ef20bSthorpej {
91da5ef20bSthorpej
92825088edSmatt #ifdef _ARM_ARCH_6
93dd02d63dSmatt if (!__builtin_constant_p(v)) {
94674f7f26Smatt uint32_t v32 = v;
95674f7f26Smatt __asm("rev16\t%0, %1" : "=r" (v32) : "0" (v32));
961ed40762Smartin return (uint16_t)v32;
97dd02d63dSmatt }
98e500dd53Smatt #elif !defined(__thumb__) && 0 /* gcc produces decent code for this */
99dd02d63dSmatt if (!__builtin_constant_p(v)) {
100e500dd53Smatt uint32_t v0 = v;
1015f1c88d7Sperry __asm volatile(
102da5ef20bSthorpej "mov %0, %1, ror #8\n"
103da5ef20bSthorpej "orr %0, %0, %0, lsr #16\n"
104da5ef20bSthorpej "bic %0, %0, %0, lsl #16"
105e500dd53Smatt : "=&r" (v0)
106e500dd53Smatt : "0" (v0));
1071ed40762Smartin return (uint16_t)v0;
108dd02d63dSmatt }
109dd02d63dSmatt #endif
110825088edSmatt v &= 0xffff;
111ddcad3a9Schristos v = (uint16_t)((v >> 8) | (v << 8));
112da5ef20bSthorpej
113*b31d312cSrin return v;
114da5ef20bSthorpej }
115da5ef20bSthorpej
116c88ae1f9Sdsl __END_DECLS
117c88ae1f9Sdsl #endif
118da5ef20bSthorpej
11967e5bbcbSmatt #endif /* _LOCORE */
120da5ef20bSthorpej
121da5ef20bSthorpej #endif /* _ARM_BYTE_SWAP_H_ */
122