SSE指令集


本篇介紹sse指令接,sse是流化SIMD擴展(Streaming SIMD Extension, SSE),提供全新的一組寄存器,處理128位打包數據。

sse提供了xmm寄存器,xmm一組8個128位的寄存器,分別名為xmm0-xmm7,sse構架提供對打包單精度浮點數的SIMD支持。

sse提供了兩個版本的指令,其一以后綴ps結尾,這組指令對打包單精度浮點值執行類似mmx操作運算,而第二種后綴ss,這些指令對一個量標單精度浮點 值進行運算操作,這些指令不對打包值中的所有浮點值操作,而只對打包值中的低位雙字節執行操作,源操作數中剩余的3個值直接傳送給結果。

指令 說明
movaps 把4個對准的單精度值傳送到xmm寄存器或者內存
movups 把4個不對准的單精度值傳送到xmm寄存器或者內存
movss 把1個單精度值傳送到內存或者寄存器的低位雙字
movlps 把2個單精度值傳送到內存或者寄存器的低四字
movhps 把2個單精度值傳送到內存或者寄存器的高四字
movlhps 把2個單精度值從低四字傳送到高四字
movhlps 把2個單精度值從高四字傳送到低四字

其中對准操作movaps要求數據在內存中對准16字節的邊界,以提交效率,否則應使用movups傳送數據。

運算指令:

指令 說明
addps 將兩個打包值相加
subps 將兩個打包值相減
mulps 將兩個打包值相乘
divps 將兩個打包值相除
rcpps 計算打包值的倒數
sqrtps 計算打包值的平方根
rsqrtps 計算打包值的平方根倒數
maxps 計算兩個打包值中的最大值
minps 計算兩個打包值中的最小值
andps 計算兩個打包值的按位邏輯與
andnps 計算兩個打包值的按位邏輯非
orps 計算兩個打包值的按位邏輯或
xorps 計算兩個打包值的按位邏輯異或

以上指令都是用兩個操作數:源操作數可以是128位內存或者xmm寄存器,目標操作數必須是xmm寄存器。

這里舉一個簡單的例子,使用gdb查看最后結果:

.section .data
    value1: .float 12.12, 34.89, 56.23, 78.45
    value2: .float 31.12, 57.124, 234.23, 67.246
.section .text
.globl _main
_main:
    enter $0, $0

    movups value1, %xmm0
    movups value2, %xmm1
    addps %xmm0, %xmm1

    movups value2, %xmm1
    maxps %xmm0, %xmm1
    leave
    ret

編譯時加-g參數加入調試信息,調用addps后查看xmm1寄存器的結果,命令如下:

(gdb) print $xmm1
$1 = {v4_float = {43.2400017, 92.0139999, 290.459991, 145.695999},
  v2_double = {26419069594869.762, 1245245520236216.2}, v16_int8 = {-61, -11,
    44, 66, 43, 7, -72, 66, -31, 58, -111, 67, 45, -78, 17, 67}, v8_int16 = {
    -2621, 16940, 1835, 17080, 15073, 17297, -19923, 17169}, v4_int32 = {
    1110242755, 1119356715, 1133591265, 1125233197}, v2_int64 = {
    4807600484593235395, 4832839782622116577},
  uint128 = 0x4311b22d43913ae142b8072b422cf5c3}
(gdb)

可以看到,調用加法指令之后,四組和都存儲在xmm1寄存器中,gdb查看時由於不知道如何解析xmm1寄存器的內容,因為可能是單精度,也可能是雙精度或者不同寬度的整數,所以只能按不同的解析方式全部顯示,查看v4_float即四個單精度浮點數的顯示。

下面介紹一下sse構架下的比較指令,sse的比較指令單獨比較128位打包單精度浮點的每個元素,結果是一個掩碼,滿足比較條件的結果全為1值,不滿足結果的全為0值(量標只對最低的雙字執行)。

指令 說明
cmpps 比較打包值
cmpss 比較標量值
comiss 比較標量值並且設置eflags寄存器
ucomiss 比較標量值(包括非法值)並設置eflags寄存器

看到這里,僅僅有一個比較指令,並沒有說明大小,何為滿足條件全1,不滿足全0呢,這樣說一下指令的使用:

cmpps imp, source, destination

其中多出來的imp是一個無符號整數,這個整數表示的含義就是條件,這個條件值如下表所示:

整數 說明
0 等於
1 小於
2 小於或等於
3 無序
4 不等於
5 不小於
6 不小於或等於
7 有序

如果需要比較兩個數是否相等,傳imp為0即可作為條件,滿足條件結果全1,這是sse的比較方式。這里說明一下條件中的無序,因為是浮點比較,寄存器或內存中的有些值並不符合規定的浮點存儲格式,相互比較是沒有意義的,稱為無序。

除了對浮點數的支持,sse指令集也有指令對mmx提供的功能進行擴展,他們對mmx寄存器中的數據執行操作:

指令 說明
pavgb 計算打包無符號字節整數的平均值
pavgw 計算打包無符號字整數的平均值
pextrw 把一個字從mmx寄存器復制到通用寄存器
pinsrw 把一個字從通用寄存器復制到mmx寄存器
pmaxub 計算打包無符號字節整數的最大值
pmaxsw 計算打包有符號字整數的最大值
pminub 計算打包無符號字節整數的最小值
pminsw 計算打包有符號字整數的最小值
pmulhuw 將打包無符號字整數相乘並且存儲高位結果
psadbw 計算無符號字節整數的絕對差的總和

SSE2 指令集又對 SSE 指令集做了很多擴充,主要對操作雙精度浮點數和128位打包整數值執行數學操作,下面介紹SSE2的使用,先來看數據傳送指令:

指令 說明
movapd 把2個對准的雙精度值傳送到xmm寄存器或者內存
movupd 把2個不對准的雙精度值傳送到xmm寄存器或者內存
movdqa 把2個對准的四字節整數傳送到xmm寄存器或者內存
movdqu 把2個不對准的四字節整數傳送到xmm寄存器或者內存
movsd 把1個雙精度值傳送到內存或者寄存器的低四字
movhpd 把1個雙精度值傳送到內存或者寄存器的高四字
movlpd 把1個雙精度值傳送到內存或者寄存器的低四字

SSE2指令集提供處理打包雙精度浮點數,打包字整數,打包雙字整數和打包四字整數值的數學指令,這里列舉SSE2的加法指令來說明這一系列指令格式:

指令 說明
addpd 將打包雙精度浮點值相加
addsd 將量標雙精度浮點值相加
paddsb 將打包帶符號字節整數相加
paddsw 將打包帶符號字整數相加
paddd 將打包帶符號雙字整數相加
paddq 將打包帶符號四字整數相加

這里雖然只列舉add系列指令,這些選項也存在於乘法和除法操作中(mulpd, mulsd, divpd, divsd等)。 另外同sse指令集,sse2指令集也提供專門的數學操作,sqrt, max, min。

最后我們來看SSE3指令集,SSE3構架並沒有提供任何新的數據類型,僅僅添加了幾條指令,用於更快的執行標准函數,下面是新指令的列表:

指令 說明
fisttp 把第一個fpu寄存器的值轉換為整數(舍入)並且從fpu堆棧彈出
lddqu 快速從內存加載128位不對准的數據值
movshdup 傳送128位值,復制第2個和第4個32位數據元素
movsldup 傳送128位值,復制第1個和第3個32位數據元素
movddup 傳送64位值,賦值值,使之成為128位值
addsubps 對於打包單精度浮點數,對第2個和第4個32位執行加法,第1和第3個32位執行減法
addsubpd 對於打包單精度浮點數,對第2對64位值執行加法,第1對位執行減法
haddps 對操作數的相鄰的元素執行單精度浮點加法操作
haddpd 對操作數的相鄰的元素執行雙精度浮點加法操作
hsubps 對操作數的相鄰的元素執行單精度浮點減法操作
hsubpd 對操作數的相鄰的元素執行雙精度浮點減法操作

SSE指令繁多,這里舉得例子卻很少,以后我會在此文繼續附加一些說明例子,方便理解。

轉載:http://fancymore.com/reading/assembler-sse-instruct.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM