/* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands. See the copyright notice in the ACK home directory, in the file "Copyright". */ /* $Id$ */ #include "flt_misc.h" void 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 */ flt_split(e1, mp); flt_split(e2, mc); 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); }