Fixture 55
modular arithmetic
C · 3 functions · 4 lanes · 12 of 12 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
Euclid, extended Euclid, modular exponentiation by square-and-multiply, and a modular inverse. Extended Euclid carries three simultaneous recurrences through one loop, which is a strong test of value identity tracking.
#include <stdint.h>
/* Euclid, extended Euclid, modular exponentiation by square-and-multiply, and
* a modular inverse. Extended Euclid carries three simultaneous recurrences
* through one loop, which is a strong test of value identity tracking. */
__attribute__((noinline)) int32_t gcd_i32(int32_t left, int32_t right) {
int32_t guard;
if (left < 0 || right < 0) {
return -1;
}
for (guard = 0; guard < 64 && right != 0; ++guard) {
int32_t remainder = left % right;
left = right;
right = remainder;
}
return left;
}
__attribute__((noinline)) int32_t
extended_gcd(int32_t a, int32_t b, int32_t *x_out, int32_t *y_out) {
int32_t old_r, r, old_s, s, old_t, t;
int32_t guard;
if (x_out == 0 || y_out == 0 || a < 0 || b < 0 || a > 100000 ||
b > 100000) {
return -1;
}
old_r = a;
r = b;
old_s = 1;
s = 0;
old_t = 0;
t = 1;
for (guard = 0; guard < 64 && r != 0; ++guard) {
int32_t quotient = old_r / r;
int32_t next_r = old_r - quotient * r;
int32_t next_s = old_s - quotient * s;
int32_t next_t = old_t - quotient * t;
old_r = r;
r = next_r;
old_s = s;
s = next_s;
old_t = t;
t = next_t;
}
*x_out = old_s;
*y_out = old_t;
return old_r;
}
__attribute__((noinline)) uint32_t
mod_pow(uint32_t base, uint32_t exponent, uint32_t modulus) {
uint64_t result = 1;
uint64_t factor;
int32_t guard;
if (modulus == 0u || modulus == 1u) {
return 0;
}
factor = (uint64_t)base % (uint64_t)modulus;
for (guard = 0; guard < 32 && exponent != 0u; ++guard) {
if ((exponent & 1u) != 0u) {
result = (result * factor) % (uint64_t)modulus;
}
factor = (factor * factor) % (uint64_t)modulus;
exponent >>= 1;
}
return (uint32_t)result;
} 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
3/3extended_gcd pass 64 lines
// glaurung: extended_gcd @ 0x1190
int32_t extended_gcd(int32_t arg0, int32_t arg1, int32_t * arg2, int32_t * arg3) {
int old_r;
int r;
int old_s;
int s;
int old_t;
int t;
int guard;
int quotient;
int next_r;
int next_s;
int next_t;
int local_4;
signed char local_4d;
if ((arg2 != 0)) {
if ((arg3 != 0)) {
if ((0 <= (long)(arg0))) {
if ((0 <= (long)(arg1))) {
if (((((unsigned long)((unsigned int)(arg0)) == 0x186a0) | ((long)(arg0) < 0x186a0)) != 0)) {
if ((((unsigned long)((unsigned int)(arg1)) == 0x186a0) | ((long)(arg1) < 0x186a0))) {
goto L_11f2;
}
}
}
}
}
}
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_11f2: ;
old_r = arg0;
r = arg1;
old_s = 1;
s = 0;
old_t = 0;
t = 1;
guard = 0;
L_1221: ;
local_4d = 0;
if (((long)(guard) < 64)) {
local_4d = ((unsigned long)((unsigned int)(r)) != 0);
}
if (((unsigned long)((unsigned char)((local_4d & 1))) != 0)) {
quotient = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(old_r))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(old_r)))) / (int)(r)));
next_r = ((unsigned int)(old_r) - (unsigned int)(((unsigned long)((unsigned int)(quotient)) * r)));
next_s = ((unsigned int)(old_s) - (unsigned int)(((unsigned long)((unsigned int)(quotient)) * s)));
next_t = ((unsigned int)(old_t) - (unsigned int)(((unsigned long)((unsigned int)(quotient)) * t)));
old_r = r;
r = next_r;
old_s = s;
s = next_s;
old_t = t;
t = next_t;
guard = ((unsigned int)(guard) + 1);
goto L_1221;
}
*(int *)((long)arg2) = old_s;
*(int *)((long)arg3) = old_t;
local_4 = old_r;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} gcd_i32 pass 36 lines
// glaurung: gcd_i32 @ 0x1100
int32_t gcd_i32(int32_t arg0, int32_t arg1) {
int guard;
int remainder;
signed char local_15;
int local_4;
int local_8;
int local_c;
local_8 = arg0;
local_c = arg1;
if ((0 <= (long)(local_8))) {
if ((0 <= (long)(local_c))) {
goto L_112a;
}
}
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_112a: ;
guard = 0;
L_1131: ;
local_15 = 0;
if (((long)(guard) < 64)) {
local_15 = ((unsigned long)((unsigned int)(local_c)) != 0);
}
if (((unsigned long)((unsigned char)((local_15 & 1))) != 0)) {
remainder = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(local_8))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(local_8)))) % (int)(local_c)));
local_8 = local_c;
local_c = remainder;
guard = ((unsigned int)(guard) + 1);
goto L_1131;
}
local_4 = local_8;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} mod_pow pass 41 lines
// glaurung: mod_pow @ 0x12d0
uint32_t mod_pow(uint32_t arg0, uint32_t arg1, uint32_t arg2) {
unsigned long result;
unsigned long factor;
int guard;
signed char local_25;
int local_4;
long var5;
result = 1;
if ((arg2 != 0)) {
if ((arg2 != 1)) {
goto L_1305;
}
}
local_4 = 0;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_1305: ;
var5 = ((unsigned long)(((((unsigned __int128)(unsigned long)((unsigned long)((unsigned int)(0))) << 64) | (unsigned long)(arg0)) % (unsigned long)(arg2))));
factor = var5;
guard = 0;
L_131b: ;
local_25 = 0;
if (((long)(guard) < 32)) {
local_25 = (arg1 != 0);
}
if (((unsigned long)((unsigned char)((local_25 & 1))) != 0)) {
if (((unsigned long)((unsigned int)((arg1 & 1))) != 0)) {
var5 = ((unsigned long)(((((unsigned __int128)(unsigned long)((unsigned long)((unsigned int)(0))) << 64) | (unsigned long)((result * factor))) % (unsigned long)(arg2))));
result = var5;
}
var5 = ((unsigned long)(((((unsigned __int128)(unsigned long)((unsigned long)((unsigned int)(0))) << 64) | (unsigned long)((factor * factor))) % (unsigned long)(arg2))));
factor = var5;
arg1 = ((unsigned int)(arg1) >> 1);
guard = ((unsigned int)(guard) + 1);
goto L_131b;
}
local_4 = result;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
3/3extended_gcd pass 94 lines
// glaurung: extended_gcd @ 0x1130
int32_t extended_gcd(int32_t arg0, int32_t arg1, int32_t * arg2, int32_t * arg3) {
int old_t;
int s;
int old_r;
int guard;
int old_s;
int r;
int t;
long local_10;
long local_18;
long ret;
long t70;
long var0;
long var1;
long var13;
long var16;
long var20;
long var23;
long var24;
long var26;
long var27;
int var30;
long var31;
int * var5;
long var6;
long var9;
local_10 = var0;
local_18 = var1;
ret = 0xffffffff;
if (((((unsigned long)((unsigned int)(arg1)) == 0x186a0) | ((long)(arg1) < 0x186a0)) == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if (((((unsigned long)((unsigned int)(arg0)) == 0x186a0) | ((long)(arg0) < 0x186a0)) == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
var5 = (int *)arg2;
var6 = (unsigned long)((unsigned int)(arg1));
if (((long)((int)((arg1 | arg0))) < 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if ((var5 == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if ((arg3 == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
if (((unsigned long)((unsigned int)(var6)) == 0)) {
var9 = 1;
old_t = 0;
var13 = (unsigned long)((unsigned int)(arg0));
} else {
var16 = 1;
var20 = 0;
var23 = 0;
var24 = (unsigned long)((unsigned int)(arg0));
s = 0;
var26 = 1;
var27 = var6;
while (1) {
old_r = (unsigned long)((unsigned int)(var27));
t70 = (((unsigned long)((long)((int)(var24))) >> 32) & 0xffffffff);
var30 = ((int)((((long long)(int)(t70) * (((long long)1) << 32)) + (unsigned int)(var24)) / (int)((unsigned long)((unsigned int)(var27)))));
var31 = ((int)((((long long)(int)(t70) * (((long long)1) << 32)) + (unsigned int)(var24)) % (int)((unsigned long)((unsigned int)(var27)))));
var9 = (unsigned long)((unsigned int)(s));
old_t = (unsigned long)((unsigned int)(var26));
var13 = (unsigned long)((unsigned int)(var27));
if (((unsigned long)(62) < (unsigned long)((unsigned long)((unsigned int)(var23))))) {
break;
}
s = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var16)) - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var30)) * var9))))));
var23 = (unsigned long)((unsigned int)((var23 + 1)));
var16 = (unsigned long)((unsigned int)(var9));
var24 = (unsigned long)((unsigned int)(old_r));
var26 = (unsigned long)((unsigned int)((var20 - (unsigned long)((unsigned int)((var30 * old_t))))));
var27 = var31;
var20 = (unsigned long)((unsigned int)(old_t));
if (((unsigned long)((unsigned int)(var31)) == 0)) {
var13 = (unsigned long)((unsigned int)(old_r));
break;
}
}
}
*(int *)((var5)) = var9;
*(int *)(((long)arg3)) = old_t;
ret = (unsigned long)((unsigned int)(var13));
// x86-64 epilogue: tear down frame
return (unsigned int)(var13);
} gcd_i32 pass 35 lines
// glaurung: gcd_i32 @ 0x1100
int32_t gcd_i32(int32_t arg0, int32_t arg1) {
int guard;
long var10;
long var13;
long var4;
long var7;
long var8;
long var9;
if (((long)((int)(((unsigned long)((unsigned int)(arg1)) | arg0))) < 0)) {
return 0xffffffff;
}
var4 = (unsigned long)((unsigned int)(arg0));
if (((unsigned long)((unsigned int)(arg1)) != 0)) {
var7 = 0;
var8 = (unsigned long)((unsigned int)(arg0));
var9 = (unsigned long)((unsigned int)(arg1));
while (1) {
var10 = (unsigned long)((unsigned int)(var8));
var8 = (unsigned long)((unsigned int)(var9));
var13 = ((int)((((long long)(int)((((unsigned long)((long)((int)(var10))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var10)) % (int)((unsigned long)((unsigned int)(var9)))));
var4 = (unsigned long)((unsigned int)(var9));
if (((unsigned long)(62) < (unsigned long)((unsigned long)((unsigned int)(var7))))) {
break;
}
var7 = (unsigned long)((unsigned int)((var7 + 1)));
var9 = var13;
var4 = var8;
if (((unsigned long)((unsigned int)(var13)) == 0)) {
break;
}
}
}
return (unsigned int)(var4);
} mod_pow pass 62 lines
// glaurung: mod_pow @ 0x11d0
uint32_t mod_pow(uint32_t arg0, uint32_t arg1, uint32_t arg2) {
unsigned long result;
unsigned long factor;
int guard;
long cf_27;
long var17;
long var19;
long var2;
long var33;
long var4;
long var42;
long var6;
long zf_27;
var2 = 0;
if (((unsigned long)(arg2) < (unsigned long)(2))) {
return (unsigned int)(var2);
}
if ((arg1 == 0)) {
return 1;
}
var4 = (unsigned long)(arg2);
var6 = 0;
result = 1;
factor = (unsigned long)((unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(arg0)) % (unsigned int)(arg2))))));
var17 = (unsigned long)(arg1);
L_1200: ;
var2 = result;
if (((unsigned long)((unsigned char)((var17 & 1))) == 0)) {
goto L_1230;
}
var19 = (result * factor);
if ((((unsigned long)(var19) >> 32) != 0)) {
var2 = ((unsigned long)(((((unsigned __int128)(unsigned long)((unsigned long)((unsigned int)(0))) << 64) | (unsigned long)(var19)) % (unsigned long)(var4))));
goto L_1230;
}
var2 = (unsigned long)((unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)((unsigned long)((unsigned int)(var19)))) % (unsigned int)(var4))))));
L_1230: ;
var33 = (factor * factor);
if ((((unsigned long)(var33) >> 32) != 0)) {
var42 = ((unsigned long)(((((unsigned __int128)(unsigned long)((unsigned long)((unsigned int)(0))) << 64) | (unsigned long)(var33)) % (unsigned long)(var4))));
if (((unsigned long)((unsigned long)((unsigned int)(var6))) <= (unsigned long)(30))) {
goto L_125e;
}
return (unsigned int)(var2);
}
var42 = (unsigned long)((unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)((unsigned long)((unsigned int)(var33)))) % (unsigned int)(var4))))));
if (((unsigned long)(30) < (unsigned long)((unsigned long)((unsigned int)(var6))))) {
return (unsigned int)(var2);
}
L_125e: ;
var6 = (unsigned long)((unsigned int)((var6 + 1)));
zf_27 = ((unsigned long)((unsigned int)(var17)) == 1);
cf_27 = ((unsigned long)((unsigned long)((unsigned int)(var17))) < (unsigned long)(1));
var17 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var17)) >> 1)));
result = var2;
factor = var42;
if (((cf_27 | zf_27) == 0)) {
goto L_1200;
}
return (unsigned int)(var2);
} gcc -O0
3/3extended_gcd pass 66 lines
// glaurung: extended_gcd @ 0x114e
int32_t extended_gcd(int32_t arg0, int32_t arg1, int32_t * arg2, int32_t * arg3) {
int old_r;
int r;
int old_s;
int s;
int old_t;
int t;
int guard;
int quotient;
int next_r;
int next_s;
int next_t;
// x86-64 prologue: save rbp
if ((arg2 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((arg3 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg0) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg0)) == 0x186a0) | ((long)(arg0) < 0x186a0)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg1)) == 0x186a0) | ((long)(arg1) < 0x186a0)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
old_r = arg0;
r = arg1;
old_s = 1;
s = 0;
old_t = 0;
t = 1;
guard = 0;
while (((((unsigned long)((unsigned int)(guard)) == 63) | ((long)(guard) < 63)) != 0)) {
if (((unsigned long)((unsigned int)(r)) == 0)) {
break;
}
quotient = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(old_r))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(old_r)))) / (int)(r)));
next_r = ((unsigned int)(old_r) - (unsigned int)(((unsigned long)((unsigned int)(quotient)) * r)));
next_s = ((unsigned int)(old_s) - (unsigned int)(((unsigned long)((unsigned int)(quotient)) * s)));
next_t = ((unsigned int)(old_t) - (unsigned int)(((unsigned long)((unsigned int)(quotient)) * t)));
old_r = r;
r = next_r;
old_s = s;
s = next_s;
old_t = t;
t = next_t;
guard = (guard + 1);
}
*(int *)((long)arg2) = old_s;
*(int *)((long)arg3) = old_t;
// x86-64 epilogue: restore rbp
return (unsigned int)(old_r);
} gcd_i32 pass 30 lines
// glaurung: gcd_i32 @ 0x10f9
int32_t gcd_i32(int32_t arg0, int32_t arg1) {
int guard;
int remainder;
int local_14;
int local_18;
// x86-64 prologue: save rbp
local_14 = arg0;
local_18 = arg1;
if (((long)(local_14) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(local_18) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
guard = 0;
while (((((unsigned long)((unsigned int)(guard)) == 63) | ((long)(guard) < 63)) != 0)) {
if (((unsigned long)((unsigned int)(local_18)) == 0)) {
break;
}
remainder = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(local_14))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(local_14)))) % (int)(local_18)));
local_14 = local_18;
local_18 = remainder;
guard = (guard + 1);
}
// x86-64 epilogue: restore rbp
return (unsigned int)(local_14);
} mod_pow pass 31 lines
// glaurung: mod_pow @ 0x1253
uint32_t mod_pow(uint32_t arg0, uint32_t arg1, uint32_t arg2) {
unsigned long result;
unsigned long factor;
int guard;
// x86-64 prologue: save rbp
result = 1;
if ((arg2 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if ((arg2 == 1)) {
// x86-64 epilogue: restore rbp
return 0;
}
factor = (unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)(0) << 32) | (unsigned int)(arg0)) % (unsigned int)(arg2)))));
guard = 0;
while (((((unsigned long)((unsigned int)(guard)) == 31) | ((long)(guard) < 31)) != 0)) {
if ((arg1 == 0)) {
break;
}
if (((unsigned long)((unsigned int)((arg1 & 1))) != 0)) {
result = ((unsigned long)(((((unsigned __int128)(unsigned long)(0) << 64) | (unsigned long)((result * factor))) % (unsigned long)(arg2))));
}
factor = ((unsigned long)(((((unsigned __int128)(unsigned long)(0) << 64) | (unsigned long)((factor * factor))) % (unsigned long)(arg2))));
arg1 = ((unsigned int)(arg1) >> 1);
guard = (guard + 1);
}
// x86-64 epilogue: restore rbp
return result;
} gcc -O2
3/3extended_gcd pass 99 lines
// glaurung: extended_gcd @ 0x1150
int32_t extended_gcd(int32_t arg0, int32_t arg1, int32_t * arg2, int32_t * arg3) {
int s;
int t;
int next_r;
int quotient;
int old_r;
int next_s;
int next_t;
int guard;
int old_s;
int old_t;
long local_18;
long local_8;
long t70;
long var1;
long var13;
long var14;
long var15;
int * var2;
long var24;
long var25;
long var27;
long var28;
long var3;
int var32;
long var33;
long var46;
long var50;
long var8;
int * var9;
if ((arg2 == 0)) {
return (unsigned int)(-1);
}
local_8 = var1;
var2 = (int *)arg3;
local_18 = var3;
if ((arg3 == 0)) {
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
if (((unsigned long)(0x186a0) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
var8 = (unsigned long)((unsigned int)(arg0));
if (((unsigned long)(0x186a0) < (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
// x86-64 epilogue: tear down frame
return 0xffffffff;
}
var9 = (int *)arg2;
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
var13 = 1;
var14 = var8;
var15 = 0;
} else {
var24 = 1;
var25 = 0;
s = 0;
var27 = 0;
var28 = var8;
t = 1;
next_r = arg1;
while (1) {
var32 = (var27 + 1);
var33 = (unsigned long)((unsigned int)(var32));
t70 = (((unsigned long)((long)((int)(var28))) >> 32) & 0xffffffff);
quotient = (unsigned long)((unsigned int)(((int)((((long long)(int)(t70) * (((long long)1) << 32)) + (unsigned int)(var28)) / (int)(next_r)))));
old_r = (unsigned long)((unsigned int)(next_r));
next_r = (unsigned long)((unsigned int)(((int)((((long long)(int)(t70) * (((long long)1) << 32)) + (unsigned int)(var28)) % (int)(next_r)))));
var46 = (unsigned long)((unsigned int)(t));
next_s = (unsigned long)((unsigned int)((var24 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(quotient)) * s))))));
next_t = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var25)) - (unsigned long)((unsigned int)((quotient * t))))));
var50 = (unsigned long)((unsigned int)(s));
var13 = (unsigned long)((unsigned int)(s));
var14 = (unsigned long)((unsigned int)(old_r));
var15 = (unsigned long)((unsigned int)(t));
if (((((unsigned long)((unsigned int)(var32)) == 63) | ((long)((int)(var32)) < 63)) == 0)) {
break;
}
var13 = (unsigned long)((unsigned int)(s));
var14 = (unsigned long)((unsigned int)(old_r));
var15 = (unsigned long)((unsigned int)(t));
if (((unsigned long)((unsigned int)(next_r)) == 0)) {
break;
}
var24 = var50;
var25 = var46;
s = (unsigned long)((unsigned int)(next_s));
var27 = var33;
var28 = (unsigned long)((unsigned int)(old_r));
t = (unsigned long)((unsigned int)(next_t));
}
}
*(int *)((var9)) = var13;
*(int *)((var2)) = var15;
// x86-64 epilogue: tear down frame
return var14;
} gcd_i32 pass 38 lines
// glaurung: gcd_i32 @ 0x1100
int32_t gcd_i32(int32_t arg0, int32_t arg1) {
int guard;
int remainder;
long var0;
long var3;
long var7;
long var8;
int var9;
var0 = (unsigned long)((unsigned int)(arg0));
var3 = (unsigned long)((unsigned int)(arg1));
if (((long)((int)((arg0 | arg1))) < 0)) {
goto L_113f;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_1138;
}
guard = 0;
var7 = var3;
do {
var8 = (unsigned long)((unsigned int)(var7));
var9 = (guard + 1);
guard = (unsigned long)((unsigned int)(var9));
remainder = ((int)((((long long)(int)((((unsigned long)((long)((int)(var0))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var0)) % (int)((unsigned long)((unsigned int)(var7)))));
var0 = (unsigned long)((unsigned int)(var7));
if (((((unsigned long)((unsigned int)(var9)) == 63) | ((long)((int)(var9)) < 63)) == 0)) {
goto L_112e;
}
var7 = (unsigned long)((unsigned int)(remainder));
} while (((unsigned long)((unsigned int)(remainder)) != 0));
L_112e: ;
return (unsigned int)(var8);
L_1138: ;
return (unsigned int)(var0);
L_113f: ;
var8 = 0xffffffff;
goto L_112e;
} mod_pow pass 35 lines
// glaurung: mod_pow @ 0x1200
uint32_t mod_pow(uint32_t arg0, uint32_t arg1, uint32_t arg2) {
unsigned long factor;
unsigned long result;
int guard;
long ret;
long var15;
int var26;
long var8;
ret = 0;
if (((unsigned long)(arg2) <= (unsigned long)(1))) {
return ret;
}
factor = ((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(arg0)) % (unsigned int)(arg2))));
if ((arg1 == 0)) {
return 1;
}
var8 = (unsigned long)(arg2);
result = 1;
guard = 0;
var15 = (unsigned long)(arg1);
do {
if (((unsigned long)((unsigned char)((var15 & 1))) != 0)) {
result = ((unsigned long)(((((unsigned __int128)(unsigned long)((unsigned long)((unsigned int)(0))) << 64) | (unsigned long)((result * factor))) % (unsigned long)(var8))));
}
var26 = (guard + 1);
guard = (unsigned long)((unsigned int)(var26));
var15 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var15)) >> 1)));
if (((((unsigned long)((unsigned int)(var26)) == 31) | ((long)((int)(var26)) < 31)) == 0)) {
return (unsigned int)(result);
}
factor = ((unsigned long)(((((unsigned __int128)(unsigned long)((unsigned long)((unsigned int)(0))) << 64) | (unsigned long)((factor * factor))) % (unsigned long)(var8))));
} while (((unsigned long)((unsigned int)(var15)) != 0));
return (unsigned int)(result);
}