summaryrefslogtreecommitdiff
path: root/clear_page.c
diff options
context:
space:
mode:
Diffstat (limited to 'clear_page.c')
-rw-r--r--clear_page.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/clear_page.c b/clear_page.c
new file mode 100644
index 0000000..6940328
--- /dev/null
+++ b/clear_page.c
@@ -0,0 +1,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
+}