chiark / gitweb /
d0b81fce32a98c20a78b497983c80a2593c16982
[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