• ISA(MIPS,ARM,RISC-V)中的算术运算溢出检测逻辑是怎样的?


    关于ISA架构,之前写过一些总结。这里单独将其中一个技术点拿出来,对比分析不同架构下实现的差异。这个技术点就是算术指令中的溢出检测。

    ARM体系结构中,通过CPSR的状态寄存器反映当前指令的溢出状态。

    而MIPS,则是通过指令触发中断的方式产生溢出信号,通知处理器,比如,MIPS有如下计算指令:

    加法操作:add rd, rs, rt

    指令作用为:rd<-rs+rt.将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行加法运算,结果保存到地址为rd的通用寄存器中。但是这里有一种特殊情况是,如果加法运算溢出,那么会产生溢出异常,同时不保存结果。

    加法操作:addu rd, rs, rt

    指令作用为rd<-rs+rt.将地址为RS的通用寄存器的值与地址为rt的通用寄存器的值进行加法运算,结果保存到地址为rd的寄存器中,与上面ADD指令的不同之处在于ADDU指令不进行溢出检查,总是将结果保存到目的寄存器。

    减法操作:sub rd, rs, rt

    指令作为用为,rd<-rs-rt,将地址为RS的通用寄存器的值与地址为rt的通用寄存器的值进行减法运算,结果保存到地址为RD的通用寄存器中,但是有一种特殊情况,如果减法操作溢出,那么将产生溢出一场,同时不保存结果。

    减法操作:subu rd, rs, rt

    指令作为用为,rd<-rs-rt,将地址为RS的通用寄存器的值与地址为rt的通用寄存器的值进行减法运算,结果保存到地址为RD的通用寄存器中,与SUB指令不同之处在于,subu指令不进行溢出检查,总是将结果保存到目的寄存器。

    比较运算指令:slt rd, rs,rt

    指令作用为: rd<-(rs

    比较运算指令:sltu rd, rs,rt

    指令作用为: rd<-(rs

    所以,可以很明显看到RISCV&MIPS和ARM的不同之处。

    现在我们通过波形来分析溢出的逻辑是如何处理的

    仿真指令:

    其中,上途中被颜色重点标记的指令OP分别为addu,ori,add,sub,subu,对应流水线执行阶段的aluop_i操作码为0x21,0x25,0x20,0x22, 0x23.

    其中的ov_sum信号的变化规律如下:

     ov_sum信号的控制逻辑,在数字电路中,减法也是通过加法器实现的,所以无论ISA中的指令是ADD还是SUM,最终在ALU电路层面都是加法器实现的计算。

    当add两个操作数分别为0x80000001和0x80000010时,得到的数字溢出,可以看到OV_SUM信号被拉高。

    ov_sum产生逻辑:

    RISCV的实现:

    软件检查溢出 大部分(但不是所有)程序都忽略整数算术溢出,因此 RISC-V 依赖于软件溢出检查。检查无符号加法的溢出只需要在指令后添加一个额外的分支指令:

    addu t0,t1,t2;

    bltu t0, t1,overflow。

    对于带符号的加法,如果已知一个操作数的符号,则溢出检查只需要在加法后添加一条分支 指令:

    addi t0,t1,+ imm;

    blt t0,t1,overflow

    这覆盖了常见的加立即数的情况。对于一般的带符号加法,我们需要在加法指令后添加三个 附加指令,当且仅当一个操作数为负数时,结果才能小于另一个操作数,否则就是溢出。

    add t0, t1, t2

    slti t3, t2, 0 

    slt t4,t0,t1

    bne t3, t4, overflow


    结束

  • 相关阅读:
    SpringBoot学习入门之Hello项目的构建、单元测试和热部署等(配图文,配置信息详解,附案例源码)
    解决Kibana初始化失败报错: Unable to connect to Elasticsearch
    观察者模式-对象间的联动
    IMX6ULL学习笔记(7)——通过SD卡启动U-Boot
    ADC、DMA以及串口之间的联系和区别?
    ES系列二之常见问题解决
    从数据库设计到性能调优,全面掌握openGemini应用开发最佳实践
    《Java 后端面试经》微服务篇
    Reactor的Publisher与Subscriber
    数据结构初阶---复杂度的OJ例题
  • 原文地址:https://blog.csdn.net/tugouxp/article/details/126234296