swab.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * vineetg: May 2011
  9. * -Support single cycle endian-swap insn in ARC700 4.10
  10. *
  11. * vineetg: June 2009
  12. * -Better htonl implementation (5 instead of 9 ALU instructions)
  13. * -Hardware assisted single cycle bswap (Use Case of ARC custom instrn)
  14. */
  15. #ifndef __ASM_ARC_SWAB_H
  16. #define __ASM_ARC_SWAB_H
  17. #include <linux/types.h>
  18. /* Native single cycle endian swap insn */
  19. #ifdef CONFIG_ARC_HAS_SWAPE
  20. #define __arch_swab32(x) \
  21. ({ \
  22. unsigned int tmp = x; \
  23. __asm__( \
  24. " swape %0, %1 \n" \
  25. : "=r" (tmp) \
  26. : "r" (tmp)); \
  27. tmp; \
  28. })
  29. #else
  30. /* Several ways of Endian-Swap Emulation for ARC
  31. * 0: kernel generic
  32. * 1: ARC optimised "C"
  33. * 2: ARC Custom instruction
  34. */
  35. #define ARC_BSWAP_TYPE 1
  36. #if (ARC_BSWAP_TYPE == 1) /******* Software only ********/
  37. /* The kernel default implementation of htonl is
  38. * return x<<24 | x>>24 |
  39. * (x & (__u32)0x0000ff00UL)<<8 | (x & (__u32)0x00ff0000UL)>>8;
  40. *
  41. * This generates 9 instructions on ARC (excluding the ld/st)
  42. *
  43. * 8051fd8c: ld r3,[r7,20] ; Mem op : Get the value to be swapped
  44. * 8051fd98: asl r5,r3,24 ; get 3rd Byte
  45. * 8051fd9c: lsr r2,r3,24 ; get 0th Byte
  46. * 8051fda0: and r4,r3,0xff00
  47. * 8051fda8: asl r4,r4,8 ; get 1st Byte
  48. * 8051fdac: and r3,r3,0x00ff0000
  49. * 8051fdb4: or r2,r2,r5 ; combine 0th and 3rd Bytes
  50. * 8051fdb8: lsr r3,r3,8 ; 2nd Byte at correct place in Dst Reg
  51. * 8051fdbc: or r2,r2,r4 ; combine 0,3 Bytes with 1st Byte
  52. * 8051fdc0: or r2,r2,r3 ; combine 0,3,1 Bytes with 2nd Byte
  53. * 8051fdc4: st r2,[r1,20] ; Mem op : save result back to mem
  54. *
  55. * Joern suggested a better "C" algorithm which is great since
  56. * (1) It is portable to any architecure
  57. * (2) At the same time it takes advantage of ARC ISA (rotate intrns)
  58. */
  59. #define __arch_swab32(x) \
  60. ({ unsigned long __in = (x), __tmp; \
  61. __tmp = __in << 8 | __in >> 24; /* ror tmp,in,24 */ \
  62. __in = __in << 24 | __in >> 8; /* ror in,in,8 */ \
  63. __tmp ^= __in; \
  64. __tmp &= 0xff00ff; \
  65. __tmp ^ __in; \
  66. })
  67. #elif (ARC_BSWAP_TYPE == 2) /* Custom single cycle bswap instruction */
  68. #define __arch_swab32(x) \
  69. ({ \
  70. unsigned int tmp = x; \
  71. __asm__( \
  72. " .extInstruction bswap, 7, 0x00, SUFFIX_NONE, SYNTAX_2OP \n"\
  73. " bswap %0, %1 \n"\
  74. : "=r" (tmp) \
  75. : "r" (tmp)); \
  76. tmp; \
  77. })
  78. #endif /* ARC_BSWAP_TYPE=zzz */
  79. #endif /* CONFIG_ARC_HAS_SWAPE */
  80. #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
  81. #define __SWAB_64_THRU_32__
  82. #endif
  83. #endif