summaryrefslogtreecommitdiff
path: root/clear_page.c
blob: 69403285a5cc8a42b22cb81b5b6f6fb84c553563 (plain)
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
/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */

#define PAGE_SIZE 8192

#define wh64(p) asm ("wh64 (%0)" : : "r"(p) : "memory")
#define ecb(p) asm("ecb (%0)" : : "r"(p) : "memory")
#define prefetch(p) asm("ldl $31, 0(%0)" : : "r"(p))
#define prefetch_en(p) asm("ldq $31, 0(%0)" : : "r"(p))
#define prefetch_m(p) asm("lds $f31, 0(%0)" : : "r"(p))
#define prefetch_men(p) asm("ldt $f31, 0(%0)" : : "r"(p))
#define nop asm("nop")

#define PREFETCH_LINES 2

//#define UNROLL_EVERYTHING

#define ZERO(p) do { \
	prefetch_m(p + PREFETCH_LINES * 8); \
	(p)[0] = 0; nop; (p)[1] = 0; nop; (p)[2] = 0; nop; (p)[3] = 0; nop; \
	(p)[4] = 0; nop; (p)[5] = 0; nop; (p)[6] = 0; nop; (p)[7] = 0; nop; \
	p += 8; \
} while (0)

#define ZERO_PAGE(p) do { \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
	ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); ZERO(p); \
} while (0)

void
clear_page(void *page)
{
    int chunks = PAGE_SIZE / 64;
    int chunks_prefetch = chunks - PREFETCH_LINES;
    int chunks_no_prefetch = PREFETCH_LINES;

    long *p = page;
#ifdef UNROLL_EVERYTHING
    long *end = page + PAGE_SIZE;
    ZERO_PAGE(p);
#else
    while (chunks_prefetch > 0) {
        prefetch_m(p + PREFETCH_LINES * 8);
        p[0] = 0; nop;
        p[1] = 0; nop;
        p[2] = 0; nop;
        p[3] = 0; nop;
        p[4] = 0; nop;
        p[5] = 0; nop;
        p[6] = 0; nop;
        p[7] = 0; nop;

        nop; nop; nop; nop;

        chunks_prefetch--;
        p += 8;
    }

    while (chunks_no_prefetch > 0) {
        p[0] = 0; nop;
        p[1] = 0; nop;
        p[2] = 0; nop;
        p[3] = 0; nop;
        p[4] = 0; nop;
        p[5] = 0; nop;
        p[6] = 0; nop;
        p[7] = 0; nop;

        nop; nop; nop; nop;

        chunks_no_prefetch--;
        p += 8;
    }
#endif
}