Windows NT 4.0 source code leak
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.

662 lines
30 KiB

4 years ago
  1. // TITLE("High-Performance Division")
  2. //++
  3. //
  4. // Copyright (c) 1993 Digital Equipment Corporation
  5. //
  6. // Module Name:
  7. //
  8. // fastdiv.s
  9. //
  10. // Abstract:
  11. //
  12. // This module implements a high-performance integer division routine
  13. // whose source is included from each of the division and remainder
  14. // functions.
  15. //
  16. // Author:
  17. //
  18. // Thomas Van Baak (tvb) 12-Jan-1993
  19. // Ken Lesniak (lesniak) 04-Nov-1992
  20. //
  21. // Environment:
  22. //
  23. // Any mode.
  24. //
  25. // Revision History:
  26. //
  27. //--
  28. //
  29. // Implementation Notes:
  30. //
  31. // This code is the main "guts" of the eight divide and remainder routines
  32. // in the C library. It is intended to be included by a wrapper function
  33. // that defines options to control 32 vs. 64-bit, division vs. remainder,
  34. // and signed vs. unsigned. The wrapper function is responsible for the
  35. // prologue and epilogue sequences, as well as overflow checking and sign
  36. // adjustment on both input arguments and the return value.
  37. //
  38. // The algorithm used here is based on long division and a table for
  39. // approximating inverses as discussed in the paper "Division by a Constant"
  40. // by Mary Payne and Robert Gries. If the divisor inverse can be constructed
  41. // from the table without an error, the division is performed as described
  42. // in the paper with a multiplication and a shift.
  43. //
  44. // If the inverse can not be found in the table, we improve the inverse with
  45. // a linear approximation, "I". A multiplication by "I" and a shift by
  46. // log2(y) is used to obtain an approximate quotient, "Q". Now, like long
  47. // division, the most significant bits are correct, therefore if we
  48. // calculate the remainder R = x-Q*y, R will be smaller than x, and R will
  49. // contain the true remainder and the error in Q, "e" multiplied by y.
  50. //
  51. // So if we do the same multiplication and shift, we will get an
  52. // approximation for e. This is just long division, and it will finish
  53. // when R, the remainder, is less than y.
  54. //
  55. // Both the division algorithm code and the large division tables used by
  56. // the code are contained in this source file (to keep them together).
  57. //
  58. //
  59. // The code below requires that the wrapper function define register numbers
  60. // for each of the following symbolic register names:
  61. //
  62. // Nu dividend (numerator)
  63. // Di divisor (denominator)
  64. // Qu quotient
  65. // Re remainder (may be the same as Qu)
  66. //
  67. // T0 temp
  68. // T1 temp
  69. // T2 temp
  70. // T3 temp
  71. // T4 temp
  72. // T5 temp
  73. // T6 temp (may be shared with Qu)
  74. //
  75. //
  76. // The code below requires that the wrapper function define the symbol
  77. // FASTDIV_OPTIONS as the logical sum of the following names:
  78. //
  79. #define THIRTY_TWO_BIT 1 // perform 32-bit computations, otherwise
  80. #define SIXTY_FOUR_BIT 0 // perform 64-bit computations
  81. #define UNSIGNED 2 // treat operands as unsigned, otherwise
  82. #define SIGNED 0 // treat operands as signed
  83. #define DIVISION 4 // return quotient in Qu register, and/or
  84. #define REMAINDER 8 // return remainder in Re register
  85. //
  86. // Define the symbols that actually control the code generation.
  87. //
  88. #define _THIRTYTWOBIT (FASTDIV_OPTIONS & THIRTY_TWO_BIT)
  89. #define _SIXTYFOURBIT (!(FASTDIV_OPTIONS & THIRTY_TWO_BIT))
  90. #define _UNSIGNED (FASTDIV_OPTIONS & UNSIGNED)
  91. #define _REMAINDER (FASTDIV_OPTIONS & REMAINDER)
  92. #define _QUOTIENT (FASTDIV_OPTIONS & DIVISION)
  93. //
  94. // These constants give the algorithm the best performance.
  95. //
  96. #define BIT_LENGTH 8
  97. #define BIT_VALUE (1 << BIT_LENGTH)
  98. #define BIT_MASK (BIT_VALUE - 1)
  99. #define K_BIT_LENGTH 8
  100. #define K_BIT_VALUE (1 << K_BIT_LENGTH)
  101. #define K_BIT_MASK (K_BIT_VALUE - 1)
  102. #define TABLE_BIAS 16384
  103. #define LOG2TAB -16384
  104. #define INV_FLAG -15360
  105. #define INV -14848
  106. #define INV_M -14840
  107. #ifndef FASTDIV_TABLES
  108. .set noat
  109. lda T3, __2divdata + TABLE_BIAS // set address of table
  110. beq Di, 30f // if zero divisor, generate trap
  111. cmpule Nu, Di, T0 // check if dividend <= divisor
  112. #if _THIRTYTWOBIT
  113. addl Di, 0, T1 // sign extend longword to quadword
  114. blt T1, 20f // high bit set so quotient <= 1
  115. #endif
  116. #if _SIXTYFOURBIT
  117. blt Di, 20f // high bit set so quotient <= 1
  118. #endif
  119. cmpbge zero, Di, T2 // perform 8 byte parallel compare
  120. bne T0, 20f // dividend <= divisor so quotient <= 1
  121. xor T2, 0xff, T0 //
  122. s4addq T0, T3, T0 //
  123. ldl AT, LOG2TAB(T0) //
  124. extbl Di, AT, T0 //
  125. s4addq T0, T3, T0 //
  126. ldl T0, LOG2TAB(T0) //
  127. s8addq AT, T0, AT //
  128. ornot zero, AT, T0 //
  129. sll Di, T0, T0 //
  130. sll T0, BIT_LENGTH + 1, T1 //
  131. bne T1, 40f //
  132. //
  133. // Short case.
  134. //
  135. subq Di, 1, T1 // compute divisor - 1
  136. and Di, T1, T2 // divisor & (divisor - 1)
  137. srl T0, 63 - (BIT_LENGTH + 1), T6 //
  138. beq T2, 10f // divisor is a power of two
  139. subq T6, BIT_VALUE + BIT_VALUE, T6 //
  140. bic T6, 1, T4 //
  141. s8addq T4, T3, T4 //
  142. ldq T5, INV(T4) //
  143. ldq T4, INV_M(T4) //
  144. subq T5, T4, T4 //
  145. cmovlbs T6, T4, T5 //
  146. addq T6, T3, T2 //
  147. ldq_u T0, INV_FLAG(T2) //
  148. extbl T0, T2, T2 //
  149. addq Nu, T2, T1 //
  150. umulh T1, T5, T3 //
  151. #if _SIXTYFOURBIT && _UNSIGNED
  152. cmoveq T1, T5, T3 //
  153. #endif
  154. srl T3, AT, Qu //
  155. #if _REMAINDER
  156. mulq Qu, Di, T0 //
  157. subq Nu, T0, Re //
  158. #endif
  159. br zero, 90f // all done, branch to epilogue code
  160. 10:
  161. //
  162. // The divisor is now known to be a power of two.
  163. //
  164. // - The quotient is the dividend shifted right by exponent bits and
  165. // the remainder is the low order exponent bits of the dividend.
  166. //
  167. // AT = log2(divisor)
  168. // T1 = divisor - 1
  169. //
  170. #if _REMAINDER
  171. and Nu, T1, Re //
  172. #endif
  173. #if _QUOTIENT
  174. srl Nu, AT, Qu //
  175. #endif
  176. br zero, 90f // all done, branch to epilogue code
  177. 20:
  178. //
  179. // The quotient is now known to be either 0 or 1.
  180. //
  181. // - if the high bit of the divisor is set, the quotient must be less
  182. // than 2, so the quotient is 0 or 1.
  183. //
  184. // - if the dividend is less than the divisor, the quotient is 0 and
  185. // the remainder is the dividend.
  186. //
  187. // - if the dividend is equal to the divisor, the quotient is 1 and
  188. // the remainder is 0.
  189. //
  190. // - if the dividend is greater than the divisor, the quotient is 1
  191. // and the remainder is the dividend minus the divisor.
  192. //
  193. #if _REMAINDER
  194. cmpule Di, Nu, T0 // if divisor <= dividend
  195. subq Nu, Di, Re // then remainder is dividend,
  196. cmoveq T0, Nu, Re // else remainder is dividend - divisor
  197. #endif
  198. #if _QUOTIENT
  199. cmpule Di, Nu, Qu // if divisor <= dividend, 1, else 0
  200. #endif
  201. br zero, 90f // all done, branch to epilogue code
  202. //
  203. // Generate divide by zero exception. If execution is continued, return
  204. // a zero result.
  205. //
  206. 30: ldiq a0, GENTRAP_INTEGER_DIVIDE_BY_ZERO
  207. GENERATE_TRAP
  208. ldiq Qu, 0 // supply 0 result if continued
  209. br zero, 90f // branch to epilogue code
  210. //
  211. // Long case.
  212. //
  213. 40: srl T0, 63-(BIT_LENGTH+K_BIT_LENGTH), T6 //
  214. srl T6, K_BIT_LENGTH, T0 //
  215. and T6, K_BIT_MASK, T6 //
  216. addq T0, T0, T0 //
  217. s8addq T0, T3, T1 //
  218. ldq T2, INV-(16*BIT_VALUE)(T1) //
  219. ldq T0, INV_M-(16*BIT_VALUE)(T1) //
  220. mulq T0, T6, T0 //
  221. srl T0, K_BIT_LENGTH-1, T0 //
  222. subq T2, T0, T6 //
  223. umulh Nu, T6, T4 //
  224. srl T4, AT, T4 //
  225. mulq T4, Di, T5 //
  226. mov zero, T3 //
  227. #if _SIXTYFOURBIT
  228. xor Nu, T5, T0 //
  229. bge T0, 50f //
  230. umulh Di, T4, T3 //
  231. 50:
  232. #endif
  233. subq Nu, T5, T5 //
  234. beq T4, 70f //
  235. cmpult Nu, T5, T0 //
  236. or T0, T3, T3 //
  237. negq T5, T1 //
  238. cmovne T3, T1, T5 //
  239. addq Di, Di, T0 //
  240. cmpule T0, T5, T0 //
  241. beq T0, 70f //
  242. //
  243. // do {
  244. //
  245. 60: umulh T5, T6, T2 //
  246. srl T2, AT, T2 //
  247. negq T2, T0 //
  248. cmoveq T3, T2, T0 //
  249. addq T4, T0, T4 //
  250. mulq T2, Di, T1 //
  251. subq T5, T1, T5 //
  252. #if _SIXTYFOURBIT
  253. ldiq T0, 1 //
  254. cmovne T3, 0, T0 //
  255. negq T5, T2 //
  256. cmovlt T5, T0, T3 //
  257. cmovlt T5, T2, T5 //
  258. #endif
  259. addq Di, Di, T0 //
  260. cmpule T5, T0, T0 //
  261. cmovne T0, 0, T1 //
  262. bne T1, 60b //
  263. //
  264. // } while
  265. //
  266. 70: cmpule Di, T5, T0 //
  267. beq T0, 80f //
  268. subq T5, Di, T5 //
  269. subq T4, 1, T0 //
  270. addq T4, 1, T4 //
  271. cmovne T3, T0, T4 //
  272. 80:
  273. cmoveq T5, 0, T3 //
  274. #if _REMAINDER
  275. subq Di, T5, Re //
  276. cmoveq T3, T5, Re //
  277. #endif
  278. #if _QUOTIENT
  279. subq T4, 1, Qu //
  280. cmoveq T3, T4, Qu //
  281. #endif
  282. 90:
  283. .set at
  284. #undef FASTDIV_OPTIONS
  285. #else
  286. //
  287. // The following data was machine generated. DO NOT EDIT MANUALLY.
  288. //
  289. .globl __2divdata
  290. .rdata
  291. .align 4
  292. __2divdata:
  293. //
  294. // LOG2TAB
  295. //
  296. .align 2
  297. .long 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
  298. .long 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
  299. .long 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
  300. .long 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
  301. .long 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
  302. .long 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
  303. .long 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
  304. .long 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
  305. .long 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  306. .long 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  307. .long 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  308. .long 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  309. .long 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  310. .long 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  311. .long 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  312. .long 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  313. //
  314. // INV_FLAG
  315. //
  316. .align 3
  317. .byte 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1
  318. .byte 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0
  319. .byte 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1
  320. .byte 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0
  321. .byte 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0
  322. .byte 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
  323. .byte 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1
  324. .byte 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0
  325. .byte 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1
  326. .byte 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1
  327. .byte 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1
  328. .byte 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1
  329. .byte 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1
  330. .byte 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0
  331. .byte 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1
  332. .byte 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0
  333. .byte 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1
  334. .byte 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0
  335. .byte 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1
  336. .byte 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0
  337. .byte 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1
  338. .byte 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1
  339. .byte 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1
  340. .byte 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
  341. .byte 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1
  342. .byte 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0
  343. .byte 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1
  344. .byte 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1
  345. .byte 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1
  346. .byte 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1
  347. .byte 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1
  348. .byte 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1
  349. //
  350. // INV INV_M
  351. //
  352. .align 4
  353. .quad 0xffffffffffffffff, 0x007fc01ff007fc01, // 0
  354. .quad 0xff00ff00ff00ff01, 0x007ec25bf68dabfe, // 1
  355. .quad 0xfe03f80fe03f80fe, 0x007dc78930f5b971, // 2
  356. .quad 0xfd08e5500fd08e55, 0x007ccf9c05f3157c, // 3
  357. .quad 0xfc0fc0fc0fc0fc10, 0x007bda891528a983, // 4
  358. .quad 0xfb18856506ddaba6, 0x007ae84535db391c, // 5
  359. .quad 0xfa232cf252138ac0, 0x0079f8c575ac2ab0, // 6
  360. .quad 0xf92fb2211855a865, 0x00790bff175cf1bf, // 7
  361. .quad 0xf83e0f83e0f83e10, 0x007821e7919ad7f4, // 8
  362. .quad 0xf74e3fc22c700f75, 0x00773a748dd2e48d, // 9
  363. .quad 0xf6603d980f6603da, 0x0076559be70da3cb, // 10
  364. .quad 0xf57403d5d00f5740, 0x00757353a8d2921b, // 11
  365. .quad 0xf4898d5f85bb3950, 0x007493920e12f0da, // 12
  366. .quad 0xf3a0d52cba872336, 0x0073b64d801bcc4b, // 13
  367. .quad 0xf2b9d6480f2b9d65, 0x0072db7c958efc82, // 14
  368. .quad 0xf1d48bcee0d399fa, 0x007203161162ec7b, // 15
  369. .quad 0xf0f0f0f0f0f0f0f1, 0x00712d10e1e8f4b3, // 16
  370. .quad 0xf00f00f00f00f00f, 0x007059641fda17d7, // 17
  371. .quad 0xef2eb71fc4345238, 0x006f88070d69f229, // 18
  372. .quad 0xee500ee500ee500f, 0x006eb8f1155fad72, // 19
  373. .quad 0xed7303b5cc0ed730, 0x006dec19ca34cd01, // 20
  374. .quad 0xec979118f3fc4da2, 0x006d2178e539a6a8, // 21
  375. .quad 0xebbdb2a5c1619c8c, 0x006c590645bf5ef6, // 22
  376. .quad 0xeae56403ab95900f, 0x006b92b9f0474060, // 23
  377. .quad 0xea0ea0ea0ea0ea0f, 0x006ace8c0db7463d, // 24
  378. .quad 0xe939651fe2d8d35c, 0x006a0c74ea93b5ce, // 25
  379. .quad 0xe865ac7b7603a197, 0x00694c6cf63da0af, // 26
  380. .quad 0xe79372e225fe30d9, 0x00688e6cc2362d3c, // 27
  381. .quad 0xe6c2b4481cd85689, 0x0067d26d016682a0, // 28
  382. .quad 0xe5f36cb00e5f36cb, 0x00671866876c373e, // 29
  383. .quad 0xe525982af70c880e, 0x0066605247ea214c, // 30
  384. .quad 0xe45932d7dc52100e, 0x0065aa2955dd6a6f, // 31
  385. .quad 0xe38e38e38e38e38e, 0x0064f5e4e2f6c80c, // 32
  386. .quad 0xe2c4a6886a4c2e10, 0x0064437e3ef7bb1b, // 33
  387. .quad 0xe1fc780e1fc780e2, 0x006392eed713bb0b, // 34
  388. .quad 0xe135a9c97500e136, 0x0062e43035553040, // 35
  389. .quad 0xe070381c0e070382, 0x0062373c00062374, // 36
  390. .quad 0xdfac1f74346c575f, 0x00618c0bf91c8837, // 37
  391. .quad 0xdee95c4ca037ba57, 0x0060e299fdaa0972, // 38
  392. .quad 0xde27eb2c41f3d9d1, 0x00603ae0054f3f9c, // 39
  393. .quad 0xdd67c8a60dd67c8a, 0x005f94d821b23932, // 40
  394. .quad 0xdca8f158c7f91ab8, 0x005ef07c7df83e6e, // 41
  395. .quad 0xdbeb61eed19c5958, 0x005e4dc75e42ba41, // 42
  396. .quad 0xdb2f171df7702919, 0x005dacb31f2f32ed, // 43
  397. .quad 0xda740da740da740e, 0x005d0d3a355a3d88, // 44
  398. .quad 0xd9ba4256c0366e91, 0x005c6f572ce55811, // 45
  399. .quad 0xd901b2036406c80e, 0x005bd304a8ff968c, // 46
  400. .quad 0xd84a598ec9151f43, 0x005b383d63711014, // 47
  401. .quad 0xd79435e50d79435e, 0x005a9efc2c28f962, // 48
  402. .quad 0xd6df43fca482f00d, 0x005a073be8ce5ae4, // 49
  403. .quad 0xd62b80d62b80d62c, 0x005970f7945350f4, // 50
  404. .quad 0xd578e97c3f5fe551, 0x0058dc2a3e8ac544, // 51
  405. .quad 0xd4c77b03531dec0d, 0x005848cf0bc0912f, // 52
  406. .quad 0xd4173289870ac52e, 0x0057b6e13453f8e0, // 53
  407. .quad 0xd3680d3680d3680d, 0x0057265c04546fe2, // 54
  408. .quad 0xd2ba083b445250ab, 0x0056973adb20982b, // 55
  409. .quad 0xd20d20d20d20d20d, 0x005609792b076ce1, // 56
  410. .quad 0xd161543e28e50274, 0x00557d1278eb8ad3, // 57
  411. .quad 0xd0b69fcbd2580d0b, 0x0054f2025be888c5, // 58
  412. .quad 0xd00d00d00d00d00d, 0x005468447cfa5248, // 59
  413. .quad 0xcf6474a8819ec8e9, 0x0053dfd496a67807, // 60
  414. .quad 0xcebcf8bb5b4169cb, 0x005358ae74a768fd, // 61
  415. .quad 0xce168a7725080ce1, 0x0052d2cdf3998842, // 62
  416. .quad 0xcd712752a886d242, 0x00524e2f00aa138f, // 63
  417. .quad 0xcccccccccccccccd, 0x0051cacd9947cecc, // 64
  418. .quad 0xcc29786c7607f99f, 0x005148a5cad5697f, // 65
  419. .quad 0xcb8727c065c393e0, 0x0050c7b3b25d9315, // 66
  420. .quad 0xcae5d85f1bbd6c95, 0x005047f37c48b368, // 67
  421. .quad 0xca4587e6b74f0329, 0x004fc96164143d25, // 68
  422. .quad 0xc9a633fcd967300d, 0x004f4bf9b40b9000, // 69
  423. .quad 0xc907da4e871146ad, 0x004ecfb8c50260f1, // 70
  424. .quad 0xc86a78900c86a789, 0x004e549afe109ef0, // 71
  425. .quad 0xc7ce0c7ce0c7ce0c, 0x004dda9cd44fcaee, // 72
  426. .quad 0xc73293d789b9f838, 0x004d61baca99ba10, // 73
  427. .quad 0xc6980c6980c6980c, 0x004ce9f17148b95b, // 74
  428. .quad 0xc5fe740317f9d00c, 0x004c733d65f90a5a, // 75
  429. .quad 0xc565c87b5f9d4d1c, 0x004bfd9b534bb06e, // 76
  430. .quad 0xc4ce07b00c4ce07b, 0x004b8907f0aa86ab, // 77
  431. .quad 0xc4372f855d824ca6, 0x004b1580020d9680, // 78
  432. .quad 0xc3a13de60495c773, 0x004aa30057c1a767, // 79
  433. .quad 0xc30c30c30c30c30c, 0x004a3185ce30004a, // 80
  434. .quad 0xc2780613c0309e02, 0x0049c10d4da7534b, // 81
  435. .quad 0xc1e4bbd595f6e947, 0x00495193ca25cceb, // 82
  436. .quad 0xc152500c152500c1, 0x0048e31643243fb8, // 83
  437. .quad 0xc0c0c0c0c0c0c0c1, 0x00487591c36265c8, // 84
  438. .quad 0xc0300c0300c0300c, 0x0048090360b4318c, // 85
  439. .quad 0xbfa02fe80bfa02ff, 0x00479d683bd0279f, // 86
  440. .quad 0xbf112a8ad278e8dd, 0x004732bd801ebb67, // 87
  441. .quad 0xbe82fa0be82fa0bf, 0x0046c900638aa88c, // 88
  442. .quad 0xbdf59c91700bdf5a, 0x0046602e26524361, // 89
  443. .quad 0xbd69104707661aa3, 0x0045f84412d9ba97, // 90
  444. .quad 0xbcdd535db1cc5b7b, 0x0045913f7d7e44a5, // 91
  445. .quad 0xbc52640bc52640bc, 0x00452b1dc46a3383, // 92
  446. .quad 0xbbc8408cd63069a1, 0x0044c5dc4f69e972, // 93
  447. .quad 0xbb3ee721a54d880c, 0x004461788fc1a9a5, // 94
  448. .quad 0xbab656100bab6561, 0x0043fdf000043fdf, // 95
  449. .quad 0xba2e8ba2e8ba2e8c, 0x00439b4023ea7a13, // 96
  450. .quad 0xb9a7862a0ff46588, 0x00433966882b6f4f, // 97
  451. .quad 0xb92143fa36f5e02e, 0x0042d860c2558f4d, // 98
  452. .quad 0xb89bc36ce3e0453a, 0x0042782c70a87632, // 99
  453. .quad 0xb81702e05c0b8170, 0x004218c739ef8000, // 100
  454. .quad 0xb79300b79300b793, 0x0041ba2ecd5d1788, // 101
  455. .quad 0xb70fbb5a19be3659, 0x00415c60e266bc99, // 102
  456. .quad 0xb68d31340e4307d8, 0x0040ff5b38a1bd6e, // 103
  457. .quad 0xb60b60b60b60b60b, 0x0040a31b97a09f52, // 104
  458. .quad 0xb58a485518d1e7e4, 0x0040479fced1329a, // 105
  459. .quad 0xb509e68a9b94821f, 0x003fece5b55b4e37, // 106
  460. .quad 0xb48a39d44685fe97, 0x003f92eb2a002f2f, // 107
  461. .quad 0xb40b40b40b40b40b, 0x003f39ae12fa7858, // 108
  462. .quad 0xb38cf9b00b38cf9b, 0x003ee12c5ddecee8, // 109
  463. .quad 0xb30f63528917c80b, 0x003e8963ff7d1056, // 110
  464. .quad 0xb2927c29da5519cf, 0x003e3252f3c21e56, // 111
  465. .quad 0xb21642c8590b2164, 0x003ddbf73d9a3d87, // 112
  466. .quad 0xb19ab5c45606f00b, 0x003d864ee6d403ca, // 113
  467. .quad 0xb11fd3b80b11fd3c, 0x003d31580003d316, // 114
  468. .quad 0xb0a59b418d749d53, 0x003cdd10a067ddc1, // 115
  469. .quad 0xb02c0b02c0b02c0b, 0x003c8976e5ccb15f, // 116
  470. .quad 0xafb321a1496fdf0e, 0x003c3688f472452e, // 117
  471. .quad 0xaf3addc680af3ade, 0x003be444f6f1897b, // 118
  472. .quad 0xaec33e1f671529a5, 0x003b92a91e2274fb, // 119
  473. .quad 0xae4c415c9882b931, 0x003b41b3a1028dad, // 120
  474. .quad 0xadd5e6323fd48a86, 0x003af162bc9bea7b, // 121
  475. .quad 0xad602b580ad602b6, 0x003aa1b4b3ecab20, // 122
  476. .quad 0xaceb0f891e6551bb, 0x003a52a7cfcee3c6, // 123
  477. .quad 0xac7691840ac76918, 0x003a043a5ee0fa15, // 124
  478. .quad 0xac02b00ac02b00ac, 0x0039b66ab56e7112, // 125
  479. .quad 0xab8f69e28359cd11, 0x003969372d5921bb, // 126
  480. .quad 0xab1cbdd3e2970f60, 0x00391c9e2602ddfa, // 127
  481. .quad 0xaaaaaaaaaaaaaaab, 0x0038d09e04377bbb, // 128
  482. .quad 0xaa392f35dc17f00b, 0x003885353217460a, // 129
  483. .quad 0xa9c84a47a07f5638, 0x00383a621f01d214, // 130
  484. .quad 0xa957fab5402a55ff, 0x0037f0233f8135f4, // 131
  485. .quad 0xa8e83f5717c0a8e8, 0x0037a6770d359f5a, // 132
  486. .quad 0xa87917088e262b6f, 0x00375d5c06c14806, // 133
  487. .quad 0xa80a80a80a80a80b, 0x003714d0afb4c633, // 134
  488. .quad 0xa79c7b16ea64d422, 0x0036ccd3907bb709, // 135
  489. .quad 0xa72f05397829cbc1, 0x003685633649c151, // 136
  490. .quad 0xa6c21df6e1625c80, 0x00363e7e3307ee8e, // 137
  491. .quad 0xa655c4392d7b73a8, 0x0035f8231d4258ba, // 138
  492. .quad 0xa5e9f6ed347f0721, 0x0035b25090162b0e, // 139
  493. .quad 0xa57eb50295fad40a, 0x00356d052b1ff400, // 140
  494. .quad 0xa513fd6bb00a5140, 0x0035283f926a46f2, // 141
  495. .quad 0xa4a9cf1d96833751, 0x0034e3fe6e5cabea, // 142
  496. .quad 0xa44029100a440291, 0x0034a0406baadbcc, // 143
  497. .quad 0xa3d70a3d70a3d70a, 0x00345d043b44478a, // 144
  498. .quad 0xa36e71a2cb033128, 0x00341a489243e8ca, // 145
  499. .quad 0xa3065e3fae7cd0e0, 0x0033d80c29e05a93, // 146
  500. .quad 0xa29ecf163bb6500a, 0x0033964dbf5c3891, // 147
  501. .quad 0xa237c32b16cfd772, 0x0033550c13f6c382, // 148
  502. .quad 0xa1d139855f7268ee, 0x00331445ecdcc986, // 149
  503. .quad 0xa16b312ea8fc377d, 0x0032d3fa1319d0d6, // 150
  504. .quad 0xa105a932f2ca891f, 0x00329427538983c8, // 151
  505. .quad 0xa0a0a0a0a0a0a0a1, 0x003254cc7ec95ca2, // 152
  506. .quad 0xa03c1688732b3032, 0x003215e8692a9028, // 153
  507. .quad 0x9fd809fd809fd80a, 0x0031d779eaa43595, // 154
  508. .quad 0x9f747a152d7836d0, 0x0031997fdec5aad6, // 155
  509. .quad 0x9f1165e7254813e2, 0x00315bf924a933d8, // 156
  510. .quad 0x9eaecc8d53ae2ddf, 0x00311ee49ee6d3cb, // 157
  511. .quad 0x9e4cad23dd5f3a20, 0x0030e24133875f2f, // 158
  512. .quad 0x9deb06c9194aa416, 0x0030a60dcbf7c5aa, // 159
  513. .quad 0x9d89d89d89d89d8a, 0x00306a4954fc927a, // 160
  514. .quad 0x9d2921c3d6411308, 0x00302ef2bea5a284, // 161
  515. .quad 0x9cc8e160c3fb19b9, 0x002ff408fc420f05, // 162
  516. .quad 0x9c69169b30446dfa, 0x002fb98b04544bcd, // 163
  517. .quad 0x9c09c09c09c09c0a, 0x002f7f77d086781f, // 164
  518. .quad 0x9baade8e4a2f6e10, 0x002f45ce5d9ee128, // 165
  519. .quad 0x9b4c6f9ef03a3caa, 0x002f0c8dab74b53e, // 166
  520. .quad 0x9aee72fcf957c10f, 0x002ed3b4bce4e6d7, // 167
  521. .quad 0x9a90e7d95bc609a9, 0x002e9b4297c73e6e, // 168
  522. .quad 0x9a33cd67009a33cd, 0x002e633644e39a62, // 169
  523. .quad 0x99d722dabde58f06, 0x002e2b8ecfe75c01, // 170
  524. .quad 0x997ae76b50efd00a, 0x002df44b475b00d8, // 171
  525. .quad 0x991f1a515885fb37, 0x002dbd6abc97e780, // 172
  526. .quad 0x98c3bac74f5db00a, 0x002d86ec43be3f17, // 173
  527. .quad 0x9868c809868c8098, 0x002d50cef3ab208e, // 174
  528. .quad 0x980e4156201301c8, 0x002d1b11e5eed122, // 175
  529. .quad 0x97b425ed097b425f, 0x002ce5b436c32d10, // 176
  530. .quad 0x975a750ff68a58af, 0x002cb0b5050239fa, // 177
  531. .quad 0x97012e025c04b809, 0x002c7c13721ce019, // 178
  532. .quad 0x96a850096a850097, 0x002c47cea211c9a1, // 179
  533. .quad 0x964fda6c0964fda7, 0x002c13e5bb646783, // 180
  534. .quad 0x95f7cc72d1b887e9, 0x002be057e7141b13, // 181
  535. .quad 0x95a02568095a0257, 0x002bad24509383a7, // 182
  536. .quad 0x9548e4979e0829fd, 0x002b7a4a25bfefbe, // 183
  537. .quad 0x94f2094f2094f209, 0x002b47c896d8f0df, // 184
  538. .quad 0x949b92ddc02526e5, 0x002b159ed67811bb, // 185
  539. .quad 0x9445809445809446, 0x002ae3cc1988adbb, // 186
  540. .quad 0x93efd1c50e726b7c, 0x002ab24f973fe99c, // 187
  541. .quad 0x939a85c40939a85c, 0x002a81288914cc5b, // 188
  542. .quad 0x93459be6b009345a, 0x002a50562ab877df, // 189
  543. .quad 0x92f113840497889c, 0x002a1fd7ba0e80df, // 190
  544. .quad 0x929cebf48bbd90e5, 0x0029efac7725656b, // 191
  545. .quad 0x9249249249249249, 0x0029bfd3a42f218e, // 192
  546. .quad 0x91f5bcb8bb02d9cd, 0x0029904c8579e17d, // 193
  547. .quad 0x91a2b3c4d5e6f809, 0x002961166168d0d3, // 194
  548. .quad 0x9150091500915009, 0x00293230806d0653, // 195
  549. .quad 0x90fdbc090fdbc091, 0x0029039a2cfe8bab, // 196
  550. .quad 0x90abcc0242af3009, 0x0028d552b39580c2, // 197
  551. .quad 0x905a38633e06c43b, 0x0028a75962a35a0f, // 198
  552. .quad 0x9009009009009009, 0x002879ad8a8c397c, // 199
  553. .quad 0x8fb823ee08fb823f, 0x00284c4e7da06171, // 200
  554. .quad 0x8f67a1e3fdc26178, 0x00281f3b9015c16f, // 201
  555. .quad 0x8f1779d9fdc3a219, 0x0027f27418019bf5, // 202
  556. .quad 0x8ec7ab397255e41d, 0x0027c5f76d52450e, // 203
  557. .quad 0x8e78356d1408e783, 0x002799c4e9c8f94d, // 204
  558. .quad 0x8e2917e0e702c6cd, 0x00276ddbe8f3cca0, // 205
  559. .quad 0x8dda520237694809, 0x0027423bc827b0a6, // 206
  560. .quad 0x8d8be33f95d71590, 0x002716e3e67a921c, // 207
  561. .quad 0x8d3dcb08d3dcb08d, 0x0026ebd3a4bd8d01, // 208
  562. .quad 0x8cf008cf008cf009, 0x0026c10a657736fa, // 209
  563. .quad 0x8ca29c046514e023, 0x002696878cddffb1, // 210
  564. .quad 0x8c55841c815ed5ca, 0x00266c4a80d2a6b2, // 211
  565. .quad 0x8c08c08c08c08c09, 0x00264252a8dac681, // 212
  566. .quad 0x8bbc50c8deb420c0, 0x0026189f6e1b7473, // 213
  567. .quad 0x8b70344a139bc75a, 0x0025ef303b53f50e, // 214
  568. .quad 0x8b246a87e19008b2, 0x0025c6047cd8847d, // 215
  569. .quad 0x8ad8f2fba9386823, 0x00259d1ba08d32c5, // 216
  570. .quad 0x8a8dcd1feeae465c, 0x0025747515e0d378, // 217
  571. .quad 0x8a42f8705669db46, 0x00254c104dc80080, // 218
  572. .quad 0x89f87469a23920e0, 0x002523ecbab82fae, // 219
  573. .quad 0x89ae4089ae4089ae, 0x0024fc09d0a2dace, // 220
  574. .quad 0x89645c4f6e055dec, 0x0024d46704f0b9de, // 221
  575. .quad 0x891ac73ae9819b50, 0x0024ad03ce7d0f24, // 222
  576. .quad 0x88d180cd3a4133d7, 0x002485dfa59104dc, // 223
  577. .quad 0x8888888888888889, 0x00245efa03df1c1d, // 224
  578. .quad 0x883fddf00883fddf, 0x00243852647eaccb, // 225
  579. .quad 0x87f78087f78087f8, 0x002411e843e77632, // 226
  580. .quad 0x87af6fd5992d0d40, 0x0023ebbb1fed4014, // 227
  581. .quad 0x8767ab5f34e47ef1, 0x0023c5ca77bb8be3, // 228
  582. .quad 0x872032ac13008720, 0x0023a015cbd155d3, // 229
  583. .quad 0x86d905447a34acc6, 0x00237a9c9dfce59b, // 230
  584. .quad 0x869222b1acf1ce96, 0x0023555e7157ae8e, // 231
  585. .quad 0x864b8a7de6d1d608, 0x0023305aca423ed8, // 232
  586. .quad 0x86053c345a0b8473, 0x00230b912e603d96, // 233
  587. .quad 0x85bf37612cee3c9b, 0x0022e70124947795, // 234
  588. .quad 0x85797b917765ab89, 0x0022c2aa34fcfa72, // 235
  589. .quad 0x8534085340853408, 0x00229e8be8ef3de8, // 236
  590. .quad 0x84eedd357c1b0085, 0x00227aa5caf45b0a, // 237
  591. .quad 0x84a9f9c8084a9f9d, 0x002256f766c5512f, // 238
  592. .quad 0x84655d9bab2f1008, 0x002233804947585d, // 239
  593. .quad 0x8421084210842108, 0x0022104000884100, // 240
  594. .quad 0x83dcf94dc7570ce1, 0x0021ed361bbae0a0, // 241
  595. .quad 0x839930523fbe3368, 0x0021ca622b338b7a, // 242
  596. .quad 0x8355ace3c897db10, 0x0021a7c3c0649abe, // 243
  597. .quad 0x83126e978d4fdf3b, 0x0021855a6ddaff33, // 244
  598. .quad 0x82cf750393ac3319, 0x00216325c73ae026, // 245
  599. .quad 0x828cbfbeb9a020a3, 0x00214125613c4656, // 246
  600. .quad 0x824a4e60b3262bc5, 0x00211f58d1a7d2cb, // 247
  601. .quad 0x8208208208208208, 0x0020fdbfaf538145, // 248
  602. .quad 0x81c635bc123fdf8e, 0x0020dc59921f7638, // 249
  603. .quad 0x81848da8faf0d277, 0x0020bb2612f2d806, // 250
  604. .quad 0x814327e3b94f462f, 0x00209a24cbb8b365, // 251
  605. .quad 0x8102040810204081, 0x00207955575ceaab, // 252
  606. .quad 0x80c121b28bd1ba98, 0x002058b751c92feb, // 253
  607. .quad 0x8080808080808081, 0x0020384a57e209a8, // 254
  608. .quad 0x8040201008040201, 0x0020180e0783e1f9, // 255
  609. #endif // FASTDIV_TABLES