我们都知道MIPS架构体系是32位精简指令集(MIPS32),事实上MIPS在进入控制器市场时还推出了MIPS16e指令集模式,号称能够使编译后的代码减少30%左右,类似于ARM架构中是arm32指令(32位)和thumb(16位)指令。内存资源紧缺型系统一般会使用MIPS16e模式进行编译,以缩减内存使用量,达到降低成本的目的。
ISAMODE是指令集运行模式的指示位,但这个比特位并不是固定在某个寄存器中。调试时可以发现,该比特位对应32位运行地址的最低比特位。为1时代表此时芯片运行的是MIPS16e模式,0即意味着MIPS32模式。指令运行过程中,两种指令集的切换是自动、无缝地完成的。在ARM架构中是arm指令和thumb指令切换。
本文说明两种指令模式的切换机制,并用实例来详细说明两者之间是如何进行切换的。一、必须跑MIPS32指令集模式的场景
这是MIPS体系结构决定的:
1. 中断/异常。CPU响应中断/异常之后就自动进入mips32模式。
2. “sync”指令必须在mips32模式下使用。
3. 协处理器cp0的读写必须在mips32模式下。
4. 因为性能的考虑,某些算法有时追求高效率,应该运行在mips32模式下。
二、运行模式切换
1. 异常/中断
MIPS异常和中断发生时会自动转到32位模式,这时EPC寄存器记录的是发生异常时的地址(该地址如果之前运行于MIPS16e模式,则是16位对齐,否则是32位对齐),其最低位就对应ISAMODE bit。中断/异常处理过程可以保存EPC并切换到16e模式运行。
在中断/异常返回时,即调用ERET指令时,可以返回到EPC中保存的地址,并把EPC的最低位赋值给ISAMODE,恢复到原来的运行模式。2. 函数调用和返回
运行模式协同工作的原理主要是在调用时将代表当前运行模式的ISAMODE BIT和返回地址一起放到RA或者某个指定的寄存器。因为mips16e/32的返回地址至少是2字节对齐,所以其最低位一定是0,ISA MODE BIT占用bit 0不会造成返回地址混乱。
在返回时,根据RA或者RX的bit 0恢复运行模式,接着返回。