| ... | ... | @@ -100,7 +100,6 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { |
| 100 | 100 | .kalimba, |
| 101 | 101 | .propeller, |
| 102 | 102 | => unreachable, // Gated by hasLlvmSupport(). |
| 103 | | |
| 104 | 103 | }; |
| 105 | 104 | |
| 106 | 105 | try llvm_triple.appendSlice(llvm_arch); |
| ... | ... | @@ -309,467 +308,154 @@ pub fn supportsTailCall(target: std.Target) bool { |
| 309 | 308 | } |
| 310 | 309 | } |
| 311 | 310 | |
| 312 | | const DataLayoutBuilder = struct { |
| 313 | | target: std.Target, |
| 311 | pub fn dataLayout(target: std.Target) []const u8 { |
| 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( |
| 316 | | self: DataLayoutBuilder, |
| 317 | | comptime _: []const u8, |
| 318 | | _: std.fmt.FormatOptions, |
| 319 | | writer: anytype, |
| 320 | | ) @TypeOf(writer).Error!void { |
| 321 | | try writer.writeByte(switch (self.target.cpu.arch.endian()) { |
| 322 | | .little => 'e', |
| 323 | | .big => 'E', |
| 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; |
| 412 | break :blk if (target.ofmt == .coff) |
| 413 | if (msvc) |
| 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" |
| 415 | else |
| 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" |
| 417 | else if (msvc) |
| 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" |
| 419 | else |
| 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"; |
| 757 | 421 | }, |
| 758 | | else => {}, |
| 759 | 422 | }, |
| 760 | | } |
| 761 | | if (kind != .vector and self.target.cpu.arch == .avr) { |
| 762 | | force_abi = true; |
| 763 | | abi = 8; |
| 764 | | pref = 8; |
| 765 | | } |
| 766 | | if (!force_abi and abi == default_abi and pref == default_pref) return; |
| 767 | | try writer.print("-{c}", .{@tagName(kind)[0]}); |
| 768 | | if (size != 0) try writer.print("{d}", .{size}); |
| 769 | | try writer.print(":{d}", .{abi}); |
| 770 | | if (pref != abi or force_pref) try writer.print(":{d}", .{pref}); |
| 771 | | } |
| 772 | | }; |
| 423 | else => if (target.ofmt == .macho) |
| 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" |
| 425 | else |
| 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", |
| 427 | }, |
| 428 | .x86_64 => if (target.os.tag.isDarwin() or target.ofmt == .macho) |
| 429 | "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" |
| 430 | else switch (target.abi) { |
| 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", |
| 432 | else => if (target.os.tag == .windows and target.ofmt == .coff) |
| 433 | "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" |
| 434 | else |
| 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 | 460 | pub const Object = struct { |
| 775 | 461 | gpa: Allocator, |
| ... | ... | @@ -856,7 +542,7 @@ pub const Object = struct { |
| 856 | 542 | }); |
| 857 | 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 | 547 | const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref = |
| 862 | 548 | if (!builder.strip) debug_info: { |