See Mips run 之 浮点支持

来源:互联网 发布:mac外设品牌 编辑:程序博客网 时间:2024/05/14 06:07

一般来说,若要支持浮点,必须支持IEEE745, IEEE745主要规定了:

  • 硬件支持的浮点操作

  结果的舍入和精度,4种选项

  什么时候一个结果被看作是异常:除以0或负数平方根或其他等。。

  当一个操作产生异常结果时采取的动作:用户让计算中断并发出信号 或者 不想让用户知道给出一个规定的值。

  • 软件仿真的操作
  • 存储方式

  包括指数,尾数和符号位。例如,MIPS单精度和双精度存储结构如下:

支持浮点计算一般有两种方法:

  • 硬件实现
  • 软件仿真


IEEE异常处理

浮点协处理器拥有专门的浮点寄存器和浮点流水线,对于产生IEEE异常结果时,协处理器可以选择:

  • 硬件信号报告

这样会导致停止整个流水线

  • 硬件自陷

这要求在去指令的时决定是否自陷。自陷的结果一般交给软件实现的自陷处理程序处理(实际上就是异常处理程序)或者产生默认的结果(例如溢出异常会产生一个无穷大的值)


浮点协处理器寄存器

  • 32/64通用寄存器,支持单精度和双精度计算
  • 控制寄存器,FCSR/FIR/FCR/FEXR/FENR
  • 控制寄存器通过指令ctc1/cfc1来操作浮点寄存器访问,通用寄存器和其他通用寄存器访问方式一样。

指令集

汇编程序需要考虑时序问题:

修改浮点协处理器的控制寄存器和状态寄存器时,会影响浮点流水线的结果。一般在ctc1之后加上一两条nop

浮点和通用寄存器之间的数据传送完成的时间比较晚,因此后续的指令要使用传送的结果需要等待

浮点寄存器加载和整数加载一样慢,后面紧跟的指令不能立即使用刚加载的值

测试指令和分支,条件分支不能紧跟测试指令之后


现代MIPS FPU常常是完全流水线化的,允许每个始终启动一个心的浮点乘法、加法或者乘加计算,但是如果你要在下一个指令使用某天指令的结果的花,就会让程序停下来等待。对于浮点来说,乘法和加减法一样快。一般将除法转换为乘法进行加速。


即需初始化和使能

FPU使能后,在中断和上下文切换时需要保存和恢复浮点寄存器。所以:

 新任务默认禁止浮点(这样不需要保存和恢复浮点寄存器)

 当发生CU1不可用的自陷时,表示该任务为浮点用户,返回之前使能浮点。

 当处于核心态或中断例程直接间接调用的软件中,禁止浮点(这样可以避免中断时保存浮点寄存器)

应当用你选用的舍入模式和自陷使能设置控制/状态寄存器。

即需初始化和使能一般发生在进程切换。

  • 初始化

在进程第一次使用浮点部件的时候,由于浮点部件默认是不可用的,因此会产生浮点部件不可用异常,异常检查进程是否是第一次使用,如果是第一次使用则初始化task_struct ,thread_info等结构体相应的标识,并打开浮点部件。

  • 浮点现场保存

在进程切换的时候检查进程是否使用了浮点部件(即检查上述初始化的标识),如果没使用则不保存,否则保存现场并关闭浮点部件。

  • 浮点现场恢复

浮点现场恢复并不是在进程切换的时候,而是在进程切换后第一次使用浮点部件的时候。因为进程切换后浮点部件一定是关闭的。(原因是浮点部件默认关闭,而且即使前一个进程打开了浮点部件,切换时也会关闭)。在第一次使用时会产生浮点部件不可用例外,例外检查到进程不是第一次使用浮点部件则恢复浮点部件现场,并打开浮点部件。



浮点仿真

对于不支持浮点协处理器来说,一般通过软件浮点库或者自陷仿真程序支持浮点计算

软浮点:计算操作使用库函数实现,数据传送加载存储使用和整数一样的方式处理

自陷和仿真:硬件检测到浮点指令而发生自陷

不管是那种方式,仿真比硬件实现要慢50-300倍



MIPS浮点相关编译选项

-mfp32
Assume that floating-point registers are 32 bits wide.
假定浮点寄存器32bit.
-mfp64
Assume that floating-point registers are 64 bits wide.
 假定浮点寄存器64bit.
-mhard-float
Use floating-point coprocessor instructions. 使用浮点协处理器指令.
-msoft-float
Do not use floating-point coprocessor instructions. Implement floating-point calculations using library calls instead.  不时用浮点协处理器指令. 而使用浮点库.

 

-msingle-float
Assume that the floating-point coprocessor only supports single-precision operations.
设定浮点协处理器只支持单精度操作.
-mdouble-float
Assume that the floating-point coprocessor supports double-precision operations. This is the default. 双精度操作.



0 0
原创粉丝点击