-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathherbceptions.cpp
63 lines (56 loc) · 1.65 KB
/
herbceptions.cpp
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
#include "thirdparty/tbv/tbv.hpp"
#include <cmath>
#include <span>
unsigned herbceptionEmulationSqrt(std::span<double> values, unsigned repeat) noexcept;
unsigned herbceptionEmulationFib(unsigned n, unsigned maxDepth) noexcept;
unsigned herbceptionsSqrt(std::span<double> values, unsigned repeat) noexcept {
// The emulation is good enough here, the call overhead is negligible
return herbceptionEmulationSqrt(values, repeat);
}
#if defined(__x86_64__) && defined(__linux__)
static unsigned doFib(unsigned n, unsigned maxDepth) __attribute__((naked));
static unsigned doFib(unsigned /*n*/, unsigned /*maxDepth*/) {
asm(R"(
.LBfib:
pushq %rbp
pushq %r14
pushq %rbx
testl %esi, %esi
je .LBB0_1
movl %edi, %r14d
movl $1, %eax
cmpl $3, %edi
jb .LBB0_4
movl %esi, %ebx
leal -2(%r14), %edi
decl %ebx
movl %ebx, %esi
callq .LBfib
jc .LBB0_5
movl %eax, %ebp
decl %r14d
movl %r14d, %edi
movl %ebx, %esi
callq .LBfib
jc .LBB0_5
addl %ebp, %eax
.LBB0_4:
clc
.LBB0_5:
popq %rbx
popq %r14
popq %rbp
retq
.LBB0_1:
xor %eax, %eax
stc
jmp .LBB0_5
)");
}
unsigned herbceptionsFib(unsigned n, unsigned maxDepth) noexcept {
return doFib(n, maxDepth);
}
#else
#warning No herbception implementation provided for this platform, falling back to emulation
unsigned herbceptionsFib(unsigned n, unsigned maxDepth) { return herbceptionEmulationFib(n, maxDepth); }
#endif