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); }