// File: /workspace/github_c_makefile_star2_O3/mbitsnbites[P]SoftFP/softfloat.c
// Function: roundAndPackFloat16
static float32 roundAndPackFloat16(flag zSign, int_fast16_t zExp,
                                   uint32_t zSig, flag ieee,
                                   float_status *status)
{
    int maxexp = ieee ? 29 : 30;
    uint32_t mask;
    uint32_t increment;
    bool rounding_bumps_exp;
    bool is_tiny = false;

    /* Calculate the mask of bits of the mantissa which are not
     * representable in half-precision and will be lost.
     */
    if (zExp < 1) {
        /* Will be denormal in halfprec */
        mask = 0x00ffffff;
        if (zExp >= -11) {
            mask >>= 11 + zExp;
        }
    } else {
        /* Normal number in halfprec */
        mask = 0x00001fff;
    }

    switch (status->float_rounding_mode) {
    case float_round_nearest_even:
        increment = (mask + 1) >> 1;
        if ((zSig & mask) == increment) {
            increment = zSig & (increment << 1);
        }
        break;
    case float_round_ties_away:
        increment = (mask + 1) >> 1;
        break;
    case float_round_up:
        increment = zSign ? 0 : mask;
        break;
    case float_round_down:
        increment = zSign ? mask : 0;
        break;
    default: /* round_to_zero */
        increment = 0;
        break;
    }

    rounding_bumps_exp = (zSig + increment >= 0x01000000);

    if (zExp > maxexp || (zExp == maxexp && rounding_bumps_exp)) {
        if (ieee) {
            float_raise(float_flag_overflow | float_flag_inexact, status);
            return packFloat16(zSign, 0x1f, 0);
        } else {
            float_raise(float_flag_invalid, status);
            return packFloat16(zSign, 0x1f, 0x3ff);
        }
    }

    if (zExp < 0) {
        /* Note that flush-to-zero does not affect half-precision results */
        is_tiny =
            (status->float_detect_tininess == float_tininess_before_rounding)
            || (zExp < -1)
            || (!rounding_bumps_exp);
    }
    if (zSig & mask) {
        float_raise(float_flag_inexact, status);
        if (is_tiny) {
            float_raise(float_flag_underflow, status);
        }
    }

    zSig += increment;
    if (rounding_bumps_exp) {
        zSig >>= 1;
        zExp++;
    }

    if (zExp < -10) {
        return packFloat16(zSign, 0, 0);
    }
    if (zExp < 0) {
        zSig >>= -zExp;
        zExp = 0;
    }
    return packFloat16(zSign, zExp, zSig >> 13);
}

// Assembly:
movl %ecx, %eax
movl $0x1fff, %r10d          # imm = 0x1FFF
testq %rsi, %rsi
jg 0xd48b
movl $0xffffff, %r10d        # imm = 0xFFFFFF
cmpq $-0xb, %rsi
jl 0xd48b
leal 0xb(%rsi), %ecx
movl $0xffffff, %r10d        # imm = 0xFFFFFF
shrl %cl, %r10d
movzbl 0x1(%r8), %ecx
xorl %r9d, %r9d
cmpq $0x4, %rcx
ja 0xd4e7
leaq 0x936c(%rip), %r11      # 0x1680c
movslq (%r11,%rcx,4), %rcx
addq %r11, %rcx
jmpq *%rcx
leal 0x1(%r10), %ecx
movl %ecx, %r9d
shrl %r9d
movl %r10d, %r11d
andl %edx, %r11d
cmpl %r9d, %r11d
jne 0xd4e7
andl %edx, %ecx
andl $-0x2, %ecx
movl %ecx, %r9d
jmp 0xd4e7
xorl %r9d, %r9d
testb %dil, %dil
cmovel %r10d, %r9d
jmp 0xd4e7
xorl %r9d, %r9d
testb %dil, %dil
cmovnel %r10d, %r9d
jmp 0xd4e7
leal 0x1(%r10), %r9d
shrl %r9d
addl %edx, %r9d
cmpl $0x1000000, %r9d        # imm = 0x1000000
setb %cl
xorl %r11d, %r11d
cmpb $0x1, %al
adcq $0x1d, %r11
cmpq %rsi, %r11
setne %r11b
jl 0xd51c
orb %cl, %r11b
je 0xd51c
testq %rsi, %rsi
js 0xd54c
testl %edx, %r10d
je 0xd57b
orb $0x20, 0x2(%r8)
jmp 0xd57b
movzbl %dil, %ecx
shll $0xf, %ecx
movb 0x2(%r8), %dl
testb %al, %al
je 0xd53d
orb $0x28, %dl
movb %dl, 0x2(%r8)
orl $0x7c00, %ecx           # imm = 0x7C00
jmp 0xd5cb
orb $0x1, %dl
movb %dl, 0x2(%r8)
orl $0x7fff, %ecx           # imm = 0x7FFF
jmp 0xd5cb
testl %edx, %r10d
je 0xd57b
movb (%r8), %cl
movb 0x2(%r8), %al
movl %eax, %edx
orb $0x20, %dl
movb %dl, 0x2(%r8)
cmpq $-0x1, %rsi
jne 0xd575
cmpb $0x1, %cl
je 0xd575
cmpl $0xffffff, %r9d         # imm = 0xFFFFFF
ja 0xd57b
orb $0x30, %al
movb %al, 0x2(%r8)
xorl %ecx, %ecx
cmpl $0x1000000, %r9d        # imm = 0x1000000
setae %cl
movq %rcx, %rax
addq %rsi, %rax
cmpq $-0xb, %rax
jg 0xd59c
movzbl %dil, %ecx
shll $0xf, %ecx
jmp 0xd5cb
shrl %cl, %r9d
movl %eax, %edx
negb %dl
movq %rax, %rcx
sarq $0x3f, %rcx
andb %dl, %cl
shrl %cl, %r9d
xorl %ecx, %ecx
testq %rax, %rax
cmovgq %rax, %rcx
shrl $0xd, %r9d
movzbl %dil, %eax
shll $0xf, %eax
shll $0xa, %ecx
addl %eax, %ecx
addl %r9d, %ecx
movzwl %cx, %eax
retq