Linux 0.12 OS. math - mul.c

/* 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];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值