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.
#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/3format_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/3format_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/3format_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/3format_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;
}