// File: /workspace/github_c_makefile_star2_O3/mbitsnbites[P]SoftFP/./softfp_template.h
// Function: add_sf32
F_UINT add_sf(F_UINT a, F_UINT b, RoundingModeEnum rm,
              uint32_t *pfflags)
{
    uint32_t a_sign, b_sign, a_exp, b_exp;
    F_UINT tmp, a_mant, b_mant;

    /* swap so that  abs(a) >= abs(b) */
    if ((a & ~SIGN_MASK) < (b & ~SIGN_MASK)) {
        tmp = a;
        a = b;
        b = tmp;
    }
    a_sign = a >> (F_SIZE - 1);
    b_sign = b >> (F_SIZE - 1);
    a_exp = (a >> MANT_SIZE) & EXP_MASK;
    b_exp = (b >> MANT_SIZE) & EXP_MASK;
    a_mant = (a & MANT_MASK) << 3;
    b_mant = (b & MANT_MASK) << 3;
    if (unlikely(a_exp == EXP_MASK)) {
        if (a_mant != 0) {
            /* NaN result */
            if (!(a_mant & (QNAN_MASK << 3)) || issignan_sf(b))
                *pfflags |= FFLAG_INVALID_OP;
            return F_QNAN;
        } else if (b_exp == EXP_MASK && a_sign != b_sign) {
            *pfflags |= FFLAG_INVALID_OP;
            return F_QNAN;
        } else {
            /* infinity */
            return a;
        }
    }
    if (a_exp == 0) {
        a_exp = 1;
    } else {
        a_mant |= (F_UINT)1 << (MANT_SIZE + 3);
    }
    if (b_exp == 0) {
        b_exp = 1;
    } else {
        b_mant |= (F_UINT)1 << (MANT_SIZE + 3);
    }
    b_mant = rshift_rnd(b_mant, a_exp - b_exp);
    if (a_sign == b_sign) {
        /* same signs : add the absolute values  */
        a_mant += b_mant;
    } else {
        /* different signs : subtract the absolute values  */
        a_mant -= b_mant;
        if (a_mant == 0) {
            /* zero result : the sign needs a specific handling */
            a_sign = (rm == RM_RDN);
        }
    }
    a_exp += (RND_SIZE - 3);
    return normalize_sf(a_sign, a_exp, a_mant, rm, pfflags);
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rcx, %r8
movl %edi, %ecx
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
andl %eax, %edi
andl %esi, %eax
cmpl %eax, %edi
movl %esi, %r10d
cmovbl %ecx, %r10d
cmovbl %esi, %ecx
movl %edx, %eax
movl %ecx, %edi
shrl $0x1f, %edi
movl %r10d, %r9d
shrl $0x1f, %r9d
movl %ecx, %ebp
shrl $0x17, %ebp
movl %r10d, %r11d
shrl $0x17, %r11d
movl $0xff, %r14d
andl %r14d, %r11d
leal (,%rcx,8), %edx
movl $0x3fffff8, %ebx        # imm = 0x3FFFFF8
andl %ebx, %edx
movl $0x1, %esi
testb %bpl, %bpl
je 0x4f58
andl %ebp, %r14d
cmpl $0xff, %r14d
je 0x4fcd
movzbl %bpl, %esi
orl $0x4000000, %edx        # imm = 0x4000000
shll $0x3, %r10d
andl %ebx, %r10d
leal 0x4000000(%r10), %ebx
cmpl $0x1, %r11d
movl %r11d, %ebp
adcl $0x0, %ebp
testl %r11d, %r11d
cmovel %r10d, %ebx
movl %esi, %ecx
subl %ebp, %ecx
je 0x4faa
cmpl $0x20, %ecx
jl 0x4f8b
xorl %ecx, %ecx
testl %ebx, %ebx
setne %cl
jmp 0x4fa8
movl $0xffffffff, %r10d      # imm = 0xFFFFFFFF
shll %cl, %r10d
notl %r10d
movl %ebx, %r11d
shrl %cl, %r11d
xorl %ecx, %ecx
testl %r10d, %ebx
setne %cl
orl %r11d, %ecx
movl %ecx, %ebx
cmpl %r9d, %edi
jne 0x4fb3
addl %ebx, %edx
jmp 0x4fc2
subl %ebx, %edx
jne 0x4fc2
xorl %edi, %edi
cmpl $0x2, %eax
sete %dil
xorl %edx, %edx
addl $0x4, %esi
movl %eax, %ecx
popq %rbx
popq %r14
popq %rbp
jmp 0x5020
testl %edx, %edx
je 0x4ffc
btl $0x16, %ecx
jae 0x5010
movl %r10d, %eax
andl $0x7fc00000, %eax       # imm = 0x7FC00000
cmpl $0x7f800000, %eax       # imm = 0x7F800000
setne %al
testl $0x7fffff, %r10d        # imm = 0x7FFFFF
sete %cl
orb %al, %cl
movl $0x7fc00000, %ecx       # imm = 0x7FC00000
je 0x5010
jmp 0x5019
cmpl $0xff, %r11d
setne %al
cmpl %r9d, %edi
sete %dl
orb %al, %dl
jne 0x5019
orb $0x10, (%r8)
movl $0x7fc00000, %ecx       # imm = 0x7FC00000
movl %ecx, %eax
popq %rbx
popq %r14
popq %rbp
retq