MCPcopy Create free account
hub / github.com/chen3feng/toft / DetectAlgorithm

Method DetectAlgorithm

base/uint32_divisor.cpp:60–141  ·  view source on GitHub ↗

Detect algorithm and corresponding parameters. the following code is from: [2] AMD Athlon Processor x86 Code Optimization Guide, page 144, and made some necessary modification. @param divisor divisor to be handled @param multiply multiply factor @param shift shift factor (0..63) @retval true if a valid mul and shift value are found.

Source from the content-addressed store, hash-verified

58/// @param shift shift factor (0..63)
59/// @retval true if a valid mul and shift value are found.
60bool UInt32Divisor::DetectAlgorithm(
61 uint32_t divisor,
62 UInt32Divisor::Algorithm* algorithm,
63 uint32_t* multiplier,
64 uint32_t* shift)
65{
66 if (divisor == 0)
67 return false;
68
69 if (divisor >= 0x80000000) {
70 *algorithm = Algorithm_Compare;
71 return true;
72 }
73
74 /* Reduce divisor until it becomes odd */
75 uint32_t lowest_zero_bits = 0;
76 uint32_t t = divisor;
77 while (!(t & 1))
78 {
79 t >>= 1;
80 lowest_zero_bits++;
81 }
82
83 // is power of 2
84 if (t == 1)
85 {
86 *algorithm = Algorithm_Shift;
87 *multiplier = 1;
88 *shift = lowest_zero_bits;
89 return true;
90 }
91
92 /* Generate multiplier, shift for algorithm 0. Based on: Granlund, T.;
93 * Montgomery,
94 * P.L.: "Division by Invariant Integers using Multiplication".
95 * SIGPLAN Notices, Vol. 29, June 1994, page 61.
96 * */
97
98 uint32_t l = log2(t) + 1;
99 uint64_t j = ((0xffffffffULL) % (uint64_t) t);
100 uint64_t k = (1ULL << (32 + l)) / (uint64_t) (0xffffffff - j);
101 uint64_t m_low = (1ULL << (32 + l)) / t;
102 uint64_t m_high = ((1ULL << (32 + l)) + k) / t;
103
104 while (((m_low >> 1) < (m_high >> 1)) && (l > 0))
105 {
106 m_low = m_low >> 1;
107 m_high = m_high >> 1;
108 --l;
109 }
110
111 if ((m_high >> 32) == 0)
112 {
113 *multiplier = (uint32_t) m_high;
114 *shift = l;
115 *algorithm = Algorithm_MultipleShift;
116 }
117 else

Callers

nothing calls this directly

Calls 1

log2Function · 0.85

Tested by

no test coverage detected