// File: /workspace/github_c_makefile_star2_O2/mbitsnbites[P]SoftFP/softfloat.c
// Function: float32_muladd
float32 float32_muladd(float32 a, float32 b, float32 c, int flags,
                       float_status *status)
{
    flag aSign, bSign, cSign, zSign;
    int_fast16_t aExp, bExp, cExp, pExp, zExp, expDiff;
    uint32_t aSig, bSig, cSig;
    flag pInf, pZero, pSign;
    uint64_t pSig64, cSig64, zSig64;
    uint32_t pSig;
    int shiftcount;
    flag signflip, infzero;

    a = float32_squash_input_denormal(a, status);
    b = float32_squash_input_denormal(b, status);
    c = float32_squash_input_denormal(c, status);
    aSig = extractFloat32Frac(a);
    aExp = extractFloat32Exp(a);
    aSign = extractFloat32Sign(a);
    bSig = extractFloat32Frac(b);
    bExp = extractFloat32Exp(b);
    bSign = extractFloat32Sign(b);
    cSig = extractFloat32Frac(c);
    cExp = extractFloat32Exp(c);
    cSign = extractFloat32Sign(c);

    infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) ||
               (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 0));

    /* It is implementation-defined whether the cases of (0,inf,qnan)
     * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
     * they return if they do), so we have to hand this information
     * off to the target-specific pick-a-NaN routine.
     */
    if (((aExp == 0xff) && aSig) ||
        ((bExp == 0xff) && bSig) ||
        ((cExp == 0xff) && cSig)) {
        return propagateFloat32MulAddNaN(a, b, c, infzero, status);
    }

    if (infzero) {
        float_raise(float_flag_invalid, status);
        return float32_default_nan;
    }

    if (flags & float_muladd_negate_c) {
        cSign ^= 1;
    }

    signflip = (flags & float_muladd_negate_result) ? 1 : 0;

    /* Work out the sign and type of the product */
    pSign = aSign ^ bSign;
    if (flags & float_muladd_negate_product) {
        pSign ^= 1;
    }
    pInf = (aExp == 0xff) || (bExp == 0xff);
    pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);

    if (cExp == 0xff) {
        if (pInf && (pSign ^ cSign)) {
            /* addition of opposite-signed infinities => InvalidOperation */
            float_raise(float_flag_invalid, status);
            return float32_default_nan;
        }
        /* Otherwise generate an infinity of the same sign */
        return packFloat32(cSign ^ signflip, 0xff, 0);
    }

    if (pInf) {
        return packFloat32(pSign ^ signflip, 0xff, 0);
    }

    if (pZero) {
        if (cExp == 0) {
            if (cSig == 0) {
                /* Adding two exact zeroes */
                if (pSign == cSign) {
                    zSign = pSign;
                } else if (status->float_rounding_mode == float_round_down) {
                    zSign = 1;
                } else {
                    zSign = 0;
                }
                return packFloat32(zSign ^ signflip, 0, 0);
            }
            /* Exact zero plus a denorm */
            if (status->flush_to_zero) {
                float_raise(float_flag_output_denormal, status);
                return packFloat32(cSign ^ signflip, 0, 0);
            }
        }
        /* Zero plus something non-zero : just return the something */
        if (flags & float_muladd_halve_result) {
            if (cExp == 0) {
                normalizeFloat32Subnormal(cSig, &cExp, &cSig);
            }
            /* Subtract one to halve, and one again because roundAndPackFloat32
             * wants one less than the true exponent.
             */
            cExp -= 2;
            cSig = (cSig | 0x00800000) << 7;
            return roundAndPackFloat32(cSign ^ signflip, cExp, cSig, status);
        }
        return packFloat32(cSign ^ signflip, cExp, cSig);
    }

    if (aExp == 0) {
        normalizeFloat32Subnormal(aSig, &aExp, &aSig);
    }
    if (bExp == 0) {
        normalizeFloat32Subnormal(bSig, &bExp, &bSig);
    }

    /* Calculate the actual result a * b + c */

    /* Multiply first; this is easy. */
    /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f
     * because we want the true exponent, not the "one-less-than"
     * flavour that roundAndPackFloat32() takes.
     */
    pExp = aExp + bExp - 0x7e;
    aSig = (aSig | 0x00800000) << 7;
    bSig = (bSig | 0x00800000) << 8;
    pSig64 = (uint64_t)aSig * bSig;
    if ((int64_t)(pSig64 << 1) >= 0) {
        pSig64 <<= 1;
        pExp--;
    }

    zSign = pSign ^ signflip;

    /* Now pSig64 is the significand of the multiply, with the explicit bit in
     * position 62.
     */
    if (cExp == 0) {
        if (!cSig) {
            /* Throw out the special case of c being an exact zero now */
            shift64RightJamming(pSig64, 32, &pSig64);
            pSig = pSig64;
            if (flags & float_muladd_halve_result) {
                pExp--;
            }
            return roundAndPackFloat32(zSign, pExp - 1,
                                       pSig, status);
        }
        normalizeFloat32Subnormal(cSig, &cExp, &cSig);
    }

    cSig64 = (uint64_t)cSig << (62 - 23);
    cSig64 |= LIT64(0x4000000000000000);
    expDiff = pExp - cExp;

    if (pSign == cSign) {
        /* Addition */
        if (expDiff > 0) {
            /* scale c to match p */
            shift64RightJamming(cSig64, expDiff, &cSig64);
            zExp = pExp;
        } else if (expDiff < 0) {
            /* scale p to match c */
            shift64RightJamming(pSig64, -expDiff, &pSig64);
            zExp = cExp;
        } else {
            /* no scaling needed */
            zExp = cExp;
        }
        /* Add significands and make sure explicit bit ends up in posn 62 */
        zSig64 = pSig64 + cSig64;
        if ((int64_t)zSig64 < 0) {
            shift64RightJamming(zSig64, 1, &zSig64);
        } else {
            zExp--;
        }
    } else {
        /* Subtraction */
        if (expDiff > 0) {
            shift64RightJamming(cSig64, expDiff, &cSig64);
            zSig64 = pSig64 - cSig64;
            zExp = pExp;
        } else if (expDiff < 0) {
            shift64RightJamming(pSig64, -expDiff, &pSig64);
            zSig64 = cSig64 - pSig64;
            zExp = cExp;
            zSign ^= 1;
        } else {
            zExp = pExp;
            if (cSig64 < pSig64) {
                zSig64 = pSig64 - cSig64;
            } else if (pSig64 < cSig64) {
                zSig64 = cSig64 - pSig64;
                zSign ^= 1;
            } else {
                /* Exact zero */
                zSign = signflip;
                if (status->float_rounding_mode == float_round_down) {
                    zSign ^= 1;
                }
                return packFloat32(zSign, 0, 0);
            }
        }
        --zExp;
        /* Normalize to put the explicit bit back into bit 62. */
        shiftcount = countLeadingZeros64(zSig64) - 1;
        zSig64 <<= shiftcount;
        zExp -= shiftcount;
    }
    if (flags & float_muladd_halve_result) {
        zExp--;
    }

    shift64RightJamming(zSig64, 32, &zSig64);
    return roundAndPackFloat32(zSign, zExp, zSig64, status);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, %rbx
movl %ecx, 0xc(%rsp)
movl %edx, %ebp
movl %esi, %r14d
movq %r8, %rsi
callq 0x91e7
movl %eax, %r15d
movl %r14d, %edi
movq %rbx, %rsi
callq 0x91e7
movl %eax, %r13d
movl %ebp, %edi
movq %rbx, 0x10(%rsp)
movq %rbx, %rsi
callq 0x91e7
movl $0x7fffff, %r14d        # imm = 0x7FFFFF
movl %r15d, %esi
andl %r14d, %esi
movl %r15d, %edi
shrl $0x17, %edi
movl $0xff, %edx
andl %edx, %edi
movl %r13d, %r12d
andl %r14d, %r12d
movl %r13d, %ebx
shrl $0x17, %ebx
andl %edx, %ebx
movl %edi, %ecx
orl %esi, %ecx
cmpl %edx, %ebx
jne 0xaef6
movl %ecx, %r8d
orl %r12d, %r8d
jne 0xaef6
xorl %r9d, %r9d
movb $0x1, %r8b
jmp 0xaf32
cmpq $0xff, %rbx
sete %r10b
cmpl $0xff, %edi
sete %r9b
movl %r12d, %r8d
orl %esi, %r8d
orl %ebx, %r8d
sete %r8b
testl %esi, %esi
setne %bpl
testl %r12d, %r12d
setne %r11b
testb %r9b, %bpl
jne 0xaf55
andb %r10b, %r11b
jne 0xaf55
andb %r9b, %r8b
andl %eax, %r14d
movl %eax, %ebp
shrl $0x17, %ebp
andl %edx, %ebp
cmpl $0xff, %ebp
setne %dl
testl %r14d, %r14d
sete %r10b
orb %dl, %r10b
jne 0xb03e
movl $0x7fc00000, %edx       # imm = 0x7FC00000
movl %r15d, %ecx
andl %edx, %ecx
movl $0x7f800000, %r9d       # imm = 0x7F800000
cmpl %r9d, %ecx
sete %sil
testl $0x3fffff, %r15d        # imm = 0x3FFFFF
setne %dil
andb %sil, %dil
movl %r13d, %esi
andl %edx, %esi
cmpl %r9d, %esi
sete %r10b
testl $0x3fffff, %r13d        # imm = 0x3FFFFF
setne %r8b
andb %r10b, %r8b
andl %eax, %edx
cmpl %r9d, %edx
sete %r9b
testl $0x3fffff, %eax         # imm = 0x3FFFFF
setne %r10b
testb %dil, %dil
movq 0x10(%rsp), %r11
jne 0xafba
testb %r8b, %r8b
jne 0xafba
andb %r10b, %r9b
je 0xafbf
orb $0x1, 0x2(%r11)
movl $0x7fc00000, %ebp       # imm = 0x7FC00000
cmpb $0x0, 0x6(%r11)
jne 0xb10d
leal (%r15,%r15), %r9d
leal (,%r13,2), %r10d
movl $0xff800000, %r11d      # imm = 0xFF800000
cmpl %r11d, %r10d
setae %r10b
orb %r8b, %r10b
movzbl %r10b, %r10d
pushq $0x2
popq %r8
subl %r10d, %r8d
xorl %r10d, %r10d
testb %dil, %dil
cmovnel %r10d, %r8d
cmpl %r11d, %r9d
cmovael %r10d, %r8d
cmpl $0x2, %r8d
je 0xb0bd
cmpl $0x1, %r8d
jne 0xb0d8
movl %r13d, %ebp
orl $0x400000, %ebp         # imm = 0x400000
testl $0x3fffff, %r13d        # imm = 0x3FFFFF
cmovel %r13d, %ebp
cmpl $0x7f800000, %esi       # imm = 0x7F800000
cmovnel %r13d, %ebp
jmp 0xb10d
testb %r8b, %r8b
je 0xb056
movq 0x10(%rsp), %rax
orb $0x1, 0x2(%rax)
movl $0x7fc00000, %ebp       # imm = 0x7FC00000
jmp 0xb10d
shrl $0x1f, %eax
cmpq $0xff, %rbx
sete %r10b
movl 0xc(%rsp), %r11d
movl %r11d, %edx
andb $0x1, %dl
xorb %al, %dl
movl %r11d, %eax
shrb $0x2, %al
andb $0x1, %al
xorl %r15d, %r13d
shrl $0x1f, %r13d
movl %r11d, %r8d
shrb %r8b
andb $0x1, %r8b
xorb %r13b, %r8b
orb %r9b, %r10b
testl %ecx, %ecx
sete %cl
movl %ebx, %r9d
orl %r12d, %r9d
sete %r9b
cmpl $0xff, %ebp
jne 0xb0f8
cmpb %dl, %r8b
setne %cl
andb %cl, %r10b
cmpb $0x1, %r10b
je 0xb043
xorb %al, %dl
movzbl %dl, %ebp
jmp 0xb104
movl %eax, %ebp
orl $0x400000, %ebp         # imm = 0x400000
testl $0x3fffff, %eax         # imm = 0x3FFFFF
cmovel %eax, %ebp
cmpl $0x7f800000, %edx       # imm = 0x7F800000
cmovnel %eax, %ebp
jmp 0xb10d
movl %r15d, %ebp
orl $0x400000, %ebp         # imm = 0x400000
testl $0x3fffff, %r15d        # imm = 0x3FFFFF
cmovel %r15d, %ebp
cmpl $0x7f800000, %ecx       # imm = 0x7F800000
cmovnel %r15d, %ebp
jmp 0xb10d
testb %r10b, %r10b
je 0xb11e
xorb %al, %r8b
movzbl %r8b, %ebp
shll $0x1f, %ebp
orl $0x7f800000, %ebp       # imm = 0x7F800000
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
orb %r9b, %cl
pushq $0x9
popq %r9
je 0xb14d
testq %rbp, %rbp
je 0xb15e
testb $0x8, %r11b
movq 0x10(%rsp), %r10
jne 0xb364
xorb %al, %dl
movzbl %dl, %eax
shll $0x1f, %eax
shll $0x17, %ebp
orl %eax, %ebp
orl %r14d, %ebp
jmp 0xb10d
testq %rdi, %rdi
jne 0xb18a
testl %esi, %esi
je 0xb17a
bsrl %esi, %edi
xorl $0x1f, %edi
jmp 0xb17d
testl %r14d, %r14d
movq 0x10(%rsp), %r10
je 0xb19e
cmpb $0x0, 0x4(%r10)
je 0xb347
orb $-0x80, 0x2(%r10)
jmp 0xb1ab
pushq $0x20
popq %rdi
leal -0x8(%rdi), %ecx
shll %cl, %esi
movl %r9d, %ecx
subl %edi, %ecx
movslq %ecx, %rdi
testq %rbx, %rbx
jne 0xb1cc
testl %r12d, %r12d
je 0xb1b8
bsrl %r12d, %r10d
xorl $0x1f, %r10d
jmp 0xb1bc
cmpb %dl, %r8b
je 0xb1ab
cmpb $0x1, 0x1(%r10)
sete %dl
xorb %al, %dl
movzbl %dl, %ebp
shll $0x1f, %ebp
jmp 0xb10d
pushq $0x20
popq %r10
leal -0x8(%r10), %ecx
shll %cl, %r12d
movl %r9d, %ecx
subl %r10d, %ecx
movslq %ecx, %rbx
shll $0x7, %esi
orl $0x40000000, %esi       # imm = 0x40000000
shll $0x8, %r12d
orl $0x80000000, %r12d      # imm = 0x80000000
imulq %rsi, %r12
movq %r12, 0x18(%rsp)
movq %r12, %rcx
addq %r12, %rcx
js 0xb202
addq %rdi, %rbx
movq %rcx, 0x18(%rsp)
addq $-0x7f, %rbx
movq %rcx, %r12
jmp 0xb209
addq %rdi, %rbx
addq $-0x7e, %rbx
movl %r8d, %r13d
xorb %al, %r13b
testq %rbp, %rbp
jne 0xb230
testl %r14d, %r14d
je 0xb322
bsrl %r14d, %esi
xorl $0x1f, %esi
leal -0x8(%rsi), %ecx
shll %cl, %r14d
subl %esi, %r9d
movslq %r9d, %rbp
orq $0x800000, %r14         # imm = 0x800000
shlq $0x27, %r14
movq %r14, 0x20(%rsp)
movq %rbx, %rsi
subq %rbp, %rsi
cmpb %dl, %r8b
jne 0xb26a
testq %rsi, %rsi
jle 0xb299
leaq 0x20(%rsp), %r15
movq %r14, %rdi
movq %r15, %rdx
callq 0x93e7
movl 0xc(%rsp), %r11d
movq (%r15), %r14
jmp 0xb2b9
testq %rsi, %rsi
jle 0xb2c3
leaq 0x20(%rsp), %r15
movq %r14, %rdi
movq %r15, %rdx
callq 0x93e7
movl 0xc(%rsp), %r11d
subq (%r15), %r12
movq %r12, %rdx
testq %rdx, %rdx
je 0xb2e9
bsrq %rdx, %rax
xorq $0x3f, %rax
jmp 0xb2ec
jns 0xb2b6
negq %rsi
leaq 0x18(%rsp), %r15
movq %r12, %rdi
movq %r15, %rdx
callq 0x93e7
movl 0xc(%rsp), %r11d
movq (%r15), %r12
movq %rbp, %rbx
addq %r12, %r14
js 0xb2da
decq %rbx
jmp 0xb2f8
js 0xb394
movq %r14, %rdx
subq %r12, %rdx
jae 0xb3be
subq %r14, %r12
jmp 0xb287
movq %r14, %rax
shrq %rax
andl $0x1, %r14d
orq %rax, %r14
jmp 0xb2f8
pushq $0x40
popq %rax
leal -0x1(%rax), %ecx
shlq %cl, %rdx
subq %rax, %rbx
movq %rdx, %r14
shll $0x1c, %r11d
sarl $0x1f, %r11d
movslq %r11d, %rsi
addq %rbx, %rsi
movq %r14, %rax
shrq $0x20, %rax
xorl %edx, %edx
testl %r14d, %r14d
setne %dl
orl %eax, %edx
movzbl %r13b, %edi
movq 0x10(%rsp), %rcx
jmp 0xb381
movq %r12, %rax
shrq $0x20, %rax
xorl %edx, %edx
testl %r12d, %r12d
setne %dl
orl %eax, %edx
shll $0x1c, %r11d
sarl $0x1f, %r11d
movslq %r11d, %rax
leaq (%rax,%rbx), %rsi
decq %rsi
jmp 0xb317
testb $0x8, %r11b
je 0xb13b
bsrl %r14d, %esi
xorl $0x1f, %esi
leal -0x8(%rsi), %ecx
shll %cl, %r14d
subl %esi, %r9d
movslq %r9d, %rbp
addq $-0x2, %rbp
shll $0x7, %r14d
orl $0x40000000, %r14d      # imm = 0x40000000
xorb %al, %dl
movzbl %dl, %edi
movq %rbp, %rsi
movl %r14d, %edx
movq %r10, %rcx
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9421
negq %rsi
leaq 0x18(%rsp), %r15
movq %r12, %rdi
movq %r15, %rdx
callq 0x93e7
movl 0xc(%rsp), %r11d
subq (%r15), %r14
xorb $0x1, %r13b
movq %r14, %rdx
movq %rbp, %rbx
jmp 0xb28a
jbe 0xb3c9
xorb $0x1, %r13b
jmp 0xb28a
movq 0x10(%rsp), %rcx
cmpb $0x1, 0x1(%rcx)
sete %cl
xorb %cl, %al
movzbl %al, %ebp
jmp 0xb1b0