| ... | @@ -10396,12 +10396,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool | ... | @@ -10396,12 +10396,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool |
| 10396 | .mips, .mipsel => return false, | 10396 | .mips, .mipsel => return false, |
| 10397 | .x86_64 => switch (target.os.tag) { | 10397 | .x86_64 => switch (target.os.tag) { |
| 10398 | .windows => return x86_64_abi.classifyWindows(fn_info.return_type, target) == .memory, | 10398 | .windows => return x86_64_abi.classifyWindows(fn_info.return_type, target) == .memory, |
| 10399 | else => { | 10399 | else => return firstParamSRetSystemV(fn_info.return_type, target), |
| 10400 | const class = x86_64_abi.classifySystemV(fn_info.return_type, target, .ret); | | |
| 10401 | if (class[0] == .memory) return true; | | |
| 10402 | if (class[0] == .x87 and class[2] != .none) return true; | | |
| 10403 | return false; | | |
| 10404 | }, | | |
| 10405 | }, | 10400 | }, |
| 10406 | .wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, target)[0] == .indirect, | 10401 | .wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, target)[0] == .indirect, |
| 10407 | .aarch64, .aarch64_be => return aarch64_c_abi.classifyType(fn_info.return_type, target) == .memory, | 10402 | .aarch64, .aarch64_be => return aarch64_c_abi.classifyType(fn_info.return_type, target) == .memory, |
| ... | @@ -10413,11 +10408,20 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool | ... | @@ -10413,11 +10408,20 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool |
| 10413 | .riscv32, .riscv64 => return riscv_c_abi.classifyType(fn_info.return_type, target) == .memory, | 10408 | .riscv32, .riscv64 => return riscv_c_abi.classifyType(fn_info.return_type, target) == .memory, |
| 10414 | else => return false, // TODO investigate C ABI for other architectures | 10409 | else => return false, // TODO investigate C ABI for other architectures |
| 10415 | }, | 10410 | }, |
| | 10411 | .SysV => return firstParamSRetSystemV(fn_info.return_type, target), |
| | 10412 | .Win64 => return x86_64_abi.classifyWindows(fn_info.return_type, target) == .memory, |
| 10416 | .Stdcall => return !isScalar(fn_info.return_type), | 10413 | .Stdcall => return !isScalar(fn_info.return_type), |
| 10417 | else => return false, | 10414 | else => return false, |
| 10418 | } | 10415 | } |
| 10419 | } | 10416 | } |
| 10420 | | 10417 | |
| | 10418 | fn firstParamSRetSystemV(ty: Type, target: std.Target) bool { |
| | 10419 | const class = x86_64_abi.classifySystemV(ty, target, .ret); |
| | 10420 | if (class[0] == .memory) return true; |
| | 10421 | if (class[0] == .x87 and class[2] != .none) return true; |
| | 10422 | return false; |
| | 10423 | } |
| | 10424 | |
| 10421 | /// In order to support the C calling convention, some return types need to be lowered | 10425 | /// In order to support the C calling convention, some return types need to be lowered |
| 10422 | /// completely differently in the function prototype to honor the C ABI, and then | 10426 | /// completely differently in the function prototype to honor the C ABI, and then |
| 10423 | /// be effectively bitcasted to the actual return type. | 10427 | /// be effectively bitcasted to the actual return type. |
| ... | @@ -10442,77 +10446,14 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { | ... | @@ -10442,77 +10446,14 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { |
| 10442 | } | 10446 | } |
| 10443 | }, | 10447 | }, |
| 10444 | .C => { | 10448 | .C => { |
| 10445 | const is_scalar = isScalar(fn_info.return_type); | | |
| 10446 | switch (target.cpu.arch) { | 10449 | switch (target.cpu.arch) { |
| 10447 | .mips, .mipsel => return dg.lowerType(fn_info.return_type), | 10450 | .mips, .mipsel => return dg.lowerType(fn_info.return_type), |
| 10448 | .x86_64 => switch (target.os.tag) { | 10451 | .x86_64 => switch (target.os.tag) { |
| 10449 | .windows => switch (x86_64_abi.classifyWindows(fn_info.return_type, target)) { | 10452 | .windows => return lowerWin64FnRetTy(dg, fn_info), |
| 10450 | .integer => { | 10453 | else => return lowerSystemVFnRetTy(dg, fn_info), |
| 10451 | if (is_scalar) { | | |
| 10452 | return dg.lowerType(fn_info.return_type); | | |
| 10453 | } else { | | |
| 10454 | const abi_size = fn_info.return_type.abiSize(target); | | |
| 10455 | return dg.context.intType(@intCast(c_uint, abi_size * 8)); | | |
| 10456 | } | | |
| 10457 | }, | | |
| 10458 | .win_i128 => return dg.context.intType(64).vectorType(2), | | |
| 10459 | .memory => return dg.context.voidType(), | | |
| 10460 | .sse => return dg.lowerType(fn_info.return_type), | | |
| 10461 | else => unreachable, | | |
| 10462 | }, | | |
| 10463 | else => { | | |
| 10464 | if (is_scalar) { | | |
| 10465 | return dg.lowerType(fn_info.return_type); | | |
| 10466 | } | | |
| 10467 | const classes = x86_64_abi.classifySystemV(fn_info.return_type, target, .ret); | | |
| 10468 | if (classes[0] == .memory) { | | |
| 10469 | return dg.context.voidType(); | | |
| 10470 | } | | |
| 10471 | var llvm_types_buffer: [8]*llvm.Type = undefined; | | |
| 10472 | var llvm_types_index: u32 = 0; | | |
| 10473 | for (classes) |class| { | | |
| 10474 | switch (class) { | | |
| 10475 | .integer => { | | |
| 10476 | llvm_types_buffer[llvm_types_index] = dg.context.intType(64); | | |
| 10477 | llvm_types_index += 1; | | |
| 10478 | }, | | |
| 10479 | .sse, .sseup => { | | |
| 10480 | llvm_types_buffer[llvm_types_index] = dg.context.doubleType(); | | |
| 10481 | llvm_types_index += 1; | | |
| 10482 | }, | | |
| 10483 | .float => { | | |
| 10484 | llvm_types_buffer[llvm_types_index] = dg.context.floatType(); | | |
| 10485 | llvm_types_index += 1; | | |
| 10486 | }, | | |
| 10487 | .float_combine => { | | |
| 10488 | llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2); | | |
| 10489 | llvm_types_index += 1; | | |
| 10490 | }, | | |
| 10491 | .x87 => { | | |
| 10492 | if (llvm_types_index != 0 or classes[2] != .none) { | | |
| 10493 | return dg.context.voidType(); | | |
| 10494 | } | | |
| 10495 | llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type(); | | |
| 10496 | llvm_types_index += 1; | | |
| 10497 | }, | | |
| 10498 | .x87up => continue, | | |
| 10499 | .complex_x87 => { | | |
| 10500 | @panic("TODO"); | | |
| 10501 | }, | | |
| 10502 | .memory => unreachable, // handled above | | |
| 10503 | .win_i128 => unreachable, // windows only | | |
| 10504 | .none => break, | | |
| 10505 | } | | |
| 10506 | } | | |
| 10507 | if (classes[0] == .integer and classes[1] == .none) { | | |
| 10508 | const abi_size = fn_info.return_type.abiSize(target); | | |
| 10509 | return dg.context.intType(@intCast(c_uint, abi_size * 8)); | | |
| 10510 | } | | |
| 10511 | return dg.context.structType(&llvm_types_buffer, llvm_types_index, .False); | | |
| 10512 | }, | | |
| 10513 | }, | 10454 | }, |
| 10514 | .wasm32 => { | 10455 | .wasm32 => { |
| 10515 | if (is_scalar) { | 10456 | if (isScalar(fn_info.return_type)) { |
| 10516 | return dg.lowerType(fn_info.return_type); | 10457 | return dg.lowerType(fn_info.return_type); |
| 10517 | } | 10458 | } |
| 10518 | const classes = wasm_c_abi.classifyType(fn_info.return_type, target); | 10459 | const classes = wasm_c_abi.classifyType(fn_info.return_type, target); |
| ... | @@ -10569,6 +10510,8 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { | ... | @@ -10569,6 +10510,8 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { |
| 10569 | else => return dg.lowerType(fn_info.return_type), | 10510 | else => return dg.lowerType(fn_info.return_type), |
| 10570 | } | 10511 | } |
| 10571 | }, | 10512 | }, |
| | 10513 | .Win64 => return lowerWin64FnRetTy(dg, fn_info), |
| | 10514 | .SysV => return lowerSystemVFnRetTy(dg, fn_info), |
| 10572 | .Stdcall => { | 10515 | .Stdcall => { |
| 10573 | if (isScalar(fn_info.return_type)) { | 10516 | if (isScalar(fn_info.return_type)) { |
| 10574 | return dg.lowerType(fn_info.return_type); | 10517 | return dg.lowerType(fn_info.return_type); |
| ... | @@ -10580,6 +10523,76 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { | ... | @@ -10580,6 +10523,76 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { |
| 10580 | } | 10523 | } |
| 10581 | } | 10524 | } |
| 10582 | | 10525 | |
| | 10526 | fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { |
| | 10527 | const target = dg.module.getTarget(); |
| | 10528 | switch (x86_64_abi.classifyWindows(fn_info.return_type, target)) { |
| | 10529 | .integer => { |
| | 10530 | if (isScalar(fn_info.return_type)) { |
| | 10531 | return dg.lowerType(fn_info.return_type); |
| | 10532 | } else { |
| | 10533 | const abi_size = fn_info.return_type.abiSize(target); |
| | 10534 | return dg.context.intType(@intCast(c_uint, abi_size * 8)); |
| | 10535 | } |
| | 10536 | }, |
| | 10537 | .win_i128 => return dg.context.intType(64).vectorType(2), |
| | 10538 | .memory => return dg.context.voidType(), |
| | 10539 | .sse => return dg.lowerType(fn_info.return_type), |
| | 10540 | else => unreachable, |
| | 10541 | } |
| | 10542 | } |
| | 10543 | |
| | 10544 | fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { |
| | 10545 | if (isScalar(fn_info.return_type)) { |
| | 10546 | return dg.lowerType(fn_info.return_type); |
| | 10547 | } |
| | 10548 | const target = dg.module.getTarget(); |
| | 10549 | const classes = x86_64_abi.classifySystemV(fn_info.return_type, target, .ret); |
| | 10550 | if (classes[0] == .memory) { |
| | 10551 | return dg.context.voidType(); |
| | 10552 | } |
| | 10553 | var llvm_types_buffer: [8]*llvm.Type = undefined; |
| | 10554 | var llvm_types_index: u32 = 0; |
| | 10555 | for (classes) |class| { |
| | 10556 | switch (class) { |
| | 10557 | .integer => { |
| | 10558 | llvm_types_buffer[llvm_types_index] = dg.context.intType(64); |
| | 10559 | llvm_types_index += 1; |
| | 10560 | }, |
| | 10561 | .sse, .sseup => { |
| | 10562 | llvm_types_buffer[llvm_types_index] = dg.context.doubleType(); |
| | 10563 | llvm_types_index += 1; |
| | 10564 | }, |
| | 10565 | .float => { |
| | 10566 | llvm_types_buffer[llvm_types_index] = dg.context.floatType(); |
| | 10567 | llvm_types_index += 1; |
| | 10568 | }, |
| | 10569 | .float_combine => { |
| | 10570 | llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2); |
| | 10571 | llvm_types_index += 1; |
| | 10572 | }, |
| | 10573 | .x87 => { |
| | 10574 | if (llvm_types_index != 0 or classes[2] != .none) { |
| | 10575 | return dg.context.voidType(); |
| | 10576 | } |
| | 10577 | llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type(); |
| | 10578 | llvm_types_index += 1; |
| | 10579 | }, |
| | 10580 | .x87up => continue, |
| | 10581 | .complex_x87 => { |
| | 10582 | @panic("TODO"); |
| | 10583 | }, |
| | 10584 | .memory => unreachable, // handled above |
| | 10585 | .win_i128 => unreachable, // windows only |
| | 10586 | .none => break, |
| | 10587 | } |
| | 10588 | } |
| | 10589 | if (classes[0] == .integer and classes[1] == .none) { |
| | 10590 | const abi_size = fn_info.return_type.abiSize(target); |
| | 10591 | return dg.context.intType(@intCast(c_uint, abi_size * 8)); |
| | 10592 | } |
| | 10593 | return dg.context.structType(&llvm_types_buffer, llvm_types_index, .False); |
| | 10594 | } |
| | 10595 | |
| 10583 | const ParamTypeIterator = struct { | 10596 | const ParamTypeIterator = struct { |
| 10584 | dg: *DeclGen, | 10597 | dg: *DeclGen, |
| 10585 | fn_info: Type.Payload.Function.Data, | 10598 | fn_info: Type.Payload.Function.Data, |
| ... | @@ -10629,7 +10642,6 @@ const ParamTypeIterator = struct { | ... | @@ -10629,7 +10642,6 @@ const ParamTypeIterator = struct { |
| 10629 | it.zig_index += 1; | 10642 | it.zig_index += 1; |
| 10630 | return .no_bits; | 10643 | return .no_bits; |
| 10631 | } | 10644 | } |
| 10632 | const dg = it.dg; | | |
| 10633 | switch (it.fn_info.cc) { | 10645 | switch (it.fn_info.cc) { |
| 10634 | .Unspecified, .Inline => { | 10646 | .Unspecified, .Inline => { |
| 10635 | it.zig_index += 1; | 10647 | it.zig_index += 1; |
| ... | @@ -10648,7 +10660,6 @@ const ParamTypeIterator = struct { | ... | @@ -10648,7 +10660,6 @@ const ParamTypeIterator = struct { |
| 10648 | @panic("TODO implement async function lowering in the LLVM backend"); | 10660 | @panic("TODO implement async function lowering in the LLVM backend"); |
| 10649 | }, | 10661 | }, |
| 10650 | .C => { | 10662 | .C => { |
| 10651 | const is_scalar = isScalar(ty); | | |
| 10652 | switch (it.target.cpu.arch) { | 10663 | switch (it.target.cpu.arch) { |
| 10653 | .mips, .mipsel => { | 10664 | .mips, .mipsel => { |
| 10654 | it.zig_index += 1; | 10665 | it.zig_index += 1; |
| ... | @@ -10656,99 +10667,13 @@ const ParamTypeIterator = struct { | ... | @@ -10656,99 +10667,13 @@ const ParamTypeIterator = struct { |
| 10656 | return .byval; | 10667 | return .byval; |
| 10657 | }, | 10668 | }, |
| 10658 | .x86_64 => switch (it.target.os.tag) { | 10669 | .x86_64 => switch (it.target.os.tag) { |
| 10659 | .windows => switch (x86_64_abi.classifyWindows(ty, it.target)) { | 10670 | .windows => return it.nextWin64(ty), |
| 10660 | .integer => { | 10671 | else => return it.nextSystemV(ty), |
| 10661 | if (is_scalar) { | | |
| 10662 | it.zig_index += 1; | | |
| 10663 | it.llvm_index += 1; | | |
| 10664 | return .byval; | | |
| 10665 | } else { | | |
| 10666 | it.zig_index += 1; | | |
| 10667 | it.llvm_index += 1; | | |
| 10668 | return .abi_sized_int; | | |
| 10669 | } | | |
| 10670 | }, | | |
| 10671 | .win_i128 => { | | |
| 10672 | it.zig_index += 1; | | |
| 10673 | it.llvm_index += 1; | | |
| 10674 | return .byref; | | |
| 10675 | }, | | |
| 10676 | .memory => { | | |
| 10677 | it.zig_index += 1; | | |
| 10678 | it.llvm_index += 1; | | |
| 10679 | return .byref_mut; | | |
| 10680 | }, | | |
| 10681 | .sse => { | | |
| 10682 | it.zig_index += 1; | | |
| 10683 | it.llvm_index += 1; | | |
| 10684 | return .byval; | | |
| 10685 | }, | | |
| 10686 | else => unreachable, | | |
| 10687 | }, | | |
| 10688 | else => { | | |
| 10689 | const classes = x86_64_abi.classifySystemV(ty, it.target, .arg); | | |
| 10690 | if (classes[0] == .memory) { | | |
| 10691 | it.zig_index += 1; | | |
| 10692 | it.llvm_index += 1; | | |
| 10693 | it.byval_attr = true; | | |
| 10694 | return .byref; | | |
| 10695 | } | | |
| 10696 | if (is_scalar) { | | |
| 10697 | it.zig_index += 1; | | |
| 10698 | it.llvm_index += 1; | | |
| 10699 | return .byval; | | |
| 10700 | } | | |
| 10701 | var llvm_types_buffer: [8]*llvm.Type = undefined; | | |
| 10702 | var llvm_types_index: u32 = 0; | | |
| 10703 | for (classes) |class| { | | |
| 10704 | switch (class) { | | |
| 10705 | .integer => { | | |
| 10706 | llvm_types_buffer[llvm_types_index] = dg.context.intType(64); | | |
| 10707 | llvm_types_index += 1; | | |
| 10708 | }, | | |
| 10709 | .sse, .sseup => { | | |
| 10710 | llvm_types_buffer[llvm_types_index] = dg.context.doubleType(); | | |
| 10711 | llvm_types_index += 1; | | |
| 10712 | }, | | |
| 10713 | .float => { | | |
| 10714 | llvm_types_buffer[llvm_types_index] = dg.context.floatType(); | | |
| 10715 | llvm_types_index += 1; | | |
| 10716 | }, | | |
| 10717 | .float_combine => { | | |
| 10718 | llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2); | | |
| 10719 | llvm_types_index += 1; | | |
| 10720 | }, | | |
| 10721 | .x87 => { | | |
| 10722 | it.zig_index += 1; | | |
| 10723 | it.llvm_index += 1; | | |
| 10724 | it.byval_attr = true; | | |
| 10725 | return .byref; | | |
| 10726 | }, | | |
| 10727 | .x87up => unreachable, | | |
| 10728 | .complex_x87 => { | | |
| 10729 | @panic("TODO"); | | |
| 10730 | }, | | |
| 10731 | .memory => unreachable, // handled above | | |
| 10732 | .win_i128 => unreachable, // windows only | | |
| 10733 | .none => break, | | |
| 10734 | } | | |
| 10735 | } | | |
| 10736 | if (classes[0] == .integer and classes[1] == .none) { | | |
| 10737 | it.zig_index += 1; | | |
| 10738 | it.llvm_index += 1; | | |
| 10739 | return .abi_sized_int; | | |
| 10740 | } | | |
| 10741 | it.llvm_types_buffer = llvm_types_buffer; | | |
| 10742 | it.llvm_types_len = llvm_types_index; | | |
| 10743 | it.llvm_index += llvm_types_index; | | |
| 10744 | it.zig_index += 1; | | |
| 10745 | return .multiple_llvm_types; | | |
| 10746 | }, | | |
| 10747 | }, | 10672 | }, |
| 10748 | .wasm32 => { | 10673 | .wasm32 => { |
| 10749 | it.zig_index += 1; | 10674 | it.zig_index += 1; |
| 10750 | it.llvm_index += 1; | 10675 | it.llvm_index += 1; |
| 10751 | if (is_scalar) { | 10676 | if (isScalar(ty)) { |
| 10752 | return .byval; | 10677 | return .byval; |
| 10753 | } | 10678 | } |
| 10754 | const classes = wasm_c_abi.classifyType(ty, it.target); | 10679 | const classes = wasm_c_abi.classifyType(ty, it.target); |
| ... | @@ -10766,7 +10691,7 @@ const ParamTypeIterator = struct { | ... | @@ -10766,7 +10691,7 @@ const ParamTypeIterator = struct { |
| 10766 | .byval => return .byval, | 10691 | .byval => return .byval, |
| 10767 | .integer => { | 10692 | .integer => { |
| 10768 | it.llvm_types_len = 1; | 10693 | it.llvm_types_len = 1; |
| 10769 | it.llvm_types_buffer[0] = dg.context.intType(64); | 10694 | it.llvm_types_buffer[0] = it.dg.context.intType(64); |
| 10770 | return .multiple_llvm_types; | 10695 | return .multiple_llvm_types; |
| 10771 | }, | 10696 | }, |
| 10772 | .double_integer => return Lowering{ .i64_array = 2 }, | 10697 | .double_integer => return Lowering{ .i64_array = 2 }, |
| ... | @@ -10806,6 +10731,8 @@ const ParamTypeIterator = struct { | ... | @@ -10806,6 +10731,8 @@ const ParamTypeIterator = struct { |
| 10806 | }, | 10731 | }, |
| 10807 | } | 10732 | } |
| 10808 | }, | 10733 | }, |
| | 10734 | .Win64 => return it.nextWin64(ty), |
| | 10735 | .SysV => return it.nextSystemV(ty), |
| 10809 | .Stdcall => { | 10736 | .Stdcall => { |
| 10810 | it.zig_index += 1; | 10737 | it.zig_index += 1; |
| 10811 | it.llvm_index += 1; | 10738 | it.llvm_index += 1; |
| ... | @@ -10824,6 +10751,98 @@ const ParamTypeIterator = struct { | ... | @@ -10824,6 +10751,98 @@ const ParamTypeIterator = struct { |
| 10824 | }, | 10751 | }, |
| 10825 | } | 10752 | } |
| 10826 | } | 10753 | } |
| | 10754 | |
| | 10755 | fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering { |
| | 10756 | switch (x86_64_abi.classifyWindows(ty, it.target)) { |
| | 10757 | .integer => { |
| | 10758 | if (isScalar(ty)) { |
| | 10759 | it.zig_index += 1; |
| | 10760 | it.llvm_index += 1; |
| | 10761 | return .byval; |
| | 10762 | } else { |
| | 10763 | it.zig_index += 1; |
| | 10764 | it.llvm_index += 1; |
| | 10765 | return .abi_sized_int; |
| | 10766 | } |
| | 10767 | }, |
| | 10768 | .win_i128 => { |
| | 10769 | it.zig_index += 1; |
| | 10770 | it.llvm_index += 1; |
| | 10771 | return .byref; |
| | 10772 | }, |
| | 10773 | .memory => { |
| | 10774 | it.zig_index += 1; |
| | 10775 | it.llvm_index += 1; |
| | 10776 | return .byref_mut; |
| | 10777 | }, |
| | 10778 | .sse => { |
| | 10779 | it.zig_index += 1; |
| | 10780 | it.llvm_index += 1; |
| | 10781 | return .byval; |
| | 10782 | }, |
| | 10783 | else => unreachable, |
| | 10784 | } |
| | 10785 | } |
| | 10786 | |
| | 10787 | fn nextSystemV(it: *ParamTypeIterator, ty: Type) ?Lowering { |
| | 10788 | const classes = x86_64_abi.classifySystemV(ty, it.target, .arg); |
| | 10789 | if (classes[0] == .memory) { |
| | 10790 | it.zig_index += 1; |
| | 10791 | it.llvm_index += 1; |
| | 10792 | it.byval_attr = true; |
| | 10793 | return .byref; |
| | 10794 | } |
| | 10795 | if (isScalar(ty)) { |
| | 10796 | it.zig_index += 1; |
| | 10797 | it.llvm_index += 1; |
| | 10798 | return .byval; |
| | 10799 | } |
| | 10800 | var llvm_types_buffer: [8]*llvm.Type = undefined; |
| | 10801 | var llvm_types_index: u32 = 0; |
| | 10802 | for (classes) |class| { |
| | 10803 | switch (class) { |
| | 10804 | .integer => { |
| | 10805 | llvm_types_buffer[llvm_types_index] = it.dg.context.intType(64); |
| | 10806 | llvm_types_index += 1; |
| | 10807 | }, |
| | 10808 | .sse, .sseup => { |
| | 10809 | llvm_types_buffer[llvm_types_index] = it.dg.context.doubleType(); |
| | 10810 | llvm_types_index += 1; |
| | 10811 | }, |
| | 10812 | .float => { |
| | 10813 | llvm_types_buffer[llvm_types_index] = it.dg.context.floatType(); |
| | 10814 | llvm_types_index += 1; |
| | 10815 | }, |
| | 10816 | .float_combine => { |
| | 10817 | llvm_types_buffer[llvm_types_index] = it.dg.context.floatType().vectorType(2); |
| | 10818 | llvm_types_index += 1; |
| | 10819 | }, |
| | 10820 | .x87 => { |
| | 10821 | it.zig_index += 1; |
| | 10822 | it.llvm_index += 1; |
| | 10823 | it.byval_attr = true; |
| | 10824 | return .byref; |
| | 10825 | }, |
| | 10826 | .x87up => unreachable, |
| | 10827 | .complex_x87 => { |
| | 10828 | @panic("TODO"); |
| | 10829 | }, |
| | 10830 | .memory => unreachable, // handled above |
| | 10831 | .win_i128 => unreachable, // windows only |
| | 10832 | .none => break, |
| | 10833 | } |
| | 10834 | } |
| | 10835 | if (classes[0] == .integer and classes[1] == .none) { |
| | 10836 | it.zig_index += 1; |
| | 10837 | it.llvm_index += 1; |
| | 10838 | return .abi_sized_int; |
| | 10839 | } |
| | 10840 | it.llvm_types_buffer = llvm_types_buffer; |
| | 10841 | it.llvm_types_len = llvm_types_index; |
| | 10842 | it.llvm_index += llvm_types_index; |
| | 10843 | it.zig_index += 1; |
| | 10844 | return .multiple_llvm_types; |
| | 10845 | } |
| 10827 | }; | 10846 | }; |
| 10828 | | 10847 | |
| 10829 | fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTypeIterator { | 10848 | fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTypeIterator { |