| STATYSTYKI |
Od 06.09.2000
|
Optymalizacja: 1024x768, IE5 |
|
| Instrukcje MMX |
Po pierwsze, wyjaśnijmy jak działa jednostka MMX. Koliduje ona z jednostką FPU, używając tych samych rejestrów. Programista ma do dyspozycji osiem 64-bitowych rejestrów MMX: MM0..MM7.
MMX wprowadza także cztery nowe typy danych. Są to: packed bytes, packed words, packed doublewords i quad word. Ponadto jednostka MMX używa technologii nazwanej SIMD (Single Instruction, Multiple Data). Oznacza to, że w wyniku wykonania jednego rozkazu można otrzymać kilka wyników.
Instrukcje MMX można podzielić na kilka grup:
- instrukcje transferu danych,
- instrukcje arytmetyczne,
- instrukcje porównawcze,
- instrukcje konwersji,
- instrukcje logiczne,
- instrukcje przesunięcia,
- instrukcje stanu MMX.
Oznaczenia:
| mm | - rejestr jednostki MMX |
| m64 | - 64-bitowa komórka pamięci |
| m32 | - 32-bitowa komórka pamięci |
| imm8 | - 8-bitowa dana |
Instrukcje:
| EMMS | Czyści rejestry MMX (i FPU). |
| MOVD mm,r/m32 | Przenosi 32 bity z rejestru MMX do pamięci lub do rejestru FPU. |
| MOVQ mm/m64,mm/m64 | Przenosi 64 bity z rejestru MMX do pamięci lub odwrotnie. Może również przenosić dane z jednego rejestru MMX do innego. |
| PACKSSWB mm,mm/m64 | Packed with Signed Saturation Word to Byte. Rozbiera i przycina 4 słowa z rejestru docelowego do bajtów -128..127 i zapisuje je w czterech najniższych bajtach rejestru docelowego. Następnie rozbiera i przycina 4 słowa z rejestru źródłowego do wartości -128..127 i zapisuje je w czterech najwyższych bajtach rejestru docelowego. |
| PACKSSDW mm,mm/m64 | Packed with Signed Saturation DoubleWord to Word. Rozbiera i przycina 2 podwójne słowa z rejestru docelowego do słów -32678..32677 i zapisuje je w dwóch najniższych słowach rejestru docelowego. Następnie rozbiera i przycina 2 podwójne słowa z rejestru źródłowego do wartości -32768..32767 i zapisuje je w dwóch najwyższych słowach rejestru docelowego. |
| PACKUSWB mm,mm/m64 | Packed with Unsigned Saturation Word to Byte. Rozbiera i przycina 4 słowa z rejestru docelowego do bajtów 0..255 i zapisuje je w czterech najniższych bajtach rejestru docelowego. Następnie rozbiera i przycina 4 słowa z rejestru źródłowego do wartości 0..255 i zapisuje je w czterech najwyższych bajtach rejestru docelowego. |
| PACKUSDW mm,mm/m64 | Packed with Unsigned Saturation DoubleWord to Word. Rozbiera i przycina 2 podwójne słowa z rejestru docelowego do słów 0..65635 i zapisuje je w dwóch najniższych słowach rejestru docelowego. Następnie rozbiera i przycina 2 podwójne słowa z rejestru źródłowego do wartości 0..65635 i zapisuje je w dwóch najwyższych słowach rejestru docelowego. |
| PADDB mm,mm/m64 | Packed Add. Dodaje pierwszy bajt ze źródłowego rejestru do pierwszego bajtu z docelowego rejestru. Wynik jest zawijany (np. 256 staje się 1) i jest przechowywany w pierwszym bajcie docelowego rejestru. To samo dzieje się dla pozostałych 7 bajtów. |
| PADDW mm,mm/m64 | Packed Add. Dodaje pierwsze słowo ze źródłowego rejestru do pierwszego słowa z docelowego rejestru. Wynik jest zawijany i jest przechowywany w pierwszym słowie docelowego rejestru. To samo dzieje się dla pozostałych 3 słów. |
| PADDD mm,mm/m64 | Packed Add. Dodaje pierwsze podwójne słowo ze źródłowego rejestru do pierwszego podwójnego słowa z docelowego rejestru. Wynik jest zawijany i jest przechowywany w pierwszym podwójnym słowie docelowego rejestru. To samo dzieje się dla drugiego podwójnego słowa. |
| PADDSB mm,mm/m64 | Packed Add with Saturation. Dodaje pierwszy bajt ze źródłowego rejestru do pierwszego bajtu docelowego rejestru. Wynik jest przycinany do wartości -128..127 (np. -190 staje się -128) i przechowywany w pierwszym bajcie rejestru docelowego. To samo dzieje się dla pozostałych 7 bajtów. |
| PADDSW mm,mm/m64 | Packed Add with Saturation. Dodaje pierwsze słowo ze źródłowego rejestru do pierwszego słowa docelowego rejestru. Wynik jest przycinany do wartości -32768..32767 i przechowywany w pierwszym słowie rejestru docelowego. To samo dzieje się dla pozostałych 3 słów. |
| PADDUSB mm,mm/m64 | Packed Add with Unsigned Saturation. Dodaje pierwszy bajt ze źródłowego rejestru do pierwszego bajtu docelowego rejestru. Wynik jest przycinany do wartości 0..255 (np. 300 staje się 255) i przechowywany w pierwszym bajcie rejestru docelowego. To samo dzieje się dla pozostałych 7 bajtów. |
| PADDUSW mm,mm/m64 | Packed Add with Unsigned Saturation. Dodaje pierwsze słowo ze źródłowego rejestru do pierwszego słowa docelowego rejestru. Wynik jest przycinany do wartości 0..65635 i przechowywany w pierwszym słowie rejestru docelowego. To samo dzieje się dla pozostałych 3 słów. |
| PAND mm,mm/m64 | Logical AND. Wykonuje operację logiczną AND. Wynik jest przechowywany w rejestrze docelowym. |
| PANDN mm,mm/m64 | Logical AND-NOT. Wykonuje operację logiczną AND-NOT. Wynik jest przechowywany w rejestrze docelowym. |
| PCMPEQB mm,mm/m64 | Packed Compare for Eqal. Porównuje pierwszy bajt z rejestru źródłowego z pierwszym bajtem rejestru docelowego. Jeśli są równe pierwszy bajt rejestru docelowego jest równy 11111111b, a jeśli nie to 00000000b. To samo dzieje się dla pozostałych 7 bajtów. |
| PCMPEQW mm,mm/m64 | Packed Compare for Eqal. Porównuje pierwsze słowo z rejestru źródłowego z pierwszym słowem rejestru docelowego. Jeśli są równe pierwsze słowo rejestru docelowego w zapisie bitowym ma same 1, a jeśli nie to same 0. To samo dzieje się dla pozostałych 3 słów. |
| PCMPEQD mm,mm/m64 | Packed Compare for Eqal. Porównuje pierwsze podwójne słowo z rejestru źródłowego z pierwszym podwójnym słowem rejestru docelowego. Jeśli są równe pierwsze podwójne słowo rejestru docelowego w zapisie bitowym ma same 1, a jeśli nie to same 0. To samo dzieje się dla drugiego podwójnego słowa. |
| PCMPGTB mm,mm/m64 | Packed Compare Greater Than. Porównuje pierwszy bajt z rejestru źródłowego z pierwszym bajtem rejestru docelowego. Jeśli pierwszy jest większy pierwszy bajt rejestru docelowego jest równy 11111111b, a jeśli nie to 00000000b. To samo dzieje się dla pozostałych 7 bajtów. |
| PCMPGTW mm,mm/m64 | Packed Compare Greater Than. Porównuje pierwsze słowo z rejestru źródłowego z pierwszym słowem rejestru docelowego. Jeśli pierwsze jest większe pierwsze słowo rejestru docelowego w zapisie bitowym ma same 1, a jeśli nie to same 0. To samo dzieje się dla pozostałych 3 słów. |
| PCMPGTD mm,mm/m64 | Packed Compare Greater Than. Porównuje pierwsze podwójne słowo z rejestru źródłowego z pierwszym podwójnym słowem rejestru docelowego. Jeśli pierwsze jest większe pierwsze podwójne słowo rejestru docelowego w zapisie bitowym ma same 1, a jeśli nie to same 0. To samo dzieje się dla drugiego podwójnego słowa. |
| PMADDWD mm,mm/m64 | Packed Multiply and Add. Mnoży pierwsze słowo z rejestru źródłowego przez pierwsze słowo rejestru docelowego. To samo dzieje się dla pozostałych 3 słów. Wynikiem mnożenia jest podwójne słowo. Pierwszy wynik jest dodawany do drugiego i przechowywany w pierwszym podwójnym docelowego rejestru. Drugi wynik jest sumowany z trzecim i przechowywany w drugim podwójnym słowie docelowego rejestru. |
| PMULHW mm,mm/m64 | Packed Multiply High. Mnoży słowa z źródłowego rejestru przez słowa rejestru docelowego. W rejestrze docelowym przechowywany są wyższe słowa z wyników tego mnożenia. |
| PMULLW mm,mm/m64 | Packed Multiply Low. Mnoży słowa z źródłowego rejestru przez słowa rejestru docelowego. W rejestrze docelowym przechowywany są niższe słowa z wyników tego mnożenia. |
| POR mm,mm/m64 | Logical OR. Wykonuje operację logiczną OR. Wynik jest przechowywany w rejestrze docelowym. |
| PSLLW mm,mm/m64/imm8 | Packed Shift Left Logical. Powoduje przesunięcie bitów w lewo w każdym słowie rejestru docelowego o liczbę określoną w słowach rejestru źródłowego. |
| PSLLD mm,mm/m64/imm8 | Packed Shift Left Logical. Powoduje przesunięcie bitów w lewo w każdym podwójnym słowie rejestru docelowego o liczbę określoną w podwójnych słowach rejestru źródłowego. |
| PSLLQ mm,mm/m64/imm8 | Packed Shift Left Logical. Powoduje przesunięcie bitów w lewo w rejestrze docelowym o liczbę określoną w rejestrze źródłowym. |
| PSRLW mm,mm/m64/imm8 | Packed Shift Right Logical. Powoduje przesunięcie bitów w prawo w każdym słowie rejestru docelowego o liczbę określoną w słowach rejestru źródłowego. |
| PSRLD mm,mm/m64/imm8 | Packed Shift Right Logical. Powoduje przesunięcie bitów w prawo w każdym podwójnym słowie rejestru docelowego o liczbę określoną w podwójnych słowach rejestru źródłowego. |
| PSRLQ mm,mm/m64/imm8 | Packed Shift Right Logical. Powoduje przesunięcie bitów w prawo w rejestrze docelowym o liczbę określoną w rejestrze źródłowym. |
| PSRAW mm,mm/m64/imm8 | Packed Shift Right Arythmetic. Działa tak jak PSRLW, lecz uwzględnia znaki słów. |
| PSRAD mm,mm/m64/imm8 | Packed Shift Right Arythmetic. Działa tak jak PSRLD, lecz uwzględnia znaki podwójnych słów. |
| PSUBB mm,mm/m64 | Packed Subtraction. Odejmuje od każdego z 8 bajtów rejestru docelowego 8 bajtów rejestru źródłowego. Wynik zapisuje w rejestrze docelowym. |
| PSUBW mm,mm/m64 | Packed Subtraction. Odejmuje od każdego z 4 słów rejestru docelowego 4 słowa rejestru źródłowego. Wynik zapisuje w rejestrze docelowym. |
| PSUBD mm,mm/m64 | Packed Subtraction. Odejmuje od każdego z 2 podwójnych słów rejestru docelowego 2 podwójne słowa rejestru źródłowego. Wynik zapisuje w rejestrze docelowym. |
| PSUBSB mm,mm/m64 | Packed Subtraction with Signed Saturation. Odejmuje od każdego z 8 bajtów ze znakiem rejestru docelowego 8 bajtów rejestru źródłowego. Wynik zapisuje w rejestrze docelowym i przycina do wartości -128..127. |
| PSUBSW mm,mm/m64 | Packed Subtraction with Signed Saturation. Odejmuje od każdego z 4 słów ze znakiem rejestru docelowego 4 słowa rejestru źródłowego. Wynik zapisuje w rejestrze docelowym i przycina do wartości -32768..32767. |
| PSUBUSB mm,mm/m64 | Packed Subtraction with Unsigned Saturation. Odejmuje od każdego z 8 bajtów bez znaku rejestru docelowego 8 bajtów rejestru źródłowego. Wynik zapisuje w rejestrze docelowym i przycina do wartości 0..255. |
| PSUBUSW mm,mm/m64 | Packed Subtraction with Unsigned Saturation. Odejmuje od każdego z 4 słów bez znaku rejestru docelowego 4 słowa rejestru źródłowego. Wynik zapisuje w rejestrze docelowym i przycina do wartości 0..65635. |
| PUNPCKHBW mm,mm/m64 | Unpack High. Instrukcja bierze 5 bajt z rejestru docelowego i przechowuje go w 1 bajcie rejestru docelowego. 6 bajt rejestru docelowego jest stawiany na 3 pozycji w tym rejestrze. 7 bajt rejestru docelowego przechowywany jest na 5 pozycji rejestru docelowego. 6 bajt rejestru źródłowego jest stawiany na pozycję 4 rejestru docelowego. 8 bajt rejestru docelowego jest stawiany na 7 pozycji tego samego rejestru. 7 bajt rejestru źródłowego jest stawiany na 6 pozycji rejestru docelowego. 8 bajt z rejestru źródłowego jest stawiany na 8 pozycję w rejestrze docelowym. Na końcu najwyższe bajty z obu rejestrów są ułożone naprzemian w rejestrze docelowym. |
| PUNPCKHWD mm,mm/m64 | Unpack High. Podobna do PUNPCKHBW tyle, że układa najwyższe słowa. |
| PUNPCKHDQ mm,mm/m64 | Unpack High. Podobna do PUNPCKHBW tyle, że układa najwyższe podwójne słowa. |
| PUNPCKLBW mm,mm/m64 | Unpack Low. Instrukcja bierze 4 bajt z rejestru źródłowego i przechowuje go w 8 bajcie rejestru docelowego. 4 bajt rejestru docelowego jest stawiany na 7 pozycji w tym rejestrze. 3 bajt rejestru źródłowego jest stawiany na 6 pozycji rejestru docelowego. 3 bajt rejestru docelowego przechowywany jest na 5 pozycji rejestru docelowego. 2 bajt rejestru źródłowego jest stawiany na pozycję 4 rejestru docelowego. 2 bajt rejestru docelowego jest stawiany na 3 pozycji tego samego rejestru. 1 bajt rejestru źródłowego jest stawiany na 2 pozycji rejestru docelowego. Na końcu najniższe bajty z obu rejestrów są ułożone naprzemian w rejestrze docelowym. |
| PUNPCKLWD mm,mm/m64 | Unpack Low. Podobna do PUNPCKLBW tyle, że układa najniższe słowa. |
| PUNPCKLDQ mm,mm/m64 | Unpack Low. Podobna do PUNPCKLBW tyle, że układa Najniższe podwójne słowa. |
| PXOR mm,mm/m64 | Logical XOR. Wykonuje operację logiczną XOR. Wynik jest przechowywany w rejestrze docelowym. |
Oto przykład użycia instrukcji MMX do rotacji 2D:
X'=COS(ALPHA)*X+SIN(ALPHA)*Y
Y'=COS(ALPHA)*Y-SIN(ALPHA)*X
Segment danych powinien wyglądać tak:
| COS_ALPHA1 | dw 00h |
| SIN_ALPHA1 | dw 00h |
| COS_ALPHA2 | dw 00h |
| SIN_ALPHA2 | dw 00h |
| X1 | dw 00h |
| Y1 | dw 00h |
| Y2 | dw 00h |
| X2 | dw 00h |
| |
| Xor Eax,Eax | |
| Xor Ebx,Ebx | |
| Mov Bx,[ALPHA] | |
| Shl Ebx,1 | |
| Mov Edi,offset SINCOSTAB | |
| Mov Ax,[Edi+Ebx+(64*2)] | |
| Mov [COS_ALPHA1],Ax | |
| Mov [COS_ALPHA2],Ax | |
| Mov Ax,[Edi+Ebx] | |
| Mov [SIN_ALPHA1],Ax | |
| Neg Ax | |
| Mov [SIN_ALPHA2],Ax | |
| |
| Mov Ax,[X_TO_ROTATE] | |
| Mov [X1],Ax | |
| Mov [X2],Ax | |
| Mov Ax,[Y_TO_ROTATE] | |
| Mov [Y1],Ax | |
| Mov [Y2],Ax | |
| MovQ mm0,QWord PTR [COS_ALPHA1] | |
| PMAddWD mm0,QWord PTR [X1] | |
| PSRAD mm0,8 | |
| MovD Eax,mm0 | |
| PSRLQ mm0,32 | |
| MovD Ebx,mm0 | |
W Eax mamy X', a Ebx Y'.
©Copyright by Konrad Łukasik
<<
|
|