162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * include/asm-xtensa/swab.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 662306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 762306a36Sopenharmony_ci * for more details. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Copyright (C) 2001 - 2005 Tensilica Inc. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#ifndef _XTENSA_SWAB_H 1362306a36Sopenharmony_ci#define _XTENSA_SWAB_H 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_ci#include <linux/compiler.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define __SWAB_64_THRU_32__ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic inline __attribute_const__ __u32 __arch_swab32(__u32 x) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci __u32 res; 2362306a36Sopenharmony_ci /* instruction sequence from Xtensa ISA release 2/2000 */ 2462306a36Sopenharmony_ci __asm__("ssai 8 \n\t" 2562306a36Sopenharmony_ci "srli %0, %1, 16 \n\t" 2662306a36Sopenharmony_ci "src %0, %0, %1 \n\t" 2762306a36Sopenharmony_ci "src %0, %0, %0 \n\t" 2862306a36Sopenharmony_ci "src %0, %1, %0 \n" 2962306a36Sopenharmony_ci : "=&a" (res) 3062306a36Sopenharmony_ci : "a" (x) 3162306a36Sopenharmony_ci ); 3262306a36Sopenharmony_ci return res; 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci#define __arch_swab32 __arch_swab32 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic inline __attribute_const__ __u16 __arch_swab16(__u16 x) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci /* Given that 'short' values are signed (i.e., can be negative), 3962306a36Sopenharmony_ci * we cannot assume that the upper 16-bits of the register are 4062306a36Sopenharmony_ci * zero. We are careful to mask values after shifting. 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci /* There exists an anomaly between xt-gcc and xt-xcc. xt-gcc 4462306a36Sopenharmony_ci * inserts an extui instruction after putting this function inline 4562306a36Sopenharmony_ci * to ensure that it uses only the least-significant 16 bits of 4662306a36Sopenharmony_ci * the result. xt-xcc doesn't use an extui, but assumes the 4762306a36Sopenharmony_ci * __asm__ macro follows convention that the upper 16 bits of an 4862306a36Sopenharmony_ci * 'unsigned short' result are still zero. This macro doesn't 4962306a36Sopenharmony_ci * follow convention; indeed, it leaves garbage in the upport 16 5062306a36Sopenharmony_ci * bits of the register. 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci * Declaring the temporary variables 'res' and 'tmp' to be 32-bit 5362306a36Sopenharmony_ci * types while the return type of the function is a 16-bit type 5462306a36Sopenharmony_ci * forces both compilers to insert exactly one extui instruction 5562306a36Sopenharmony_ci * (or equivalent) to mask off the upper 16 bits. */ 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci __u32 res; 5862306a36Sopenharmony_ci __u32 tmp; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci __asm__("extui %1, %2, 8, 8\n\t" 6162306a36Sopenharmony_ci "slli %0, %2, 8 \n\t" 6262306a36Sopenharmony_ci "or %0, %0, %1 \n" 6362306a36Sopenharmony_ci : "=&a" (res), "=&a" (tmp) 6462306a36Sopenharmony_ci : "a" (x) 6562306a36Sopenharmony_ci ); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci return res; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci#define __arch_swab16 __arch_swab16 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci#endif /* _XTENSA_SWAB_H */ 72