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