Int32Math.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "CommonCommonPch.h"
  6. bool
  7. Int32Math::Add(int32 left, int32 right, int32 *pResult)
  8. {
  9. #if __has_builtin(__builtin_add_overflow) || TARGET_32
  10. return IntMathCommon<int32>::Add(left, right, pResult);
  11. #else
  12. Assert(sizeof(void *) == 8);
  13. int64 result64 = (int64)left + (int64)right;
  14. *pResult = (int32)result64;
  15. return result64 != (int64)(*pResult);
  16. #endif
  17. }
  18. bool
  19. Int32Math::Mul(int32 left, int32 right, int32 *pResult)
  20. {
  21. #if __has_builtin(__builtin_mul_overflow) && !(defined(_ARM_) && defined(__clang__))
  22. return IntMathCommon<int32>::Mul(left, right, pResult);
  23. #else
  24. bool fOverflow;
  25. #if _M_IX86
  26. __asm
  27. {
  28. mov eax, left
  29. imul right
  30. seto fOverflow
  31. mov ecx, pResult
  32. mov[ecx], eax
  33. }
  34. #else
  35. int64 result64 = (int64)left * (int64)right;
  36. *pResult = (int32)result64;
  37. fOverflow = (result64 != (int64)(*pResult));
  38. #endif
  39. return fOverflow;
  40. #endif // !__has_builtin(__builtin_mul_overflow)
  41. }
  42. bool
  43. Int32Math::Mul(int32 left, int32 right, int32 *pResult, int32* pOverflowValue)
  44. {
  45. bool fOverflow;
  46. #if _M_IX86
  47. __asm
  48. {
  49. mov eax, left
  50. imul right
  51. seto fOverflow
  52. mov ecx, pResult
  53. mov[ecx], eax
  54. mov ecx, pOverflowValue
  55. mov[ecx], edx
  56. }
  57. #else
  58. int64 result64 = (int64)left * (int64)right;
  59. *pResult = (int32)result64;
  60. *pOverflowValue = (int32)(result64 >> 32);
  61. fOverflow = (result64 != (int64)(*pResult));
  62. #endif
  63. return fOverflow;
  64. }
  65. bool
  66. Int32Math::Shl(int32 left, int32 right, int32 *pResult)
  67. {
  68. *pResult = left << (right & 0x1F);
  69. return (left != (int32)((uint32)*pResult >> right));
  70. }
  71. bool
  72. Int32Math::Shr(int32 left, int32 right, int32 *pResult)
  73. {
  74. *pResult = left >> (right & 0x1F);
  75. return false;
  76. }
  77. bool
  78. Int32Math::ShrU(int32 left, int32 right, int32 *pResult)
  79. {
  80. uint32 uResult = ((uint32)left) >> (right & 0x1F);
  81. *pResult = uResult;
  82. return false;
  83. }