解决 ARM7TDMI 乘法进位标志的谜团

这篇博客主要介绍了 Gameboy Advance 的 ARM7TDMI 处理器的乘法算法及其相关细节,包括标准算法、改进的 Booth 算法、加法操作、并行性、提前终止等方面,具体内容如下:

  • 基础要求:假定读者对 C 编程语言和位运算有一定基础,阅读过程中如有疑问可在此处联系作者。
  • 乘法指令相关:ARM7TDMI 的乘法指令有有趣的副作用,手册说明乘法指令执行后进位标志被设置为“无意义值”,软件不应依赖此值,但其似乎具有确定性,这引发了作者的研究兴趣。
  • 标准算法:最简单的乘法算法是利用乘法分配律,将乘法拆分为多个加法,二进制下可更方便地计算加数,但需要计算大量加数,速度较慢。
  • 改进的 Booth 算法:是标准算法的改进,通过一系列变换将加数数量减半,利用 Booth 编码将乘法转换为更易计算的形式,硬件中乘法乘 5 以下的数较容易计算,还给出了 Booth 编码的 C 代码实现及相关资源。
  • 加法操作:常规全加器使 ARM7TDMI 每个周期只能加两个数,效率低,引入进位保存加法器(CSAs)可输出无进位传播的结果和进位列表,通过链式 CSAs 可将加数数量减少,再用常规加法器相加,乘法速度加快。
  • 并行性:可以同时生成和添加加数,ARM7TDMI 每个周期生成 4 个加数,用 4 个 CSAs 压缩为 2 个,还可利用乘法累加指令实现乘法累加,不过 CPU 每次周期只能读取两个寄存器值,使用累加会额外增加周期。
  • 提前终止:ARM7TDMI 在乘法算法中会根据乘数的高位情况提前终止某些周期的计算,若高位为 0 或 1(有符号乘法时高位为 1),则相应周期的加数为 0,可跳过该周期。
  • 整体流程:给出了乘法器组织的高级概述图,介绍了部分和/部分进位的计算及旋转,还说明了 Booth 算法中进位的处理方式,通过特定的代码实现了 CSA 数组的操作。
  • 矛盾与解决思路:发现描述的算法与 ARM7TDMI 的算法存在差异,如特定乘法的周期数不同,提出了多种可能的解决方案但都存在问题,最终通过在算法开始时左移乘数等操作解决了部分问题。
  • 数学技巧:包括处理 64 位累加和有符号乘法,通过初始化部分和、对 CSA 及编码后的加数进行符号扩展等操作来实现,还详细说明了相关的代码实现及数学原理。
  • 提前终止的具体细节:介绍了提前终止的条件及相关代码实现,包括乘数的处理、部分和与部分进位的寄存器操作等,还说明了 ARM7TDMI 中桶形移位器的使用及旋转值,尽管对专利中的旋转值理解困难,但只要输出相同,进位标志就相同。

总之,这篇博客详细阐述了 ARM7TDMI 处理器乘法相关的各种技术和细节,包括算法改进、硬件操作等方面。

阅读 33
0 条评论