Fixture 45

string algorithms

C · 3 functions · 4 lanes · 11 of 12 function-lanes behave identically

One lane has a function that returns a different result after decompilation: gcc-O0 (2/3).

Bounded string conversions and predicates. Signed parsing accumulates in a wider type and saturates, and the digit emitter divides by ten -- both are where recovered integer widths and division idioms are visible.

tests/decompiler_fixtures/src/45_string_algorithms.c source
#include <stdint.h>

/* Bounded string conversions and predicates.  Signed parsing accumulates in a
 * wider type and saturates, and the digit emitter divides by ten -- both are
 * where recovered integer widths and division idioms are visible. */

#define STR_MAX 16

__attribute__((noinline)) int32_t
parse_decimal(const uint8_t *text, int32_t length, int32_t *value) {
    int64_t accumulator = 0;
    int32_t negative = 0;
    int32_t index = 0;
    int32_t digits = 0;
    if (text == 0 || value == 0 || length < 0 || length > STR_MAX) {
        return -1;
    }
    if (index < length && (text[index] == (uint8_t)'-' ||
                           text[index] == (uint8_t)'+')) {
        negative = (text[index] == (uint8_t)'-');
        index += 1;
    }
    while (index < length && text[index] >= (uint8_t)'0' &&
           text[index] <= (uint8_t)'9') {
        accumulator = accumulator * 10 + (int64_t)(text[index] - (uint8_t)'0');
        if (accumulator > 2147483647LL) {
            return -2;
        }
        digits += 1;
        index += 1;
    }
    if (digits == 0) {
        return -3;
    }
    *value = (int32_t)(negative ? -accumulator : accumulator);
    return digits;
}

__attribute__((noinline)) int32_t
format_decimal(int32_t value, uint8_t *output, int32_t capacity) {
    uint8_t digits[12];
    uint32_t magnitude;
    int32_t count = 0;
    int32_t produced = 0;
    int32_t index;
    if (output == 0 || capacity < 1 || capacity > STR_MAX) {
        return -1;
    }
    magnitude = (value < 0) ? (uint32_t)(-(int64_t)value) : (uint32_t)value;
    do {
        digits[count] = (uint8_t)((uint32_t)'0' + (magnitude % 10u));
        magnitude /= 10u;
        count += 1;
    } while (magnitude != 0u && count < 12);
    if (value < 0) {
        if (produced >= capacity) {
            return -2;
        }
        output[produced] = (uint8_t)'-';
        produced += 1;
    }
    for (index = count - 1; index >= 0; --index) {
        if (produced >= capacity) {
            return -2;
        }
        output[produced] = digits[index];
        produced += 1;
    }
    return produced;
}

__attribute__((noinline)) int32_t
is_palindrome(const uint8_t *text, int32_t length) {
    int32_t head = 0;
    int32_t tail;
    if (text == 0 || length < 0 || length > STR_MAX) {
        return -1;
    }
    tail = length - 1;
    while (head < tail) {
        if (text[head] != text[tail]) {
            return 0;
        }
        head += 1;
        tail -= 1;
    }
    return 1;
}

Recovered C

Generated by glaurung decompile --style decbench at b47f6b43. baseline.json records the result after recompiling the C and calling it beside the original with seeded inputs.

gcc -O0

2/3
format_decimal fail 76 lines
// glaurung: format_decimal @ 0x126d
int32_t format_decimal(int32_t arg0, uint8_t * arg1, int32_t arg2) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int count;
    int produced;
    unsigned int magnitude;
    int index;
    unsigned char local_14[12];
    long local_8;
    long ret;
    long var13;
    int var17;
    long var4;
    local_8 = (long)(0x28);
    count = 0;
    produced = 0;
    if ((arg1 != 0)) {
        if (((((unsigned long)((unsigned int)(arg2)) == 0) | ((long)(arg2) < 0)) == 0)) {
            if ((((unsigned long)((unsigned int)(arg2)) == 16) | ((long)(arg2) < 16))) {
                goto L_12bd;
            }
        }
    }
    ret = 0xffffffff;
    goto L_1397;
    L_12bd: ;
    if (((long)(arg0) < 0)) {
        var4 = (-(unsigned long)((unsigned int)(arg0)));
        goto L_12cd;
    }
    var4 = (unsigned long)((unsigned int)(arg0));
    L_12cd: ;
    magnitude = var4;
    L_12d0: ;
    var13 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((0xcccccccd * magnitude)) >> 32))) >> 3)));
    var17 = ((unsigned int)(((unsigned long)((unsigned int)(var13)) << 2)) + var13);
    *(signed char *)((&local_14[0] + (long)(count))) = ((unsigned long)((unsigned int)((magnitude - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var17)) + (unsigned long)((unsigned int)(var17)))))))) + 48);
    magnitude = ((unsigned long)((unsigned int)(((unsigned long)((0xcccccccd * magnitude)) >> 32))) >> 3);
    count = (count + 1);
    if ((magnitude != 0)) {
        if ((((unsigned long)((unsigned int)(count)) == 11) | ((long)(count) < 11))) {
            goto L_12d0;
        }
    }
    if (((long)(arg0) < 0)) {
        if ((arg2 <= produced)) {
            ret = 0xfffffffe;
            goto L_1397;
        }
        arg1[produced] = 45;
        produced = (produced + 1);
    }
    index = ((unsigned int)(count) - 1);
    goto L_138e;
    L_135e: ;
    if ((arg2 <= produced)) {
        ret = 0xfffffffe;
        goto L_1397;
    }
    arg1[produced] = *(char *)((&local_14[0] + (long)(index)));
    produced = (produced + 1);
    index = (index - 1);
    L_138e: ;
    if ((0 <= (long)(index))) {
        goto L_135e;
    }
    ret = (unsigned long)((unsigned int)(produced));
    L_1397: ;
    if ((local_8 == 0x28)) {
        // x86-64 epilogue: restore rbp
        return ret;
    }
    __stack_chk_fail();
    // x86-64 epilogue: restore rbp
    return ret;
}
is_palindrome pass 31 lines
// glaurung: is_palindrome @ 0x13ad
int32_t is_palindrome(const uint8_t * arg0, int32_t arg1) {
    int head;
    int tail;
    head = 0;
    if ((arg0 != 0)) {
        if ((0 <= (long)(arg1))) {
            if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
                goto L_13dd;
            }
        }
    }
    // x86-64 epilogue: restore rbp
    return 0xffffffff;
    L_13dd: ;
    tail = ((unsigned int)(arg1) - 1);
    goto L_141b;
    L_13e8: ;
    if (((unsigned char)(((unsigned int)((unsigned char)(arg0[head])) & 255)) != (unsigned char)(((unsigned int)((unsigned char)(arg0[tail])) & 255)))) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    head = (head + 1);
    tail = (tail - 1);
    L_141b: ;
    if ((head < tail)) {
        goto L_13e8;
    }
    // x86-64 epilogue: restore rbp
    return 1;
}
parse_decimal pass 66 lines
// glaurung: parse_decimal @ 0x1119
int32_t parse_decimal(const uint8_t * arg0, int32_t arg1, int32_t * arg2) {
    long accumulator;
    int negative;
    int index;
    int digits;
    long var22;
    long var49;
    accumulator = 0;
    negative = 0;
    index = 0;
    digits = 0;
    if ((arg0 != 0)) {
        if ((arg2 != 0)) {
            if ((0 <= (long)(arg1))) {
                if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
                    goto L_116d;
                }
            }
        }
    }
    // x86-64 epilogue: restore rbp
    return 0xffffffff;
    L_116d: ;
    if ((arg1 <= index)) {
        goto L_120f;
    }
    if (((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255))) != 45)) {
        if (((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255))) != 43)) {
            goto L_120f;
        }
    }
    negative = ((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255))) == 45);
    index = (index + 1);
    goto L_120f;
    L_11c2: ;
    var22 = ((accumulator << 2) + accumulator);
    accumulator = ((long)((int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255))) - 48))) + (var22 + var22));
    if ((0x80000000 <= accumulator)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    digits = (digits + 1);
    index = (index + 1);
    L_120f: ;
    if ((index < arg1)) {
        if (((unsigned long)(47) < (unsigned long)((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255)))))) {
            if (((unsigned long)((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255)))) <= (unsigned long)(57))) {
                goto L_11c2;
            }
        }
    }
    if (((unsigned long)((unsigned int)(digits)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffd;
    }
    if (((unsigned long)((unsigned int)(negative)) != 0)) {
        var49 = (unsigned long)((unsigned int)((-accumulator)));
        goto L_1262;
    }
    var49 = (unsigned long)((unsigned int)(accumulator));
    L_1262: ;
    *(int *)((long)arg2) = var49;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(digits);
}

clang -O0

3/3
format_decimal pass 65 lines
// glaurung: format_decimal @ 0x12b0
__attribute__((no_stack_protector)) int32_t format_decimal(int32_t arg0, uint8_t * arg1, int32_t arg2) {
    int count;
    int produced;
    unsigned int magnitude;
    int index;
    unsigned char local_20[12];
    int local_34;
    signed char local_35;
    int local_4;
    count = 0;
    produced = 0;
    if ((arg1 != 0)) {
        if ((1 <= (long)(arg2))) {
            if ((((unsigned long)((unsigned int)(arg2)) == 16) | ((long)(arg2) < 16))) {
                goto L_12f7;
            }
        }
    }
    local_4 = -1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    L_12f7: ;
    if (((long)(arg0) < 0)) {
        local_34 = (0 - (long)(arg0));
        goto L_1318;
    }
    local_34 = arg0;
    L_1318: ;
    magnitude = local_34;
    do {
        *(signed char *)((&local_20[0] + (long)(count))) = (((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(magnitude)) % (unsigned int)(10)))) + 48);
        magnitude = ((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(magnitude)) / (unsigned int)(10))));
        count = ((unsigned int)(count) + 1);
        local_35 = 0;
        if ((magnitude != 0)) {
            local_35 = ((long)(count) < 12);
        }
    } while (((unsigned long)((unsigned char)((local_35 & 1))) != 0));
    if (((long)(arg0) < 0)) {
        if ((arg2 <= produced)) {
            local_4 = -2;
            // x86-64 epilogue: restore rbp
            return (unsigned int)(local_4);
        }
        arg1[produced] = 45;
        produced = ((unsigned int)(produced) + 1);
    }
    index = ((unsigned int)(count) - 1);
    L_13b3: ;
    if ((0 <= (long)(index))) {
        if ((arg2 <= produced)) {
            local_4 = -2;
            // x86-64 epilogue: restore rbp
            return (unsigned int)(local_4);
        }
        arg1[produced] = *(char *)((&local_20[0] + (long)(index)));
        produced = ((unsigned int)(produced) + 1);
        index = ((unsigned int)(index) - 1);
        goto L_13b3;
    }
    local_4 = produced;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
is_palindrome pass 31 lines
// glaurung: is_palindrome @ 0x1410
int32_t is_palindrome(const uint8_t * arg0, int32_t arg1) {
    int head;
    int tail;
    int local_4;
    head = 0;
    if ((arg0 != 0)) {
        if ((0 <= (long)(arg1))) {
            if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
                goto L_144d;
            }
        }
    }
    local_4 = -1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    L_144d: ;
    tail = ((unsigned int)(arg1) - 1);
    L_1456: ;
    if ((head < tail)) {
        if (((unsigned int)((unsigned char)(arg0[head])) != (unsigned int)((unsigned char)(arg0[tail])))) {
            // x86-64 epilogue: restore rbp
            return 0;
        }
        head = ((unsigned int)(head) + 1);
        tail = ((unsigned int)(tail) - 1);
        goto L_1456;
    }
    // x86-64 epilogue: restore rbp
    return 1;
}
parse_decimal pass 77 lines
// glaurung: parse_decimal @ 0x1100
int32_t parse_decimal(const uint8_t * arg0, int32_t arg1, int32_t * arg2) {
    long accumulator;
    int negative;
    int index;
    int digits;
    signed char local_35;
    int local_4;
    long local_40;
    int var25;
    int var29;
    accumulator = 0;
    negative = 0;
    index = 0;
    digits = 0;
    if ((arg0 != 0)) {
        if ((arg2 != 0)) {
            if ((0 <= (long)(arg1))) {
                if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
                    goto L_1162;
                }
            }
        }
    }
    local_4 = -1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    L_1162: ;
    if ((arg1 <= index)) {
        goto L_11bb;
    }
    if (((unsigned long)((unsigned int)((unsigned char)(arg0[index]))) != 45)) {
        if (((unsigned long)((unsigned int)((unsigned char)(arg0[index]))) != 43)) {
            goto L_11bb;
        }
    }
    negative = ((unsigned long)((unsigned int)((unsigned char)(arg0[index]))) == 45);
    index = ((unsigned int)(index) + 1);
    L_11bb: ;
    goto L_11c0;
    L_11c0: ;
    local_35 = 0;
    if ((index < arg1)) {
        var25 = (unsigned int)((unsigned char)(arg0[index]));
        local_35 = 0;
        if ((48 <= (long)((int)(var25)))) {
            var29 = (unsigned int)((unsigned char)(arg0[index]));
            local_35 = (((unsigned long)((unsigned int)(var29)) == 57) | ((long)((int)(var29)) < 57));
        }
    }
    if (((unsigned long)((unsigned char)((local_35 & 1))) != 0)) {
        accumulator = ((accumulator * 10) + (long)((int)(((unsigned int)((unsigned char)(arg0[index])) - 48))));
        if ((0x7fffffff < accumulator)) {
            local_4 = -2;
            // x86-64 epilogue: restore rbp
            return (unsigned int)(local_4);
        }
        digits = ((unsigned int)(digits) + 1);
        index = ((unsigned int)(index) + 1);
        goto L_11c0;
    }
    if (((unsigned long)((unsigned int)(digits)) == 0)) {
        local_4 = -3;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((unsigned long)((unsigned int)(negative)) != 0)) {
        local_40 = (0 - accumulator);
        goto L_1296;
    }
    local_40 = accumulator;
    L_1296: ;
    *(int *)((long)arg2) = local_40;
    local_4 = digits;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

3/3
format_decimal pass 130 lines
// glaurung: format_decimal @ 0x11b0
int32_t format_decimal(int32_t arg0, uint8_t * arg1, int32_t arg2) {
    unsigned int magnitude;
    int count;
    int produced;
    long cf_12;
    long ret;
    long rsp;
    long t156;
    long var0;
    long var10;
    long var105;
    long var108;
    long var110;
    long var15;
    long var26;
    long var28;
    long var29;
    long var33;
    long var34;
    long var36;
    long var38;
    long var41;
    long var43;
    long var45;
    long var47;
    long var5;
    long var52;
    long var54;
    long var57;
    long var59;
    long var66;
    int var67;
    int var68;
    int var69;
    int var70;
    long var8;
    long var9;
    // x86-64 prologue: save callee registers, frame 32 bytes
    var0 = 0xffffffff;
    ret = 0xffffffff;
    if ((arg1 == 0)) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    ret = var0;
    if (((unsigned long)((unsigned long)((unsigned int)((arg2 - 17)))) < (unsigned long)(0xfffffff0))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    t156 = (-(unsigned long)((unsigned int)(arg0)));
    var5 = (rsp - 28);
    var8 = 0xcccccccd;
    var9 = 0;
    var10 = (((long)((int)(t156)) < 0) ? arg0 : t156);
    while (1) {
        magnitude = ((unsigned long)(((unsigned long)((unsigned int)(var10)) * var8)) >> 35);
        var15 = (unsigned long)((unsigned int)((magnitude + magnitude)));
        *(signed char *)((var5 + 0x10)) = (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var10)) - (unsigned long)((unsigned int)((var15 + (var15 * 4))))))) & 255) | 48);
        count = (var9 + 1);
        var5 = (var5 + 1);
        if (((unsigned long)((unsigned long)((unsigned int)(var10))) < (unsigned long)(10))) {
            break;
        }
        cf_12 = ((unsigned long)(var9) < (unsigned long)(11));
        var9 = (unsigned long)((unsigned int)(count));
        var10 = (unsigned long)(magnitude);
        if ((cf_12 == 0)) {
            break;
        }
    }
    var26 = 0;
    if (((long)(arg0) < 0)) {
        *(signed char *)(((long)arg1)) = 45;
        var26 = 1;
    }
    var28 = (unsigned long)((unsigned int)(var26));
    var29 = (((((unsigned int)(var26) == (unsigned int)(arg2)) | ((long)((int)(var26)) < (long)(arg2))) == 0) ? var26 : arg2);
    var33 = (~(unsigned long)((unsigned int)(var26)));
    var34 = ((unsigned long)((unsigned int)((var26 + count))) + var33);
    var36 = (var29 - (unsigned long)((unsigned int)(var26)));
    var38 = ((((unsigned long)(var36) <= (unsigned long)(var34)) ? var36 : var34) + 1);
    if (((unsigned long)(17) <= (unsigned long)(var38))) {
        var41 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var38)) & 15)));
        var43 = ((var41 != 0) ? var41 : 16);
        var45 = ((var38 - var43) + var28);
        var47 = ((unsigned long)((unsigned int)((var28 + count))) + var33);
        var52 = (((unsigned long)((unsigned int)(count)) + (var43 - (((unsigned long)(var36) <= (unsigned long)(var47)) ? var36 : var47))) - 2);
        var54 = ((unsigned long)((unsigned int)((var28 + count))) + var33);
        var57 = (((((unsigned long)(var36) <= (unsigned long)(var54)) ? var36 : var54) - var43) + 1);
        var59 = 0;
        do {
            var66 = (var59 | var28);
            var67 = *(int *)((var5));
            var68 = *(int *)((var5 + 0x4));
            var69 = *(int *)((var5 + 0x8));
            var70 = *(int *)((var5 + 0xc));
            /* asm: punpckhbw */
            /* asm: packuswb */
            *(int *)(((long)arg1 + var66)) = ((unsigned int)((unsigned short)((((unsigned int)(var70) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)(var70)) << 16));
            *(int *)(((long)arg1 + var66 + 0x4)) = ((unsigned int)((unsigned short)((((unsigned int)(var69) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)(var69)) << 16));
            *(int *)(((long)arg1 + var66 + 0x8)) = ((unsigned int)((unsigned short)((((unsigned int)(var68) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)(var68)) << 16));
            *(int *)(((long)arg1 + var66 + 0xc)) = ((unsigned int)((unsigned short)((((unsigned int)(var67) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)(var67)) << 16));
            var59 = (var59 + 16);
            var5 = (var5 - 16);
            var105 = var45;
        } while ((var57 != var59));
    } else {
        var52 = ((unsigned long)((unsigned int)(count)) - 1);
        var105 = var28;
    }
    var108 = (unsigned long)((unsigned int)((var28 + count)));
    var110 = ((rsp + var52) - 12);
    produced = var105;
    L_1320: ;
    while ((var29 != produced)) {
        *(signed char *)(((long)arg1 + produced)) = *(char *)((var110));
        produced = (produced + 1);
        var110 = (var110 - 1);
        if ((var108 != produced)) {
            goto L_1320;
        } else {
            ret = (unsigned long)((unsigned int)(produced));
        }
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    // x86-64 epilogue: restore callee registers
    return 0xfffffffe;
}
is_palindrome pass 31 lines
// glaurung: is_palindrome @ 0x1350
int32_t is_palindrome(const uint8_t * arg0, int32_t arg1) {
    int head;
    int tail;
    long of_9;
    long ret;
    long sf_9;
    ret = 0xffffffff;
    if ((arg0 == 0)) {
        return ret;
    }
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    ret = 1;
    if (((unsigned long)((unsigned long)((unsigned int)(arg1))) < (unsigned long)(2))) {
        return ret;
    }
    head = 0;
    tail = ((unsigned int)(arg1) - 2);
    while (((unsigned char)(((unsigned int)((unsigned char)(*(char *)(((long)arg0 + head)))) & 255)) == (unsigned char)(*(char *)(((long)arg0 + tail + 0x1))))) {
        head = (head + 1);
        sf_9 = ((head - tail) < 0);
        of_9 = ((head < tail) ^ ((head - tail) < 0));
        tail = (tail - 1);
        if (((sf_9 ^ of_9) == 0)) {
            return ret;
        }
    }
    return 0;
}
parse_decimal pass 82 lines
// glaurung: parse_decimal @ 0x1100
int32_t parse_decimal(const uint8_t * arg0, int32_t arg1, int32_t * arg2) {
    int negative;
    int index;
    int digits;
    long accumulator;
    long ret;
    long var1;
    long var16;
    long var17;
    int var23;
    long var28;
    long var7;
    ret = 0xffffffff;
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    if ((arg0 == 0)) {
        return ret;
    }
    if ((arg2 == 0)) {
        return ret;
    }
    var1 = 0;
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        negative = var1;
        index = 0;
    } else {
        var7 = (*(char *)(((long)arg0)) & 255);
        if (((unsigned long)((unsigned char)((var7 & 255))) == 45)) {
            L_1136: ;
            negative = ((unsigned long)((unsigned char)((var7 & 255))) == 45);
            index = 1;
        } else {
            negative = var1;
            index = 0;
            if (((unsigned long)((unsigned char)((var7 & 255))) != 43)) {
                goto L_1148;
            }
            goto L_1136;
        }
    }
    L_1148: ;
    ret = 0xfffffffd;
    if (((unsigned long)((unsigned long)((unsigned int)(arg1))) <= (unsigned long)((unsigned long)((unsigned int)(index))))) {
        return ret;
    }
    var16 = (unsigned long)((unsigned int)((arg1 - index)));
    var17 = (long)(((long)arg0 + (unsigned long)((unsigned int)(index))));
    digits = 0;
    accumulator = 0;
    L_1160: ;
    while (1) {
        var23 = (unsigned int)((unsigned char)(*(char *)((var17 + digits))));
        if (((unsigned long)(9) < (unsigned long)((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((var23 - 48))) & 255)))))) {
            break;
        }
        accumulator = ((unsigned long)((unsigned int)((var23 - 48))) + ((accumulator + (accumulator * 4)) * 2));
        if ((0x7fffffff < accumulator)) {
            return 0xfffffffe;
        }
        var28 = ((unsigned long)((unsigned int)(digits)) + 1);
        digits = var28;
        if (((unsigned int)(var16) != (unsigned int)(var28))) {
            goto L_1160;
        }
        goto L_118c;
    }
    var16 = (unsigned long)((unsigned int)(digits));
    if (((unsigned long)((unsigned int)(digits)) != 0)) {
        L_1190: ;
        *(int *)(((long)arg2)) = (((unsigned long)((unsigned int)(negative)) == 0) ? accumulator : (-(unsigned long)((unsigned int)(accumulator))));
        return (unsigned int)(var16);
    }
    L_11a0: ;
    return ret;
    L_118c: ;
    if (((unsigned long)((unsigned int)(var16)) == 0)) {
        goto L_11a0;
    }
    goto L_1190;
}

gcc -O2

3/3
format_decimal pass 91 lines
// glaurung: format_decimal @ 0x1210
int32_t format_decimal(int32_t arg0, uint8_t * arg1, int32_t arg2) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int count;
    int produced;
    unsigned int magnitude;
    long local_20;
    unsigned char local_2c[12];
    long t140;
    long var11;
    long var12;
    long var17;
    long var21;
    long var22;
    long var27;
    long var32;
    long var35;
    long var4;
    long var40;
    long var42;
    int var43;
    int var44;
    long var5;
    long var6;
    long var8;
    long var9;
    local_20 = (long)(0x28);
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)((arg2 - 1)))))) {
        L_12f8: ;
        var4 = 0xffffffff;
    } else {
        var5 = (long)arg1;
        if ((arg1 == 0)) {
            goto L_12f8;
        } else {
            var6 = (unsigned long)((unsigned int)(arg2));
            var8 = (long)(&local_2c[0]);
            var9 = (unsigned long)((unsigned int)(arg0));
            t140 = (-(unsigned long)((unsigned int)(arg0)));
            var11 = (long)(&local_2c[0]);
            var12 = 0xcccccccd;
            count = 0;
            var17 = (((long)((int)(t140)) < 0) ? arg0 : t140);
            while (1) {
                var11 = (var11 + 1);
                var21 = ((unsigned long)(((unsigned long)((unsigned int)(var17)) * var12)) >> 35);
                var22 = (unsigned long)((unsigned int)((var21 + (var21 * 4))));
                var27 = (unsigned long)((unsigned int)(count));
                count = (unsigned long)((unsigned int)((count + 1)));
                *(signed char *)((var11 - 0x1)) = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var17)) - (unsigned long)((unsigned int)((var22 + var22)))))) + 48);
                var32 = (unsigned long)((unsigned int)(var21));
                if (((unsigned long)((unsigned long)((unsigned int)(var17))) <= (unsigned long)(9))) {
                    break;
                }
                var17 = var32;
                if (((((unsigned long)((unsigned int)(count)) == 11) | ((long)(count) < 11)) == 0)) {
                    break;
                }
            }
            var35 = 0;
            if (((long)((int)(var9)) < 0)) {
                *(signed char *)((var5)) = 45;
                var35 = 1;
            }
            var40 = ((long)((int)(var35)) + var5);
            var4 = (unsigned long)((unsigned int)(((var35 + var27) + 1)));
            produced = var35;
            var42 = (var8 + (long)((int)(var27)));
            L_12b8: ;
            while (((((unsigned int)(var6) == (unsigned int)(produced)) | ((long)((int)(var6)) < (long)(produced))) == 0)) {
                var43 = (unsigned int)((unsigned char)(*(char *)((var42))));
                var44 = (produced + 1);
                produced = (unsigned long)((unsigned int)(var44));
                var42 = (var42 - 1);
                var40 = (var40 + 1);
                *(signed char *)((var40 - 0x1)) = var43;
                if (((unsigned int)(var44) != (unsigned int)(var4))) {
                    goto L_12b8;
                }
                goto L_12d4;
            }
            var4 = 0xfffffffe;
        }
    }
    L_12d4: ;
    if ((local_20 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: tear down frame
    return (unsigned int)(var4);
}
is_palindrome pass 28 lines
// glaurung: is_palindrome @ 0x1310
int32_t is_palindrome(const uint8_t * arg0, int32_t arg1) {
    int tail;
    int head;
    long var2;
    long var7;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    tail = (unsigned long)((unsigned int)((arg1 - 1)));
    if ((((unsigned long)((unsigned int)(tail)) == 0) | ((long)(tail) < 0))) {
        return 1;
    }
    var2 = (long)(tail);
    head = 0;
    while (((unsigned char)(*(char *)(((long)arg0 + head))) == (unsigned char)(((unsigned int)((unsigned char)(*(char *)(((long)arg0 + var2)))) & 255)))) {
        var7 = ((unsigned long)((unsigned int)(head)) + 1);
        var2 = (var2 - 1);
        head = var7;
        if (((long)((int)(var2)) <= (long)((int)(var7)))) {
            return 1;
        }
    }
    return 0;
}
parse_decimal pass 102 lines
// glaurung: parse_decimal @ 0x1120
int32_t parse_decimal(const uint8_t * arg0, int32_t arg1, int32_t * arg2) {
    long accumulator;
    int digits;
    int index;
    int negative;
    long local_8;
    long var0;
    int * var1;
    long var14;
    long var15;
    long var18;
    long var2;
    long var23;
    long var24;
    long var25;
    int var3;
    long var32;
    long var33;
    long var38;
    int var4;
    int var40;
    long var7;
    long var8;
    var0 = (long)arg0;
    if ((arg0 == 0)) {
        goto L_11f3;
    }
    var1 = (int *)arg2;
    if ((arg2 == 0)) {
        goto L_11f3;
    }
    var2 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        goto L_11f3;
    }
    var3 = 0xfffffffd;
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        goto L_11f9;
    }
    var4 = (unsigned int)((unsigned char)(*(char *)((var0))));
    var8 = ((var7 & -256) | ((unsigned long)((unsigned char)((var4 & 255))) == 45));
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var4 - 43))) & 253))) == 0)) {
        goto L_11d0;
    }
    var14 = 0;
    var15 = 0;
    L_116f: ;
    local_8 = var18;
    var23 = (long)((int)((var14 + 1)));
    var24 = 0x80000000;
    var25 = 0;
    accumulator = 0;
    goto L_11ab;
    L_1188: ;
    accumulator = ((long)((int)((var4 - 48))) + ((accumulator + (accumulator * 4)) * 2));
    if ((var24 <= accumulator)) {
        goto L_11e8;
    }
    var32 = (unsigned long)((unsigned int)((var25 + 1)));
    var33 = accumulator;
    if ((((unsigned int)(var2) == (unsigned int)(var23)) | ((long)((int)(var2)) < (long)((int)(var23))))) {
        goto L_11b9;
    }
    var4 = (unsigned int)((unsigned char)(*(char *)((var0 + var23))));
    var23 = (var23 + 1);
    var25 = var32;
    L_11ab: ;
    if (((unsigned long)((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((var4 - 48))) & 255)))) <= (unsigned long)(9))) {
        goto L_1188;
    }
    var32 = var25;
    var33 = accumulator;
    if (((unsigned long)((unsigned int)(var25)) == 0)) {
        goto L_1200;
    }
    L_11b9: ;
    *(int *)((var1)) = (((unsigned long)((unsigned int)(var15)) != 0) ? (-(unsigned long)((unsigned int)(var33))) : var33);
    var38 = var32;
    L_11c6: ;
    // x86-64 epilogue: tear down frame
    return (unsigned int)(var38);
    L_11d0: ;
    var40 = (unsigned int)((unsigned char)((var8 & 255)));
    if (((unsigned long)((unsigned int)(arg1)) == 1)) {
        goto L_11f9;
    }
    var4 = (unsigned int)((unsigned char)(*(char *)((var0 + 0x1))));
    var14 = 1;
    var15 = (unsigned long)((unsigned int)(var40));
    goto L_116f;
    L_11e8: ;
    // x86-64 epilogue: tear down frame
    return 0xfffffffe;
    L_11f3: ;
    var3 = 0xffffffff;
    L_11f9: ;
    return (unsigned int)(var3);
    L_1200: ;
    var38 = 0xfffffffd;
    goto L_11c6;
}

← 213 fixtures