Linux 0.12 OS. math - get_put.c

get_put.c提供浮点协处理器与操作数之间的交互功能,get_xxx可以把操作数读取出来转换为临时实数,put_xxx可以把浮点指令计算结果写到目的操作数里。

一 get/put_xxx说明

- get/put_short_real:load/store单精度实数(m32r)

- get/put_long_real:load/store双精度实数(m64r)

- get/put_temp_real:load/store临时实数(m80r)

- get/put_short_int:load/store短整数(m16j)

- get/put_long_int:load/store整数(m32j)

- get/put_longlong_int:load/store长整数(m64j)

二 temp_int临时整数

在短整数、整数和长整数读写的时候,需要用到一个临时整数的结构数据,然后临时整数在与临时实数进行转换,临时整数从结构体布局看和临时实数区别不大,但是代表的意义完全不同

typedef struct {
	long a,b;
	short sign;
} temp_int;

a和b成员变量可以看成是64位长整数的无符号形式,而符号位用一个短整数sign表示。

三 get/put_xxx函数

I. get_xxx

void get_short_real(temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	short_real sr; /* 单精度实数 */

	addr = ea(info,code); /* 得到操作数地址 */
	sr = get_fs_long((unsigned long *) addr); /* 取出内容 */
	short_to_temp(&sr,tmp); /* 转换为临时实数 */
}

void get_long_real(temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	long_real lr; /* 双精度实数 */

	addr = ea(info,code); /* 得到操作数地址 */
	lr.a = get_fs_long((unsigned long *) addr); /* 取出内容 */
	lr.b = get_fs_long(1 + (unsigned long *) addr);
	long_to_temp(&lr,tmp); /* 转换为临时实数 */
}

void get_temp_real(temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;

	addr = ea(info,code); /* 得到操作数地址 */
	tmp->a = get_fs_long((unsigned long *) addr); /* 取出内容 */
	tmp->b = get_fs_long(1 + (unsigned long *) addr);
	tmp->exponent = get_fs_word(4 + (unsigned short *) addr);
}

void get_short_int(temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	temp_int ti; /* 临时整数 */

	addr = ea(info,code); /* 得到操作数地址 */
	ti.a = (signed short) get_fs_word((unsigned short *) addr); /* 取出内容 */
	ti.b = 0; 
	if ((ti.sign = (ti.a < 0))) /* 确定符号 */
		ti.a = - ti.a; /* 若为负数,则负负得正 */
	int_to_real(&ti,tmp); /* 转换为临时实数 */
}

void get_long_int(temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	temp_int ti; /* 临时整数 */

	addr = ea(info,code); /* 得到操作数地址 */
	ti.a = get_fs_long((unsigned long *) addr); /* 取出内容 */
	ti.b = 0;
	if ((ti.sign = (ti.a < 0))) /* 确定符号 */
		ti.a = - ti.a; /* 若为负数,则负负得正 */
	int_to_real(&ti,tmp); /* 转换为临时实数 */
}

void get_longlong_int(temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	temp_int ti; /* 临时整数 */

	addr = ea(info,code); /* 得到操作数地址 */
	ti.a = get_fs_long((unsigned long *) addr); /* 取出内容 */
	ti.b = get_fs_long(1 + (unsigned long *) addr);
	if ((ti.sign = (ti.b < 0))) /* 确定符号 */
		__asm__("notl %0 ; notl %1\n\t"
			"addl $1,%0 ; adcl $0,%1"
			:"=r" (ti.a),"=r" (ti.b)
			:"0" (ti.a),"1" (ti.b)); /* 若为负数,则负负得正(即取反加1)*/
	int_to_real(&ti,tmp); /* 转换为临时实数 */
}

II. put_xxx

void put_short_real(const temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	short_real sr; /* 单精度实数 */

	addr = ea(info,code); /* 得到操作数地址 */
	verify_area(addr,4); /* 验证是否可写(4个字节) */
	temp_to_short(tmp,&sr); /* 转换为单精度实数 */
	put_fs_long(sr,(unsigned long *) addr); /* 写入内容 */
}

void put_long_real(const temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	long_real lr; /* 双精度实数 */

	addr = ea(info,code); /* 得到操作数地址 */
	verify_area(addr,8); /* 验证是否可写(8个字节)*/
	temp_to_long(tmp,&lr); /* 转换为双精度实数 */
	put_fs_long(lr.a, (unsigned long *) addr); /* 写入内容 */
	put_fs_long(lr.b, 1 + (unsigned long *) addr);
}

void put_temp_real(const temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;

	addr = ea(info,code); /* 得到操作数地址 */
	verify_area(addr,10); /* 验证是否可写(10个字节)*/
	put_fs_long(tmp->a, (unsigned long *) addr); /* 写入内容 */
	put_fs_long(tmp->b, 1 + (unsigned long *) addr);
	put_fs_word(tmp->exponent, 4 + (short *) addr);
}

void put_short_int(const temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	temp_int ti; /* 临时整数 */

	addr = ea(info,code); /* 得到操作数地址 */
	real_to_int(tmp,&ti); /* 转换为整数 */
	verify_area(addr,2); /* 验证是否可写(2个字节)*/
	if (ti.sign) /* 若为负数,则转换为负数 */
		ti.a = -ti.a;
	put_fs_word(ti.a,(short *) addr); /* 写入内容 */
}

void put_long_int(const temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	temp_int ti; /* 临时整数 */

	addr = ea(info,code); /* 得到操作数地址 */
	real_to_int(tmp,&ti); /* 转换为整数 */
	verify_area(addr,4); /* 验证是否可写(4个字节)*/
	if (ti.sign) /* 若为负数,则转换为负数 */
		ti.a = -ti.a;
	put_fs_long(ti.a,(unsigned long *) addr); /* 写入内容 */
}

void put_longlong_int(const temp_real * tmp,
	struct info * info, unsigned short code)
{
	char * addr;
	temp_int ti; /* 临时整数 */

	addr = ea(info,code); /* 得到操作数地址 */
	real_to_int(tmp,&ti); /* 转换为整数 */
	verify_area(addr,8); /* 验证是否可写(8个字节)*/
	if (ti.sign) /*若为负数,则转换为负数(即取反加1)*/
		__asm__("notl %0 ; notl %1\n\t"
			"addl $1,%0 ; adcl $0,%1"
			:"=r" (ti.a),"=r" (ti.b)
			:"0" (ti.a),"1" (ti.b));
	put_fs_long(ti.a,(unsigned long *) addr); /* 写入内容 */
	put_fs_long(ti.b,1 + (unsigned long *) addr);
}

你可能感兴趣的:(Linux 0.12 OS. math - get_put.c)