| ... | @@ -45,9 +45,11 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { | ... | @@ -45,9 +45,11 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { |
| 45 | if (x86) { | 45 | if (x86) { |
| 46 | // Intel processors have a unified instruction and data cache | 46 | // Intel processors have a unified instruction and data cache |
| 47 | // so there is nothing to do | 47 | // so there is nothing to do |
| | 48 | exportIt(); |
| 48 | } else if (os == .windows and (arm32 or arm64)) { | 49 | } else if (os == .windows and (arm32 or arm64)) { |
| 49 | @compileError("TODO"); | 50 | // TODO |
| 50 | // FlushInstructionCache(GetCurrentProcess(), start, end - start); | 51 | // FlushInstructionCache(GetCurrentProcess(), start, end - start); |
| | 52 | // exportIt(); |
| 51 | } else if (arm32 and !apple) { | 53 | } else if (arm32 and !apple) { |
| 52 | switch (os) { | 54 | switch (os) { |
| 53 | .freebsd, .netbsd => { | 55 | .freebsd, .netbsd => { |
| ... | @@ -57,23 +59,28 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { | ... | @@ -57,23 +59,28 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { |
| 57 | }; | 59 | }; |
| 58 | const result = sysarch(ARM_SYNC_ICACHE, @ptrToInt(&arg)); | 60 | const result = sysarch(ARM_SYNC_ICACHE, @ptrToInt(&arg)); |
| 59 | std.debug.assert(result == 0); | 61 | std.debug.assert(result == 0); |
| | 62 | exportIt(); |
| 60 | }, | 63 | }, |
| 61 | .linux => { | 64 | .linux => { |
| 62 | const result = std.os.linux.syscall3(.cacheflush, start, end, 0); | 65 | const result = std.os.linux.syscall3(.cacheflush, start, end, 0); |
| 63 | std.debug.assert(result == 0); | 66 | std.debug.assert(result == 0); |
| | 67 | exportIt(); |
| 64 | }, | 68 | }, |
| 65 | else => @compileError("TODO"), | 69 | else => {}, |
| 66 | } | 70 | } |
| 67 | } else if (os == .linux and mips) { | 71 | } else if (os == .linux and mips) { |
| 68 | const flags = 3; // ICACHE | DCACHE | 72 | const flags = 3; // ICACHE | DCACHE |
| 69 | const result = std.os.linux.syscall3(std.os.linux.SYS_cacheflush, start, end - start, flags); | 73 | const result = std.os.linux.syscall3(.cacheflush, start, end - start, flags); |
| 70 | std.debug.assert(result == 0); | 74 | std.debug.assert(result == 0); |
| | 75 | exportIt(); |
| 71 | } else if (mips and os == .openbsd) { | 76 | } else if (mips and os == .openbsd) { |
| 72 | @compileError("TODO"); | 77 | // TODO |
| 73 | //cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE); | 78 | //cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE); |
| | 79 | // exportIt(); |
| 74 | } else if (os == .linux and riscv) { | 80 | } else if (os == .linux and riscv) { |
| 75 | const result = std.os.linux.syscall3(std.os.linux.SYS_riscv_flush_icache, start, end - start, 0); | 81 | const result = std.os.linux.syscall3(.riscv_flush_icache, start, end - start, 0); |
| 76 | std.debug.assert(result == 0); | 82 | std.debug.assert(result == 0); |
| | 83 | exportIt(); |
| 77 | } else if (arm64 and !apple) { | 84 | } else if (arm64 and !apple) { |
| 78 | // Get Cache Type Info. | 85 | // Get Cache Type Info. |
| 79 | // TODO memoize this? | 86 | // TODO memoize this? |
| ... | @@ -112,8 +119,9 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { | ... | @@ -112,8 +119,9 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { |
| 112 | } | 119 | } |
| 113 | } | 120 | } |
| 114 | asm volatile ("isb sy"); | 121 | asm volatile ("isb sy"); |
| | 122 | exportIt(); |
| 115 | } else if (powerpc64) { | 123 | } else if (powerpc64) { |
| 116 | @compileError("TODO"); | 124 | // TODO |
| 117 | //const size_t line_size = 32; | 125 | //const size_t line_size = 32; |
| 118 | //const size_t len = (uintptr_t)end - (uintptr_t)start; | 126 | //const size_t len = (uintptr_t)end - (uintptr_t)start; |
| 119 | // | 127 | // |
| ... | @@ -128,8 +136,9 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { | ... | @@ -128,8 +136,9 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { |
| 128 | //for (uintptr_t line = start_line; line < end_line; line += line_size) | 136 | //for (uintptr_t line = start_line; line < end_line; line += line_size) |
| 129 | // __asm__ volatile("icbi 0, %0" : : "r"(line)); | 137 | // __asm__ volatile("icbi 0, %0" : : "r"(line)); |
| 130 | //__asm__ volatile("isync"); | 138 | //__asm__ volatile("isync"); |
| | 139 | // exportIt(); |
| 131 | } else if (sparc) { | 140 | } else if (sparc) { |
| 132 | @compileError("TODO"); | 141 | // TODO |
| 133 | //const size_t dword_size = 8; | 142 | //const size_t dword_size = 8; |
| 134 | //const size_t len = (uintptr_t)end - (uintptr_t)start; | 143 | //const size_t len = (uintptr_t)end - (uintptr_t)start; |
| 135 | // | 144 | // |
| ... | @@ -139,14 +148,20 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { | ... | @@ -139,14 +148,20 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void { |
| 139 | // | 148 | // |
| 140 | //for (uintptr_t dword = start_dword; dword < end_dword; dword += dword_size) | 149 | //for (uintptr_t dword = start_dword; dword < end_dword; dword += dword_size) |
| 141 | // __asm__ volatile("flush %0" : : "r"(dword)); | 150 | // __asm__ volatile("flush %0" : : "r"(dword)); |
| | 151 | // exportIt(); |
| 142 | } else if (apple) { | 152 | } else if (apple) { |
| 143 | // On Darwin, sys_icache_invalidate() provides this functionality | 153 | // On Darwin, sys_icache_invalidate() provides this functionality |
| 144 | sys_icache_invalidate(start, end - start); | 154 | sys_icache_invalidate(start, end - start); |
| 145 | } else { | 155 | exportIt(); |
| 146 | @compileError("no __clear_cache implementation available for this target"); | | |
| 147 | } | 156 | } |
| 148 | } | 157 | } |
| 149 | | 158 | |
| | 159 | const linkage = if (std.builtin.is_test) std.builtin.GlobalLinkage.Internal else std.builtin.GlobalLinkage.Weak; |
| | 160 | |
| | 161 | inline fn exportIt() void { |
| | 162 | @export(clear_cache, .{ .name = "__clear_cache", .linkage = linkage }); |
| | 163 | } |
| | 164 | |
| 150 | // Darwin-only | 165 | // Darwin-only |
| 151 | extern fn sys_icache_invalidate(start: usize, len: usize) void; | 166 | extern fn sys_icache_invalidate(start: usize, len: usize) void; |
| 152 | // BSD-only | 167 | // BSD-only |