2.4 乘累加器

两个乘累加器(MAC0、MAC1)执行定点乘法运算和乘累加操作,乘累加操作可用于累加或累减。乘法器定点指令对16-bit数据进行操作,产生32-bit结果,它可被加到An里或从中减去。输入可以是小数或整数,无符号或补码数。乘法器指令包括:乘法、乘累加(带圆整选项)、乘累减(带圆整选项)、同时包含前面两种操作。

2.4.1 乘法器操作

每个乘法器有两个32-bit输入,可从中得到两个16-bit操作数。对于单个乘累加指令,操作数可以是任意Rn。每个乘法器可累加其结果到它的A1或A0,An结果可饱和成32或40位,乘法器结果也可圆整后直接写入16-bit或32-bit目的寄存器里。

每个乘法器指令要限定输入都是整数类型或小数类型,结果的类型和输入的类型是一致的。对于MAC0,两个输入都被当做无符号数或有符号数来处理。对于MAC1,有一个混合类型的选项。若两个输入都是小数形式并且是有符号数,乘法器将结果左移一位,以消除冗余符号位。而对于无符号小数、整数或混合类型,则不执行符号位修正的移位操作。乘法指令选项指定了输入数据的格式,更多信息请参见“乘法器指令选项”。

将乘法结果存入乘法器An 如图2-7所示,每个乘法器有一个专属的累加器A0或A1。乘法器向An写入时32-bit结果被存入An的低位比特中,MSB是符号扩展的,扩展进高8位(A0.X/A1.X)里。乘法输出也可以存入Rn的16-bit或32-bit的寄存器中。

乘法器结果的圆整或饱和 在一个乘累加操作中,An数据可以被饱和处理,并可选择地进行圆整操作以提取数据给一个寄存器或半个寄存器。当乘法器仅把结果存入一个寄存器或半个寄存器时,饱和和圆整工作方式相同。饱和和圆整操作如下:

(1)圆整仅用于小数结果,除非有IH选项,该选项用于对一个整数结果的高半字进行圆整和抽取。该选项通过加0x8000到An(对于MAC)或乘法结果(对于乘法)以得到圆整的结果,然后饱和处理为32-bit值。

(2)如果发生了上溢出或下溢出,饱和操作设置指定的结果寄存器为最大的正值或最小的负值。乘法结果溢出时,ASTAT指示了乘法器溢出状态,如图2-2所示。

乘法器指令汇总 表2-10列出了乘法器指令。

表2-10 乘法器指令汇总

乘法器指令选项 乘法器指令选项描述见表2-11,不是所有选项对所有指令都可用的。

表2-11 乘法器指令选项

2.4.2 乘法器数据流描述

如图2-7所示为寄存器文件和ALU,以及乘/累加器。每个乘法器有两个16-bit输入,可执行一个16-bit乘法,并将其结果存入到An里,或提取到一个16-bit或32-bit寄存器中。两个32-bit字可用于MAC的输入,有4个16-bit操作数以供选择,其中一个操作数必须是一个32-bit字的低半字或高半字,另一个操作数必须是另一个32-bit字的低半字或高半字,因此为每个MAC提供了4种可能的输入操作数的组合。这两个32-bit字可以包含同一个寄存器信息,这就给出了一种选择——平方以及同一个寄存器的高半字与低半字进行相乘。如图2-9所示为这些可能的组合。

图2-9 MAC操作中4个可能的组合

32-bit乘积结果传递给An,并可以在An里加上或减去这个新的乘积,也可以将这个新的乘积直接送到Rn。例如指令:

        A0=R3.L * R4.H;

这是MAC0执行一个乘法,并将结果存入A0。

        A1+=R3.H * R4.H;

这是MAC1执行一个乘法,并将其结果累加到A1的先前结果上。

不带累加的乘法 乘法器可进行无累加功能的操作,乘积结果直接存入Rn 或An。目的寄存器可以是16位或32位的,如果16-bit目的寄存器是一个低半字则使用MAC0,如果是一个高半字则使用MAC1。对于一个32-bit目的寄存器,MAC0和MAC1都可以使用。

如果目的寄存器是16位的,那么从乘法器提取的字取决于输入数据的类型。

(1)如果乘法使用了小数操作数或带有IH选项,那么结果的高半字将被提取并存入16-bit目的寄存器。

(2)如果乘法使用了整数操作数,那么结果的低半字将被提取并存入16-bit目的寄存器。

这些提取,对于所选择的数据类型,提供了最有用的信息到结果的16-bit字。例如,下面指令使用了无符号小数操作数:

        R0.L=R1.L * R2.L (FU);

这条指令对乘法结果进行圆整和饱和处理并存储其高16位到R0.L,使用了MAC0。

下面指令使用了无符号整数操作数:

        R0.H=R2.H * R3.H (IU) ;

它对乘法结果进行要求的饱和处理并存储其低16位到R0.H,使用了MAC1。

对于下面指令:

        R0=R1.L * R2.L;

不管操作数类型,它都将32位乘法器结果饱和处理后存入R0,使用了MAC0。

特殊的32-bit整数MAC指令 处理器支持一个多周期32-bit MAC指令。

        Dreg*=Dreg;

这个单指令是两个32-bit整数操作数相乘得到一个32-bit整数结果,并存入到其中一个输入操作数单元里。这条指令执行要花费多个周期,这个宏功能是可中断的,而且不会修改A0或A1里的数据。

双MAC操作 处理器有两个16-bit MAC,可用于同样的操作,使MAC吞吐率加倍。同样的两个32-bit输入寄存器可提供给每个MAC单元,为每个MAC提供了4种可能组合的16-bit输入操作数。双MAC操作通常被称为矢量操作,因为一个程序能够存储样点矢量到4个输入操作数,并执行矢量计算。双乘法和累加指令的一个例子如下:

        A1+=R1.H * R2.L, A0+=R1.L * R2.H;

这条指令描述了两个乘法和累加操作:

(1)在第1个操作(MAC1)里,R1高半字与R2低半字相乘并累加到A1里。

(2)在第2个操作(MAC0)里,R1低半字与R2高半字相乘并累加到A0里。

MAC操作的结果可以有多种方式写入寄存器:作为一对16-bit半寄存器、作为一对32-bit寄存器以及作为一个独立的16-bit半寄存器或32-bit寄存器。例如指令:

        R3.H=(A1 += R1.H * R2.H), R3.L=(A0 += R1.L * R2.L);

它是将An装入一个16-bit半寄存器,MAC1的结果必须传送到一个目的寄存器的高半字,MAC0的结果必须传送到同一个目的寄存器的低半字。操作数类型决定了从An提取正确的位并存入16-bit目的寄存器,参见“不带累加的乘法”。

        R3=(A1 += R1.H * R2.H), R2=(A0 += R1.L * R2.L);

它是将An装入两个32-bit寄存器,这些寄存器必须是寄存器对(R[1:0],R[3:2],R[5:4],R[7:6])。

        R3.H=(A1 += R1.H * R2.H), A0+=R1.L * R2.L;

它是将其中一个累加器传送到一个寄存器,16-bit或32-bit寄存器可作为目的寄存器。