| ... | @@ -341,34 +341,40 @@ const DataLayoutBuilder = struct { | ... | @@ -341,34 +341,40 @@ const DataLayoutBuilder = struct { |
| 341 | writer: anytype, | 341 | writer: anytype, |
| 342 | ) @TypeOf(writer).Error!void { | 342 | ) @TypeOf(writer).Error!void { |
| 343 | const is_aarch64_windows = self.target.cpu.arch == .aarch64 and self.target.os.tag == .windows; | 343 | const is_aarch64_windows = self.target.cpu.arch == .aarch64 and self.target.os.tag == .windows; |
| 344 | try writer.print("{c}-m:{c}", .{ | 344 | try writer.writeByte(switch (self.target.cpu.arch.endian()) { |
| 345 | @as(u8, switch (self.target.cpu.arch.endian()) { | 345 | .Little => 'e', |
| 346 | .Little => 'e', | 346 | .Big => 'E', |
| 347 | .Big => 'E', | 347 | }); |
| 348 | }), | 348 | switch (self.target.cpu.arch) { |
| 349 | @as(u8, if (self.target.cpu.arch.isMIPS()) | 349 | .amdgcn, |
| 350 | 'm' // Mips mangling: Private symbols get a $ prefix. | 350 | .nvptx, |
| 351 | else switch (self.target.ofmt) { | 351 | .nvptx64, |
| 352 | .elf => 'e', // ELF mangling: Private symbols get a `.L` prefix. | 352 | => {}, |
| 353 | //.goff => 'l', // GOFF mangling: Private symbols get a `@` prefix. | 353 | .avr => try writer.writeAll("-P1"), |
| 354 | .macho => 'o', // Mach-O mangling: Private symbols get `L` prefix. | 354 | else => try writer.print("-m:{c}", .{@as(u8, switch (self.target.cpu.arch) { |
| 355 | // Other symbols get a `_` prefix. | 355 | .mips, .mipsel => 'm', // Mips mangling: Private symbols get a $ prefix. |
| 356 | .coff => switch (self.target.os.tag) { | 356 | else => switch (self.target.ofmt) { |
| 357 | .windows => switch (self.target.cpu.arch) { | 357 | .elf => 'e', // ELF mangling: Private symbols get a `.L` prefix. |
| 358 | .x86 => 'x', // Windows x86 COFF mangling: Private symbols get the usual prefix. | 358 | //.goff => 'l', // GOFF mangling: Private symbols get a `@` prefix. |
| 359 | // Regular C symbols get a `_` prefix. Functions with `__stdcall`, `__fastcall`, | 359 | .macho => 'o', // Mach-O mangling: Private symbols get `L` prefix. |
| 360 | // and `__vectorcall` have custom mangling that appends `@N` where N is the | 360 | // Other symbols get a `_` prefix. |
| 361 | // number of bytes used to pass parameters. C++ symbols starting with `?` are | 361 | .coff => switch (self.target.os.tag) { |
| 362 | // not mangled in any way. | 362 | .windows => switch (self.target.cpu.arch) { |
| 363 | else => 'w', // Windows COFF mangling: Similar to x, except that normal C | 363 | .x86 => 'x', // Windows x86 COFF mangling: Private symbols get the usual |
| 364 | // symbols do not receive a `_` prefix. | 364 | // prefix. Regular C symbols get a `_` prefix. Functions with `__stdcall`, |
| | 365 | //`__fastcall`, and `__vectorcall` have custom mangling that appends `@N` |
| | 366 | // where N is the number of bytes used to pass parameters. C++ symbols |
| | 367 | // starting with `?` are not mangled in any way. |
| | 368 | else => 'w', // Windows COFF mangling: Similar to x, except that normal C |
| | 369 | // symbols do not receive a `_` prefix. |
| | 370 | }, |
| | 371 | else => 'e', |
| 365 | }, | 372 | }, |
| | 373 | //.xcoff => 'a', // XCOFF mangling: Private symbols get a `L..` prefix. |
| 366 | else => 'e', | 374 | else => 'e', |
| 367 | }, | 375 | }, |
| 368 | //.xcoff => 'a', // XCOFF mangling: Private symbols get a `L..` prefix. | 376 | })}), |
| 369 | else => 'e', | 377 | } |
| 370 | }), | | |
| 371 | }); | | |
| 372 | var any_non_integral = false; | 378 | var any_non_integral = false; |
| 373 | const ptr_bit_width = self.target.ptrBitWidth(); | 379 | const ptr_bit_width = self.target.ptrBitWidth(); |
| 374 | var default_info = struct { size: u16, abi: u16, pref: u16, idx: u16 }{ | 380 | var default_info = struct { size: u16, abi: u16, pref: u16, idx: u16 }{ |
| ... | @@ -399,66 +405,134 @@ const DataLayoutBuilder = struct { | ... | @@ -399,66 +405,134 @@ const DataLayoutBuilder = struct { |
| 399 | .pref = pref, | 405 | .pref = pref, |
| 400 | .idx = idx, | 406 | .idx = idx, |
| 401 | }; | 407 | }; |
| | 408 | if (self.target.cpu.arch == .aarch64_32) continue; |
| 402 | if (!info.force_in_data_layout and matches_default and | 409 | if (!info.force_in_data_layout and matches_default and |
| 403 | self.target.cpu.arch != .riscv64 and !is_aarch64_windows) continue; | 410 | self.target.cpu.arch != .riscv64 and !is_aarch64_windows and |
| | 411 | self.target.cpu.arch != .bpfeb and self.target.cpu.arch != .bpfel) continue; |
| 404 | try writer.writeAll("-p"); | 412 | try writer.writeAll("-p"); |
| 405 | if (info.llvm != .default) try writer.print("{d}", .{@intFromEnum(info.llvm)}); | 413 | if (info.llvm != .default) try writer.print("{d}", .{@intFromEnum(info.llvm)}); |
| 406 | try writer.print(":{d}:{d}", .{ size, abi }); | 414 | try writer.print(":{d}:{d}", .{ size, abi }); |
| 407 | if (pref != abi or idx != size) { | 415 | if (pref != abi or idx != size or self.target.cpu.arch == .hexagon) { |
| 408 | try writer.print(":{d}", .{pref}); | 416 | try writer.print(":{d}", .{pref}); |
| 409 | if (idx != size) try writer.print(":{d}", .{idx}); | 417 | if (idx != size) try writer.print(":{d}", .{idx}); |
| 410 | } | 418 | } |
| 411 | } | 419 | } |
| 412 | if (self.target.cpu.arch.isARM() or self.target.cpu.arch.isThumb()) | 420 | if (self.target.cpu.arch.isARM() or self.target.cpu.arch.isThumb()) |
| 413 | try writer.writeAll("-Fi8"); // for thumb interwork | 421 | try writer.writeAll("-Fi8"); // for thumb interwork |
| 414 | try self.typeAlignment(.integer, 8, 8, 8, false, writer); | 422 | if (self.target.cpu.arch != .hexagon) { |
| 415 | try self.typeAlignment(.integer, 16, 16, 16, false, writer); | 423 | if (self.target.cpu.arch == .s390x) try self.typeAlignment(.integer, 1, 8, 8, false, writer); |
| 416 | try self.typeAlignment(.integer, 32, if (is_aarch64_windows) 0 else 32, 32, false, writer); | 424 | try self.typeAlignment(.integer, 8, 8, 8, false, writer); |
| 417 | try self.typeAlignment(.integer, 64, 32, 64, false, writer); | 425 | try self.typeAlignment(.integer, 16, 16, 16, false, writer); |
| 418 | try self.typeAlignment(.integer, 128, 32, 64, false, writer); | 426 | try self.typeAlignment(.integer, 32, if (is_aarch64_windows) 0 else 32, 32, false, writer); |
| 419 | if (backendSupportsF16(self.target)) try self.typeAlignment(.float, 16, 16, 16, false, writer); | 427 | try self.typeAlignment(.integer, 64, 32, 64, false, writer); |
| 420 | try self.typeAlignment(.float, 32, 32, 32, false, writer); | 428 | try self.typeAlignment(.integer, 128, 32, 64, false, writer); |
| 421 | try self.typeAlignment(.float, 64, 64, 64, false, writer); | 429 | if (backendSupportsF16(self.target)) try self.typeAlignment(.float, 16, 16, 16, false, writer); |
| 422 | if (backendSupportsF80(self.target)) try self.typeAlignment(.float, 80, 0, 0, false, writer); | 430 | try self.typeAlignment(.float, 32, 32, 32, false, writer); |
| 423 | try self.typeAlignment(.float, 128, 128, 128, false, writer); | 431 | try self.typeAlignment(.float, 64, 64, 64, false, writer); |
| 424 | try self.typeAlignment(.vector, 64, 64, 64, false, writer); | 432 | if (backendSupportsF80(self.target)) try self.typeAlignment(.float, 80, 0, 0, false, writer); |
| 425 | try self.typeAlignment(.vector, 128, 128, 128, false, writer); | 433 | try self.typeAlignment(.float, 128, 128, 128, false, writer); |
| 426 | if (self.target.os.tag != .windows) try self.typeAlignment(.aggregate, 0, 0, 64, false, writer); | 434 | } |
| | 435 | switch (self.target.cpu.arch) { |
| | 436 | .amdgcn => { |
| | 437 | try self.typeAlignment(.vector, 16, 16, 16, false, writer); |
| | 438 | try self.typeAlignment(.vector, 24, 32, 32, false, writer); |
| | 439 | try self.typeAlignment(.vector, 32, 32, 32, false, writer); |
| | 440 | try self.typeAlignment(.vector, 48, 64, 64, false, writer); |
| | 441 | try self.typeAlignment(.vector, 96, 128, 128, false, writer); |
| | 442 | try self.typeAlignment(.vector, 192, 256, 256, false, writer); |
| | 443 | try self.typeAlignment(.vector, 256, 256, 256, false, writer); |
| | 444 | try self.typeAlignment(.vector, 512, 512, 512, false, writer); |
| | 445 | try self.typeAlignment(.vector, 1024, 1024, 1024, false, writer); |
| | 446 | try self.typeAlignment(.vector, 2048, 2048, 2048, false, writer); |
| | 447 | }, |
| | 448 | .ve => {}, |
| | 449 | else => { |
| | 450 | try self.typeAlignment(.vector, 16, 32, 32, false, writer); |
| | 451 | try self.typeAlignment(.vector, 32, 32, 32, false, writer); |
| | 452 | try self.typeAlignment(.vector, 64, 64, 64, false, writer); |
| | 453 | try self.typeAlignment(.vector, 128, 128, 128, true, writer); |
| | 454 | }, |
| | 455 | } |
| | 456 | if (self.target.os.tag != .windows and self.target.cpu.arch != .avr) |
| | 457 | try self.typeAlignment(.aggregate, 0, 0, 64, false, writer); |
| 427 | for (@as([]const u24, switch (self.target.cpu.arch) { | 458 | for (@as([]const u24, switch (self.target.cpu.arch) { |
| 428 | .aarch64_32, | 459 | .avr => &.{8}, |
| | 460 | .msp430 => &.{ 8, 16 }, |
| 429 | .arm, | 461 | .arm, |
| 430 | .armeb, | 462 | .armeb, |
| 431 | .mips, | 463 | .mips, |
| 432 | .mipsel, | 464 | .mipsel, |
| 433 | .powerpc, | 465 | .powerpc, |
| 434 | .powerpcle, | 466 | .powerpcle, |
| | 467 | .riscv32, |
| | 468 | .sparc, |
| | 469 | .sparcel, |
| 435 | .thumb, | 470 | .thumb, |
| 436 | .thumbeb, | 471 | .thumbeb, |
| 437 | .riscv32, | | |
| 438 | => &.{32}, | 472 | => &.{32}, |
| 439 | .aarch64, | 473 | .aarch64, |
| 440 | .aarch64_be, | 474 | .aarch64_be, |
| | 475 | .aarch64_32, |
| | 476 | .amdgcn, |
| | 477 | .bpfeb, |
| | 478 | .bpfel, |
| 441 | .mips64, | 479 | .mips64, |
| 442 | .mips64el, | 480 | .mips64el, |
| 443 | .powerpc64, | 481 | .powerpc64, |
| 444 | .powerpc64le, | 482 | .powerpc64le, |
| 445 | .riscv64, | 483 | .riscv64, |
| | 484 | .s390x, |
| | 485 | .sparc64, |
| | 486 | .ve, |
| 446 | .wasm32, | 487 | .wasm32, |
| 447 | .wasm64, | 488 | .wasm64, |
| 448 | => &.{ 32, 64 }, | 489 | => &.{ 32, 64 }, |
| | 490 | .hexagon => &.{ 16, 32 }, |
| 449 | .x86 => &.{ 8, 16, 32 }, | 491 | .x86 => &.{ 8, 16, 32 }, |
| | 492 | .nvptx, |
| | 493 | .nvptx64, |
| | 494 | => &.{ 16, 32, 64 }, |
| 450 | .x86_64 => &.{ 8, 16, 32, 64 }, | 495 | .x86_64 => &.{ 8, 16, 32, 64 }, |
| 451 | else => &.{}, | 496 | else => &.{}, |
| 452 | }), 0..) |natural, index| switch (index) { | 497 | }), 0..) |natural, index| switch (index) { |
| 453 | 0 => try writer.print("-n{d}", .{natural}), | 498 | 0 => try writer.print("-n{d}", .{natural}), |
| 454 | else => try writer.print(":{d}", .{natural}), | 499 | else => try writer.print(":{d}", .{natural}), |
| 455 | }; | 500 | }; |
| 456 | if (self.target.os.tag == .windows) try self.typeAlignment(.aggregate, 0, 0, 64, false, writer); | 501 | if (self.target.cpu.arch == .hexagon) { |
| | 502 | try self.typeAlignment(.integer, 64, 64, 64, true, writer); |
| | 503 | try self.typeAlignment(.integer, 32, 32, 32, true, writer); |
| | 504 | try self.typeAlignment(.integer, 16, 16, 16, true, writer); |
| | 505 | try self.typeAlignment(.integer, 1, 8, 8, true, writer); |
| | 506 | try self.typeAlignment(.float, 32, 32, 32, true, writer); |
| | 507 | try self.typeAlignment(.float, 64, 64, 64, true, writer); |
| | 508 | } |
| | 509 | if (self.target.os.tag == .windows or self.target.cpu.arch == .avr) |
| | 510 | try self.typeAlignment(.aggregate, 0, 0, 64, false, writer); |
| 457 | const stack_abi = self.target.stackAlignment() * 8; | 511 | const stack_abi = self.target.stackAlignment() * 8; |
| 458 | if (self.target.os.tag == .windows or stack_abi != ptr_bit_width) | 512 | if (self.target.os.tag == .windows or self.target.cpu.arch == .msp430 or |
| | 513 | stack_abi != ptr_bit_width) |
| 459 | try writer.print("-S{d}", .{stack_abi}); | 514 | try writer.print("-S{d}", .{stack_abi}); |
| 460 | try self.typeAlignment(.vector, 256, 128, 128, true, writer); | 515 | switch (self.target.cpu.arch) { |
| 461 | try self.typeAlignment(.vector, 512, 128, 128, true, writer); | 516 | .hexagon, .ve => { |
| | 517 | try self.typeAlignment(.vector, 32, 128, 128, true, writer); |
| | 518 | try self.typeAlignment(.vector, 64, 128, 128, true, writer); |
| | 519 | try self.typeAlignment(.vector, 128, 128, 128, true, writer); |
| | 520 | }, |
| | 521 | else => {}, |
| | 522 | } |
| | 523 | if (self.target.cpu.arch != .amdgcn) { |
| | 524 | try self.typeAlignment(.vector, 256, 128, 128, true, writer); |
| | 525 | try self.typeAlignment(.vector, 512, 128, 128, true, writer); |
| | 526 | try self.typeAlignment(.vector, 1024, 128, 128, true, writer); |
| | 527 | try self.typeAlignment(.vector, 2048, 128, 128, true, writer); |
| | 528 | try self.typeAlignment(.vector, 4096, 128, 128, true, writer); |
| | 529 | try self.typeAlignment(.vector, 8192, 128, 128, true, writer); |
| | 530 | try self.typeAlignment(.vector, 16384, 128, 128, true, writer); |
| | 531 | } |
| | 532 | const alloca_addr_space = llvmAllocaAddressSpace(self.target); |
| | 533 | if (alloca_addr_space != .default) try writer.print("-A{d}", .{@intFromEnum(alloca_addr_space)}); |
| | 534 | const global_addr_space = llvmDefaultGlobalAddressSpace(self.target); |
| | 535 | if (global_addr_space != .default) try writer.print("-G{d}", .{@intFromEnum(global_addr_space)}); |
| 462 | if (any_non_integral) { | 536 | if (any_non_integral) { |
| 463 | try writer.writeAll("-ni"); | 537 | try writer.writeAll("-ni"); |
| 464 | for (addr_space_info) |info| if (info.non_integral) | 538 | for (addr_space_info) |info| if (info.non_integral) |
| ... | @@ -472,11 +546,13 @@ const DataLayoutBuilder = struct { | ... | @@ -472,11 +546,13 @@ const DataLayoutBuilder = struct { |
| 472 | size: u24, | 546 | size: u24, |
| 473 | default_abi: u24, | 547 | default_abi: u24, |
| 474 | default_pref: u24, | 548 | default_pref: u24, |
| 475 | force_pref: bool, | 549 | default_force_pref: bool, |
| 476 | writer: anytype, | 550 | writer: anytype, |
| 477 | ) @TypeOf(writer).Error!void { | 551 | ) @TypeOf(writer).Error!void { |
| 478 | var abi = default_abi; | 552 | var abi = default_abi; |
| 479 | var pref = default_pref; | 553 | var pref = default_pref; |
| | 554 | var force_abi = false; |
| | 555 | var force_pref = default_force_pref; |
| 480 | if (kind == .float and size == 80) { | 556 | if (kind == .float and size == 80) { |
| 481 | abi = 128; | 557 | abi = 128; |
| 482 | pref = 128; | 558 | pref = 128; |
| ... | @@ -493,21 +569,45 @@ const DataLayoutBuilder = struct { | ... | @@ -493,21 +569,45 @@ const DataLayoutBuilder = struct { |
| 493 | } | 569 | } |
| 494 | switch (kind) { | 570 | switch (kind) { |
| 495 | .integer => { | 571 | .integer => { |
| | 572 | if (self.target.ptrBitWidth() <= 16 and size >= 128) return; |
| 496 | abi = @min(abi, self.target.maxIntAlignment() * 8); | 573 | abi = @min(abi, self.target.maxIntAlignment() * 8); |
| 497 | switch (self.target.os.tag) { | 574 | switch (self.target.os.tag) { |
| 498 | .linux => switch (self.target.cpu.arch) { | 575 | .linux => switch (self.target.cpu.arch) { |
| 499 | .aarch64, .aarch64_be, .mips, .mipsel => pref = @max(pref, 32), | 576 | .aarch64, |
| | 577 | .aarch64_be, |
| | 578 | .aarch64_32, |
| | 579 | .mips, |
| | 580 | .mipsel, |
| | 581 | => pref = @max(pref, 32), |
| 500 | else => {}, | 582 | else => {}, |
| 501 | }, | 583 | }, |
| 502 | else => {}, | 584 | else => {}, |
| 503 | } | 585 | } |
| 504 | switch (self.target.cpu.arch) { | 586 | switch (self.target.cpu.arch) { |
| 505 | .aarch64, .aarch64_be, .riscv64 => switch (size) { | 587 | .aarch64, |
| 506 | 128 => { | 588 | .aarch64_be, |
| 507 | abi = size; | 589 | .aarch64_32, |
| 508 | pref = size; | 590 | .bpfeb, |
| 509 | }, | 591 | .bpfel, |
| 510 | else => {}, | 592 | .nvptx, |
| | 593 | .nvptx64, |
| | 594 | .riscv64, |
| | 595 | => if (size == 128) { |
| | 596 | abi = size; |
| | 597 | pref = size; |
| | 598 | }, |
| | 599 | .hexagon => force_abi = true, |
| | 600 | .mips64, |
| | 601 | .mips64el, |
| | 602 | => if (size <= 32) { |
| | 603 | pref = 32; |
| | 604 | }, |
| | 605 | .s390x => if (size <= 16) { |
| | 606 | pref = 16; |
| | 607 | }, |
| | 608 | .ve => if (size == 64) { |
| | 609 | abi = size; |
| | 610 | pref = size; |
| 511 | }, | 611 | }, |
| 512 | else => {}, | 612 | else => {}, |
| 513 | } | 613 | } |
| ... | @@ -517,18 +617,66 @@ const DataLayoutBuilder = struct { | ... | @@ -517,18 +617,66 @@ const DataLayoutBuilder = struct { |
| 517 | 128 => abi = 64, | 617 | 128 => abi = 64, |
| 518 | else => {}, | 618 | else => {}, |
| 519 | } | 619 | } |
| 520 | } else if (self.target.cpu.arch.isPPC64()) { | 620 | } else if ((self.target.cpu.arch.isPPC64() and (size == 256 or size == 512)) or |
| | 621 | (self.target.cpu.arch.isNvptx() and (size == 16 or size == 32))) |
| | 622 | { |
| | 623 | force_abi = true; |
| | 624 | abi = size; |
| | 625 | pref = size; |
| | 626 | } else if (self.target.cpu.arch == .amdgcn and size <= 2048) { |
| | 627 | force_abi = true; |
| | 628 | } else if (self.target.cpu.arch == .hexagon and |
| | 629 | ((size >= 32 and size <= 64) or (size >= 512 and size <= 2048))) |
| | 630 | { |
| 521 | abi = size; | 631 | abi = size; |
| 522 | pref = size; | 632 | pref = size; |
| | 633 | force_pref = true; |
| | 634 | } else if (self.target.cpu.arch == .s390x and size == 128) { |
| | 635 | abi = 64; |
| | 636 | pref = 64; |
| | 637 | force_pref = false; |
| | 638 | } else if (self.target.cpu.arch == .ve and (size >= 64 and size <= 16384)) { |
| | 639 | abi = 64; |
| | 640 | pref = 64; |
| | 641 | force_abi = true; |
| | 642 | force_pref = true; |
| | 643 | }, |
| | 644 | .float => switch (self.target.cpu.arch) { |
| | 645 | .avr, .msp430, .sparc64 => if (size != 32 and size != 64) return, |
| | 646 | .hexagon => if (size == 32 or size == 64) { |
| | 647 | force_abi = true; |
| | 648 | }, |
| | 649 | .aarch64_32 => if (size == 128) { |
| | 650 | abi = size; |
| | 651 | pref = size; |
| | 652 | }, |
| | 653 | .ve => if (size == 64) { |
| | 654 | abi = size; |
| | 655 | pref = size; |
| | 656 | }, |
| | 657 | else => {}, |
| 523 | }, | 658 | }, |
| 524 | .float => {}, | | |
| 525 | .aggregate => if (self.target.os.tag == .windows or | 659 | .aggregate => if (self.target.os.tag == .windows or |
| 526 | self.target.cpu.arch.isARM() or self.target.cpu.arch.isThumb()) | 660 | self.target.cpu.arch.isARM() or self.target.cpu.arch.isThumb()) |
| 527 | { | 661 | { |
| 528 | pref = @min(pref, self.target.ptrBitWidth()); | 662 | pref = @min(pref, self.target.ptrBitWidth()); |
| | 663 | } else if (self.target.cpu.arch == .hexagon) { |
| | 664 | abi = 0; |
| | 665 | pref = 0; |
| | 666 | } else if (self.target.cpu.arch == .s390x) { |
| | 667 | abi = 8; |
| | 668 | pref = 16; |
| | 669 | } else if (self.target.cpu.arch == .msp430) { |
| | 670 | abi = 8; |
| | 671 | pref = 8; |
| 529 | }, | 672 | }, |
| 530 | } | 673 | } |
| 531 | if (abi == default_abi and pref == default_pref) return; | 674 | if (kind != .vector and self.target.cpu.arch == .avr) { |
| | 675 | force_abi = true; |
| | 676 | abi = 8; |
| | 677 | pref = 8; |
| | 678 | } |
| | 679 | if (!force_abi and abi == default_abi and pref == default_pref) return; |
| 532 | try writer.print("-{c}", .{@tagName(kind)[0]}); | 680 | try writer.print("-{c}", .{@tagName(kind)[0]}); |
| 533 | if (size != 0) try writer.print("{d}", .{size}); | 681 | if (size != 0) try writer.print("{d}", .{size}); |
| 534 | try writer.print(":{d}", .{abi}); | 682 | try writer.print(":{d}", .{abi}); |
| ... | @@ -5096,12 +5244,15 @@ pub const FuncGen = struct { | ... | @@ -5096,12 +5244,15 @@ pub const FuncGen = struct { |
| 5096 | // In this case the function return type is honoring the calling convention by having | 5244 | // In this case the function return type is honoring the calling convention by having |
| 5097 | // a different LLVM type than the usual one. We solve this here at the callsite | 5245 | // a different LLVM type than the usual one. We solve this here at the callsite |
| 5098 | // by using our canonical type, then loading it if necessary. | 5246 | // by using our canonical type, then loading it if necessary. |
| 5099 | const rp = try self.buildAlloca(llvm_ret_ty, .default); | 5247 | const alignment = Builder.Alignment.fromByteUnits( |
| 5100 | _ = try self.wip.store(.normal, call, rp, .default); | 5248 | o.target_data.abiAlignmentOfType(abi_ret_ty.toLlvm(&o.builder)), |
| | 5249 | ); |
| | 5250 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); |
| | 5251 | _ = try self.wip.store(.normal, call, rp, alignment); |
| 5101 | return if (isByRef(return_type, mod)) | 5252 | return if (isByRef(return_type, mod)) |
| 5102 | rp | 5253 | rp |
| 5103 | else | 5254 | else |
| 5104 | try self.wip.load(.normal, llvm_ret_ty, rp, .default, ""); | 5255 | try self.wip.load(.normal, llvm_ret_ty, rp, alignment, ""); |
| 5105 | } | 5256 | } |
| 5106 | | 5257 | |
| 5107 | if (isByRef(return_type, mod)) { | 5258 | if (isByRef(return_type, mod)) { |
| ... | @@ -10923,23 +11074,26 @@ fn llvmAddrSpaceInfo(target: std.Target) []const AddrSpaceInfo { | ... | @@ -10923,23 +11074,26 @@ fn llvmAddrSpaceInfo(target: std.Target) []const AddrSpaceInfo { |
| 10923 | .{ .zig = .local, .llvm = Builder.AddrSpace.nvptx.local }, | 11074 | .{ .zig = .local, .llvm = Builder.AddrSpace.nvptx.local }, |
| 10924 | }, | 11075 | }, |
| 10925 | .amdgcn => &.{ | 11076 | .amdgcn => &.{ |
| 10926 | .{ .zig = .generic, .llvm = Builder.AddrSpace.amdgpu.flat }, | 11077 | .{ .zig = .generic, .llvm = Builder.AddrSpace.amdgpu.flat, .force_in_data_layout = true }, |
| 10927 | .{ .zig = .global, .llvm = Builder.AddrSpace.amdgpu.global }, | 11078 | .{ .zig = .global, .llvm = Builder.AddrSpace.amdgpu.global, .force_in_data_layout = true }, |
| 10928 | .{ .zig = .constant, .llvm = Builder.AddrSpace.amdgpu.constant }, | 11079 | .{ .zig = null, .llvm = Builder.AddrSpace.amdgpu.region, .size = 32, .abi = 32 }, |
| 10929 | .{ .zig = .shared, .llvm = Builder.AddrSpace.amdgpu.local }, | 11080 | .{ .zig = .shared, .llvm = Builder.AddrSpace.amdgpu.local, .size = 32, .abi = 32 }, |
| 10930 | .{ .zig = .local, .llvm = Builder.AddrSpace.amdgpu.private }, | 11081 | .{ .zig = .constant, .llvm = Builder.AddrSpace.amdgpu.constant, .force_in_data_layout = true }, |
| | 11082 | .{ .zig = .local, .llvm = Builder.AddrSpace.amdgpu.private, .size = 32, .abi = 32 }, |
| | 11083 | .{ .zig = null, .llvm = Builder.AddrSpace.amdgpu.constant_32bit, .size = 32, .abi = 32 }, |
| | 11084 | .{ .zig = null, .llvm = Builder.AddrSpace.amdgpu.buffer_fat_pointer, .non_integral = true }, |
| 10931 | }, | 11085 | }, |
| 10932 | .avr => &.{ | 11086 | .avr => &.{ |
| 10933 | .{ .zig = .generic, .llvm = .default }, | 11087 | .{ .zig = .generic, .llvm = .default, .abi = 8 }, |
| 10934 | .{ .zig = .flash, .llvm = Builder.AddrSpace.avr.flash }, | 11088 | .{ .zig = .flash, .llvm = Builder.AddrSpace.avr.flash, .abi = 8 }, |
| 10935 | .{ .zig = .flash1, .llvm = Builder.AddrSpace.avr.flash1 }, | 11089 | .{ .zig = .flash1, .llvm = Builder.AddrSpace.avr.flash1, .abi = 8 }, |
| 10936 | .{ .zig = .flash2, .llvm = Builder.AddrSpace.avr.flash2 }, | 11090 | .{ .zig = .flash2, .llvm = Builder.AddrSpace.avr.flash2, .abi = 8 }, |
| 10937 | .{ .zig = .flash3, .llvm = Builder.AddrSpace.avr.flash3 }, | 11091 | .{ .zig = .flash3, .llvm = Builder.AddrSpace.avr.flash3, .abi = 8 }, |
| 10938 | .{ .zig = .flash4, .llvm = Builder.AddrSpace.avr.flash4 }, | 11092 | .{ .zig = .flash4, .llvm = Builder.AddrSpace.avr.flash4, .abi = 8 }, |
| 10939 | .{ .zig = .flash5, .llvm = Builder.AddrSpace.avr.flash5 }, | 11093 | .{ .zig = .flash5, .llvm = Builder.AddrSpace.avr.flash5, .abi = 8 }, |
| 10940 | }, | 11094 | }, |
| 10941 | .wasm32, .wasm64 => &.{ | 11095 | .wasm32, .wasm64 => &.{ |
| 10942 | .{ .zig = .generic, .llvm = .default }, | 11096 | .{ .zig = .generic, .llvm = .default, .force_in_data_layout = true }, |
| 10943 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.variable, .non_integral = true }, | 11097 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.variable, .non_integral = true }, |
| 10944 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.externref, .non_integral = true, .size = 8, .abi = 8 }, | 11098 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.externref, .non_integral = true, .size = 8, .abi = 8 }, |
| 10945 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.funcref, .non_integral = true, .size = 8, .abi = 8 }, | 11099 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.funcref, .non_integral = true, .size = 8, .abi = 8 }, |