|
|
1.1 root 1: /*
2: * linux/kernel/math/mul.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
7: /*
8: * temporary real multiplication routine.
9: */
10:
11: #include <linux/math_emu.h>
12:
13: static void shift(int * c)
14: {
15: __asm__("movl (%0),%%eax ; addl %%eax,(%0)\n\t"
16: "movl 4(%0),%%eax ; adcl %%eax,4(%0)\n\t"
17: "movl 8(%0),%%eax ; adcl %%eax,8(%0)\n\t"
18: "movl 12(%0),%%eax ; adcl %%eax,12(%0)"
19: ::"r" ((long) c):"ax");
20: }
21:
22: static void mul64(const temp_real * a, const temp_real * b, int * c)
23: {
24: __asm__("movl (%0),%%eax\n\t"
25: "mull (%1)\n\t"
26: "movl %%eax,(%2)\n\t"
27: "movl %%edx,4(%2)\n\t"
28: "movl 4(%0),%%eax\n\t"
29: "mull 4(%1)\n\t"
30: "movl %%eax,8(%2)\n\t"
31: "movl %%edx,12(%2)\n\t"
32: "movl (%0),%%eax\n\t"
33: "mull 4(%1)\n\t"
34: "addl %%eax,4(%2)\n\t"
35: "adcl %%edx,8(%2)\n\t"
36: "adcl $0,12(%2)\n\t"
37: "movl 4(%0),%%eax\n\t"
38: "mull (%1)\n\t"
39: "addl %%eax,4(%2)\n\t"
40: "adcl %%edx,8(%2)\n\t"
41: "adcl $0,12(%2)"
42: ::"b" ((long) a),"c" ((long) b),"D" ((long) c)
43: :"ax","dx");
44: }
45:
46: void fmul(const temp_real * src1, const temp_real * src2, temp_real * result)
47: {
48: int i,sign;
49: int tmp[4] = {0,0,0,0};
50:
51: sign = (src1->exponent ^ src2->exponent) & 0x8000;
52: i = (src1->exponent & 0x7fff) + (src2->exponent & 0x7fff) - 16383 + 1;
53: if (i<0) {
54: result->exponent = sign;
55: result->a = result->b = 0;
56: return;
57: }
58: if (i>0x7fff) {
59: set_OE();
60: return;
61: }
62: mul64(src1,src2,tmp);
63: if (tmp[0] || tmp[1] || tmp[2] || tmp[3])
64: while (i && tmp[3] >= 0) {
65: i--;
66: shift(tmp);
67: }
68: else
69: i = 0;
70: result->exponent = i | sign;
71: result->a = tmp[2];
72: result->b = tmp[3];
73: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.