-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvector_mul.asm
47 lines (35 loc) · 1.48 KB
/
vector_mul.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
section .text
global _vector_mul
; функция принимает <a, b> - два вектора из short'ов
; и возвращает res - вектор из интов, такой, что res[i] = a[i] * b[i]
_vector_mul:
mov eax, [esp + 8]
movq mm0, [eax]
mov eax, [esp + 12]
movq mm1, [eax]
; сохраняем два исходных вектора слов
movq mm2, mm0
pmullw mm2, mm1
; в mm2 хранятся младшие половины результатов
; |4|.|3|.|2|.|1| * |4'|.|3'|.|2'|.|1'| = |(4 * 4')L|.|(3 * 3')L|.|(2 * 2')L|.|(1 * 1')L|
pmulhw mm0, mm1
; в mm0 - старшие
; |4|.|3|.|2|.|1| * |4'|.|3'|.|2'|.|1'| = |(4 * 4')H|.|(3 * 3')H|.|(2 * 2')H|.|(1 * 1')H|
movq mm3, mm2
punpcklwd mm3, mm0
; теперь в mm3 хранятся результаты перемножения 1 и 2 элементов векторов
; punpckl |(4 * 4')L|.|(3 * 3')L|.|(2 * 2')L|.|(1 * 1')L|, |(4 * 4')H|.|(3 * 3')H|.|(2 * 2')H|.|(1 * 1')H| =
; |(4 * 4')H|.|(3 * 3')H|.|(2 * 2')H|.|(1 * 1')H| V |(4 * 4')L|.|(3 * 3')L|.|(2 * 2')L|.|(1 * 1')L| =
; |(2 * 2')H, (2 * 2')L|.|(1 * 1')H, (1 * 1')L| = |2 * 2'|.|1 * 1'|
punpckhwd mm2, mm0
; в mm2 - результаты перемножения 3 и 4
; punpckh |(4 * 4')L|.|(3 * 3')L|.|(2 * 2')L|.|(1 * 1')L|, |(4 * 4')H|.|(3 * 3')H|.|(2 * 2')H|.|(1 * 1')H| =
; |(4 * 4')H|.|(3 * 3')H|.|(2 * 2')H|.|(1 * 1')H| ^ |(4 * 4')L|.|(3 * 3')L|.|(2 * 2')L|.|(1 * 1')L| =
; |(4 * 4')H, (4 * 4')L|.|(3 * 3')H, (3 * 3')L| = |4 * 4'|.|3 * 3'|
mov eax, [esp + 4]
movq [eax], mm3
; так как мы положили два 4-байтовых числа
movq [eax + 8], mm2
; пометить все mm-регистры как свободные (для соблюдения конвенции вызова)
emms
ret