Release 2.1.2.
[u/mdw/catacomb] / karatsuba.h
1 /* -*-c-*-
2 *
3 * $Id: karatsuba.h,v 1.3 2004/04/08 01:36:15 mdw Exp $
4 *
5 * Macros for Karatsuba functions
6 *
7 * (c) 2000 Straylight/Edgeware
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30 #ifndef CATACOMB_KARATSUBA_H
31 #define CATACOMB_KARATSUBA_H
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #ifndef CATACOMB_MPW_H
40 # include "mpw.h"
41 #endif
42
43 /*----- Normal arithmetic macros ------------------------------------------*/
44
45 #define UADD(dv, av, avl) do { \
46 mpw *_dv = (dv); \
47 const mpw *_av = (av), *_avl = (avl); \
48 mpw _c = 0; \
49 \
50 while (_av < _avl) { \
51 mpw _a, _b; \
52 mpd _x; \
53 _a = *_av++; \
54 _b = *_dv; \
55 _x = (mpd)_a + (mpd)_b + _c; \
56 *_dv++ = MPW(_x); \
57 _c = _x >> MPW_BITS; \
58 } \
59 while (_c) { \
60 mpd _x = (mpd)*_dv + (mpd)_c; \
61 *_dv++ = MPW(_x); \
62 _c = _x >> MPW_BITS; \
63 } \
64 } while (0)
65
66 #define UADD2(dv, dvl, av, avl, bv, bvl) do { \
67 mpw *_dv = (dv), *_dvl = (dvl); \
68 const mpw *_av = (av), *_avl = (avl); \
69 const mpw *_bv = (bv), *_bvl = (bvl); \
70 mpw _c = 0; \
71 \
72 while (_av < _avl || _bv < _bvl) { \
73 mpw _a, _b; \
74 mpd _x; \
75 _a = (_av < _avl) ? *_av++ : 0; \
76 _b = (_bv < _bvl) ? *_bv++ : 0; \
77 _x = (mpd)_a + (mpd)_b + _c; \
78 *_dv++ = MPW(_x); \
79 _c = _x >> MPW_BITS; \
80 } \
81 *_dv++ = _c; \
82 while (_dv < _dvl) \
83 *_dv++ = 0; \
84 } while (0)
85
86 #define USUB(dv, av, avl) do { \
87 mpw *_dv = (dv); \
88 const mpw *_av = (av), *_avl = (avl); \
89 mpw _c = 0; \
90 \
91 while (_av < _avl) { \
92 mpw _a, _b; \
93 mpd _x; \
94 _a = *_av++; \
95 _b = *_dv; \
96 _x = (mpd)_b - (mpd)_a - _c; \
97 *_dv++ = MPW(_x); \
98 if (_x >> MPW_BITS) \
99 _c = 1; \
100 else \
101 _c = 0; \
102 } \
103 while (_c) { \
104 mpd _x = (mpd)*_dv - (mpd)_c; \
105 *_dv++ = MPW(_x); \
106 if (_x >> MPW_BITS) \
107 _c = 1; \
108 else \
109 _c = 0; \
110 } \
111 } while (0)
112
113 /*----- Binary polynomial arithmetic macros -------------------------------*/
114
115 #define UXOR(dv, av, avl) do { \
116 mpw *_dv = (dv); \
117 const mpw *_av = (av), *_avl = (avl); \
118 \
119 while (_av < _avl) \
120 *_dv++ ^= *_av++; \
121 } while (0)
122
123 #define UXOR2(dv, dvl, av, avl, bv, bvl) do { \
124 mpw *_dv = (dv), *_dvl = (dvl); \
125 const mpw *_av = (av), *_avl = (avl); \
126 const mpw *_bv = (bv), *_bvl = (bvl); \
127 \
128 while (_av < _avl || _bv < _bvl) { \
129 mpw _a, _b; \
130 _a = (_av < _avl) ? *_av++ : 0; \
131 _b = (_bv < _bvl) ? *_bv++ : 0; \
132 *_dv++ = _a ^ _b; \
133 } \
134 while (_dv < _dvl) \
135 *_dv++ = 0; \
136 } while (0)
137
138 /*----- That's all, folks -------------------------------------------------*/
139
140 #ifdef __cplusplus
141 }
142 #endif
143
144 #endif