| ... | @@ -100,7 +100,6 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { | ... | @@ -100,7 +100,6 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { |
| 100 | .kalimba, | 100 | .kalimba, |
| 101 | .propeller, | 101 | .propeller, |
| 102 | => unreachable, // Gated by hasLlvmSupport(). | 102 | => unreachable, // Gated by hasLlvmSupport(). |
| 103 | | | |
| 104 | }; | 103 | }; |
| 105 | | 104 | |
| 106 | try llvm_triple.appendSlice(llvm_arch); | 105 | try llvm_triple.appendSlice(llvm_arch); |
| ... | @@ -309,467 +308,154 @@ pub fn supportsTailCall(target: std.Target) bool { | ... | @@ -309,467 +308,154 @@ pub fn supportsTailCall(target: std.Target) bool { |
| 309 | } | 308 | } |
| 310 | } | 309 | } |
| 311 | | 310 | |
| 312 | const DataLayoutBuilder = struct { | 311 | pub fn dataLayout(target: std.Target) []const u8 { |
| 313 | target: std.Target, | 312 | // These data layouts should match Clang. |
| | 313 | return switch (target.cpu.arch) { |
| | 314 | .arc => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32", |
| | 315 | .xcore => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32", |
| | 316 | .hexagon => "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048", |
| | 317 | .lanai => "E-m:e-p:32:32-i64:64-a:0:32-n32-S64", |
| | 318 | .aarch64 => if (target.ofmt == .macho) |
| | 319 | if (target.os.tag == .windows) |
| | 320 | "e-m:o-i64:64-i128:128-n32:64-S128-Fn32" |
| | 321 | else if (target.abi == .ilp32) |
| | 322 | "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32" |
| | 323 | else |
| | 324 | "e-m:o-i64:64-i128:128-n32:64-S128-Fn32" |
| | 325 | else if (target.os.tag == .windows) |
| | 326 | "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" |
| | 327 | else |
| | 328 | "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", |
| | 329 | .aarch64_be => "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", |
| | 330 | .arm => if (target.ofmt == .macho) |
| | 331 | "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" |
| | 332 | else |
| | 333 | "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", |
| | 334 | .armeb, .thumbeb => if (target.ofmt == .macho) |
| | 335 | "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" |
| | 336 | else |
| | 337 | "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", |
| | 338 | .thumb => if (target.ofmt == .macho) |
| | 339 | "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" |
| | 340 | else if (target.os.tag == .windows) |
| | 341 | "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" |
| | 342 | else |
| | 343 | "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", |
| | 344 | .avr => "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8", |
| | 345 | .bpfeb => "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128", |
| | 346 | .bpfel => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", |
| | 347 | .msp430 => "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16", |
| | 348 | .mips => "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64", |
| | 349 | .mipsel => "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64", |
| | 350 | .mips64 => switch (target.abi) { |
| | 351 | .gnuabin32, .muslabin32 => "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128", |
| | 352 | else => "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128", |
| | 353 | }, |
| | 354 | .mips64el => switch (target.abi) { |
| | 355 | .gnuabin32, .muslabin32 => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128", |
| | 356 | else => "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128", |
| | 357 | }, |
| | 358 | .m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16", |
| | 359 | .powerpc => if (target.os.tag == .aix) |
| | 360 | "E-m:a-p:32:32-Fi32-i64:64-n32" |
| | 361 | else |
| | 362 | "E-m:e-p:32:32-Fn32-i64:64-n32", |
| | 363 | .powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32", |
| | 364 | .powerpc64 => switch (target.os.tag) { |
| | 365 | .aix => "E-m:a-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512", |
| | 366 | .linux => if (target.abi.isMusl()) |
| | 367 | "E-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512" |
| | 368 | else |
| | 369 | "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512", |
| | 370 | .ps3 => "E-m:e-p:32:32-Fi64-i64:64-n32:64", |
| | 371 | else => if (target.os.tag == .openbsd or |
| | 372 | (target.os.tag == .freebsd and target.os.version_range.semver.isAtLeast(.{ .major = 13, .minor = 0, .patch = 0 }) orelse false)) |
| | 373 | "E-m:e-Fn32-i64:64-n32:64" |
| | 374 | else |
| | 375 | "E-m:e-Fi64-i64:64-n32:64", |
| | 376 | }, |
| | 377 | .powerpc64le => if (target.os.tag == .linux) |
| | 378 | "e-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512" |
| | 379 | else |
| | 380 | "e-m:e-Fn32-i64:64-n32:64", |
| | 381 | .nvptx => "e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64", |
| | 382 | .nvptx64 => "e-i64:64-i128:128-v16:16-v32:32-n16:32:64", |
| | 383 | .amdgcn => "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9", |
| | 384 | .riscv32 => if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) |
| | 385 | "e-m:e-p:32:32-i64:64-n32-S32" |
| | 386 | else |
| | 387 | "e-m:e-p:32:32-i64:64-n32-S128", |
| | 388 | .riscv64 => if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) |
| | 389 | "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64" |
| | 390 | else |
| | 391 | "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", |
| | 392 | .sparc => "E-m:e-p:32:32-i64:64-f128:64-n32-S64", |
| | 393 | .sparc64 => "E-m:e-i64:64-n32:64-S128", |
| | 394 | .s390x => if (target.os.tag == .zos) |
| | 395 | "E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64" |
| | 396 | else |
| | 397 | "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64", |
| | 398 | .x86 => switch (target.os.tag) { |
| | 399 | .elfiamcu => "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32", |
| | 400 | .windows => switch (target.abi) { |
| | 401 | .cygnus => "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32", |
| | 402 | .gnu => if (target.ofmt == .coff) |
| | 403 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" |
| | 404 | else |
| | 405 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32", |
| | 406 | else => blk: { |
| | 407 | const msvc = switch (target.abi) { |
| | 408 | .none, .msvc => true, |
| | 409 | else => false, |
| | 410 | }; |
| 314 | | 411 | |
| 315 | pub fn format( | 412 | break :blk if (target.ofmt == .coff) |
| 316 | self: DataLayoutBuilder, | 413 | if (msvc) |
| 317 | comptime _: []const u8, | 414 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" |
| 318 | _: std.fmt.FormatOptions, | 415 | else |
| 319 | writer: anytype, | 416 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" |
| 320 | ) @TypeOf(writer).Error!void { | 417 | else if (msvc) |
| 321 | try writer.writeByte(switch (self.target.cpu.arch.endian()) { | 418 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" |
| 322 | .little => 'e', | 419 | else |
| 323 | .big => 'E', | 420 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"; |
| 324 | }); | | |
| 325 | switch (self.target.cpu.arch) { | | |
| 326 | .amdgcn, | | |
| 327 | .nvptx, | | |
| 328 | .nvptx64, | | |
| 329 | => {}, | | |
| 330 | .avr => try writer.writeAll("-P1"), | | |
| 331 | else => try writer.print("-m:{c}", .{@as(u8, switch (self.target.cpu.arch) { | | |
| 332 | .mips, .mipsel => 'm', // Mips mangling: Private symbols get a $ prefix. | | |
| 333 | else => switch (self.target.ofmt) { | | |
| 334 | .elf => 'e', // ELF mangling: Private symbols get a `.L` prefix. | | |
| 335 | //.goff => 'l', // GOFF mangling: Private symbols get a `@` prefix. | | |
| 336 | .macho => 'o', // Mach-O mangling: Private symbols get `L` prefix. | | |
| 337 | // Other symbols get a `_` prefix. | | |
| 338 | .coff => switch (self.target.os.tag) { | | |
| 339 | .uefi, .windows => switch (self.target.cpu.arch) { | | |
| 340 | .x86 => 'x', // Windows x86 COFF mangling: Private symbols get the usual | | |
| 341 | // prefix. Regular C symbols get a `_` prefix. Functions with `__stdcall`, | | |
| 342 | //`__fastcall`, and `__vectorcall` have custom mangling that appends `@N` | | |
| 343 | // where N is the number of bytes used to pass parameters. C++ symbols | | |
| 344 | // starting with `?` are not mangled in any way. | | |
| 345 | else => 'w', // Windows COFF mangling: Similar to x, except that normal C | | |
| 346 | // symbols do not receive a `_` prefix. | | |
| 347 | }, | | |
| 348 | else => 'e', | | |
| 349 | }, | | |
| 350 | //.xcoff => 'a', // XCOFF mangling: Private symbols get a `L..` prefix. | | |
| 351 | else => 'e', | | |
| 352 | }, | | |
| 353 | })}), | | |
| 354 | } | | |
| 355 | const stack_abi = self.target.stackAlignment() * 8; | | |
| 356 | if (self.target.cpu.arch == .csky) try writer.print("-S{d}", .{stack_abi}); | | |
| 357 | var any_non_integral = false; | | |
| 358 | const ptr_bit_width = self.target.ptrBitWidth(); | | |
| 359 | var default_info = struct { size: u16, abi: u16, pref: u16, idx: u16 }{ | | |
| 360 | .size = 64, | | |
| 361 | .abi = 64, | | |
| 362 | .pref = 64, | | |
| 363 | .idx = 64, | | |
| 364 | }; | | |
| 365 | const addr_space_info = llvmAddrSpaceInfo(self.target); | | |
| 366 | for (addr_space_info, 0..) |info, i| { | | |
| 367 | assert((info.llvm == .default) == (i == 0)); | | |
| 368 | if (info.non_integral) { | | |
| 369 | assert(info.llvm != .default); | | |
| 370 | any_non_integral = true; | | |
| 371 | } | | |
| 372 | const size = info.size orelse ptr_bit_width; | | |
| 373 | const abi = info.abi orelse ptr_bit_width; | | |
| 374 | const pref = info.pref orelse abi; | | |
| 375 | const idx = info.idx orelse size; | | |
| 376 | const matches_default = | | |
| 377 | size == default_info.size and | | |
| 378 | abi == default_info.abi and | | |
| 379 | pref == default_info.pref and | | |
| 380 | idx == default_info.idx; | | |
| 381 | if (info.llvm == .default) default_info = .{ | | |
| 382 | .size = size, | | |
| 383 | .abi = abi, | | |
| 384 | .pref = pref, | | |
| 385 | .idx = idx, | | |
| 386 | }; | | |
| 387 | if (!info.force_in_data_layout and matches_default and | | |
| 388 | self.target.cpu.arch != .riscv64 and | | |
| 389 | self.target.cpu.arch != .loongarch64 and | | |
| 390 | !(self.target.cpu.arch == .aarch64 and | | |
| 391 | (self.target.os.tag == .uefi or self.target.os.tag == .windows)) and | | |
| 392 | self.target.cpu.arch != .bpfeb and self.target.cpu.arch != .bpfel) continue; | | |
| 393 | try writer.writeAll("-p"); | | |
| 394 | if (info.llvm != .default) try writer.print("{d}", .{@intFromEnum(info.llvm)}); | | |
| 395 | try writer.print(":{d}:{d}", .{ size, abi }); | | |
| 396 | if (pref != abi or idx != size or self.target.cpu.arch == .hexagon) { | | |
| 397 | try writer.print(":{d}", .{pref}); | | |
| 398 | if (idx != size) try writer.print(":{d}", .{idx}); | | |
| 399 | } | | |
| 400 | } | | |
| 401 | if (self.target.cpu.arch.isArm()) | | |
| 402 | try writer.writeAll("-Fi8") // for thumb interwork | | |
| 403 | else if (self.target.cpu.arch == .powerpc64 and | | |
| 404 | self.target.os.tag != .freebsd and | | |
| 405 | self.target.os.tag != .openbsd and | | |
| 406 | !self.target.abi.isMusl()) | | |
| 407 | try writer.writeAll("-Fi64") | | |
| 408 | else if (self.target.cpu.arch.isPowerPC() and self.target.os.tag == .aix) | | |
| 409 | try writer.writeAll(if (self.target.cpu.arch.isPowerPC64()) "-Fi64" else "-Fi32") | | |
| 410 | else if (self.target.cpu.arch.isPowerPC()) | | |
| 411 | try writer.writeAll("-Fn32"); | | |
| 412 | if (self.target.cpu.arch != .hexagon) { | | |
| 413 | if (self.target.cpu.arch == .arc or self.target.cpu.arch == .s390x) | | |
| 414 | try self.typeAlignment(.integer, 1, 8, 8, false, writer); | | |
| 415 | try self.typeAlignment(.integer, 8, 8, 8, false, writer); | | |
| 416 | try self.typeAlignment(.integer, 16, 16, 16, false, writer); | | |
| 417 | try self.typeAlignment(.integer, 32, 32, 32, false, writer); | | |
| 418 | if (self.target.cpu.arch == .arc) | | |
| 419 | try self.typeAlignment(.float, 32, 32, 32, false, writer); | | |
| 420 | try self.typeAlignment(.integer, 64, 32, 64, false, writer); | | |
| 421 | try self.typeAlignment(.integer, 128, 32, 64, false, writer); | | |
| 422 | if (backendSupportsF16(self.target)) | | |
| 423 | try self.typeAlignment(.float, 16, 16, 16, false, writer); | | |
| 424 | if (self.target.cpu.arch != .arc) | | |
| 425 | try self.typeAlignment(.float, 32, 32, 32, false, writer); | | |
| 426 | try self.typeAlignment(.float, 64, 64, 64, false, writer); | | |
| 427 | if (self.target.cpu.arch.isX86()) try self.typeAlignment(.float, 80, 0, 0, false, writer); | | |
| 428 | try self.typeAlignment(.float, 128, 128, 128, false, writer); | | |
| 429 | } | | |
| 430 | switch (self.target.cpu.arch) { | | |
| 431 | .amdgcn => { | | |
| 432 | try self.typeAlignment(.vector, 16, 16, 16, false, writer); | | |
| 433 | try self.typeAlignment(.vector, 24, 32, 32, false, writer); | | |
| 434 | try self.typeAlignment(.vector, 32, 32, 32, false, writer); | | |
| 435 | try self.typeAlignment(.vector, 48, 64, 64, false, writer); | | |
| 436 | try self.typeAlignment(.vector, 96, 128, 128, false, writer); | | |
| 437 | try self.typeAlignment(.vector, 192, 256, 256, false, writer); | | |
| 438 | try self.typeAlignment(.vector, 256, 256, 256, false, writer); | | |
| 439 | try self.typeAlignment(.vector, 512, 512, 512, false, writer); | | |
| 440 | try self.typeAlignment(.vector, 1024, 1024, 1024, false, writer); | | |
| 441 | try self.typeAlignment(.vector, 2048, 2048, 2048, false, writer); | | |
| 442 | }, | | |
| 443 | .ve => {}, | | |
| 444 | else => { | | |
| 445 | try self.typeAlignment(.vector, 16, 32, 32, false, writer); | | |
| 446 | try self.typeAlignment(.vector, 32, 32, 32, false, writer); | | |
| 447 | try self.typeAlignment(.vector, 64, 64, 64, false, writer); | | |
| 448 | try self.typeAlignment(.vector, 128, 128, 128, true, writer); | | |
| 449 | }, | | |
| 450 | } | | |
| 451 | const swap_agg_nat = switch (self.target.cpu.arch) { | | |
| 452 | .x86, .x86_64 => switch (self.target.os.tag) { | | |
| 453 | .uefi, .windows => true, | | |
| 454 | else => false, | | |
| 455 | }, | | |
| 456 | .avr, .m68k => true, | | |
| 457 | else => false, | | |
| 458 | }; | | |
| 459 | if (!swap_agg_nat) try self.typeAlignment(.aggregate, 0, 0, 64, false, writer); | | |
| 460 | if (self.target.cpu.arch == .csky) try writer.writeAll("-Fi32"); | | |
| 461 | for (@as([]const u24, switch (self.target.cpu.arch) { | | |
| 462 | .avr => &.{8}, | | |
| 463 | .msp430 => &.{ 8, 16 }, | | |
| 464 | .arc, | | |
| 465 | .arm, | | |
| 466 | .armeb, | | |
| 467 | .csky, | | |
| 468 | .loongarch32, | | |
| 469 | .mips, | | |
| 470 | .mipsel, | | |
| 471 | .powerpc, | | |
| 472 | .powerpcle, | | |
| 473 | .riscv32, | | |
| 474 | .sparc, | | |
| 475 | .thumb, | | |
| 476 | .thumbeb, | | |
| 477 | .xtensa, | | |
| 478 | => &.{32}, | | |
| 479 | .aarch64, | | |
| 480 | .aarch64_be, | | |
| 481 | .amdgcn, | | |
| 482 | .bpfeb, | | |
| 483 | .bpfel, | | |
| 484 | .loongarch64, | | |
| 485 | .mips64, | | |
| 486 | .mips64el, | | |
| 487 | .powerpc64, | | |
| 488 | .powerpc64le, | | |
| 489 | .riscv64, | | |
| 490 | .s390x, | | |
| 491 | .sparc64, | | |
| 492 | .ve, | | |
| 493 | .wasm32, | | |
| 494 | .wasm64, | | |
| 495 | => &.{ 32, 64 }, | | |
| 496 | .hexagon => &.{ 16, 32 }, | | |
| 497 | .m68k, | | |
| 498 | .x86, | | |
| 499 | => &.{ 8, 16, 32 }, | | |
| 500 | .nvptx, | | |
| 501 | .nvptx64, | | |
| 502 | => &.{ 16, 32, 64 }, | | |
| 503 | .x86_64 => &.{ 8, 16, 32, 64 }, | | |
| 504 | else => &.{}, | | |
| 505 | }), 0..) |natural, index| switch (index) { | | |
| 506 | 0 => try writer.print("-n{d}", .{natural}), | | |
| 507 | else => try writer.print(":{d}", .{natural}), | | |
| 508 | }; | | |
| 509 | if (swap_agg_nat) try self.typeAlignment(.aggregate, 0, 0, 64, false, writer); | | |
| 510 | if (self.target.cpu.arch == .hexagon) { | | |
| 511 | try self.typeAlignment(.integer, 64, 64, 64, true, writer); | | |
| 512 | try self.typeAlignment(.integer, 32, 32, 32, true, writer); | | |
| 513 | try self.typeAlignment(.integer, 16, 16, 16, true, writer); | | |
| 514 | try self.typeAlignment(.integer, 1, 8, 8, true, writer); | | |
| 515 | try self.typeAlignment(.float, 32, 32, 32, true, writer); | | |
| 516 | try self.typeAlignment(.float, 64, 64, 64, true, writer); | | |
| 517 | } | | |
| 518 | if (stack_abi != ptr_bit_width or self.target.cpu.arch == .msp430 or | | |
| 519 | self.target.os.tag == .uefi or self.target.os.tag == .windows or | | |
| 520 | self.target.cpu.arch == .riscv32) | | |
| 521 | try writer.print("-S{d}", .{stack_abi}); | | |
| 522 | if (self.target.cpu.arch.isAARCH64()) | | |
| 523 | try writer.writeAll("-Fn32"); | | |
| 524 | switch (self.target.cpu.arch) { | | |
| 525 | .hexagon, .ve => { | | |
| 526 | try self.typeAlignment(.vector, 32, 128, 128, true, writer); | | |
| 527 | try self.typeAlignment(.vector, 64, 128, 128, true, writer); | | |
| 528 | try self.typeAlignment(.vector, 128, 128, 128, true, writer); | | |
| 529 | }, | | |
| 530 | else => {}, | | |
| 531 | } | | |
| 532 | if (self.target.cpu.arch != .amdgcn) { | | |
| 533 | try self.typeAlignment(.vector, 256, 128, 128, true, writer); | | |
| 534 | try self.typeAlignment(.vector, 512, 128, 128, true, writer); | | |
| 535 | try self.typeAlignment(.vector, 1024, 128, 128, true, writer); | | |
| 536 | try self.typeAlignment(.vector, 2048, 128, 128, true, writer); | | |
| 537 | try self.typeAlignment(.vector, 4096, 128, 128, true, writer); | | |
| 538 | try self.typeAlignment(.vector, 8192, 128, 128, true, writer); | | |
| 539 | try self.typeAlignment(.vector, 16384, 128, 128, true, writer); | | |
| 540 | } | | |
| 541 | const alloca_addr_space = llvmAllocaAddressSpace(self.target); | | |
| 542 | if (alloca_addr_space != .default) try writer.print("-A{d}", .{@intFromEnum(alloca_addr_space)}); | | |
| 543 | const global_addr_space = llvmDefaultGlobalAddressSpace(self.target); | | |
| 544 | if (global_addr_space != .default) try writer.print("-G{d}", .{@intFromEnum(global_addr_space)}); | | |
| 545 | if (any_non_integral) { | | |
| 546 | try writer.writeAll("-ni"); | | |
| 547 | for (addr_space_info) |info| if (info.non_integral) | | |
| 548 | try writer.print(":{d}", .{@intFromEnum(info.llvm)}); | | |
| 549 | } | | |
| 550 | } | | |
| 551 | | | |
| 552 | fn typeAlignment( | | |
| 553 | self: DataLayoutBuilder, | | |
| 554 | kind: enum { integer, vector, float, aggregate }, | | |
| 555 | size: u24, | | |
| 556 | default_abi: u24, | | |
| 557 | default_pref: u24, | | |
| 558 | default_force_pref: bool, | | |
| 559 | writer: anytype, | | |
| 560 | ) @TypeOf(writer).Error!void { | | |
| 561 | var abi = default_abi; | | |
| 562 | var pref = default_pref; | | |
| 563 | var force_abi = false; | | |
| 564 | var force_pref = default_force_pref; | | |
| 565 | if (kind == .float and size == 80) { | | |
| 566 | abi = 128; | | |
| 567 | pref = 128; | | |
| 568 | } | | |
| 569 | for (@as([]const std.Target.CType, switch (kind) { | | |
| 570 | .integer => &.{ .char, .short, .int, .long, .longlong }, | | |
| 571 | .float => &.{ .float, .double, .longdouble }, | | |
| 572 | .vector, .aggregate => &.{}, | | |
| 573 | })) |cty| { | | |
| 574 | if (self.target.cTypeBitSize(cty) != size) continue; | | |
| 575 | abi = self.target.cTypeAlignment(cty) * 8; | | |
| 576 | pref = self.target.cTypePreferredAlignment(cty) * 8; | | |
| 577 | break; | | |
| 578 | } | | |
| 579 | switch (kind) { | | |
| 580 | .integer => { | | |
| 581 | if (self.target.ptrBitWidth() <= 16 and size >= 128) return; | | |
| 582 | abi = @min(abi, Type.maxIntAlignment(self.target) * 8); | | |
| 583 | switch (self.target.cpu.arch) { | | |
| 584 | .aarch64, | | |
| 585 | .aarch64_be, | | |
| 586 | => if (size == 128) { | | |
| 587 | abi = size; | | |
| 588 | pref = size; | | |
| 589 | } else switch (self.target.os.tag) { | | |
| 590 | .macos, .ios, .watchos, .tvos, .visionos => {}, | | |
| 591 | .uefi, .windows => { | | |
| 592 | pref = size; | | |
| 593 | force_abi = size >= 32; | | |
| 594 | }, | | |
| 595 | else => pref = @max(pref, 32), | | |
| 596 | }, | | |
| 597 | .arc => if (size <= 64) { | | |
| 598 | abi = @min((std.math.divCeil(u24, size, 8) catch unreachable) * 8, 32); | | |
| 599 | pref = 32; | | |
| 600 | force_abi = true; | | |
| 601 | force_pref = size <= 32; | | |
| 602 | }, | | |
| 603 | .bpfeb, | | |
| 604 | .bpfel, | | |
| 605 | .nvptx, | | |
| 606 | .nvptx64, | | |
| 607 | .riscv64, | | |
| 608 | => if (size == 128) { | | |
| 609 | abi = size; | | |
| 610 | pref = size; | | |
| 611 | }, | | |
| 612 | .csky => if (size == 32 or size == 64) { | | |
| 613 | abi = 32; | | |
| 614 | pref = 32; | | |
| 615 | force_abi = true; | | |
| 616 | force_pref = true; | | |
| 617 | }, | | |
| 618 | .hexagon => force_abi = true, | | |
| 619 | .m68k => if (size <= 32) { | | |
| 620 | abi = @min(size, 16); | | |
| 621 | pref = size; | | |
| 622 | force_abi = true; | | |
| 623 | force_pref = true; | | |
| 624 | } else if (size == 64) { | | |
| 625 | abi = 32; | | |
| 626 | pref = size; | | |
| 627 | }, | | |
| 628 | .mips, | | |
| 629 | .mipsel, | | |
| 630 | .mips64, | | |
| 631 | .mips64el, | | |
| 632 | => pref = @max(pref, 32), | | |
| 633 | .s390x => pref = @max(pref, 16), | | |
| 634 | .ve => if (size == 64) { | | |
| 635 | abi = size; | | |
| 636 | pref = size; | | |
| 637 | }, | | |
| 638 | .xtensa => if (size <= 64) { | | |
| 639 | pref = @max(size, 32); | | |
| 640 | abi = size; | | |
| 641 | force_abi = size == 64; | | |
| 642 | }, | | |
| 643 | .x86 => switch (size) { | | |
| 644 | 128 => { | | |
| 645 | abi = size; | | |
| 646 | pref = size; | | |
| 647 | }, | | |
| 648 | else => {}, | | |
| 649 | }, | | |
| 650 | .x86_64 => switch (size) { | | |
| 651 | 64, 128 => { | | |
| 652 | abi = size; | | |
| 653 | pref = size; | | |
| 654 | }, | | |
| 655 | else => {}, | | |
| 656 | }, | | |
| 657 | .loongarch64 => switch (size) { | | |
| 658 | 128 => { | | |
| 659 | abi = size; | | |
| 660 | pref = size; | | |
| 661 | force_abi = true; | | |
| 662 | }, | | |
| 663 | else => {}, | | |
| 664 | }, | | |
| 665 | else => {}, | | |
| 666 | } | | |
| 667 | }, | | |
| 668 | .vector => if (self.target.cpu.arch.isArm()) { | | |
| 669 | switch (size) { | | |
| 670 | 128 => abi = 64, | | |
| 671 | else => {}, | | |
| 672 | } | | |
| 673 | } else if ((self.target.cpu.arch.isPowerPC64() and self.target.os.tag == .linux and | | |
| 674 | (size == 256 or size == 512)) or | | |
| 675 | (self.target.cpu.arch.isNvptx() and (size == 16 or size == 32))) | | |
| 676 | { | | |
| 677 | force_abi = true; | | |
| 678 | abi = size; | | |
| 679 | pref = size; | | |
| 680 | } else if (self.target.cpu.arch == .amdgcn and size <= 2048) { | | |
| 681 | force_abi = true; | | |
| 682 | } else if (self.target.cpu.arch == .csky and (size == 64 or size == 128)) { | | |
| 683 | abi = 32; | | |
| 684 | pref = 32; | | |
| 685 | force_pref = true; | | |
| 686 | } else if (self.target.cpu.arch == .hexagon and | | |
| 687 | ((size >= 32 and size <= 64) or (size >= 512 and size <= 2048))) | | |
| 688 | { | | |
| 689 | abi = size; | | |
| 690 | pref = size; | | |
| 691 | force_pref = true; | | |
| 692 | } else if (self.target.cpu.arch == .s390x and size == 128) { | | |
| 693 | abi = 64; | | |
| 694 | pref = 64; | | |
| 695 | force_pref = false; | | |
| 696 | } else if (self.target.cpu.arch == .ve and (size >= 64 and size <= 16384)) { | | |
| 697 | abi = 64; | | |
| 698 | pref = 64; | | |
| 699 | force_abi = true; | | |
| 700 | force_pref = true; | | |
| 701 | }, | | |
| 702 | .float => switch (self.target.cpu.arch) { | | |
| 703 | .amdgcn => if (size == 128) { | | |
| 704 | abi = size; | | |
| 705 | pref = size; | | |
| 706 | }, | | |
| 707 | .arc => if (size == 32 or size == 64) { | | |
| 708 | abi = 32; | | |
| 709 | pref = 32; | | |
| 710 | force_abi = true; | | |
| 711 | force_pref = size == 32; | | |
| 712 | }, | | |
| 713 | .avr, .msp430, .sparc64 => if (size != 32 and size != 64) return, | | |
| 714 | .csky => if (size == 32 or size == 64) { | | |
| 715 | abi = 32; | | |
| 716 | pref = 32; | | |
| 717 | force_abi = true; | | |
| 718 | force_pref = true; | | |
| 719 | }, | | |
| 720 | .hexagon => if (size == 32 or size == 64) { | | |
| 721 | force_abi = true; | | |
| 722 | }, | | |
| 723 | .ve, .xtensa => if (size == 64) { | | |
| 724 | abi = size; | | |
| 725 | pref = size; | | |
| 726 | }, | | |
| 727 | .wasm32, .wasm64 => if (self.target.os.tag == .emscripten and size == 128) { | | |
| 728 | abi = 64; | | |
| 729 | pref = 64; | | |
| 730 | }, | | |
| 731 | else => {}, | | |
| 732 | }, | | |
| 733 | .aggregate => if (self.target.os.tag == .uefi or self.target.os.tag == .windows or | | |
| 734 | self.target.cpu.arch.isArm()) | | |
| 735 | { | | |
| 736 | pref = @min(pref, self.target.ptrBitWidth()); | | |
| 737 | } else switch (self.target.cpu.arch) { | | |
| 738 | .arc, .csky => { | | |
| 739 | abi = 0; | | |
| 740 | pref = 32; | | |
| 741 | }, | | |
| 742 | .hexagon => { | | |
| 743 | abi = 0; | | |
| 744 | pref = 0; | | |
| 745 | }, | | |
| 746 | .m68k => { | | |
| 747 | abi = 0; | | |
| 748 | pref = 16; | | |
| 749 | }, | | |
| 750 | .msp430 => { | | |
| 751 | abi = 8; | | |
| 752 | pref = 8; | | |
| 753 | }, | | |
| 754 | .s390x => { | | |
| 755 | abi = 8; | | |
| 756 | pref = 16; | | |
| 757 | }, | 421 | }, |
| 758 | else => {}, | | |
| 759 | }, | 422 | }, |
| 760 | } | 423 | else => if (target.ofmt == .macho) |
| 761 | if (kind != .vector and self.target.cpu.arch == .avr) { | 424 | "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128" |
| 762 | force_abi = true; | 425 | else |
| 763 | abi = 8; | 426 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128", |
| 764 | pref = 8; | 427 | }, |
| 765 | } | 428 | .x86_64 => if (target.os.tag.isDarwin() or target.ofmt == .macho) |
| 766 | if (!force_abi and abi == default_abi and pref == default_pref) return; | 429 | "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" |
| 767 | try writer.print("-{c}", .{@tagName(kind)[0]}); | 430 | else switch (target.abi) { |
| 768 | if (size != 0) try writer.print("{d}", .{size}); | 431 | .gnux32, .muslx32 => "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", |
| 769 | try writer.print(":{d}", .{abi}); | 432 | else => if (target.os.tag == .windows and target.ofmt == .coff) |
| 770 | if (pref != abi or force_pref) try writer.print(":{d}", .{pref}); | 433 | "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" |
| 771 | } | 434 | else |
| 772 | }; | 435 | "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", |
| | 436 | }, |
| | 437 | .spirv => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", |
| | 438 | .spirv32 => "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", |
| | 439 | .spirv64 => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", |
| | 440 | .wasm32 => if (target.os.tag == .emscripten) |
| | 441 | "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-S128-ni:1:10:20" |
| | 442 | else |
| | 443 | "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20", |
| | 444 | .wasm64 => if (target.os.tag == .emscripten) |
| | 445 | "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-S128-ni:1:10:20" |
| | 446 | else |
| | 447 | "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20", |
| | 448 | .ve => "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64", |
| | 449 | .csky => "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32", |
| | 450 | .loongarch32 => "e-m:e-p:32:32-i64:64-n32-S128", |
| | 451 | .loongarch64 => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", |
| | 452 | .xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32", |
| | 453 | |
| | 454 | .kalimba, |
| | 455 | .propeller, |
| | 456 | => unreachable, // Gated by hasLlvmSupport(). |
| | 457 | }; |
| | 458 | } |
| 773 | | 459 | |
| 774 | pub const Object = struct { | 460 | pub const Object = struct { |
| 775 | gpa: Allocator, | 461 | gpa: Allocator, |
| ... | @@ -856,7 +542,7 @@ pub const Object = struct { | ... | @@ -856,7 +542,7 @@ pub const Object = struct { |
| 856 | }); | 542 | }); |
| 857 | errdefer builder.deinit(); | 543 | errdefer builder.deinit(); |
| 858 | | 544 | |
| 859 | builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }}); | 545 | builder.data_layout = try builder.string(dataLayout(target)); |
| 860 | | 546 | |
| 861 | const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref = | 547 | const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref = |
| 862 | if (!builder.strip) debug_info: { | 548 | if (!builder.strip) debug_info: { |