Fixture 57
bignum
C · 2 functions · 4 lanes · 8 of 8 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
Multi-limb unsigned arithmetic over base 2^16 limbs. Carry propagation across limbs is the whole point: a lost carry or a truncated intermediate is invisible in structure but fatal in the differential.
#include <stdint.h>
/* Multi-limb unsigned arithmetic over base 2^16 limbs. Carry propagation
* across limbs is the whole point: a lost carry or a truncated intermediate is
* invisible in structure but fatal in the differential. */
#define LIMB_MAX 8
#define LIMB_BASE 65536u
__attribute__((noinline)) int32_t
bignum_add(const uint32_t *left, int32_t left_limbs, const uint32_t *right,
int32_t right_limbs, uint32_t *output, int32_t capacity) {
uint32_t carry = 0;
int32_t index;
int32_t limbs;
if (left == 0 || right == 0 || output == 0 || left_limbs < 0 ||
right_limbs < 0 || left_limbs > LIMB_MAX || right_limbs > LIMB_MAX ||
capacity < 1 || capacity > LIMB_MAX) {
return -1;
}
limbs = (left_limbs > right_limbs) ? left_limbs : right_limbs;
if (limbs > capacity) {
return -2;
}
for (index = 0; index < limbs; ++index) {
uint32_t a = (index < left_limbs) ? (left[index] % LIMB_BASE) : 0u;
uint32_t b = (index < right_limbs) ? (right[index] % LIMB_BASE) : 0u;
uint32_t sum = a + b + carry;
output[index] = sum % LIMB_BASE;
carry = sum / LIMB_BASE;
}
if (carry != 0u && limbs < capacity) {
output[limbs] = carry;
limbs += 1;
}
return limbs;
}
__attribute__((noinline)) int32_t
bignum_mul_small(const uint32_t *value, int32_t limbs, uint32_t multiplier,
uint32_t *output, int32_t capacity) {
uint32_t carry = 0;
int32_t index;
int32_t produced;
if (value == 0 || output == 0 || limbs < 0 || limbs > LIMB_MAX ||
capacity < 1 || capacity > LIMB_MAX || multiplier >= LIMB_BASE) {
return -1;
}
if (limbs > capacity) {
return -2;
}
for (index = 0; index < limbs; ++index) {
uint32_t product = (value[index] % LIMB_BASE) * multiplier + carry;
output[index] = product % LIMB_BASE;
carry = product / LIMB_BASE;
}
produced = limbs;
while (carry != 0u && produced < capacity) {
output[produced] = carry % LIMB_BASE;
carry /= LIMB_BASE;
produced += 1;
}
return produced;
} 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.
clang -O0
2/2bignum_add pass 82 lines
// glaurung: bignum_add @ 0x1100
int32_t bignum_add(const uint32_t * arg0, int32_t arg1, const uint32_t * arg2, int32_t arg3, uint32_t * arg4, int32_t arg5) {
unsigned int carry;
int limbs;
int index;
unsigned int a;
unsigned int b;
unsigned int sum;
int local_4;
int local_50;
int local_54;
int local_58;
// x86-64 prologue: save rbp
carry = 0;
if ((arg0 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if ((arg2 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if ((arg4 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((long)(arg1) < 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((long)(arg3) < 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg3)) == 8) | ((long)(arg3) < 8)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((long)(arg5) < 1)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg5)) == 8) | ((long)(arg5) < 8)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_50 = ((((unsigned int)(arg1) == (unsigned int)(arg3)) | (arg1 < arg3)) ? (unsigned long)((unsigned int)(arg3)) : (unsigned long)((unsigned int)(arg1)));
limbs = local_50;
if ((((unsigned int)(limbs) == (unsigned int)(arg5)) | (limbs < arg5))) {
for (index = 0; (index < limbs); index++) {
local_54 = ((arg1 <= index) ? 0 : ((unsigned long)((unsigned int)(arg0[(long)(index)])) & 0xffff));
a = local_54;
local_58 = ((arg3 <= index) ? 0 : ((unsigned long)((unsigned int)(arg2[(long)(index)])) & 0xffff));
b = local_58;
sum = ((unsigned int)((a + b)) + carry);
arg4[(long)(index)] = (sum & 0xffff);
carry = ((unsigned int)(sum) >> 16);
}
if ((carry != 0)) {
if ((limbs < arg5)) {
arg4[(long)(limbs)] = carry;
limbs = ((unsigned int)(limbs) + 1);
}
}
return (unsigned int)(limbs);
} else {
return (unsigned int)(-2);
}
} bignum_mul_small pass 58 lines
// glaurung: bignum_mul_small @ 0x12b0
int32_t bignum_mul_small(const uint32_t * arg0, int32_t arg1, uint32_t arg2, uint32_t * arg3, int32_t arg4) {
unsigned int carry;
int index;
unsigned int product;
int produced;
signed char local_35;
int local_4;
carry = 0;
if ((arg0 != 0)) {
if ((arg3 != 0)) {
if ((0 <= (long)(arg1))) {
if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) != 0)) {
if ((1 <= (long)(arg4))) {
if (((((unsigned long)((unsigned int)(arg4)) == 8) | ((long)(arg4) < 8)) != 0)) {
if (((unsigned long)(arg2) < (unsigned long)(0x10000))) {
goto L_1324;
}
}
}
}
}
}
}
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_1324: ;
if (((((unsigned int)(arg1) == (unsigned int)(arg4)) | (arg1 < arg4)) == 0)) {
local_4 = -2;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
index = 0;
L_1343: ;
if ((index < arg1)) {
product = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(index)])) & 0xffff))) * arg2)) + carry);
arg3[(long)(index)] = (product & 0xffff);
carry = ((unsigned int)(product) >> 16);
index = ((unsigned int)(index) + 1);
goto L_1343;
}
produced = arg1;
L_139a: ;
local_35 = 0;
if ((carry != 0)) {
local_35 = (produced < arg4);
}
if (((unsigned long)((unsigned char)((local_35 & 1))) != 0)) {
arg3[(long)(produced)] = (carry & 0xffff);
carry = ((unsigned int)(carry) >> 16);
produced = ((unsigned int)(produced) + 1);
goto L_139a;
}
local_4 = produced;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
2/2bignum_add pass 90 lines
// glaurung: bignum_add @ 0x1100
int32_t bignum_add(const uint32_t * arg0, int32_t arg1, const uint32_t * arg2, int32_t arg3, uint32_t * arg4, int32_t arg5) {
int limbs;
int index;
unsigned int carry;
unsigned int b;
unsigned int sum;
unsigned int a;
long local_10;
long local_18;
long ret;
long var0;
long var1;
long var11;
long var12;
long var13;
long var14;
long var23;
int var31;
long var37;
local_10 = var0;
local_18 = var1;
ret = 0xffffffff;
if (((unsigned long)((unsigned long)((unsigned int)((arg5 - 9)))) < (unsigned long)(0xfffffff8))) {
// x86-64 epilogue: tear down frame
return ret;
}
if (((((unsigned long)((unsigned int)(arg3)) == 8) | ((long)(arg3) < 8)) == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if (((long)((int)(((unsigned long)((unsigned int)(arg3)) | arg1))) < 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if ((arg0 == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if ((arg2 == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if ((arg4 == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
limbs = (((((unsigned int)(arg1) == (unsigned int)(arg3)) | (arg1 < arg3)) == 0) ? arg1 : (unsigned long)((unsigned int)(arg3)));
ret = 0xfffffffe;
if (((((unsigned int)(limbs) == (unsigned int)(arg5)) | (limbs < arg5)) == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
var11 = (unsigned long)((unsigned int)(limbs));
if (((((unsigned long)((unsigned int)(limbs)) == 0) | ((long)(limbs) < 0)) == 0)) {
var12 = (long)(arg1);
var13 = (long)(arg3);
var14 = (unsigned long)((unsigned int)(limbs));
index = 0;
carry = 0;
do {
var23 = 0;
if ((index < var12)) {
var23 = (unsigned int)((unsigned short)(*(short *)(((long)arg0 + index * 4))));
}
b = 0;
if ((index < var13)) {
b = (unsigned int)((unsigned short)(*(short *)(((long)arg2 + index * 4))));
}
var31 = ((unsigned int)((var23 + carry)) + b);
sum = (unsigned long)((unsigned int)(var31));
*(int *)(((long)arg4 + index * 4)) = (unsigned short)(((unsigned long)((unsigned int)(var31)) & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var31)) >> 16)));
var37 = ((unsigned long)((unsigned int)(index)) + 1);
index = var37;
} while ((var14 != var37));
var11 = (unsigned long)((unsigned int)(limbs));
if (((limbs < arg5) && ((unsigned long)(0x10000) <= (unsigned long)(sum)))) {
arg4[(long)(limbs)] = 1;
var11 = (unsigned long)((unsigned int)((limbs + 1)));
}
}
ret = (unsigned long)((unsigned int)(var11));
// x86-64 epilogue: tear down frame
return (unsigned int)(var11);
} bignum_mul_small pass 93 lines
// glaurung: bignum_mul_small @ 0x11e0
int32_t bignum_mul_small(const uint32_t * arg0, int32_t arg1, uint32_t arg2, uint32_t * arg3, int32_t arg4) {
unsigned int product;
unsigned int carry;
int index;
long ret;
int var12;
int var20;
int var28;
int var36;
int var44;
int var52;
int var60;
long var66;
ret = 0xffffffff;
if (((unsigned long)(0xffff) < (unsigned long)(arg2))) {
return ret;
}
if (((unsigned long)((unsigned long)((unsigned int)((arg4 - 9)))) < (unsigned long)(0xfffffff8))) {
return ret;
}
if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if ((arg0 == 0)) {
return ret;
}
if ((arg3 == 0)) {
return ret;
}
ret = 0xfffffffe;
if (((unsigned long)((unsigned long)((unsigned int)(arg4))) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
product = (unsigned long)((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0)))) * arg2)));
*(int *)(((long)arg3)) = (unsigned short)((product & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned int)(product) >> 16)));
if (((unsigned long)((unsigned int)(arg1)) != 1)) {
var12 = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0x4)))) * arg2)) + carry);
product = (unsigned long)((unsigned int)(var12));
*(int *)(((long)arg3 + 0x4)) = (unsigned short)(((unsigned long)((unsigned int)(var12)) & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var12)) >> 16)));
if (((unsigned long)((unsigned int)(arg1)) != 2)) {
var20 = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0x8)))) * arg2)) + carry);
product = (unsigned long)((unsigned int)(var20));
*(int *)(((long)arg3 + 0x8)) = (unsigned short)(((unsigned long)((unsigned int)(var20)) & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var20)) >> 16)));
if (((unsigned long)((unsigned int)(arg1)) != 3)) {
var28 = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0xc)))) * arg2)) + carry);
product = (unsigned long)((unsigned int)(var28));
*(int *)(((long)arg3 + 0xc)) = (unsigned short)(((unsigned long)((unsigned int)(var28)) & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var28)) >> 16)));
if (((unsigned long)((unsigned int)(arg1)) != 4)) {
var36 = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0x10)))) * arg2)) + carry);
product = (unsigned long)((unsigned int)(var36));
*(int *)(((long)arg3 + 0x10)) = (unsigned short)(((unsigned long)((unsigned int)(var36)) & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var36)) >> 16)));
if (((unsigned long)((unsigned int)(arg1)) != 5)) {
var44 = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0x14)))) * arg2)) + carry);
product = (unsigned long)((unsigned int)(var44));
*(int *)(((long)arg3 + 0x14)) = (unsigned short)(((unsigned long)((unsigned int)(var44)) & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var44)) >> 16)));
if (((unsigned long)((unsigned int)(arg1)) != 6)) {
var52 = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0x18)))) * arg2)) + carry);
product = (unsigned long)((unsigned int)(var52));
*(int *)(((long)arg3 + 0x18)) = (unsigned short)(((unsigned long)((unsigned int)(var52)) & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var52)) >> 16)));
if (((unsigned long)((unsigned int)(arg1)) != 7)) {
var60 = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0x1c)))) * arg2)) + carry);
product = (unsigned long)((unsigned int)(var60));
*(int *)(((long)arg3 + 0x1c)) = (unsigned short)(((unsigned long)((unsigned int)(var60)) & 0xffff));
carry = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var60)) >> 16)));
}
}
}
}
}
}
}
var66 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(0x10000) <= (unsigned long)(product))) {
var66 = (unsigned long)((unsigned int)(arg1));
if ((arg4 <= arg1)) {
return (unsigned int)(var66);
}
arg3[(long)(arg1)] = carry;
var66 = (unsigned long)((unsigned int)((arg1 + 1)));
}
return (unsigned int)(var66);
} gcc -O0
2/2bignum_add pass 66 lines
// glaurung: bignum_add @ 0x10f9
int32_t bignum_add(const uint32_t * arg0, int32_t arg1, const uint32_t * arg2, int32_t arg3, uint32_t * arg4, int32_t arg5) {
unsigned int carry;
int limbs;
int index;
unsigned int a;
unsigned int b;
unsigned int sum;
// x86-64 prologue: save rbp
carry = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((arg2 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((arg4 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg3) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg3)) == 8) | ((long)(arg3) < 8)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((((unsigned long)((unsigned int)(arg5)) == 0) | ((long)(arg5) < 0))) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg5)) == 8) | ((long)(arg5) < 8)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
limbs = ((arg1 <= arg3) ? (unsigned long)((unsigned int)(arg3)) : (unsigned long)((unsigned int)(arg1)));
if ((((unsigned int)(limbs) == (unsigned int)(arg5)) | (limbs < arg5))) {
for (index = 0; (index < limbs); index++) {
a = ((arg1 <= index) ? 0 : (unsigned int)((unsigned short)(((unsigned long)((unsigned int)(arg0[(long)(index)])) & 0xffff))));
b = ((arg3 <= index) ? 0 : (unsigned int)((unsigned short)(((unsigned long)((unsigned int)(arg2[(long)(index)])) & 0xffff))));
sum = (carry + (unsigned int)((a + b)));
arg4[(long)(index)] = (unsigned short)((sum & 0xffff));
carry = ((unsigned int)(sum) >> 16);
}
if ((carry != 0)) {
if ((limbs < arg5)) {
arg4[(long)(limbs)] = carry;
limbs = (limbs + 1);
}
}
return (unsigned int)(limbs);
} else {
return 0xfffffffe;
}
} bignum_mul_small pass 56 lines
// glaurung: bignum_mul_small @ 0x1258
int32_t bignum_mul_small(const uint32_t * arg0, int32_t arg1, uint32_t arg2, uint32_t * arg3, int32_t arg4) {
unsigned int carry;
int index;
unsigned int product;
int produced;
// x86-64 prologue: save rbp
carry = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((arg3 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((((unsigned long)((unsigned int)(arg4)) == 0) | ((long)(arg4) < 0))) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg4)) == 8) | ((long)(arg4) < 8)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((unsigned long)(0xffff) < (unsigned long)(arg2))) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((((unsigned int)(arg1) == (unsigned int)(arg4)) | (arg1 < arg4))) {
for (index = 0; (index < arg1); index++) {
product = (carry + (unsigned int)(((unsigned int)((unsigned short)(((unsigned long)((unsigned int)(arg0[(long)(index)])) & 0xffff))) * arg2)));
arg3[(long)(index)] = (unsigned short)((product & 0xffff));
carry = ((unsigned int)(product) >> 16);
}
produced = arg1;
while ((carry != 0)) {
if ((arg4 <= produced)) {
break;
}
arg3[(long)(produced)] = (unsigned short)((carry & 0xffff));
carry = ((unsigned int)(carry) >> 16);
produced = (produced + 1);
}
return (unsigned int)(produced);
} else {
return 0xfffffffe;
}
} gcc -O2
2/2bignum_add pass 96 lines
// glaurung: bignum_add @ 0x1100
int32_t bignum_add(const uint32_t * arg0, int32_t arg1, const uint32_t * arg2, int32_t arg3, uint32_t * arg4, int32_t arg5) {
int limbs;
int index;
unsigned int carry;
unsigned int a;
unsigned int sum;
long local_10;
long var0;
long var1;
long var18;
long var19;
long var22;
long var24;
long var3;
long var32;
long var33;
long var6;
long var7;
long var9;
local_10 = var0;
var1 = (long)arg0;
if ((arg0 == 0)) {
var3 = 0xffffffff;
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
var6 = (long)arg2;
if ((arg2 == 0)) {
var3 = 0xffffffff;
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
if ((arg4 == 0)) {
var3 = 0xffffffff;
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
var7 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
var3 = 0xffffffff;
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)((arg5 - 1)))))) {
var3 = 0xffffffff;
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
var9 = (unsigned long)((unsigned int)(arg3));
if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg3))))) {
var3 = 0xffffffff;
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
limbs = ((arg3 <= arg1) ? arg1 : (unsigned long)((unsigned int)(arg3)));
if ((arg5 < limbs)) {
return 0xfffffffe;
}
var3 = (unsigned long)((unsigned int)(limbs));
if (((unsigned long)((unsigned int)(limbs)) == 0)) {
// x86-64 epilogue: tear down frame
return (unsigned int)(var3);
}
index = 0;
var18 = 0;
do {
var19 = (unsigned long)((unsigned int)(index));
var22 = 0;
if (((((unsigned int)(var7) == (unsigned int)(index)) | ((long)((int)(var7)) < (long)(index))) == 0)) {
var22 = (unsigned int)((unsigned short)(*(short *)((var1 + index * 4))));
}
var24 = var22;
if (((((unsigned int)(var9) == (unsigned int)(var19)) | ((long)((int)(var9)) < (long)((int)(var19)))) == 0)) {
var24 = (unsigned long)((unsigned int)((var22 + (unsigned int)((unsigned short)(*(short *)((var6 + index * 4)))))));
}
carry = (var18 + var24);
var32 = (unsigned long)((unsigned int)(((unsigned int)(carry) >> 16)));
*(int *)(((long)arg4 + index * 4)) = (unsigned short)((carry & 0xffff));
var33 = ((unsigned long)((unsigned int)(index)) + 1);
index = var33;
var18 = var32;
} while (((((unsigned int)(limbs) == (unsigned int)(var33)) | ((long)(limbs) < (long)((int)(var33)))) == 0));
var3 = (unsigned long)((unsigned int)(limbs));
if ((((unsigned int)(arg5) == (unsigned int)(limbs)) | (arg5 < limbs))) {
// x86-64 epilogue: tear down frame
return (unsigned int)(var3);
}
var3 = (unsigned long)((unsigned int)(limbs));
if (((unsigned long)((unsigned int)((var32 & 1))) != 0)) {
arg4[(long)(limbs)] = 1;
var3 = (unsigned long)((unsigned int)((limbs + 1)));
}
// x86-64 epilogue: tear down frame
return (unsigned int)(var3);
} bignum_mul_small pass 57 lines
// glaurung: bignum_mul_small @ 0x11c0
int32_t bignum_mul_small(const uint32_t * arg0, int32_t arg1, uint32_t arg2, uint32_t * arg3, int32_t arg4) {
int produced;
int index;
unsigned int carry;
unsigned int product;
long var0;
long var1;
long var16;
long var18;
int var19;
long var7;
var0 = (long)arg0;
produced = (unsigned long)((unsigned int)(arg1));
var1 = (unsigned long)(arg2);
if ((arg0 == 0)) {
return 0xffffffff;
}
if ((arg3 == 0)) {
return 0xffffffff;
}
if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)((arg4 - 1)))))) {
return 0xffffffff;
}
if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
if (((unsigned long)(0xffff) < (unsigned long)((unsigned long)(arg2)))) {
return 0xffffffff;
}
if (((((unsigned int)(arg1) == (unsigned int)(arg4)) | (arg1 < arg4)) == 0)) {
return 0xfffffffe;
}
index = 0;
var7 = 0;
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return produced;
}
do {
carry = (var7 + (unsigned int)(((unsigned int)((unsigned short)(*(short *)((var0 + index * 4)))) * var1)));
var16 = (unsigned long)((unsigned int)(((unsigned int)(carry) >> 16)));
*(int *)(((long)arg3 + index * 4)) = (unsigned short)((carry & 0xffff));
index = (index + 1);
var7 = var16;
} while (((((unsigned int)(produced) == (unsigned int)(index)) | ((long)(produced) < (long)(index))) == 0));
if (((long)(arg4) <= (long)(produced))) {
return produced;
}
if (((unsigned long)((unsigned int)(var16)) == 0)) {
return produced;
}
var18 = (long)(produced);
var19 = (produced + 1);
produced = (unsigned long)((unsigned int)(var19));
*(int *)(((long)arg3 + var18 * 4)) = var16;
return (unsigned int)(var19);
}