You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
3.1KB

  1. /*
  2. * Alpha optimized DSP utils
  3. * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #ifndef LIBAVCODEC_ALPHA_ASM_H
  20. #define LIBAVCODEC_ALPHA_ASM_H
  21. #include <stdint.h>
  22. #define AMASK_BWX (1 << 0)
  23. #define AMASK_FIX (1 << 1)
  24. #define AMASK_MVI (1 << 8)
  25. static inline uint64_t BYTE_VEC(uint64_t x)
  26. {
  27. x |= x << 8;
  28. x |= x << 16;
  29. x |= x << 32;
  30. return x;
  31. }
  32. static inline uint64_t WORD_VEC(uint64_t x)
  33. {
  34. x |= x << 16;
  35. x |= x << 32;
  36. return x;
  37. }
  38. static inline int32_t ldl(const void* p)
  39. {
  40. return *(const int32_t*) p;
  41. }
  42. static inline uint64_t ldq(const void* p)
  43. {
  44. return *(const uint64_t*) p;
  45. }
  46. /* FIXME ccc doesn't seem to get it? Use inline asm? */
  47. static inline uint64_t ldq_u(const void* p)
  48. {
  49. return *(const uint64_t*) ((uintptr_t) p & ~7ul);
  50. }
  51. static inline void stl(uint32_t l, void* p)
  52. {
  53. *(uint32_t*) p = l;
  54. }
  55. static inline void stq(uint64_t l, void* p)
  56. {
  57. *(uint64_t*) p = l;
  58. }
  59. #ifdef __GNUC__
  60. #define OPCODE1(name) \
  61. static inline uint64_t name(uint64_t l) \
  62. { \
  63. uint64_t r; \
  64. asm (#name " %1, %0" : "=r" (r) : "r" (l)); \
  65. return r; \
  66. }
  67. #define OPCODE2(name) \
  68. static inline uint64_t name(uint64_t l1, uint64_t l2) \
  69. { \
  70. uint64_t r; \
  71. asm (#name " %1, %2, %0" : "=r" (r) : "r" (l1), "rI" (l2)); \
  72. return r; \
  73. }
  74. /* We don't want gcc to move this around or combine it with another
  75. rpcc, so mark it volatile. */
  76. static inline uint64_t rpcc(void)
  77. {
  78. uint64_t r;
  79. asm volatile ("rpcc %0" : "=r" (r));
  80. return r;
  81. }
  82. static inline uint64_t uldq(const void* v)
  83. {
  84. struct foo {
  85. unsigned long l;
  86. } __attribute__((packed));
  87. return ((const struct foo*) v)->l;
  88. }
  89. #elif defined(__DECC) /* Compaq "ccc" compiler */
  90. #include <c_asm.h>
  91. #define OPCODE1(name) \
  92. static inline uint64_t name(uint64_t l) \
  93. { \
  94. return asm (#name " %a0, %v0", l); \
  95. }
  96. #define OPCODE2(name) \
  97. static inline uint64_t name(uint64_t l1, uint64_t l2) \
  98. { \
  99. return asm (#name " %a0, %a1, %v0", l1, l2); \
  100. }
  101. static inline uint64_t rpcc(void)
  102. {
  103. return asm ("rpcc %v0");
  104. }
  105. static inline uint64_t uldq(const void* v)
  106. {
  107. return *(const __unaligned uint64_t *) v;
  108. }
  109. #endif
  110. OPCODE1(amask);
  111. OPCODE1(unpkbw);
  112. OPCODE1(pkwb);
  113. OPCODE2(extql);
  114. OPCODE2(extqh);
  115. OPCODE2(zap);
  116. OPCODE2(cmpbge);
  117. OPCODE2(minsw4);
  118. OPCODE2(minuw4);
  119. OPCODE2(minub8);
  120. OPCODE2(maxsw4);
  121. OPCODE2(maxuw4);
  122. OPCODE2(perr);
  123. #endif /* LIBAVCODEC_ALPHA_ASM_H */