xref: /titanic_44/usr/src/lib/libbc/libc/gen/common/_base_S.c (revision 5d54f3d8999eac1762fe0a8c7177d20f1f201fae)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1988 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include "base_conversion.h"
30 
31 /*	Fundamental utilities for base conversion that should be recoded as assembly language subprograms or as inline expansion templates. */
32 
33 /* Converts t < 10000 into four ascii digits at *pc.     */
34 void
_fourdigitsquick(short unsigned t,char * d)35 _fourdigitsquick(short unsigned t, char *d)
36 {
37 	short  i;
38 
39 	i = 3;
40 	do {
41 		d[i] = '0' + t % 10;
42 		t = t / 10;
43 	}
44 	while (--i != -1);
45 }
46 
47 void
_multiply_base_two_vector(short unsigned n,_BIG_FLOAT_DIGIT * px,short unsigned * py,_BIG_FLOAT_DIGIT product[3])48 _multiply_base_two_vector(short unsigned n, _BIG_FLOAT_DIGIT *px,
49     short unsigned *py, _BIG_FLOAT_DIGIT product[3])
50 {
51 	/*
52 	 * Given xi and yi, base 2**16 vectors of length n, computes dot
53 	 * product
54 	 *
55 	 * sum (i=0,n-1) of x[i]*y[n-1-i]
56 	 *
57 	 * Product may fill as many as three short-unsigned buckets. Product[0]
58 	 * is least significant, product[2] most.
59 	 */
60 
61 	unsigned long   acc, p;
62 	short unsigned  carry;
63 	int             i;
64 
65 	acc = 0;
66 	carry = 0;
67 	for (i = 0; i < n; i++) {
68 	p=_umac(px[i],py[n - 1 - i],acc);
69 		if (p < acc)
70 			carry++;
71 		acc = p;
72 	}
73 	product[0] = (_BIG_FLOAT_DIGIT) (acc & 0xffff);
74 	product[1] = (_BIG_FLOAT_DIGIT) (acc >> 16);
75 	product[2] = (_BIG_FLOAT_DIGIT) (carry);
76 }
77 
78 void
_multiply_base_ten_vector(short unsigned n,_BIG_FLOAT_DIGIT * px,short unsigned * py,_BIG_FLOAT_DIGIT product[3])79 _multiply_base_ten_vector(short unsigned n, _BIG_FLOAT_DIGIT *px,
80     short unsigned *py, _BIG_FLOAT_DIGIT product[3])
81 {
82 	/*
83 	 * Given xi and yi, base 10**4 vectors of length n, computes dot
84 	 * product
85 	 *
86 	 * sum (i=0,n-1) of x[i]*y[n-1-i]
87 	 *
88 	 * Product may fill as many as three short-unsigned buckets. Product[0]
89 	 * is least significant, product[2] most.
90 	 */
91 
92 #define ABASE	3000000000U	/* Base of accumulator. */
93 
94 	unsigned long   acc;
95 	short unsigned  carry;
96 	int             i;
97 
98 	acc = 0;
99 	carry = 0;
100 	for (i = 0; i < n; i++) {
101 	acc=_umac(px[i],py[n - 1 - i],acc);
102 		if (acc >= (unsigned long) ABASE) {
103 			carry++;
104 			acc -= ABASE;
105 		}
106 	}
107 	/*
108 	 NOTE: because
109 		acc * <= ABASE-1,
110 		acc/10000 <= 299999
111 	 which would overflow a short unsigned
112 	 */
113 	product[0] = (_BIG_FLOAT_DIGIT) (acc % 10000);
114 	acc /= 10000;
115 	product[1] = (_BIG_FLOAT_DIGIT) (acc % 10000);
116 	acc /= 10000;
117 	product[2] = (_BIG_FLOAT_DIGIT) (acc + (ABASE / 100000000) * carry);
118 }
119