OpenSolaris_b135/lib/libbc/libc/gen/common/_base_S.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 1988 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include "base_conversion.h"

/*	Fundamental utilities for base conversion that should be recoded as assembly language subprograms or as inline expansion templates. */

/* Converts t < 10000 into four ascii digits at *pc.     */
void
_fourdigitsquick(short unsigned t, char *d)
{
	short  i;

	i = 3;
	do {
		d[i] = '0' + t % 10;
		t = t / 10;
	}
	while (--i != -1);
}

void
_multiply_base_two_vector(short unsigned n, _BIG_FLOAT_DIGIT *px,
    short unsigned *py, _BIG_FLOAT_DIGIT product[3])
{
	/*
	 * Given xi and yi, base 2**16 vectors of length n, computes dot
	 * product
	 * 
	 * sum (i=0,n-1) of x[i]*y[n-1-i]
	 * 
	 * Product may fill as many as three short-unsigned buckets. Product[0]
	 * is least significant, product[2] most.
	 */

	unsigned long   acc, p;
	short unsigned  carry;
	int             i;

	acc = 0;
	carry = 0;
	for (i = 0; i < n; i++) {
	p=_umac(px[i],py[n - 1 - i],acc);
		if (p < acc)
			carry++;
		acc = p;
	}
	product[0] = (_BIG_FLOAT_DIGIT) (acc & 0xffff);
	product[1] = (_BIG_FLOAT_DIGIT) (acc >> 16);
	product[2] = (_BIG_FLOAT_DIGIT) (carry);
}

void
_multiply_base_ten_vector(short unsigned n, _BIG_FLOAT_DIGIT *px,
    short unsigned *py, _BIG_FLOAT_DIGIT product[3])
{
	/*
	 * Given xi and yi, base 10**4 vectors of length n, computes dot
	 * product
	 * 
	 * sum (i=0,n-1) of x[i]*y[n-1-i]
	 * 
	 * Product may fill as many as three short-unsigned buckets. Product[0]
	 * is least significant, product[2] most.
	 */

#define ABASE	3000000000U	/* Base of accumulator. */

	unsigned long   acc;
	short unsigned  carry;
	int             i;

	acc = 0;
	carry = 0;
	for (i = 0; i < n; i++) {
	acc=_umac(px[i],py[n - 1 - i],acc);
		if (acc >= (unsigned long) ABASE) {
			carry++;
			acc -= ABASE;
		}
	}
	/*
	 NOTE: because 
		acc * <= ABASE-1,
		acc/10000 <= 299999
	 which would overflow a short unsigned
	 */
	product[0] = (_BIG_FLOAT_DIGIT) (acc % 10000);
	acc /= 10000;
	product[1] = (_BIG_FLOAT_DIGIT) (acc % 10000);
	acc /= 10000;
	product[2] = (_BIG_FLOAT_DIGIT) (acc + (ABASE / 100000000) * carry);
}