12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- /*
- (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);
- }
|