85 lines
1.8 KiB
C

/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
#include "misc.h"
flt_mul(e1,e2,e3)
register flt_arith *e1,*e2,*e3;
{
/* Multiply the extended numbers e1 and e2, and put the
result in e3.
*/
register int i,j; /* loop control */
unsigned short mp[4];
unsigned short mc[4];
unsigned short result[8]; /* result */
register unsigned short *pres;
flt_status = 0;
/* first save the sign (XOR) */
e3->flt_sign = e1->flt_sign ^ e2->flt_sign;
/* compute new exponent */
e3->flt_exp = e1->flt_exp + e2->flt_exp + 1;
/* 128 bit multiply of mantissas */
/* assign unknown long formats */
/* to known unsigned word formats */
mp[0] = (e1->m1 >> 16) & 0xFFFF;
mp[1] = e1->m1 & 0xFFFF;
mp[2] = (e1->m2 >> 16) & 0xFFFF;
mp[3] = e1->m2 & 0xFFFF;
mc[0] = (e2->m1 >> 16) & 0xFFFF;
mc[1] = e2->m1 & 0xFFFF;
mc[2] = (e2->m2 >> 16) & 0xFFFF;
mc[3] = e2->m2 & 0xFFFF;
for (i = 8; i--;) {
result[i] = 0;
}
/*
* fill registers with their components
*/
for(i=4, pres = &result[4];i--;pres--) if (mp[i]) {
unsigned short k = 0;
long mpi = mp[i];
for(j=4;j--;) {
long tmp = (long)pres[j] + k;
if (mc[j]) tmp += mpi * mc[j];
pres[j] = tmp & 0xFFFF;
k = (tmp >> 16) & 0xFFFF;
}
pres[-1] = k;
}
if (! (result[0] & 0x8000)) {
e3->flt_exp--;
for (i = 0; i <= 3; i++) {
result[i] <<= 1;
if (result[i+1]&0x8000) result[i] |= 1;
}
result[4] <<= 1;
}
/*
* combine the registers to a total
*/
e3->m1 = ((long)result[0] << 16) + result[1];
e3->m2 = ((long)result[2] << 16) + result[3];
if (result[4] & 0x8000) {
if (++e3->m2 == 0 || (e3->m2 & ~ 0xFFFFFFFF)) {
e3->m2 = 0;
if (++e3->m1 == 0 || (e3->m1 & ~ 0xFFFFFFFF)) {
e3->m1 = 0x80000000;
e3->flt_exp++;
}
}
}
flt_chk(e3);
}