直接算术运算在RISC架构的小型数字(Direct Arithmetic Operations on

2019-09-30 18:02发布

是否有任何的RISC体系结构,其允许单独地施加到字节算术运算,半字和其它数据单元,其大小小于所述CPU的通用寄存器的大小?

在英特尔86(IA-32)和x86-64(称为EM64T或AMD64)处理器不仅整个寄存器是可用的,但其更小的部分可操作为好。 英特尔ISA允许对整个寄存器执行所有的运算,它的一半,季度和字节(更精确地说,在寄存器两个字节是可用的,例如AL和AH中RAX)。 执行该操作后,就可以使溢出检查,如果上次运转过程中,发生了溢出,它可以很容易地处理。 无论我们对整个字(32位宽的IA-32位和64位宽的EM64T)是否已经运行或算法指令用更小的尺寸(半字四分之一字或者数据执行字节),如果该结果超过所选择的数据单元的尺寸时,相应的标记(OF或CF)将因此,在英特尔架构被设置为1,不需要模拟处理这样的错误,它与小发生在操作大小的数据,用分析结果的高位比特的指令的链。

现在的问题是是否有任何的RISC体系结构,其中小数据直接算术运算是可能的,这些操作由处理器硬件的装置被实现为(不需要软件仿真来执行它们),并且溢出,承载并在这样的操作借入发生的与字节,半字等由处理器设备追踪,它们不应该被以软件方式进行检查。 或许这种做法违背了整个RISC的理念和无RISC处理器无论是在本也不在过去曾经实施的呢?

Answer 1:

TL:DR:无,AFAIK没有RISC的ISA与标记设置局部寄存器OPS大于32位窄。 但许多的64位RISC的ISA(如AArch64)具有FLAGS在所有可以从32位运算的结果设定。

看到最后一节:这是因为普遍缺乏对软件的整数溢出检查,或鸡/蛋的问题的需求。 通常你只需要比较的16位值/分支,你可以做到这一点就好了与他们零或符号扩展至32位或64位。

只有一个RISC其中寄存器宽度为8位或16位可以由操作数大小设置标志。 例如AVR 8位RISC与32个寄存器和16位指令字。 它需要扩展精度添加/ ADC只是实现16位int

这主要是一个历史的事情:86具有16位操作数大小的,因为它从16位仅286演变当80386设计的方式一切,这是很重要的,它能够为16位,只运行代码全速,并且它们提供的方式递增地添加32位OPS到16位的代码。 和所使用的相同的机制,以允许在32位代码的16位OPS。

在x86 8位低/高寄存器的东西(AX = AH:AL)又是部分原因是如何8086被设计为一个继任者8080,使移植容易(甚至可以自动)查看为什么前四86个GPR在这种直观的顺序命名的? 。 (而且也因为它是具有8个1字节寄存器,并在同一时间四个2字节寄存器只是简单有用的。)


相关: 其中2的补整数运算可以在不投入归零高位被使用,如果只有结果的低部分被通缉? 对于许多计算,您不必每次操作后重新归零的高位,以获得相同的结果。 因此, 缺乏的8位/ 16位操作数的大小是不会成为阻碍高效实现逻辑上包裹其结果,以8或16位的大多数代码。

64位RISC机器通常具有如至少一些重要的指令的32位版本的add ,所以可以得到一个零扩展add结果为免费,而不必单独截断它,例如,以使代码像array[i++]高效与uint32_t i和64位指针。 但从来没有局部寄存器的操作数大小窄于32位,在任何RISC我听说过。

DEC Alpha是有趣的,因为它是一个新的设计,从地上爬起来,而不是 64位扩展到现有ISA MIPS64的方式是64位。 此的阿尔法助记符表表明,加/减/ MUL /格都可以在32和64位的形式,而是移位,并比较则没有。 (也有字节操作指令是SIMD基本上洗牌/掩模/插入/内部64位整数寄存器提取物,和一个SIMD packged - 比较用于有效串的东西)。

根据这个官方MIPS64 ISA DOC (4.3节CPU寄存器)。

甲MIPS64处理器总是产生一个64位的结果,即使对于那些架构定义为在32位进行操作的那些指令。 这样的指令典型地符号扩展他们的32位结果为64位。 这样一来,32位程序按预期工作,虽然寄存器实际上是64个位宽而不是32位。

(您可使用完整的64位寄存器特殊说明,像DADDU (双字加无符号),而不是ADDU 。请注意,非-U版本adddadd陷阱2的补符号溢出(32位或64位操作数大小),所以你必须使用U版包裹签署数学。在(ISA引用链接mips.com )。无论如何,MIPS没有为32位特殊的模式,而是一个操作系统将需要关心32位程序与64位,因为32位将假定所有的指针都在虚拟地址空间中的低32。


在RISC加载/存储设备,你通常只使用零扩展(或符号扩展)字节/半字加载。 当你做,你会使用一个字节/半字商店买截断结果。 (用无符号BASE2,或2的补签字,通常是你想要的。)这是怎样一个编译器(或人)将实施所用的C源shortuint8_t

半相关:C的整数提升规则自动推进的一切比窄int高达int作为一个操作数像一个二进制运算符时+ ,所以大多很好地映射到计算的这种方式。 (即unsigned result = (a+b) * c中C没有截断a+b导致回uint8_t乘法之前,如果A,B和C都是uint8_t ,但它很糟糕, uint16_t促进以签署int ,所以uint16_t a,b; unsigned c = a * b风险签订溢出UB从促进到签署int 。用于乘法)无论如何,C的促销规则看起来就有点像他们设计的机器不完全支持狭窄的操作数大小,因为这是在很多硬件的常见的。


但是,你问从窄OPS溢出检查/标志置位。

并非所有的RISC机器甚至一个标志位寄存器 。 ARM的做法,但例如MIPS和Alpha没有。 ARM不会对每一个指令设置的标志:你必须明确地使用指令的标志置位的形式。

不带标志的CPU通常有一些简单的比较和分支指令(通常针对零,如MIPS bltz ),和其他人比较两个输入和写0/1结果到另一个整数寄存器(例如MIPS SLTIU -设置在小于即时无符号)。 您可以使用Set指令+一个bne零创建更复杂的分支条件。


高效溢出检查硬件和软件支持是普遍的一个问题 。 把一个jcc每x86指令后吸了不少了。

但是,部分原因是因为大多数语言不让它容易写,每一个指令后需要溢出检查码,CPU建筑师没有在硬件提供它,尤其不适合狭窄的操作数大小。

MIPS是捕捉有趣的add有符号溢出。

如何有效地实现它可能包括具有“粘性”标志,路上FPU异常标志是置顶:无效标志撑除以零(和生产NAN)后置; 其他FP指令不清除它。 所以,你可以在一系列计算的末尾检查有无异常标志,或一个循环之后。 这使得它足够便宜,实际上在实践中使用,如果有它一个软件框架。

随着FP代码,通常你不需要看标志,因为NaN的本身就是“粘”或者“传染性”。 大多数二元运算产生NaN的,如果任一输入为NaN。 但是,无符号和2的补码整数表示没有任何备用的位模式:它们都代表具体的数字。 (1的补数具有负零...)

欲了解更多有关ISA设计,将使得溢出检查可能的,看看讨论昂纳雾的提议一个新的ISA,结合86的最佳功能(代码密度,大量的每条指令的工作)和RISC(简单的解码)的高性能纸架构。 一些有趣的SIMD想法,包括使未来的扩展矢量宽度透明的,所以你不必重新编译运行具有更宽的矢量更快。



Answer 2:

是否有任何...

你只说对市场上或也即将上大学的学生等商业项目的CPU?

我自己设计了一个RISC CPU用于教育目的,可以做到8位,16位和32位运算。 因此,这表明,至少有可能做到这一点。

64位嵌入式PowerPC架构也有类似的东西:他们可以在64位寄存器的低32位做32位运算。

这种架构没有8位和16位运算。 然而CISC CPU的也不支持与较小的宽度其他计算机支持的所有宽度:

86既不支持4位操作也不12位操作虽然有CPU的(英特尔4004和DEC PDP-8),使用这些宽度。

执行该操作后,就可以使溢出检查,如果上次运转过程中,发生了溢出,它可以很容易地处理。

64位SPARC架构有趣的是在这里:

为了让32位软件要在64位CPU也有一些特殊的功能执行。

其中之一是,所有的标志(携带,零,...)是重复的:一旦低32位,一次针对整个64位。

这样做的“ADD”操作(这只能完成64位)后,您可以检查64位的标志或32位的标志。



Answer 3:

大多数的64位RISC架构还支持您通过具有32位或64位字操作说明预期的限量表。 许多还支持位域操作,虽然我不知道如果有的话,您可以直接对位域做算术题

但有一个这种不规则RISC架构命名Blackfin处理器 ,其中所述数据寄存器可作为一个整体被访问或用作多种分开的部分。 从它的文档 (格式化成子弹由我为了便于阅读):

  • 累加器:该组的40位寄存器A1A0 ,通常包含正被操纵的数据。 每个累加器有五种方式访问​​:
    • 作为一个40位寄存器
    • 作为一个32位寄存器(指定为A1.WA0.W
    • 为两个16位寄存器类似于数据寄存器(指定为A1.HA1.LA0.H ,或A0.L
    • 并且作为一个8位寄存器(指定A1.XA0.X )为延伸超过位31的位。
  • 数据寄存器:该组的32位寄存器( R0R1R2R3R4R5R6 ,和R7 ),该通常包含数据操纵。 缩写d-寄存器或沉渣。
    • 数据寄存器可以作为访问
      • 32位寄存器
      • 或任选地作为两个独立的16位寄存器。
    • 每个寄存器的至少显著16个比特被称为“低”一半并且被指定为“.L”以下的寄存器名。 最显著16位被称为“高”的一半,被指定为“.H”在名字后。 例如: R7.Lr2.hr4.LR0.h

它甚至有在算术状态 (ASTAT)注册,以便更容易混合运算多个独立的进位和溢出标志


另一个有趣的情况是的SuperH SH-5 ,其不通用内部SIMD运算寄存器 ,即使它有一组独立的64个浮点寄存器。 所以,你可以在真正的字节/字/双字做算术。 换句话说,它做的SWAR技术在硬件


在英特尔1960年也以自己的方式独特。 它是唯一奇怪的是RISC架构,32个寄存器,但没有一个零寄存器,它有指令可比较字节和短裤 ,即使它仍然不能对字节其它算术操作

cmpi    Compare Integer
cmpib   Compare Integer Byte
cmpis   Compare Integer Short
cmpo    Compare Ordinal
cmpob   Compare Ordinal Byte
cmpos   Compare Ordinal Short
concmpi Conditional Compare Integer
concmpo Conditional Compare Ordinal


文章来源: Direct Arithmetic Operations on Small-sized Numbers in RISC Architectures