Mips

阶段一:骨架与基础数据结构

阶段二:函数级代码生成

阶段三:表达式与控制流

  • 扩展指令使用: 根据 IR 基本块遍历生成算术:add/sub → MipsAlu;赋值/变量访问:寄存器直接用,内存用 lw/sw
  • 加载常数:若小常数用 addiu / 若需要可临时增加伪指令支持(可后放)。
  • 控制流: 基本块起始插入 MipsLabel;终结指令 br/条件跳转→ beq/bne + 目标标签;无条件跳转 → j labelreturn → 写返回值到 $v0 后栈帧恢复 + jr $ra
  • 修改: 在中端 IR 到 MIPS 的转换流程中加分支与跳转映射逻辑。

阶段四:全局与数据段

阶段五:调用约定与返回值处理

  • 扩展 MipsBuilder:增加参数寄存器分配方法 AllocateRegForParam(IrParameter, Register)
  • 在函数入口:加载超出前四的参数(从调用者栈)到局部栈或寄存器。
  • 在函数调用点生成:
    • 传参:前四参数放 $a0-$a3,额外参数按逆序入栈。
    • 保存调用者活跃的 $s 寄存器与 $ra(如多级调用)。
    • 发起调用:jal funcLabel;弹栈/恢复 $s 寄存器。
    • 获取返回值:用 $v0 映射到 IR 目的值的寄存器或存栈。
  • 若需:简单活跃分析可暂用“所有用到的 S 寄存器都保存”策略(后续阶段优化)。

阶段六:比较、逻辑、乘除扩展

  • 新增指令类: MipsCompare(支持 SLT/SGT/SEQ/SNE 等,或用组合 slt + 逻辑指令)与 MipsMdumult/div/mflo/mfhi)。
  • 表达式扩展: <, <=, >, >=, ==, != 映射:
    • 直接用 MipsCompare 或 slt + 取反/交换操作;结果落到临时寄存器作为布尔值 (0/1)。
  • 逻辑与或:短路实现(生成分支跳转)或直接用布尔值与/或(需要 and/or 指令)。
  • 乘除: mult rs rt 后 mflo rd;除法同理(若需余数用 mfhi)。
  • 更新中端到后端的指令选择表。

阶段七:窥孔优化与指令合并

阶段八:测试验证与迭代优化

  • 编写或复用简单驱动:调用前端+中端+后端,打印 MIPS。
  • 用 test/Code-test 中多个样例运行,人工或脚本比对预期(检查是否有 main:、系统调用、栈帧平衡)。
  • 验证点:寄存器重用冲突(临时值覆盖问题)、栈偏移正确性、调用嵌套返回值正确性。
  • 添加更多 peephole:
    • 删除死标签(无跳转目标的标签)。
    • 合并 li + move
    • 简化分支:beq $zero,$zero label → j label
  • 若出现溢出:实现简单线性扫描分配策略(活跃期冲突时把旧值 spill 到栈)。

整体文件/类时间线概览(按阶段逐步出现)

如果你希望,我可以直接开始阶段一的文件创建与最小指令迁移。是否继续执行阶段一代码实现?告诉我即可。

Built with MDFriday ❤️