commandProcessing.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * linux/arch/arm/vfp/vfp.h
  3. *
  4. * Copyright (C) 2004 ARM Limited.
  5. * Written by Deep Blue Solutions Limited.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift)
  12. {
  13. if (shift) {
  14. if (shift < 32)
  15. val = val >> shift | ((val << (32 - shift)) != 0);
  16. else
  17. val = val != 0;
  18. }
  19. return val;
  20. }
  21. static inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift)
  22. {
  23. if (shift) {
  24. if (shift < 64)
  25. val = val >> shift | ((val << (64 - shift)) != 0);
  26. else
  27. val = val != 0;
  28. }
  29. return val;
  30. }
  31. static inline u32 vfp_hi64to32jamming(u64 val)
  32. {
  33. u32 v;
  34. asm(
  35. "cmp %Q1, #1 @ vfp_hi64to32jamming\n\t"
  36. "movcc %0, %R1\n\t"
  37. "orrcs %0, %R1, #1"
  38. : "=r" (v) : "r" (val) : "cc");
  39. return v;
  40. }
  41. static inline void add128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml)
  42. {
  43. asm( "adds %Q0, %Q2, %Q4\n\t"
  44. "adcs %R0, %R2, %R4\n\t"
  45. "adcs %Q1, %Q3, %Q5\n\t"
  46. "adc %R1, %R3, %R5"
  47. : "=r" (nl), "=r" (nh)
  48. : "0" (nl), "1" (nh), "r" (ml), "r" (mh)
  49. : "cc");
  50. *resh = nh;
  51. *resl = nl;
  52. }
  53. static inline void sub128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml)
  54. {
  55. asm( "subs %Q0, %Q2, %Q4\n\t"
  56. "sbcs %R0, %R2, %R4\n\t"
  57. "sbcs %Q1, %Q3, %Q5\n\t"
  58. "sbc %R1, %R3, %R5\n\t"
  59. : "=r" (nl), "=r" (nh)
  60. : "0" (nl), "1" (nh), "r" (ml), "r" (mh)
  61. : "cc");
  62. *resh = nh;
  63. *resl = nl;
  64. }
  65. static inline void mul64to128(u64 *resh, u64 *resl, u64 n, u64 m)
  66. {
  67. u32 nh, nl, mh, ml;
  68. u64 rh, rma, rmb, rl;
  69. nl = n;
  70. ml = m;
  71. rl = (u64)nl * ml;
  72. nh = n >> 32;
  73. rma = (u64)nh * ml;
  74. mh = m >> 32;
  75. rmb = (u64)nl * mh;
  76. rma += rmb;
  77. rh = (u64)nh * mh;
  78. rh += ((u64)(rma < rmb) << 32) + (rma >> 32);
  79. rma <<= 32;
  80. rl += rma;
  81. rh += (rl < rma);
  82. *resl = rl;
  83. *resh = rh;
  84. }
  85. static inline void shift64left(u64 *resh, u64 *resl, u64 n)
  86. {
  87. *resh = n >> 63;
  88. *resl = n << 1;
  89. }
  90. static inline u64 vfp_hi64multiply64(u64 n, u64 m)
  91. {
  92. u64 rh, rl;
  93. mul64to128(&rh, &rl, n, m);
  94. return rh | (rl != 0);
  95. }
  96. static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
  97. {
  98. u64 mh, ml, remh, reml, termh, terml, z;
  99. if (nh >= m)
  100. return ~0ULL;
  101. mh = m >> 32;
  102. if (mh << 32 <= nh) {
  103. z = 0xffffffff00000000ULL;
  104. } else {
  105. z = nh;
  106. do_div(z, mh);
  107. z <<= 32;
  108. }
  109. mul64to128(&termh, &terml, m, z);
  110. sub128(&remh, &reml, nh, nl, termh, terml);
  111. ml = m << 32;
  112. while ((s64)remh < 0) {
  113. z -= 0x100000000ULL;
  114. add128(&remh, &reml, remh, reml, mh, ml);
  115. }
  116. remh = (remh << 32) | (reml >> 32);
  117. if (mh << 32 <= remh) {
  118. z |= 0xffffffff;
  119. } else {
  120. do_div(remh, mh);
  121. z |= remh;
  122. }
  123. return z;