標籤:style class blog code ext color
在Intel Haswell架構裡引入了Gather特性。它使得CPU可以使用向量索引儲存空間編址從儲存空間取非連續的資料元素。這些gather指令引入了一種新的儲存空間定址形式,該形式由一個基地址寄存器(仍然是通用目的寄存器)和通過一個向量寄存器(XMM或YMM)所指定的多個索引構成。資料元素大小支援32位與64位,並且資料類型支援浮點型和整型。
我們先回顧一下普通的x86定址方式:[<base register> + <index register> * <scale> + <offset>]
在AT&T形式下表達為:<offset>(<base register>, <index register>, <scale>)
其中,<base register>為基地址寄存器;<index register>為索引寄存器;<scale>為刻度因子,它是一個立即數,並僅支援0,1,2,4,8這幾個值;<offset>表示位移量,它是一個立即數。
那麼下面我們就先來談談上面所提到的向量儲存空間定址。
向量SIB(VSIB)儲存空間定址
在AVX2中,跟在ModR/M位元組後面的SIB(S表示Scale;I表示Index;B表示Base)位元組可以支援對一組線性地址的VSIB儲存空間定址。VSIB定址僅在AVX2指令的子集中支援。VSIB儲存空間定址要求32位或64位的有效定址。在32位元模式下,當地址大小屬性被重載為16位時,VSIB定址不被支援。在16位保護模式下,VSIB定址是被允許的,若地址大小屬性被重載為32位的話。此外,VSIB儲存空間定址僅伴隨VEX首碼而被支援。
在VSIB儲存空間定址中,SIB位元組由以下部分組成:
● 刻度域(位7:6)指定了刻度因子。
● 索引域(位5:3)指定了向量索引寄存器的寄存器編號,該向量儲存空間中的每個元素都指定了一個索引。
● 基地址域(位2:0)指定了基地址寄存器的編號。
比如:
vgatherdpd %xmm0, 128(%rdi, %xmm2, 4), %xmm3
上述指令中,基地址寄存器為RDI,索引寄存器為XMM2,刻度因子是4,位移量是128。而指令vgatherdpd是將索引寄存器的元素作為雙字(即4位元組)進行劃分,然後乘上刻度因子後加到基地址上。而位移量則作用於每個基地址元素。
下面我們將提供一個比較完整的範例程式碼來描述VGATHERDPD指令。
先看彙編指令:
_InstTest: // 設定索引寄存器的每個元素 mov $4, %eax // 前一個索引為4 movd %eax, %xmm2 mov $8, %eax // 後一個索引為8 pinsrd $1, %eax, %xmm2 // 將兩個double元素的mask全都置1 mov $0xffffffffffffffff, %rax movq %rax, %xmm0 punpcklqdq %xmm0, %xmm0 vgatherdpd %xmm0, 8(%rdi, %xmm2, 2), %xmm3 ret
這裡,rdi寄存器作為第一個輸入參數,存放了基地址。
下面是C函數的調用:
int main(void){ extern void InstTest(void *p); unsigned __attribute__((aligned(64))) buffer[] = { 0x01020304, 0x05060708, 0x090a0b0c, 0x10121314, 0x15161718, 0x191a1b1c, 0x20212223, 0x24252627 }; InstTest(buffer); return 0;}
我們通過在return 0;這條語句設定斷點,然後通過lldb調試器可以發現XMM3寄存器的最後內容為:
xmm3 = {0x18 0x17 0x16 0x15 0x1c 0x1b 0x1a 0x19 0x23 0x22 0x21 0x20 0x27 0x26 0x25 0x24}
。
以上代碼的編譯環境為:OS X 10.9.3, Xcode 5.1, Apple LLVM 5.1
運行環境為:MacBook Air 2013版,Intel Core i7 4650U, 8GB DDR3。