/* c数组有128位,采用加法加自身即可 */
static void shift(int * c)
{
__asm__("movl (%0),%%eax ; addl %%eax,(%0)\n\t"
"movl 4(%0),%%eax ; adcl %%eax,4(%0)\n\t"
"movl 8(%0),%%eax ; adcl %%eax,8(%0)\n\t"
"movl 12(%0),%%eax ; adcl %%eax,12(%0)"
::"r" ((long) c));
}
static void mul64(const temp_real * a, const temp_real * b, int * c)
{
/*
(%0)x(%1)=(%2)的乘法:
(%1) b a
(%0) b a x
------------------------
a*b a*a
b*b b*a
------------------------
12(%2) 8(%2) 4(%2) 0(%2)
mul指令:() x %eax = %edx,%eax
*/
__asm__("movl (%0),%%eax\n\t"
"mull (%1)\n\t"
"movl %%eax,(%2)\n\t"
"movl %%edx,4(%2)\n\t"
"movl 4(%0),%%eax\n\t"
"mull 4(%1)\n\t"
"movl %%eax,8(%2)\n\t"
"movl %%edx,12(%2)\n\t"
"movl (%0),%%eax\n\t"
"mull 4(%1)\n\t"
"addl %%eax,4(%2)\n\t"
"adcl %%edx,8(%2)\n\t"
"adcl $0,12(%2)\n\t"
"movl 4(%0),%%eax\n\t"
"mull (%1)\n\t"
"addl %%eax,4(%2)\n\t"
"adcl %%edx,8(%2)\n\t"
"adcl $0,12(%2)"
::"b" ((long) a),"c" ((long) b),"D" ((long) c));
}
void fmul(const temp_real * src1, const temp_real * src2, temp_real * result)
{
int i,sign;
int tmp[4] = {0,0,0,0}; /* 乘法的结果存储 */
sign = (src1->exponent ^ src2->exponent) & 0x8000; /* 异或计算出符号位 */
i = (src1->exponent & 0x7fff) + (src2->exponent & 0x7fff) - 16383 + 1; /* 计算指数部分,为嘛+1? */
if (i<0) { /* 很小趋近于0 */
result->exponent = sign;
result->a = result->b = 0;
return;
}
if (i>0x7fff) { /* 很大,溢出 */
set_OE();
return;
}
mul64(src1,src2,tmp); /* 做乘法 */
if (tmp[0] || tmp[1] || tmp[2] || tmp[3])
while (i && tmp[3] >= 0) { /* 规范化 */
i--;
shift(tmp);
}
else /* 结果为0 */
i = 0;
result->exponent = i | sign;
result->a = tmp[2]; /* 取高64位 */
result->b = tmp[3];
}
Linux 0.12 OS. math - mul.c
最新推荐文章于 2019-04-29 10:17:04 发布