// File: /workspace/github_c_makefile_star2_O0/mbitsnbites[P]SoftFP/./softfp_template.h
// Function: fma_sf32
F_UINT fma_sf(F_UINT a, F_UINT b, F_UINT c, RoundingModeEnum rm,
              uint32_t *pfflags)
{
    uint32_t a_sign, b_sign, c_sign, r_sign;
    int32_t a_exp, b_exp, c_exp, r_exp, shift;
    F_UINT a_mant, b_mant, c_mant, r_mant1, r_mant0, c_mant1, c_mant0, mask;

    a_sign = a >> (F_SIZE - 1);
    b_sign = b >> (F_SIZE - 1);
    c_sign = c >> (F_SIZE - 1);
    r_sign = a_sign ^ b_sign;
    a_exp = (a >> MANT_SIZE) & EXP_MASK;
    b_exp = (b >> MANT_SIZE) & EXP_MASK;
    c_exp = (c >> MANT_SIZE) & EXP_MASK;
    a_mant = a & MANT_MASK;
    b_mant = b & MANT_MASK;
    c_mant = c & MANT_MASK;
    if (a_exp == EXP_MASK || b_exp == EXP_MASK || c_exp == EXP_MASK) {
        if (isnan_sf(a) || isnan_sf(b) || isnan_sf(c)) {
            if (issignan_sf(a) || issignan_sf(b) || issignan_sf(c)) {
                *pfflags |= FFLAG_INVALID_OP;
            }
            return F_QNAN;
        } else {
            /* infinities */
            if ((a_exp == EXP_MASK && (b_exp == 0 && b_mant == 0)) ||
                (b_exp == EXP_MASK && (a_exp == 0 && a_mant == 0)) ||
                ((a_exp == EXP_MASK || b_exp == EXP_MASK) &&
                 (c_exp == EXP_MASK && r_sign != c_sign))) {
                *pfflags |= FFLAG_INVALID_OP;
                return F_QNAN;
            } else if (c_exp == EXP_MASK) {
                return pack_sf(c_sign, EXP_MASK, 0);
            } else {
                return pack_sf(r_sign, EXP_MASK, 0);
            }
        }
    }
    if (a_exp == 0) {
        if (a_mant == 0)
            goto mul_zero;
        a_mant = normalize_subnormal_sf(&a_exp, a_mant);
    } else {
        a_mant |= (F_UINT)1 << MANT_SIZE;
    }
    if (b_exp == 0) {
        if (b_mant == 0) {
        mul_zero:
            if (c_exp == 0 && c_mant == 0) {
                if (c_sign != r_sign)
                    r_sign = (rm == RM_RDN);
                return pack_sf(r_sign, 0, 0);
            } else {
                return c;
            }
        }
        b_mant = normalize_subnormal_sf(&b_exp, b_mant);
    } else {
        b_mant |= (F_UINT)1 << MANT_SIZE;
    }
    /* multiply */
    r_exp = a_exp + b_exp - (1 << (EXP_SIZE - 1)) + 3;
    
    r_mant1 = mul_u(&r_mant0, a_mant << RND_SIZE, b_mant << RND_SIZE);
    /* normalize to F_SIZE - 3 */
    if (r_mant1 < ((F_UINT)1 << (F_SIZE - 3))) {
        r_mant1 = (r_mant1 << 1) | (r_mant0 >> (F_SIZE - 1));
        r_mant0 <<= 1;
        r_exp--;
    }

    /* add */
    if (c_exp == 0) {
        if (c_mant == 0) {
            /* add zero */
            r_mant1 |= (r_mant0 != 0);
            return normalize_sf(r_sign, r_exp, r_mant1, rm, pfflags);
        }
        c_mant = normalize_subnormal_sf(&c_exp, c_mant);
    } else {
        c_mant |= (F_UINT)1 << MANT_SIZE;
    }
    c_exp++;
    c_mant1 = c_mant << (RND_SIZE - 1);
    c_mant0 = 0;

    //    printf("r_s=%d r_exp=%d r_mant=%08x %08x\n", r_sign, r_exp, (uint32_t)r_mant1, (uint32_t)r_mant0);
    //    printf("c_s=%d c_exp=%d c_mant=%08x %08x\n", c_sign, c_exp, (uint32_t)c_mant1, (uint32_t)c_mant0);

    /* ensure that abs(r) >= abs(c) */
    if (!(r_exp > c_exp || (r_exp == c_exp && r_mant1 >= c_mant1))) {
        F_UINT tmp;
        int32_t c_tmp;
        /* swap */
        tmp = r_mant1; r_mant1 = c_mant1; c_mant1 = tmp;
        tmp = r_mant0; r_mant0 = c_mant0; c_mant0 = tmp;
        c_tmp = r_exp; r_exp = c_exp; c_exp = c_tmp;
        c_tmp = r_sign; r_sign = c_sign; c_sign = c_tmp;
    }
    /* right shift c_mant */
    shift = r_exp - c_exp;
    if (shift >= 2 * F_SIZE) {
        c_mant0 = (c_mant0 | c_mant1) != 0;
        c_mant1 = 0;
    } else if (shift >= F_SIZE + 1) {
        c_mant0 = rshift_rnd(c_mant1, shift - F_SIZE);
        c_mant1 = 0;
    } else if (shift == F_SIZE) {
        c_mant0 = c_mant1 | (c_mant0 != 0);
        c_mant1 = 0;
    } else if (shift != 0) {
        mask = ((F_UINT)1 << shift) - 1;
        c_mant0 = (c_mant1 << (F_SIZE - shift)) | (c_mant0 >> shift) | ((c_mant0 & mask) != 0);
        c_mant1 = c_mant1 >> shift;
    }
    //    printf("  r_mant=%08x %08x\n", (uint32_t)r_mant1, (uint32_t)r_mant0);
    //    printf("  c_mant=%08x %08x\n", (uint32_t)c_mant1, (uint32_t)c_mant0);
    /* add or subtract */
    if (r_sign == c_sign) {
        r_mant0 += c_mant0;
        r_mant1 += c_mant1 + (r_mant0 < c_mant0);
    } else {
        F_UINT tmp;
        tmp = r_mant0;
        r_mant0 -= c_mant0;
        r_mant1 = r_mant1 - c_mant1 - (r_mant0 > tmp);
        if ((r_mant0 | r_mant1) == 0) {
            /* zero result : the sign needs a specific handling */
            r_sign = (rm == RM_RDN);
        }
    }
#if 0
    //    printf("  r1_mant=%08x %08x\n", (uint32_t)r_mant1, (uint32_t)r_mant0);
    /* normalize */
    if (r_mant1 == 0) {
        r_mant1 = r_mant0;
        r_exp -= F_SIZE;
    } else {
        shift = clz(r_mant1) - (F_SIZE - 1 - IMANT_SIZE);
        if (shift != 0) {
            r_mant1 = (r_mant1 << shift) | (r_mant0 >> (F_SIZE - shift));
            r_mant0 <<= shift;
            r_exp -= shift;
        }
        r_mant1 |= (r_mant0 != 0);
    }
    return normalize_sf(r_sign, r_exp, r_mant1, rm, pfflags);
#else
    return normalize2_sf(r_sign, r_exp, r_mant1, r_mant0, rm, pfflags);
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movl %edi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl %ecx, -0x14(%rbp)
movq %r8, -0x20(%rbp)
movl -0x8(%rbp), %eax
shrl $0x1f, %eax
movl %eax, -0x24(%rbp)
movl -0xc(%rbp), %eax
shrl $0x1f, %eax
movl %eax, -0x28(%rbp)
movl -0x10(%rbp), %eax
shrl $0x1f, %eax
movl %eax, -0x2c(%rbp)
movl -0x24(%rbp), %eax
xorl -0x28(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x8(%rbp), %eax
shrl $0x17, %eax
andl $0xff, %eax
movl %eax, -0x34(%rbp)
movl -0xc(%rbp), %eax
shrl $0x17, %eax
andl $0xff, %eax
movl %eax, -0x38(%rbp)
movl -0x10(%rbp), %eax
shrl $0x17, %eax
andl $0xff, %eax
movl %eax, -0x3c(%rbp)
movl -0x8(%rbp), %eax
andl $0x7fffff, %eax         # imm = 0x7FFFFF
movl %eax, -0x48(%rbp)
movl -0xc(%rbp), %eax
andl $0x7fffff, %eax         # imm = 0x7FFFFF
movl %eax, -0x4c(%rbp)
movl -0x10(%rbp), %eax
andl $0x7fffff, %eax         # imm = 0x7FFFFF
movl %eax, -0x50(%rbp)
cmpl $0xff, -0x34(%rbp)
je 0x72c6
cmpl $0xff, -0x38(%rbp)
je 0x72c6
cmpl $0xff, -0x3c(%rbp)
jne 0x73c6
movl -0x8(%rbp), %edi
callq 0x6c50
cmpl $0x0, %eax
jne 0x72ed
movl -0xc(%rbp), %edi
callq 0x6c50
cmpl $0x0, %eax
jne 0x72ed
movl -0x10(%rbp), %edi
callq 0x6c50
cmpl $0x0, %eax
je 0x732b
movl -0x8(%rbp), %edi
callq 0x6c00
cmpl $0x0, %eax
jne 0x7314
movl -0xc(%rbp), %edi
callq 0x6c00
cmpl $0x0, %eax
jne 0x7314
movl -0x10(%rbp), %edi
callq 0x6c00
cmpl $0x0, %eax
je 0x731f
movq -0x20(%rbp), %rax
movl (%rax), %ecx
orl $0x10, %ecx
movl %ecx, (%rax)
movl $0x7fc00000, -0x4(%rbp) # imm = 0x7FC00000
jmp 0x76d9
cmpl $0xff, -0x34(%rbp)
jne 0x7340
cmpl $0x0, -0x38(%rbp)
jne 0x7340
cmpl $0x0, -0x4c(%rbp)
je 0x7378
cmpl $0xff, -0x38(%rbp)
jne 0x7355
cmpl $0x0, -0x34(%rbp)
jne 0x7355
cmpl $0x0, -0x48(%rbp)
je 0x7378
cmpl $0xff, -0x34(%rbp)
je 0x7367
cmpl $0xff, -0x38(%rbp)
jne 0x738f
cmpl $0xff, -0x3c(%rbp)
jne 0x738f
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
je 0x738f
movq -0x20(%rbp), %rax
movl (%rax), %ecx
orl $0x10, %ecx
movl %ecx, (%rax)
movl $0x7fc00000, -0x4(%rbp) # imm = 0x7FC00000
jmp 0x76d9
cmpl $0xff, -0x3c(%rbp)
jne 0x73af
movl -0x2c(%rbp), %edi
movl $0xff, %esi
xorl %edx, %edx
callq 0x7160
movl %eax, -0x4(%rbp)
jmp 0x76d9
movl -0x30(%rbp), %edi
movl $0xff, %esi
xorl %edx, %edx
callq 0x7160
movl %eax, -0x4(%rbp)
jmp 0x76d9
cmpl $0x0, -0x34(%rbp)
jne 0x73e5
cmpl $0x0, -0x48(%rbp)
jne 0x73d4
jmp 0x73fe
movl -0x48(%rbp), %esi
leaq -0x34(%rbp), %rdi
callq 0x7190
movl %eax, -0x48(%rbp)
jmp 0x73f0
movl -0x48(%rbp), %eax
orl $0x800000, %eax         # imm = 0x800000
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x38(%rbp)
jne 0x7451
cmpl $0x0, -0x4c(%rbp)
jne 0x7440
jmp 0x73fe
cmpl $0x0, -0x3c(%rbp)
jne 0x7435
cmpl $0x0, -0x50(%rbp)
jne 0x7435
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
je 0x7421
cmpl $0x2, -0x14(%rbp)
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %edi
xorl %edx, %edx
movl %edx, %esi
callq 0x7160
movl %eax, -0x4(%rbp)
jmp 0x76d9
movl -0x10(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x76d9
movl -0x4c(%rbp), %esi
leaq -0x38(%rbp), %rdi
callq 0x7190
movl %eax, -0x4c(%rbp)
jmp 0x745c
movl -0x4c(%rbp), %eax
orl $0x800000, %eax         # imm = 0x800000
movl %eax, -0x4c(%rbp)
movl -0x34(%rbp), %eax
addl -0x38(%rbp), %eax
subl $0x80, %eax
addl $0x3, %eax
movl %eax, -0x40(%rbp)
movl -0x48(%rbp), %esi
shll $0x7, %esi
movl -0x4c(%rbp), %edx
shll $0x7, %edx
leaq -0x58(%rbp), %rdi
callq 0x71e0
movl %eax, -0x54(%rbp)
cmpl $0x20000000, -0x54(%rbp) # imm = 0x20000000
jae 0x74af
movl -0x54(%rbp), %eax
shll %eax
movl -0x58(%rbp), %ecx
shrl $0x1f, %ecx
orl %ecx, %eax
movl %eax, -0x54(%rbp)
movl -0x58(%rbp), %eax
shll %eax
movl %eax, -0x58(%rbp)
movl -0x40(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x40(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x74fb
cmpl $0x0, -0x50(%rbp)
jne 0x74ea
cmpl $0x0, -0x58(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %eax
orl -0x54(%rbp), %eax
movl %eax, -0x54(%rbp)
movl -0x30(%rbp), %edi
movl -0x40(%rbp), %esi
movl -0x54(%rbp), %edx
movl -0x14(%rbp), %ecx
movq -0x20(%rbp), %r8
callq 0x6eb0
movl %eax, -0x4(%rbp)
jmp 0x76d9
movl -0x50(%rbp), %esi
leaq -0x3c(%rbp), %rdi
callq 0x7190
movl %eax, -0x50(%rbp)
jmp 0x7506
movl -0x50(%rbp), %eax
orl $0x800000, %eax         # imm = 0x800000
movl %eax, -0x50(%rbp)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
movl -0x50(%rbp), %eax
shll $0x6, %eax
movl %eax, -0x5c(%rbp)
movl $0x0, -0x60(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jg 0x757f
movl -0x40(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jne 0x7537
movl -0x54(%rbp), %eax
cmpl -0x5c(%rbp), %eax
jae 0x757f
movl -0x54(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x54(%rbp)
movl -0x68(%rbp), %eax
movl %eax, -0x5c(%rbp)
movl -0x58(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0x60(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x68(%rbp), %eax
movl %eax, -0x60(%rbp)
movl -0x40(%rbp), %eax
movl %eax, -0x6c(%rbp)
movl -0x3c(%rbp), %eax
movl %eax, -0x40(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl -0x30(%rbp), %eax
movl %eax, -0x6c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x2c(%rbp)
movl -0x40(%rbp), %eax
subl -0x3c(%rbp), %eax
movl %eax, -0x44(%rbp)
cmpl $0x40, -0x44(%rbp)
jl 0x75ae
movl -0x60(%rbp), %eax
orl -0x5c(%rbp), %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x60(%rbp)
movl $0x0, -0x5c(%rbp)
jmp 0x7649
cmpl $0x21, -0x44(%rbp)
jl 0x75ce
movl -0x5c(%rbp), %edi
movl -0x44(%rbp), %esi
subl $0x20, %esi
callq 0x6e50
movl %eax, -0x60(%rbp)
movl $0x0, -0x5c(%rbp)
jmp 0x7647
cmpl $0x20, -0x44(%rbp)
jne 0x75f2
movl -0x5c(%rbp), %eax
cmpl $0x0, -0x60(%rbp)
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
movl %eax, -0x60(%rbp)
movl $0x0, -0x5c(%rbp)
jmp 0x7645
cmpl $0x0, -0x44(%rbp)
je 0x7643
movl -0x44(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
subl $0x1, %eax
movl %eax, -0x64(%rbp)
movl -0x5c(%rbp), %eax
movl $0x20, %ecx
subl -0x44(%rbp), %ecx
shll %cl, %eax
movl -0x60(%rbp), %edx
movl -0x44(%rbp), %ecx
shrl %cl, %edx
movl %edx, %ecx
orl %ecx, %eax
movl -0x60(%rbp), %ecx
andl -0x64(%rbp), %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
movl %eax, -0x60(%rbp)
movl -0x5c(%rbp), %eax
movl -0x44(%rbp), %ecx
shrl %cl, %eax
movl %eax, -0x5c(%rbp)
jmp 0x7645
jmp 0x7647
jmp 0x7649
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jne 0x7676
movl -0x60(%rbp), %eax
addl -0x58(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x5c(%rbp), %eax
movl -0x58(%rbp), %ecx
cmpl -0x60(%rbp), %ecx
setb %cl
andb $0x1, %cl
movzbl %cl, %ecx
addl %ecx, %eax
addl -0x54(%rbp), %eax
movl %eax, -0x54(%rbp)
jmp 0x76bd
movl -0x58(%rbp), %eax
movl %eax, -0x70(%rbp)
movl -0x60(%rbp), %ecx
movl -0x58(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x58(%rbp)
movl -0x54(%rbp), %eax
subl -0x5c(%rbp), %eax
movl -0x58(%rbp), %ecx
cmpl -0x70(%rbp), %ecx
seta %cl
andb $0x1, %cl
movzbl %cl, %ecx
subl %ecx, %eax
movl %eax, -0x54(%rbp)
movl -0x58(%rbp), %eax
orl -0x54(%rbp), %eax
cmpl $0x0, %eax
jne 0x76bb
cmpl $0x2, -0x14(%rbp)
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x30(%rbp)
jmp 0x76bd
movl -0x30(%rbp), %edi
movl -0x40(%rbp), %esi
movl -0x54(%rbp), %edx
movl -0x58(%rbp), %ecx
movl -0x14(%rbp), %r8d
movq -0x20(%rbp), %r9
callq 0x76f0
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)