| 131 | // ******************************************************** |
| 132 | |
| 133 | class DWord { |
| 134 | public: |
| 135 | DWord() {} |
| 136 | |
| 137 | #ifdef TAOCRYPT_NATIVE_DWORD_AVAILABLE |
| 138 | explicit DWord(word low) |
| 139 | { |
| 140 | whole_ = low; |
| 141 | } |
| 142 | #else |
| 143 | explicit DWord(word low) |
| 144 | { |
| 145 | halfs_.low = low; |
| 146 | halfs_.high = 0; |
| 147 | } |
| 148 | #endif |
| 149 | |
| 150 | DWord(word low, word high) |
| 151 | { |
| 152 | halfs_.low = low; |
| 153 | halfs_.high = high; |
| 154 | } |
| 155 | |
| 156 | static DWord Multiply(word a, word b) |
| 157 | { |
| 158 | DWord r; |
| 159 | |
| 160 | #ifdef TAOCRYPT_NATIVE_DWORD_AVAILABLE |
| 161 | r.whole_ = (dword)a * b; |
| 162 | |
| 163 | #elif defined(_M_X64) || defined(_M_IA64) |
| 164 | r.halfs_.low = _umul128(a, b, &r.halfs_.high); |
| 165 | |
| 166 | #elif defined(__alpha__) |
| 167 | r.halfs_.low = a*b; |
| 168 | #ifdef __GNUC__ |
| 169 | __asm__("umulh %1,%2,%0" : "=r" (r.halfs_.high) |
| 170 | : "r" (a), "r" (b)); |
| 171 | #elif defined(__DECCXX) |
| 172 | r.halfs_.high = asm("umulh %a0, %a1, %v0", a, b); |
| 173 | #else |
| 174 | #error unknown alpha compiler |
| 175 | #endif |
| 176 | |
| 177 | #elif defined(__ia64__) |
| 178 | r.halfs_.low = a*b; |
| 179 | __asm__("xmpy.hu %0=%1,%2" : "=f" (r.halfs_.high) |
| 180 | : "f" (a), "f" (b)); |
| 181 | |
| 182 | #elif defined(_ARCH_PPC64) |
| 183 | r.halfs_.low = a*b; |
| 184 | __asm__("mulhdu %0,%1,%2" : "=r" (r.halfs_.high) |
| 185 | : "r" (a), "r" (b) : "cc"); |
| 186 | |
| 187 | #elif defined(__x86_64__) |
| 188 | __asm__("mulq %3" : "=d" (r.halfs_.high), "=a" (r.halfs_.low) : |
| 189 | "a" (a), "rm" (b) : "cc"); |
| 190 | |