math.c revision 1.1.1.1.2.2 1 1.1.1.1.2.2 pgoyette /* $NetBSD: math.c,v 1.1.1.1.2.2 2018/09/06 06:56:39 pgoyette Exp $ */
2 1.1.1.1.2.2 pgoyette
3 1.1.1.1.2.2 pgoyette /*
4 1.1.1.1.2.2 pgoyette * Copright (C) 2014 Linaro Ltd.
5 1.1.1.1.2.2 pgoyette * Author: Ard Biesheuvel <ard.biesheuvel (at) linaro.org>
6 1.1.1.1.2.2 pgoyette *
7 1.1.1.1.2.2 pgoyette * Redistribution and use in source and binary forms, with or without
8 1.1.1.1.2.2 pgoyette * modification, are permitted provided that the following conditions
9 1.1.1.1.2.2 pgoyette * are met:
10 1.1.1.1.2.2 pgoyette * 1. Redistributions of source code must retain the above copyright
11 1.1.1.1.2.2 pgoyette * notice and this list of conditions, without modification.
12 1.1.1.1.2.2 pgoyette * 2. The name of the author may not be used to endorse or promote products
13 1.1.1.1.2.2 pgoyette * derived from this software without specific prior written permission.
14 1.1.1.1.2.2 pgoyette *
15 1.1.1.1.2.2 pgoyette * Alternatively, this software may be distributed under the terms of the
16 1.1.1.1.2.2 pgoyette * GNU General Public License as published by the Free Software Foundation;
17 1.1.1.1.2.2 pgoyette * either version 2 of the License, or (at your option) any later version.
18 1.1.1.1.2.2 pgoyette */
19 1.1.1.1.2.2 pgoyette
20 1.1.1.1.2.2 pgoyette #include "lib.h"
21 1.1.1.1.2.2 pgoyette
22 1.1.1.1.2.2 pgoyette UINT64
23 1.1.1.1.2.2 pgoyette LShiftU64 (
24 1.1.1.1.2.2 pgoyette IN UINT64 Operand,
25 1.1.1.1.2.2 pgoyette IN UINTN Count
26 1.1.1.1.2.2 pgoyette )
27 1.1.1.1.2.2 pgoyette // Left shift 64bit by 32bit and get a 64bit result
28 1.1.1.1.2.2 pgoyette {
29 1.1.1.1.2.2 pgoyette return Operand << Count;
30 1.1.1.1.2.2 pgoyette }
31 1.1.1.1.2.2 pgoyette
32 1.1.1.1.2.2 pgoyette UINT64
33 1.1.1.1.2.2 pgoyette RShiftU64 (
34 1.1.1.1.2.2 pgoyette IN UINT64 Operand,
35 1.1.1.1.2.2 pgoyette IN UINTN Count
36 1.1.1.1.2.2 pgoyette )
37 1.1.1.1.2.2 pgoyette // Right shift 64bit by 32bit and get a 64bit result
38 1.1.1.1.2.2 pgoyette {
39 1.1.1.1.2.2 pgoyette return Operand >> Count;
40 1.1.1.1.2.2 pgoyette }
41 1.1.1.1.2.2 pgoyette
42 1.1.1.1.2.2 pgoyette
43 1.1.1.1.2.2 pgoyette UINT64
44 1.1.1.1.2.2 pgoyette MultU64x32 (
45 1.1.1.1.2.2 pgoyette IN UINT64 Multiplicand,
46 1.1.1.1.2.2 pgoyette IN UINTN Multiplier
47 1.1.1.1.2.2 pgoyette )
48 1.1.1.1.2.2 pgoyette // Multiply 64bit by 32bit and get a 64bit result
49 1.1.1.1.2.2 pgoyette {
50 1.1.1.1.2.2 pgoyette return Multiplicand * Multiplier;
51 1.1.1.1.2.2 pgoyette }
52 1.1.1.1.2.2 pgoyette
53 1.1.1.1.2.2 pgoyette UINT64
54 1.1.1.1.2.2 pgoyette DivU64x32 (
55 1.1.1.1.2.2 pgoyette IN UINT64 Dividend,
56 1.1.1.1.2.2 pgoyette IN UINTN Divisor,
57 1.1.1.1.2.2 pgoyette OUT UINTN *Remainder OPTIONAL
58 1.1.1.1.2.2 pgoyette )
59 1.1.1.1.2.2 pgoyette {
60 1.1.1.1.2.2 pgoyette /*
61 1.1.1.1.2.2 pgoyette * GCC turns a division into a multiplication and shift with precalculated
62 1.1.1.1.2.2 pgoyette * constants if the divisor is constant and the dividend fits into a 32 bit
63 1.1.1.1.2.2 pgoyette * variable. Otherwise, it will turn this into calls into the 32-bit div
64 1.1.1.1.2.2 pgoyette * library functions.
65 1.1.1.1.2.2 pgoyette */
66 1.1.1.1.2.2 pgoyette if (Remainder)
67 1.1.1.1.2.2 pgoyette *Remainder = Dividend % Divisor;
68 1.1.1.1.2.2 pgoyette return Dividend / Divisor;
69 1.1.1.1.2.2 pgoyette }
70