authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-31 10:49:06-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-31 10:49:06-04:00
log6d25e451231d611887468c48ae72af441797c712
treee3afe2b2dca825295dc842f2f1d6804886c8fa79
parentd57b5205c61d1110745484cbade5fcac51835023
parent0e372ccff511a9e286949328037d87af64e31875
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'LemonBoy-more-cache'


2 files changed, 55 insertions(+), 39 deletions(-)

lib/std/special/compiler_rt.zig+3-16
......@@ -17,25 +17,12 @@ comptime {
1717 .linkage = linkage,
1818 }),
1919
20 .aarch64,
21 .aarch64_be,
22 .aarch64_32,
23 => @export(@import("compiler_rt/clear_cache.zig").clear_cache, .{
24 .name = "__clear_cache",
25 .linkage = linkage,
26 }),
27
28 .arm, .armeb, .thumb, .thumbeb => switch (builtin.os.tag) {
29 .linux => @export(@import("compiler_rt/clear_cache.zig").clear_cache, .{
30 .name = "__clear_cache",
31 .linkage = linkage,
32 }),
33 else => {},
34 },
35
3620 else => {},
3721 }
3822
23 // __clear_cache manages its own logic about whether to be exported or not.
24 _ = @import("compiler_rt/clear_cache.zig").clear_cache;
25
3926 @export(@import("compiler_rt/compareXf2.zig").__lesf2, .{ .name = "__lesf2", .linkage = linkage });
4027 @export(@import("compiler_rt/compareXf2.zig").__ledf2, .{ .name = "__ledf2", .linkage = linkage });
4128 @export(@import("compiler_rt/compareXf2.zig").__letf2, .{ .name = "__letf2", .linkage = linkage });
lib/std/special/compiler_rt/clear_cache.zig+52-23
......@@ -26,6 +26,10 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
2626 .mips, .mipsel, .mips64, .mips64el => true,
2727 else => false,
2828 };
29 const riscv = switch (arch) {
30 .riscv32, .riscv64 => true,
31 else => false,
32 };
2933 const powerpc64 = switch (arch) {
3034 .powerpc64, .powerpc64le => true,
3135 else => false,
......@@ -41,32 +45,42 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
4145 if (x86) {
4246 // Intel processors have a unified instruction and data cache
4347 // so there is nothing to do
48 exportIt();
4449 } else if (os == .windows and (arm32 or arm64)) {
45 @compileError("TODO");
50 // TODO
4651 // FlushInstructionCache(GetCurrentProcess(), start, end - start);
52 // exportIt();
4753 } else if (arm32 and !apple) {
48 if (os == .freebsd or os == .netbsd) {
49 // struct arm_sync_icache_args arg;
50 //
51 // arg.addr = (uintptr_t)start;
52 // arg.len = (uintptr_t)end - (uintptr_t)start;
53 //
54 // sysarch(ARM_SYNC_ICACHE, &arg);
55 @compileError("TODO: implement for NetBSD/FreeBSD");
56 } else if (os == .linux) {
57 const result = std.os.linux.syscall3(.cacheflush, start, end, 0);
58 std.debug.assert(result == 0);
59 } else {
60 @compileError("no __clear_cache implementation available for this target");
54 switch (os) {
55 .freebsd, .netbsd => {
56 var arg = arm_sync_icache_args{
57 .addr = start,
58 .len = end - start,
59 };
60 const result = sysarch(ARM_SYNC_ICACHE, @ptrToInt(&arg));
61 std.debug.assert(result == 0);
62 exportIt();
63 },
64 .linux => {
65 const result = std.os.linux.syscall3(.cacheflush, start, end, 0);
66 std.debug.assert(result == 0);
67 exportIt();
68 },
69 else => {},
6170 }
6271 } else if (os == .linux and mips) {
63 @compileError("TODO");
64 //const uintptr_t start_int = (uintptr_t)start;
65 //const uintptr_t end_int = (uintptr_t)end;
66 //syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE);
72 const flags = 3; // ICACHE | DCACHE
73 const result = std.os.linux.syscall3(.cacheflush, start, end - start, flags);
74 std.debug.assert(result == 0);
75 exportIt();
6776 } else if (mips and os == .openbsd) {
68 @compileError("TODO");
77 // TODO
6978 //cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE);
79 // exportIt();
80 } else if (os == .linux and riscv) {
81 const result = std.os.linux.syscall3(.riscv_flush_icache, start, end - start, 0);
82 std.debug.assert(result == 0);
83 exportIt();
7084 } else if (arm64 and !apple) {
7185 // Get Cache Type Info.
7286 // TODO memoize this?
......@@ -105,8 +119,9 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
105119 }
106120 }
107121 asm volatile ("isb sy");
122 exportIt();
108123 } else if (powerpc64) {
109 @compileError("TODO");
124 // TODO
110125 //const size_t line_size = 32;
111126 //const size_t len = (uintptr_t)end - (uintptr_t)start;
112127 //
......@@ -121,8 +136,9 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
121136 //for (uintptr_t line = start_line; line < end_line; line += line_size)
122137 // __asm__ volatile("icbi 0, %0" : : "r"(line));
123138 //__asm__ volatile("isync");
139 // exportIt();
124140 } else if (sparc) {
125 @compileError("TODO");
141 // TODO
126142 //const size_t dword_size = 8;
127143 //const size_t len = (uintptr_t)end - (uintptr_t)start;
128144 //
......@@ -132,13 +148,26 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
132148 //
133149 //for (uintptr_t dword = start_dword; dword < end_dword; dword += dword_size)
134150 // __asm__ volatile("flush %0" : : "r"(dword));
151 // exportIt();
135152 } else if (apple) {
136153 // On Darwin, sys_icache_invalidate() provides this functionality
137154 sys_icache_invalidate(start, end - start);
138 } else {
139 @compileError("no __clear_cache implementation available for this target");
155 exportIt();
140156 }
141157}
142158
159const linkage = if (std.builtin.is_test) std.builtin.GlobalLinkage.Internal else std.builtin.GlobalLinkage.Weak;
160
161inline fn exportIt() void {
162 @export(clear_cache, .{ .name = "__clear_cache", .linkage = linkage });
163}
164
143165// Darwin-only
144166extern fn sys_icache_invalidate(start: usize, len: usize) void;
167// BSD-only
168const arm_sync_icache_args = extern struct {
169 addr: usize, // Virtual start address
170 len: usize, // Region size
171};
172const ARM_SYNC_ICACHE = 0;
173extern "c" fn sysarch(number: i32, args: usize) i32;