| ... | @@ -487,6 +487,53 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { | ... | @@ -487,6 +487,53 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { |
| 487 | addLLVMFnAttr(llvm_fn, "noreturn"); | 487 | addLLVMFnAttr(llvm_fn, "noreturn"); |
| 488 | } | 488 | } |
| 489 | | 489 | |
| | 490 | if (!calling_convention_allows_zig_types(cc)) { |
| | 491 | // A simplistic and desperate attempt at making the compiler respect the |
| | 492 | // target ABI for return types. |
| | 493 | // This is just enough to avoid miscompiling the test suite, it will be |
| | 494 | // better in stage2. |
| | 495 | ZigType *int_type = return_type->id == ZigTypeIdInt ? return_type : |
| | 496 | return_type->id == ZigTypeIdEnum ? return_type->data.enumeration.tag_int_type : |
| | 497 | nullptr; |
| | 498 | |
| | 499 | if (int_type != nullptr) { |
| | 500 | const bool is_signed = int_type->data.integral.is_signed; |
| | 501 | const uint32_t bit_width = int_type->data.integral.bit_count; |
| | 502 | bool should_extend = false; |
| | 503 | |
| | 504 | // Rough equivalent of Clang's isPromotableIntegerType. |
| | 505 | switch (bit_width) { |
| | 506 | case 1: // bool |
| | 507 | case 8: // {un,}signed char |
| | 508 | case 16: // {un,}signed short |
| | 509 | should_extend = true; |
| | 510 | break; |
| | 511 | default: |
| | 512 | break; |
| | 513 | } |
| | 514 | |
| | 515 | switch (g->zig_target->arch) { |
| | 516 | case ZigLLVM_sparcv9: |
| | 517 | case ZigLLVM_riscv64: |
| | 518 | case ZigLLVM_ppc64: |
| | 519 | case ZigLLVM_ppc64le: |
| | 520 | // Always extend to the register width. |
| | 521 | should_extend = bit_width < 64; |
| | 522 | break; |
| | 523 | default: |
| | 524 | break; |
| | 525 | } |
| | 526 | |
| | 527 | // {zero,sign}-extend the result. |
| | 528 | if (should_extend) { |
| | 529 | if (is_signed) |
| | 530 | addLLVMAttr(llvm_fn, 0, "signext"); |
| | 531 | else |
| | 532 | addLLVMAttr(llvm_fn, 0, "zeroext"); |
| | 533 | } |
| | 534 | } |
| | 535 | } |
| | 536 | |
| 490 | if (fn->body_node != nullptr) { | 537 | if (fn->body_node != nullptr) { |
| 491 | maybe_export_dll(g, llvm_fn, linkage); | 538 | maybe_export_dll(g, llvm_fn, linkage); |
| 492 | | 539 | |