| ... | @@ -46,7 +46,7 @@ const Variant = enum { | ... | @@ -46,7 +46,7 @@ const Variant = enum { |
| 46 | /// -------------------------------------^------------- | 46 | /// -------------------------------------^------------- |
| 47 | /// `-- The TP register points here. | 47 | /// `-- The TP register points here. |
| 48 | /// | 48 | /// |
| 49 | /// The offset (which can be zero) is applied to the TP only; there is never physical gap | 49 | /// The offset (which can be zero) is applied to the TP only; there is never a physical gap |
| 50 | /// between the ABI TCB and the TLS blocks. This implies that we only need to align the TP. | 50 | /// between the ABI TCB and the TLS blocks. This implies that we only need to align the TP. |
| 51 | /// | 51 | /// |
| 52 | /// The first (and only) word in the ABI TCB points to the DTV. | 52 | /// The first (and only) word in the ABI TCB points to the DTV. |
| ... | @@ -71,6 +71,8 @@ const current_variant: Variant = switch (native_arch) { | ... | @@ -71,6 +71,8 @@ const current_variant: Variant = switch (native_arch) { |
| 71 | .arm, | 71 | .arm, |
| 72 | .armeb, | 72 | .armeb, |
| 73 | .csky, | 73 | .csky, |
| | 74 | .microblaze, |
| | 75 | .microblazeel, |
| 74 | .thumb, | 76 | .thumb, |
| 75 | .thumbeb, | 77 | .thumbeb, |
| 76 | => .I_original, | 78 | => .I_original, |
| ... | @@ -135,19 +137,19 @@ const current_dtv_offset = switch (native_arch) { | ... | @@ -135,19 +137,19 @@ const current_dtv_offset = switch (native_arch) { |
| 135 | /// Per-thread storage for the ELF TLS ABI. | 137 | /// Per-thread storage for the ELF TLS ABI. |
| 136 | const AbiTcb = switch (current_variant) { | 138 | const AbiTcb = switch (current_variant) { |
| 137 | .I_original, .I_modified => switch (native_arch) { | 139 | .I_original, .I_modified => switch (native_arch) { |
| 138 | // ARM EABI mandates enough space for two pointers: the first one points to the DTV as | | |
| 139 | // usual, while the second one is unspecified. | | |
| 140 | .aarch64, | 140 | .aarch64, |
| 141 | .aarch64_be, | 141 | .aarch64_be, |
| 142 | .alpha, | 142 | .alpha, |
| 143 | .arm, | 143 | .arm, |
| 144 | .armeb, | 144 | .armeb, |
| | 145 | .microblaze, |
| | 146 | .microblazeel, |
| 145 | .thumb, | 147 | .thumb, |
| 146 | .thumbeb, | 148 | .thumbeb, |
| 147 | => extern struct { | 149 | => extern struct { |
| 148 | /// This is offset by `current_dtv_offset`. | 150 | /// This is offset by `current_dtv_offset`. |
| 149 | dtv: usize, | 151 | dtv: usize, |
| 150 | reserved: ?*anyopaque, | 152 | _reserved: ?*anyopaque, |
| 151 | }, | 153 | }, |
| 152 | else => extern struct { | 154 | else => extern struct { |
| 153 | /// This is offset by `current_dtv_offset`. | 155 | /// This is offset by `current_dtv_offset`. |
| ... | @@ -297,6 +299,13 @@ pub fn setThreadPointer(addr: usize) void { | ... | @@ -297,6 +299,13 @@ pub fn setThreadPointer(addr: usize) void { |
| 297 | const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr }); | 299 | const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr }); |
| 298 | assert(rc == 0); | 300 | assert(rc == 0); |
| 299 | }, | 301 | }, |
| | 302 | .microblaze, .microblazeel => { |
| | 303 | asm volatile ( |
| | 304 | \\ ori r21, %[addr], 0 |
| | 305 | : |
| | 306 | : [addr] "r" (addr), |
| | 307 | ); |
| | 308 | }, |
| 300 | .or1k => { | 309 | .or1k => { |
| 301 | asm volatile ( | 310 | asm volatile ( |
| 302 | \\ l.ori r10, %[addr], 0 | 311 | \\ l.ori r10, %[addr], 0 |