-
+ 5CB7ABB0AE6C0C5D83D867DA564C67C84BD775F7F5089219EEF842DF04F5390C94DF546BFC48735E9965A3C363591C97167B99299EE94046C55714B83555E9E0
ffa/libffa/w_mul.adb
(0 . 0)(1 . 135)
222 ------------------------------------------------------------------------------
223 ------------------------------------------------------------------------------
224 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. --
225 -- --
226 -- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org ) --
227 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html --
228 -- --
229 -- You do not have, nor can you ever acquire the right to use, copy or --
230 -- distribute this software ; Should you use this software for any purpose, --
231 -- or copy and distribute it to anyone or in any manner, you are breaking --
232 -- the laws of whatever soi-disant jurisdiction, and you promise to --
233 -- continue doing so for the indefinite future. In any case, please --
234 -- always : read and understand any software ; verify any PGP signatures --
235 -- that you use - for any purpose. --
236 -- --
237 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . --
238 ------------------------------------------------------------------------------
239 ------------------------------------------------------------------------------
240
241 with W_Shifts; use W_Shifts;
242
243
244 package body W_Mul is
245
246 -- Multiply half-words X and Y, producing a Word-sized product
247 function Mul_HalfWord(X : in HalfWord; Y : in HalfWord) return Word is
248
249 -- X-Slide
250 XS : Word := X;
251
252 -- Y-Slide
253 YS : Word := Y;
254
255 -- Gate Mask
256 GM : Word;
257
258 -- The Product
259 XY : Word := 0;
260
261 -- Performed for each bit of HalfWord's bitness:
262 procedure Bit is
263 begin
264
265 -- Compute the gate mask
266 GM := 0 - (YS and 1);
267
268 -- Perform the gated addition
269 XY := XY + (XS and GM);
270
271 -- Crank the next Y-slide bit into position
272 YS := Shift_Right(YS, 1);
273
274 -- Advance the X-slide by 1 bit
275 XS := Shift_Left(XS, 1);
276
277 end Bit;
278 pragma Inline_Always(Bit);
279
280 begin
281
282 -- For each bit of the Y-Slide (unrolled) :
283 for b in 1 .. HalfByteness loop
284
285 Bit; Bit; Bit; Bit; Bit; Bit; Bit; Bit;
286
287 end loop;
288
289 -- Return the Product
290 return XY;
291
292 end Mul_HalfWord;
293 pragma Inline_Always(Mul_HalfWord);
294
295
296 -- Get the bottom half of a Word
297 function BottomHW(W : in Word) return HalfWord is
298 begin
299 return W and (2**HalfBitness - 1);
300 end BottomHW;
301 pragma Inline_Always(BottomHW);
302
303
304 -- Get the top half of a Word
305 function TopHW(W : in Word) return HalfWord is
306 begin
307 return Shift_Right(W, HalfBitness);
308 end TopHW;
309 pragma Inline_Always(TopHW);
310
311
312 -- Carry out X*Y mult, return lower word XY_LW and upper word XY_HW.
313 procedure Mul_Word(X : in Word;
314 Y : in Word;
315 XY_LW : out Word;
316 XY_HW : out Word) is
317
318 -- Bottom half of multiplicand X
319 XL : constant HalfWord := BottomHW(X);
320
321 -- Top half of multiplicand X
322 XH : constant HalfWord := TopHW(X);
323
324 -- Bottom half of multiplicand Y
325 YL : constant HalfWord := BottomHW(Y);
326
327 -- Top half of multiplicand Y
328 YH : constant HalfWord := TopHW(Y);
329
330 -- XL * YL
331 LL : constant Word := Mul_HalfWord(XL, YL);
332
333 -- XL * YH
334 LH : constant Word := Mul_HalfWord(XL, YH);
335
336 -- XH * YL
337 HL : constant Word := Mul_HalfWord(XH, YL);
338
339 -- XH * YH
340 HH : constant Word := Mul_HalfWord(XH, YH);
341
342 -- Carry
343 CL : constant Word := TopHW(TopHW(LL) + BottomHW(LH) + BottomHW(HL));
344
345 begin
346
347 -- Get the bottom half of the Product:
348 XY_LW := LL + Shift_Left(LH + HL, HalfBitness);
349
350 -- Get the top half of the Product:
351 XY_HW := HH + TopHW(HL) + TopHW(LH) + CL;
352
353 end Mul_Word;
354 pragma Inline_Always(Mul_Word);
355
356 end W_Mul;