| author | |
| committer | |
| log | 11bb8ab9b3cf832a5e391ac8c73cbc33221db19d |
| tree | b7b1dbe0280a1843a515678f63955de1bc4c996e |
| parent | b3747dd707eeaf06e0bacbde259bf71ef525a961 |
| parent | 84a100b3e06afec33d4077052a50f8126396021f |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/354639 files changed, 260 insertions(+), 3 deletions(-)
lib/std/Thread.zig+10| ... | ... | @@ -1411,6 +1411,16 @@ const LinuxThreadImpl = struct { |
| 1411 | 1411 | : [ptr] "{r4}" (@intFromPtr(self.mapped.ptr)), |
| 1412 | 1412 | [len] "{r5}" (self.mapped.len), |
| 1413 | 1413 | : .{ .memory = true }), |
| 1414 | .xtensa, .xtensaeb => asm volatile ( | |
| 1415 | \\ movi a2, 81 // SYS_munmap | |
| 1416 | \\ syscall | |
| 1417 | \\ movi a6, 0 | |
| 1418 | \\ movi a2, 118 // SYS_exit | |
| 1419 | \\ syscall | |
| 1420 | : | |
| 1421 | : [ptr] "{a6}" (@intFromPtr(self.mapped.ptr)), | |
| 1422 | [len] "{a3}" (self.mapped.len), | |
| 1423 | : .{ .memory = true }), | |
| 1414 | 1424 | else => |cpu_arch| @compileError("Unsupported linux arch: " ++ @tagName(cpu_arch)), |
| 1415 | 1425 | } |
| 1416 | 1426 | unreachable; |
lib/std/debug.zig+2| ... | ... | @@ -994,6 +994,8 @@ const StackIterator = union(enum) { |
| 994 | 994 | .sh, |
| 995 | 995 | .sheb, |
| 996 | 996 | .xcore, |
| 997 | .xtensa, | |
| 998 | .xtensaeb, | |
| 997 | 999 | => .useless, |
| 998 | 1000 | .hexagon, |
| 999 | 1001 | // The PowerPC ABIs don't actually strictly require a backchain pointer; they allow omitting |
lib/std/elf.zig+3| ... | ... | @@ -224,6 +224,9 @@ pub const DT_PPC64_NUM = 4; |
| 224 | 224 | pub const DT_IA_64_PLT_RESERVE = (DT_LOPROC + 0); |
| 225 | 225 | pub const DT_IA_64_NUM = 1; |
| 226 | 226 | |
| 227 | pub const DT_XTENSA_GOT_LOC_OFF = 0x70000000; | |
| 228 | pub const DT_XTENSA_GOT_LOC_SZ = 0x70000001; | |
| 229 | ||
| 227 | 230 | pub const DT_NIOS2_GP = 0x70000002; |
| 228 | 231 | |
| 229 | 232 | pub const DF_ORIGIN = 0x00000001; |
lib/std/os.zig-3| ... | ... | @@ -28,9 +28,6 @@ pub fn targetRequiresLibC(target: *const std.Target) bool { |
| 28 | 28 | .sheb, |
| 29 | 29 | // https://codeberg.org/ziglang/zig/issues/30945 |
| 30 | 30 | .sparc, |
| 31 | // https://codeberg.org/ziglang/zig/issues/30947 | |
| 32 | .xtensa, | |
| 33 | .xtensaeb, | |
| 34 | 31 | => true, |
| 35 | 32 | else => false, |
| 36 | 33 | }, |
lib/std/os/linux.zig+32| ... | ... | @@ -56,6 +56,7 @@ const arch_bits = switch (native_arch) { |
| 56 | 56 | .gnux32, .muslx32 => @import("linux/x32.zig"), |
| 57 | 57 | else => @import("linux/x86_64.zig"), |
| 58 | 58 | }, |
| 59 | .xtensa, .xtensaeb => @import("linux/xtensa.zig"), | |
| 59 | 60 | else => struct {}, |
| 60 | 61 | }; |
| 61 | 62 | |
| ... | ... | @@ -338,6 +339,29 @@ pub const MAP = switch (native_arch) { |
| 338 | 339 | _20: u1 = 0, |
| 339 | 340 | _: u5 = 0, |
| 340 | 341 | }, |
| 342 | .xtensa, .xtensaeb => packed struct(u32) { | |
| 343 | TYPE: MAP_TYPE, | |
| 344 | FIXED: bool = false, | |
| 345 | _RENAME: bool = false, | |
| 346 | _AUTOGROW: bool = false, | |
| 347 | _LOCAL: bool = false, | |
| 348 | _AUTORSRV: bool = false, | |
| 349 | _1: u1 = 0, | |
| 350 | NORESERVE: bool = false, | |
| 351 | ANONYMOUS: bool = false, | |
| 352 | GROWSDOWN: bool = false, | |
| 353 | DENYWRITE: bool = false, | |
| 354 | EXECUTABLE: bool = false, | |
| 355 | LOCKED: bool = false, | |
| 356 | POPULATE: bool = false, | |
| 357 | NONBLOCK: bool = false, | |
| 358 | STACK: bool = false, | |
| 359 | HUGETLB: bool = false, | |
| 360 | FIXED_NOREPLACE: bool = false, | |
| 361 | _2: u5 = 0, | |
| 362 | UNINITIALIZED: bool = false, | |
| 363 | _3: u5 = 0, | |
| 364 | }, | |
| 341 | 365 | else => @compileError("missing std.os.linux.MAP constants for this architecture"), |
| 342 | 366 | }; |
| 343 | 367 | |
| ... | ... | @@ -497,6 +521,8 @@ pub const O = switch (native_arch) { |
| 497 | 521 | .hexagon, |
| 498 | 522 | .or1k, |
| 499 | 523 | .s390x, |
| 524 | .xtensa, | |
| 525 | .xtensaeb, | |
| 500 | 526 | => packed struct(u32) { |
| 501 | 527 | ACCMODE: ACCMODE = .RDONLY, |
| 502 | 528 | _2: u4 = 0, |
| ... | ... | @@ -6617,6 +6643,12 @@ pub const k_sigaction = switch (native_arch) { |
| 6617 | 6643 | mask: sigset_t, |
| 6618 | 6644 | flags: c_int, |
| 6619 | 6645 | }, |
| 6646 | .xtensa, .xtensaeb => extern struct { | |
| 6647 | handler: k_sigaction_funcs.handler, | |
| 6648 | mask: sigset_t, | |
| 6649 | flags: c_ulong, | |
| 6650 | restorer: k_sigaction_funcs.restorer, | |
| 6651 | }, | |
| 6620 | 6652 | else => extern struct { |
| 6621 | 6653 | handler: k_sigaction_funcs.handler, |
| 6622 | 6654 | flags: c_ulong, |
lib/std/os/linux/tls.zig+11| ... | ... | @@ -78,6 +78,8 @@ const current_variant: Variant = switch (native_arch) { |
| 78 | 78 | .sheb, |
| 79 | 79 | .thumb, |
| 80 | 80 | .thumbeb, |
| 81 | .xtensa, | |
| 82 | .xtensaeb, | |
| 81 | 83 | => .I_original, |
| 82 | 84 | .loongarch32, |
| 83 | 85 | .loongarch64, |
| ... | ... | @@ -152,6 +154,8 @@ const AbiTcb = switch (current_variant) { |
| 152 | 154 | .sheb, |
| 153 | 155 | .thumb, |
| 154 | 156 | .thumbeb, |
| 157 | .xtensa, | |
| 158 | .xtensaeb, | |
| 155 | 159 | => extern struct { |
| 156 | 160 | /// This is offset by `current_dtv_offset`. |
| 157 | 161 | dtv: usize, |
| ... | ... | @@ -364,6 +368,13 @@ pub fn setThreadPointer(addr: usize) void { |
| 364 | 368 | : [addr] "r" (addr), |
| 365 | 369 | ); |
| 366 | 370 | }, |
| 371 | .xtensa, .xtensaeb => { | |
| 372 | asm volatile ( | |
| 373 | \\ wur %[addr], threadptr | |
| 374 | : | |
| 375 | : [addr] "a" (addr), | |
| 376 | ); | |
| 377 | }, | |
| 367 | 378 | else => @compileError("Unsupported architecture"), |
| 368 | 379 | } |
| 369 | 380 | } |
lib/std/os/linux/xtensa.zig created+171| ... | ... | @@ -0,0 +1,171 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("../../std.zig"); | |
| 3 | const SYS = std.os.linux.SYS; | |
| 4 | ||
| 5 | pub const syscall_arg_t = u32; | |
| 6 | ||
| 7 | pub fn syscall0( | |
| 8 | number: SYS, | |
| 9 | ) u32 { | |
| 10 | return asm volatile ("syscall" | |
| 11 | : [ret] "={a2}" (-> u32), | |
| 12 | : [number] "{a2}" (@intFromEnum(number)), | |
| 13 | : .{ .memory = true }); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn syscall1( | |
| 17 | number: SYS, | |
| 18 | arg1: syscall_arg_t, | |
| 19 | ) u32 { | |
| 20 | return asm volatile ("syscall" | |
| 21 | : [ret] "={a2}" (-> u32), | |
| 22 | : [number] "{a2}" (@intFromEnum(number)), | |
| 23 | [arg1] "{a6}" (arg1), | |
| 24 | : .{ .memory = true }); | |
| 25 | } | |
| 26 | ||
| 27 | pub fn syscall2( | |
| 28 | number: SYS, | |
| 29 | arg1: syscall_arg_t, | |
| 30 | arg2: syscall_arg_t, | |
| 31 | ) u32 { | |
| 32 | return asm volatile ("syscall" | |
| 33 | : [ret] "={a2}" (-> u32), | |
| 34 | : [number] "{a2}" (@intFromEnum(number)), | |
| 35 | [arg1] "{a6}" (arg1), | |
| 36 | [arg2] "{a3}" (arg2), | |
| 37 | : .{ .memory = true }); | |
| 38 | } | |
| 39 | ||
| 40 | pub fn syscall3( | |
| 41 | number: SYS, | |
| 42 | arg1: syscall_arg_t, | |
| 43 | arg2: syscall_arg_t, | |
| 44 | arg3: syscall_arg_t, | |
| 45 | ) u32 { | |
| 46 | return asm volatile ("syscall" | |
| 47 | : [ret] "={a2}" (-> u32), | |
| 48 | : [number] "{a2}" (@intFromEnum(number)), | |
| 49 | [arg1] "{a6}" (arg1), | |
| 50 | [arg2] "{a3}" (arg2), | |
| 51 | [arg3] "{a4}" (arg3), | |
| 52 | : .{ .memory = true }); | |
| 53 | } | |
| 54 | ||
| 55 | pub fn syscall4( | |
| 56 | number: SYS, | |
| 57 | arg1: syscall_arg_t, | |
| 58 | arg2: syscall_arg_t, | |
| 59 | arg3: syscall_arg_t, | |
| 60 | arg4: syscall_arg_t, | |
| 61 | ) u32 { | |
| 62 | return asm volatile ("syscall" | |
| 63 | : [ret] "={a2}" (-> u32), | |
| 64 | : [number] "{a2}" (@intFromEnum(number)), | |
| 65 | [arg1] "{a6}" (arg1), | |
| 66 | [arg2] "{a3}" (arg2), | |
| 67 | [arg3] "{a4}" (arg3), | |
| 68 | [arg4] "{a5}" (arg4), | |
| 69 | : .{ .memory = true }); | |
| 70 | } | |
| 71 | ||
| 72 | pub fn syscall5( | |
| 73 | number: SYS, | |
| 74 | arg1: syscall_arg_t, | |
| 75 | arg2: syscall_arg_t, | |
| 76 | arg3: syscall_arg_t, | |
| 77 | arg4: syscall_arg_t, | |
| 78 | arg5: syscall_arg_t, | |
| 79 | ) u32 { | |
| 80 | return asm volatile ("syscall" | |
| 81 | : [ret] "={a2}" (-> u32), | |
| 82 | : [number] "{a2}" (@intFromEnum(number)), | |
| 83 | [arg1] "{a6}" (arg1), | |
| 84 | [arg2] "{a3}" (arg2), | |
| 85 | [arg3] "{a4}" (arg3), | |
| 86 | [arg4] "{a5}" (arg4), | |
| 87 | [arg5] "{a8}" (arg5), | |
| 88 | : .{ .memory = true }); | |
| 89 | } | |
| 90 | ||
| 91 | pub fn syscall6( | |
| 92 | number: SYS, | |
| 93 | arg1: syscall_arg_t, | |
| 94 | arg2: syscall_arg_t, | |
| 95 | arg3: syscall_arg_t, | |
| 96 | arg4: syscall_arg_t, | |
| 97 | arg5: syscall_arg_t, | |
| 98 | arg6: syscall_arg_t, | |
| 99 | ) u32 { | |
| 100 | return asm volatile ("syscall" | |
| 101 | : [ret] "={a2}" (-> u32), | |
| 102 | : [number] "{a2}" (@intFromEnum(number)), | |
| 103 | [arg1] "{a6}" (arg1), | |
| 104 | [arg2] "{a3}" (arg2), | |
| 105 | [arg3] "{a4}" (arg3), | |
| 106 | [arg4] "{a5}" (arg4), | |
| 107 | [arg5] "{a8}" (arg5), | |
| 108 | [arg6] "{a9}" (arg6), | |
| 109 | : .{ .memory = true }); | |
| 110 | } | |
| 111 | ||
| 112 | pub fn clone() callconv(.naked) u32 { | |
| 113 | // __clone(func, stack, flags, arg, ptid, tls, ctid) | |
| 114 | // a2, a3, a4, a5, a6, a7, +16 | |
| 115 | // | |
| 116 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) | |
| 117 | // a2 a6, a3, a4, a5, a8 | |
| 118 | asm volatile ( | |
| 119 | \\ entry sp, 16 | |
| 120 | \\ | |
| 121 | \\ movi a8, -16 | |
| 122 | \\ and a3, a3, a8 | |
| 123 | \\ | |
| 124 | \\ mov a9, a2 | |
| 125 | \\ mov a10, a5 | |
| 126 | \\ | |
| 127 | \\ mov a5, a7 | |
| 128 | \\ mov a8, a6 | |
| 129 | \\ mov a6, a4 | |
| 130 | \\ mov a4, a8 | |
| 131 | \\ l32i a8, sp, 16 | |
| 132 | \\ movi a2, 116 // SYS_clone | |
| 133 | \\ syscall | |
| 134 | \\ | |
| 135 | \\ beqz a2, 1f | |
| 136 | \\ // parent | |
| 137 | \\ retw | |
| 138 | \\ | |
| 139 | \\ // child | |
| 140 | \\1: | |
| 141 | \\ movi a7, 0 | |
| 142 | \\ movi a0, 0 | |
| 143 | \\ | |
| 144 | \\ mov a2, a10 | |
| 145 | \\ callx0 a9 | |
| 146 | \\ movi a2, 118 // SYS_exit | |
| 147 | \\ syscall | |
| 148 | ); | |
| 149 | } | |
| 150 | ||
| 151 | pub const restore = restore_rt; | |
| 152 | ||
| 153 | pub fn restore_rt() callconv(.naked) noreturn { | |
| 154 | switch (builtin.zig_backend) { | |
| 155 | .stage2_c => asm volatile ( | |
| 156 | \\ movi a2, %[number] | |
| 157 | \\ syscall | |
| 158 | : | |
| 159 | : [number] "I" (@intFromEnum(SYS.rt_sigreturn)), | |
| 160 | ), | |
| 161 | else => asm volatile ( | |
| 162 | \\ syscall | |
| 163 | : | |
| 164 | : [number] "{a2}" (@intFromEnum(SYS.rt_sigreturn)), | |
| 165 | ), | |
| 166 | } | |
| 167 | } | |
| 168 | ||
| 169 | pub const VDSO = void; | |
| 170 | ||
| 171 | pub const time_t = i32; |
lib/std/pie.zig+21| ... | ... | @@ -22,6 +22,7 @@ const R_RISCV_RELATIVE = 3; |
| 22 | 22 | const R_390_RELATIVE = 12; |
| 23 | 23 | const R_SH_RELATIVE = 165; |
| 24 | 24 | const R_SPARC_RELATIVE = 22; |
| 25 | const R_XTENSA_RELATIVE = 5; | |
| 25 | 26 | |
| 26 | 27 | const R_RELATIVE = switch (builtin.cpu.arch) { |
| 27 | 28 | .x86 => R_386_RELATIVE, |
| ... | ... | @@ -43,6 +44,7 @@ const R_RELATIVE = switch (builtin.cpu.arch) { |
| 43 | 44 | .s390x => R_390_RELATIVE, |
| 44 | 45 | .sh, .sheb => R_SH_RELATIVE, |
| 45 | 46 | .sparc, .sparc64 => R_SPARC_RELATIVE, |
| 47 | .xtensa, .xtensaeb => R_XTENSA_RELATIVE, | |
| 46 | 48 | else => @compileError("Missing R_RELATIVE definition for this target"), |
| 47 | 49 | }; |
| 48 | 50 | |
| ... | ... | @@ -261,6 +263,25 @@ inline fn getDynamicSymbol() [*]const elf.Dyn { |
| 261 | 263 | : [ret] "=r" (-> [*]const elf.Dyn), |
| 262 | 264 | : |
| 263 | 265 | : .{ .l7 = true }), |
| 266 | .xtensa, .xtensaeb => asm volatile ( | |
| 267 | \\ .weak _DYNAMIC | |
| 268 | \\ .hidden _DYNAMIC | |
| 269 | // Set things up such that after the `call0`, `a0` will point 1 byte before the | |
| 270 | // embedded constant. Note that `call0` is a 3-byte instruction, so we need both | |
| 271 | // `.balign` directives to be safe. | |
| 272 | \\ .balign 4 | |
| 273 | \\ .begin no-transform | |
| 274 | \\ call0 1f | |
| 275 | \\ .end no-transform | |
| 276 | \\ .balign 4 | |
| 277 | \\ .word _DYNAMIC - . | |
| 278 | \\1: | |
| 279 | \\ add a0, a0, 1 | |
| 280 | \\ l32i a8, a0, 0 | |
| 281 | \\ add %[ret], a0, a8 | |
| 282 | : [ret] "=a" (-> [*]const elf.Dyn), | |
| 283 | : | |
| 284 | : .{ .a0 = true, .a8 = true }), | |
| 264 | 285 | else => { |
| 265 | 286 | @compileError("PIE startup is not yet supported for this target!"); |
| 266 | 287 | }, |
lib/std/start.zig+10| ... | ... | @@ -183,6 +183,7 @@ fn _start() callconv(.naked) noreturn { |
| 183 | 183 | .sparc, .sparc64 => ".cfi_undefined %%i7", |
| 184 | 184 | .x86 => ".cfi_undefined %%eip", |
| 185 | 185 | .x86_64 => ".cfi_undefined %%rip", |
| 186 | .xtensa, .xtensaeb => "", // No CFI support. | |
| 186 | 187 | else => @compileError("unsupported arch"), |
| 187 | 188 | }); |
| 188 | 189 | |
| ... | ... | @@ -486,6 +487,15 @@ fn _start() callconv(.naked) noreturn { |
| 486 | 487 | \\ sub %%sp, 2047, %%sp |
| 487 | 488 | \\ ba,a %[posixCallMainAndExit] |
| 488 | 489 | , |
| 490 | .xtensa, .xtensaeb => | |
| 491 | // a0 = LR, a7 = FP, a1 = SP | |
| 492 | \\ movi a0, 0 | |
| 493 | \\ movi a7, 0 | |
| 494 | \\ mov a2, sp | |
| 495 | \\ movi a8, -16 | |
| 496 | \\ and sp, sp, a8 | |
| 497 | \\ callx0 %[posixCallMainAndExit] | |
| 498 | , | |
| 489 | 499 | else => @compileError("unsupported arch"), |
| 490 | 500 | } |
| 491 | 501 | : |