quad.h revision 50477
1240116Smarcel/*-
2240116Smarcel * Copyright (c) 1992, 1993
3240116Smarcel *	The Regents of the University of California.  All rights reserved.
4240116Smarcel *
5240116Smarcel * This software was developed by the Computer Systems Engineering group
6240116Smarcel * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7240116Smarcel * contributed to Berkeley.
8240116Smarcel *
9240116Smarcel * Redistribution and use in source and binary forms, with or without
10240116Smarcel * modification, are permitted provided that the following conditions
11240116Smarcel * are met:
12240116Smarcel * 1. Redistributions of source code must retain the above copyright
13240116Smarcel *    notice, this list of conditions and the following disclaimer.
14240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright
15240116Smarcel *    notice, this list of conditions and the following disclaimer in the
16240116Smarcel *    documentation and/or other materials provided with the distribution.
17240116Smarcel * 3. All advertising materials mentioning features or use of this software
18240116Smarcel *    must display the following acknowledgement:
19240116Smarcel *	This product includes software developed by the University of
20240116Smarcel *	California, Berkeley and its contributors.
21240116Smarcel * 4. Neither the name of the University nor the names of its contributors
22240116Smarcel *    may be used to endorse or promote products derived from this software
23240116Smarcel *    without specific prior written permission.
24240116Smarcel *
25240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26240116Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27240116Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28240116Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29240116Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31240116Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32240116Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33240116Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34240116Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35240116Smarcel * SUCH DAMAGE.
36240116Smarcel *
37240116Smarcel *	@(#)quad.h	8.1 (Berkeley) 6/4/93
38240116Smarcel * $FreeBSD: head/sys/libkern/quad.h 50477 1999-08-28 01:08:13Z peter $
39240116Smarcel */
40240116Smarcel
41240116Smarcel/*
42240116Smarcel * Quad arithmetic.
43240116Smarcel *
44240116Smarcel * This library makes the following assumptions:
45240116Smarcel *
46240116Smarcel *  - The type long long (aka quad_t) exists.
47240116Smarcel *
48240116Smarcel *  - A quad variable is exactly twice as long as `long'.
49240116Smarcel *
50240116Smarcel *  - The machine's arithmetic is two's complement.
51240116Smarcel *
52240116Smarcel * This library can provide 128-bit arithmetic on a machine with 128-bit
53240116Smarcel * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines
54240116Smarcel * with 48-bit longs.
55240116Smarcel */
56240116Smarcel
57240116Smarcel#include <sys/cdefs.h>
58240116Smarcel#include <sys/types.h>
59240116Smarcel#include <limits.h>
60240116Smarcel
61240116Smarcel/*
62240116Smarcel * Depending on the desired operation, we view a `long long' (aka quad_t) in
63240116Smarcel * one or more of the following formats.
64240116Smarcel */
65240116Smarcelunion uu {
66240116Smarcel	quad_t	q;		/* as a (signed) quad */
67240116Smarcel	quad_t	uq;		/* as an unsigned quad */
68240116Smarcel	long	sl[2];		/* as two signed longs */
69240116Smarcel	u_long	ul[2];		/* as two unsigned longs */
70240116Smarcel};
71240116Smarcel
72240116Smarcel/*
73240116Smarcel * Define high and low longwords.
74240116Smarcel */
75240116Smarcel#define	H		_QUAD_HIGHWORD
76240116Smarcel#define	L		_QUAD_LOWWORD
77240116Smarcel
78240116Smarcel/*
79240116Smarcel * Total number of bits in a quad_t and in the pieces that make it up.
80240116Smarcel * These are used for shifting, and also below for halfword extraction
81240116Smarcel * and assembly.
82240116Smarcel */
83240116Smarcel#define	QUAD_BITS	(sizeof(quad_t) * CHAR_BIT)
84240116Smarcel#define	LONG_BITS	(sizeof(long) * CHAR_BIT)
85240116Smarcel#define	HALF_BITS	(sizeof(long) * CHAR_BIT / 2)
86240116Smarcel
87240116Smarcel/*
88240116Smarcel * Extract high and low shortwords from longword, and move low shortword of
89240116Smarcel * longword to upper half of long, i.e., produce the upper longword of
90240116Smarcel * ((quad_t)(x) << (number_of_bits_in_long/2)).  (`x' must actually be u_long.)
91240116Smarcel *
92240116Smarcel * These are used in the multiply code, to split a longword into upper
93240116Smarcel * and lower halves, and to reassemble a product as a quad_t, shifted left
94240116Smarcel * (sizeof(long)*CHAR_BIT/2).
95240116Smarcel */
96240116Smarcel#define	HHALF(x)	((x) >> HALF_BITS)
97240116Smarcel#define	LHALF(x)	((x) & ((1 << HALF_BITS) - 1))
98240116Smarcel#define	LHUP(x)		((x) << HALF_BITS)
99240116Smarcel
100240116Smarcelquad_t		__divdi3 __P((quad_t a, quad_t b));
101240116Smarcelquad_t		__moddi3 __P((quad_t a, quad_t b));
102240116Smarcelu_quad_t	__qdivrem __P((u_quad_t u, u_quad_t v, u_quad_t *rem));
103240116Smarcelu_quad_t	__udivdi3 __P((u_quad_t a, u_quad_t b));
104240116Smarcelu_quad_t	__umoddi3 __P((u_quad_t a, u_quad_t b));
105240116Smarcel
106240116Smarcel/*
107240116Smarcel * XXX
108240116Smarcel * Compensate for gcc 1 vs gcc 2.  Gcc 1 defines ?sh?di3's second argument
109240116Smarcel * as u_quad_t, while gcc 2 correctly uses int.  Unfortunately, we still use
110240116Smarcel * both compilers.
111240116Smarcel */
112240116Smarcel#if __GNUC__ >= 2
113240116Smarceltypedef unsigned int	qshift_t;
114240116Smarcel#else
115240116Smarceltypedef u_quad_t	qshift_t;
116240116Smarcel#endif
117240116Smarcel