XOP指令与AVX指令采取了相同的编码设计规则,在XOP指令中使用了3 bytes的XOP pref ix来定义XOP指令集,这个XOP prefix是8F字节,AVX prefix采用了C4/C5作为AVX prefix,在AVX指令的定义中区分了AVX 128和AVX 256指令,分别处理128位和256 位数据,这是通过VEX.L来实现,XOP指令中同样使用XOP.L来确定128位和256位数据的处理。接下来,由于篇幅有限笔者只简要介绍一下它们的编码设计方案,AVX与XOP指令编码与通用指令结构上是一致的,如下图3所示:
这个Extended Prefix是AVX prefix或者XOP prefix,在AVX prefix中分为2 bytes与3 bytes,XOP prefix仅使用3 bytes,AVX/XOPprefix,opcode以及ModRM是必须提供,其它部分是可选的。Extended prefix部分是确定AVX指令还是XOP指令的关键。
图3
SSE系列指令将x86指令系统推上复杂化,它们常使用两个特殊的pref ix作为opcode的一部分:
escape opcode(或称escape prefix),包括:0F,0F 38以及0F 3A
SIMD prefix,包括:66,F2以及F3
它们事实上会作为指令的opcode组成部分一起被提供在指令参考手册上,已经脱离了原本作为prefix的意义。
从图4中我们可以了解到AVX与XOP的组成部分:第1个字节是C4/8F(3bytes),C5(2 bytes)接下来的2个字节或1个字节,组成部分为:
图4
VEX.R,VEX.X,VEX.B;VEX.mmmmm;VEX.W;VEX.vvvvv;VEX.L;VEX.pp
大部分情况下,同一条AV X指令可以选择实现2 bytes的版本或者3 bytes的版本,满足指令中的escape opcode为0F或无需扩展ModRM.r/m域,SIB.base以及SIB.base这两种情况时3 bytes版本可以转为2 bytes版本。主流的编译器会优先选择生成2 bytes VEX prefix的AVX指令encode,以产生更短的指令序列。
1、集成了REX prefix
VEX.RXB以及VEX.W是对通用指令中的REX prefix提供了对扩展registers的访问功能,与REX prefix一样,我们能够对扩展的新寄存器进行访问。
2、集成了escape opcode
VEX.mmmmm域中集成了escape opcode,VEX.mmmmm使用5 bits来表达,这样使得它可以在未来的指令集中可以扩展更多的escape opcode。
3、集成了SIMD prefix
VEX.pp集成了原有的SIMD prefix。由于VEX prefix对原SSE指令opcode部分的集成,使得AVX指令轻易地从SSE指令转为AVX指令,除了新提供的AVX指令外,大部分AVX指令都有对应的SSE版本。
XOP.mmmmm与VEX.mmmmm存在区别,XOP.mmmmm不集成escape opcode,它有两个选项值,意
义是:XOP.mmmmm = 8时,表示指令需要immediate操作数
XOP.mmmmm = 9时,表示指令不需要immediate操作数
与此同时,VEX.vvvv(XOP.vvvv)是提供源或目标操作数的寄存器寻址,这个寄存器编码与原有的寄存器编码是相反的。
AVX指令和XOP指令都可以提供4个操作数的寻址,这4个操作数是: ModRM.regVEX.vvvv(或XOP.vvvv)ModRM.r/mimm8[7:4]
对于只有两个操作数的指令来说,VEX.vvvv将不需要提供寻址,VEX.vvvv必须置为1111值,额外的第4个操作数(第3个源操作数)有两个情境:寄存器操作数:由8位immediate操作数的高4位提供;立即数操作数:这种情况下它提供的是immediate值,大多数表现为一些mask值。
从编码设计方式来看,Intel无疑再次获得了行业的话语权,统一了未来一段时间的指令设计方式。但从实际指令集来看,AMD重新定义了SSE5指令,根据AVX编码方式扩展出了XOP、FMA4等一系列更完善的指令集。在保证了兼容性的基础上,强化了整数运算效能。这也从侧面印证了AMD要将异构运算进行到底的未来规划。毕竟Radeon系列GPU的浮点运算能力十分出众,对于未来的APU来说,x86核心更多的是负责整数运算,加强指令集整数运算的效能显然符合AMD的预期。至于新一代处理器指令集的效能究竟几何,还跟实际处理器的架构和运行程序的优化程度有关,究竟鹿死谁手还让我们拭目以待。