-
Notifications
You must be signed in to change notification settings - Fork 0
/
arctan_scalar.asm
89 lines (68 loc) · 1.79 KB
/
arctan_scalar.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
section .text
global _arctan_scalar
_arctan_scalar:
; скалярные операции SSE работают по младшему слову xmm-регистра (у нас little endian)
mov eax, [esp + 4]
mov [BUFFER], eax
; младшее двойное слово BUFFER = x
movups xmm0, [BUFFER]
; младшее двойное слово xmm0 - x
; в младшем двойном слове xmm0 хранится текущий числитель
mov ecx, [esp + 8]
; ecx - количество ненулевых членов в разложении artcg(x) в степенной ряд
mov edx, [TWO]
mov [BUFFER], edx
movups xmm1, [BUFFER]
; инициализация xmm1, в младшем двойном слове хранится 2.0
; если k <= 0, вернуть 0
cmp ecx, 0
jle return_zero
mov edx, [ONE]
mov [BUFFER], edx
movups xmm2, [BUFFER]
; инициализация xmm2 значением 1.0
; в xmm2 хранится текущий числитель
mov edx, [MINUS_ONE]
mov [BUFFER], edx
movups xmm7, [BUFFER]
; в младшем двойном слове xmm7 хранится -1
movups xmm3, xmm0
mulss xmm3, xmm3
mulss xmm3, xmm7
; в младшем двойном слове xmm3 хранится x * x * (-1) = -x^2
movups xmm4, xmm0
; в младшем двойном слове xmm4 хранится сумма k первых членов arctg(x)
dec ecx
; результат уже равен x, так что уменьшим k на 1
test ecx, ecx
jz return
main_loop:
mulss xmm0, xmm3
; в xmm0 хранится корректный текущий числитель
addss xmm2, xmm1
; в xmm2 хранится корректный текущий числитель
movups xmm7, xmm0
divss xmm7, xmm2
; в xmm7 хранится текущий_числитель / текущий_знаменатель
addss xmm4, xmm7
; в xmm4 хранится текущая сумма
dec ecx
test ecx, ecx
jnz main_loop
return:
; инициализируем FPU чтобы вернуть на его вершине значение
finit
movups [BUFFER], xmm4
fld dword [BUFFER]
ret
return_zero:
finit
fldz
ret
section .rdata
TWO : dd 2.0
ONE : dd 1.0
MINUS_ONE : dd -1.0
section .bss
; Буфер для переноса в mmx-регистр из памяти или регистров общего назначени
BUFFER : resd 4