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.

96 lines
2.3KB

  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. /**
  19. * @file check_altivec.c
  20. * Checks for AltiVec presence.
  21. */
  22. #ifdef __APPLE__
  23. #include <sys/sysctl.h>
  24. #elif __AMIGAOS4__
  25. #include <exec/exec.h>
  26. #include <interfaces/exec.h>
  27. #include <proto/exec.h>
  28. #else
  29. #include <signal.h>
  30. #include <setjmp.h>
  31. static sigjmp_buf jmpbuf;
  32. static volatile sig_atomic_t canjump = 0;
  33. static void sigill_handler (int sig)
  34. {
  35. if (!canjump) {
  36. signal (sig, SIG_DFL);
  37. raise (sig);
  38. }
  39. canjump = 0;
  40. siglongjmp (jmpbuf, 1);
  41. }
  42. #endif /* __APPLE__ */
  43. /**
  44. * This function MAY rely on signal() or fork() in order to make sure altivec
  45. * is present
  46. */
  47. int has_altivec(void)
  48. {
  49. #ifdef __AMIGAOS4__
  50. ULONG result = 0;
  51. extern struct ExecIFace *IExec;
  52. IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);
  53. if (result == VECTORTYPE_ALTIVEC) return 1;
  54. return 0;
  55. #elif __APPLE__
  56. int sels[2] = {CTL_HW, HW_VECTORUNIT};
  57. int has_vu = 0;
  58. size_t len = sizeof(has_vu);
  59. int err;
  60. err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
  61. if (err == 0) return (has_vu != 0);
  62. return 0;
  63. #else
  64. /* Do it the brute-force way, borrowed from the libmpeg2 library. */
  65. {
  66. signal (SIGILL, sigill_handler);
  67. if (sigsetjmp (jmpbuf, 1)) {
  68. signal (SIGILL, SIG_DFL);
  69. } else {
  70. canjump = 1;
  71. asm volatile ("mtspr 256, %0\n\t"
  72. "vand %%v0, %%v0, %%v0"
  73. :
  74. : "r" (-1));
  75. signal (SIGILL, SIG_DFL);
  76. return 1;
  77. }
  78. }
  79. return 0;
  80. #endif /* __AMIGAOS4__ */
  81. }