Fixture 185
subword signed division
C · 7 functions · 4 lanes · 28 of 28 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
Signed division at 8 and 16 bits.
COVERAGE TARGET: Cbw and Cwd. x86 divides through a register PAIR, and the pair is built by a sign-extension instruction chosen for the operand width: cbw (al -> ax) before idiv r/m8, cwd (ax -> dx:ax) before idiv r/m16, cdq/cqo at 32 and 64. The corpus divides only at 32 and 64 bits, so cbw and cwd are never lifted — and getting them wrong is invisible on non-negative inputs, because zero-extension and sign-extension agree there.
Every function is therefore exercised with negative dividends, and every divisor is guarded: x / 0 is undefined, and so is INT_MIN / -1 at every width, including the promoted int the sub-word operands become.
#include <stdint.h>
/* Signed division at 8 and 16 bits.
*
* COVERAGE TARGET: `Cbw` and `Cwd`. x86 divides through a register PAIR, and
* the pair is built by a sign-extension instruction chosen for the operand
* width: `cbw` (al -> ax) before `idiv r/m8`, `cwd` (ax -> dx:ax) before `idiv
* r/m16`, `cdq`/`cqo` at 32 and 64. The corpus divides only at 32 and 64 bits,
* so `cbw` and `cwd` are never lifted — and getting them wrong is invisible on
* non-negative inputs, because zero-extension and sign-extension agree there.
*
* Every function is therefore exercised with negative dividends, and every
* divisor is guarded: `x / 0` is undefined, and so is `INT_MIN / -1` at every
* width, including the promoted `int` the sub-word operands become. */
__attribute__((noinline)) int32_t divide_signed_bytes(int32_t left,
int32_t right) {
int8_t dividend = (int8_t)left;
int8_t divisor = (int8_t)right;
if (divisor == 0) {
return 0;
}
/* `INT8_MIN / -1` is 128, which is not an `int8_t`; the promotion to `int`
* makes it defined, and the cast back is what x86 computes in `al`. */
if (dividend == INT8_MIN && divisor == -1) {
return INT8_MIN;
}
return (int32_t)(int8_t)(dividend / divisor);
}
__attribute__((noinline)) int32_t remainder_signed_bytes(int32_t left,
int32_t right) {
int8_t dividend = (int8_t)left;
int8_t divisor = (int8_t)right;
if (divisor == 0) {
return 0;
}
if (dividend == INT8_MIN && divisor == -1) {
return 0;
}
/* C truncates toward zero, so the remainder carries the DIVIDEND's sign —
* the fact a zero-extending recovery gets wrong for every negative input. */
return (int32_t)(int8_t)(dividend % divisor);
}
__attribute__((noinline)) int32_t divide_signed_shorts(int32_t left,
int32_t right) {
int16_t dividend = (int16_t)left;
int16_t divisor = (int16_t)right;
if (divisor == 0) {
return 0;
}
if (dividend == INT16_MIN && divisor == -1) {
return INT16_MIN;
}
return (int32_t)(int16_t)(dividend / divisor);
}
__attribute__((noinline)) int32_t remainder_signed_shorts(int32_t left,
int32_t right) {
int16_t dividend = (int16_t)left;
int16_t divisor = (int16_t)right;
if (divisor == 0) {
return 0;
}
if (dividend == INT16_MIN && divisor == -1) {
return 0;
}
return (int32_t)(int16_t)(dividend % divisor);
}
/* The unsigned siblings, which use `xor ah,ah` / `xor dx,dx` instead of
* `cbw` / `cwd`. Present so a recovery that sign-extends everything is caught
* as surely as one that zero-extends everything. */
__attribute__((noinline)) int32_t divide_unsigned_bytes(int32_t left,
int32_t right) {
uint8_t dividend = (uint8_t)left;
uint8_t divisor = (uint8_t)right;
if (divisor == 0u) {
return 0;
}
return (int32_t)(uint8_t)(dividend / divisor);
}
__attribute__((noinline)) int32_t divide_unsigned_shorts(int32_t left,
int32_t right) {
uint16_t dividend = (uint16_t)left;
uint16_t divisor = (uint16_t)right;
if (divisor == 0u) {
return 0;
}
return (int32_t)(uint16_t)(dividend / divisor);
}
/* Division by a CONSTANT at sub-word width: the compiler replaces the divide
* with a multiply-high and a shift, and the correction step for a negative
* dividend is where a mis-recovered sign extension shows up as an off-by-one. */
__attribute__((noinline)) int32_t divide_short_by_seven(int32_t value) {
int16_t dividend = (int16_t)value;
return (int32_t)(int16_t)(dividend / 7);
} 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
7/7divide_short_by_seven pass 8 lines
// glaurung: divide_short_by_seven @ 0x1360
int32_t divide_short_by_seven(int32_t arg0) {
short dividend;
// x86-64 prologue: save rbp
dividend = arg0;
// x86-64 epilogue: restore rbp
return (int)((short)(((int)((((long long)(int)((((unsigned long)((long)((int)(dividend))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(7)))));
} divide_signed_bytes pass 33 lines
// glaurung: divide_signed_bytes @ 0x1100
int32_t divide_signed_bytes(int32_t arg0, int32_t arg1) {
signed char dividend;
signed char divisor;
int local_4;
long var6;
long var7;
int var9;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned int)(divisor)) != 0)) {
if (((unsigned long)((unsigned int)(dividend)) != 0xffffff80)) {
var6 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var7 = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)));
var9 = (int)((signed char)((var7 & 255)));
local_4 = var9;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((unsigned long)((unsigned int)(divisor)) != 0xffffffff)) {
var6 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var7 = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)));
var9 = (int)((signed char)((var7 & 255)));
local_4 = var9;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
return (unsigned int)(-128);
} else {
return 0;
}
} divide_signed_shorts pass 35 lines
// glaurung: divide_signed_shorts @ 0x11e0
int32_t divide_signed_shorts(int32_t arg0, int32_t arg1) {
short dividend;
short divisor;
int local_4;
long ret;
long var6;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned int)(divisor)) != 0)) {
if (((unsigned long)((unsigned int)(dividend)) != 0xffff8000)) {
var6 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
ret = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)));
local_4 = (short)(ret);
ret = (unsigned long)((unsigned int)(local_4));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((unsigned long)((unsigned int)(divisor)) != 0xffffffff)) {
var6 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
ret = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)));
local_4 = (short)(ret);
ret = (unsigned long)((unsigned int)(local_4));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_4 = -0x8000LL;
} else {
local_4 = 0;
}
ret = (unsigned long)((unsigned int)(local_4));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} divide_unsigned_bytes pass 13 lines
// glaurung: divide_unsigned_bytes @ 0x12c0
int32_t divide_unsigned_bytes(int32_t arg0, int32_t arg1) {
unsigned char dividend;
unsigned char divisor;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned long)(divisor)) != 0)) {
return (unsigned int)((unsigned char)((((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned int)(dividend)))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned int)(dividend))) / (int)((unsigned int)(divisor)))) & 255)));
} else {
return 0;
}
} divide_unsigned_shorts pass 13 lines
// glaurung: divide_unsigned_shorts @ 0x1310
int32_t divide_unsigned_shorts(int32_t arg0, int32_t arg1) {
unsigned short dividend;
unsigned short divisor;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned long)(divisor)) != 0)) {
return (unsigned int)((unsigned short)((((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned int)(dividend)))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned int)(dividend))) / (int)((unsigned int)(divisor)))) & 0xffff)));
} else {
return 0;
}
} remainder_signed_bytes pass 39 lines
// glaurung: remainder_signed_bytes @ 0x1170
int32_t remainder_signed_bytes(int32_t arg0, int32_t arg1) {
signed char dividend;
signed char divisor;
int local_4;
long t76;
long var10;
int var11;
long var6;
long var8;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned int)(divisor)) != 0)) {
if (((unsigned long)((unsigned int)(dividend)) != 0xffffff80)) {
var6 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var8 = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) % (int)(divisor)));
t76 = (var8 & 255);
var10 = (t76 & 255);
var11 = (int)((signed char)((var10 & 255)));
local_4 = var11;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((unsigned long)((unsigned int)(divisor)) != 0xffffffff)) {
var6 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var8 = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) % (int)(divisor)));
t76 = (var8 & 255);
var10 = (t76 & 255);
var11 = (int)((signed char)((var10 & 255)));
local_4 = var11;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
return 0;
} else {
return 0;
}
} remainder_signed_shorts pass 47 lines
// glaurung: remainder_signed_shorts @ 0x1250
int32_t remainder_signed_shorts(int32_t arg0, int32_t arg1) {
short dividend;
short divisor;
int local_4;
long ret;
long t76;
long var6;
long var7;
long var8;
long var9;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned int)(divisor)) != 0)) {
if (((unsigned long)((unsigned int)(dividend)) != 0xffff8000)) {
var6 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var7 = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)));
var8 = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) % (int)(divisor)));
t76 = (var8 & 0xffff);
var9 = (var7 & -0x10000LL);
ret = (var9 | (t76 & 0xffff));
local_4 = (short)(ret);
ret = (unsigned long)((unsigned int)(local_4));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((unsigned long)((unsigned int)(divisor)) != 0xffffffff)) {
var6 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var7 = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)));
var8 = ((int)((((long long)(int)(var6) * (((long long)1) << 32)) + (unsigned int)(dividend)) % (int)(divisor)));
t76 = (var8 & 0xffff);
var9 = (var7 & -0x10000LL);
ret = (var9 | (t76 & 0xffff));
local_4 = (short)(ret);
ret = (unsigned long)((unsigned int)(local_4));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_4 = 0;
} else {
local_4 = 0;
}
ret = (unsigned long)((unsigned int)(local_4));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
7/7divide_short_by_seven pass 6 lines
// glaurung: divide_short_by_seven @ 0x1210
int32_t divide_short_by_seven(int32_t arg0) {
int var1;
var1 = ((int)((short)((arg0 & 0xffff))) * 0x4925);
return (unsigned int)(((unsigned long)((unsigned int)(((int)(var1) >> 17))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) >> 31)))));
} divide_signed_bytes pass 50 lines
// glaurung: divide_signed_bytes @ 0x1100
int32_t divide_signed_bytes(int32_t arg0, int32_t arg1) {
long ret;
long t5;
long t69;
long t70;
long t71;
long t73;
int var1;
long var11;
long var13;
long var2;
long var5;
int var6;
int var8;
var1 = ((unsigned long)((unsigned int)(arg1)) << 24);
var2 = (unsigned long)((unsigned int)(var1));
if (((unsigned long)((unsigned int)(var1)) == 0)) {
return 0;
}
var5 = (unsigned long)((unsigned int)((arg0 << 24)));
if (((unsigned long)((unsigned int)(var5)) != 0x80000000)) {
var6 = (int)((signed char)((arg1 & 255)));
var8 = ((int)(var5) >> 24);
ret = (unsigned long)((unsigned int)(var8));
t5 = ((short)(var8) >> 15);
var11 = (t5 & 0xffff);
t69 = ((unsigned long)((unsigned int)(var6)) & 0xffff);
t70 = (var11 & 0xffff);
t71 = ((unsigned long)((unsigned int)(var8)) & 0xffff);
t73 = ((short)((((int)(short)(t70) * (((int)1) << 16)) + (unsigned short)(t71)) / (short)(t69)));
var13 = (t73 & 0xffff);
return (int)((signed char)((var13 & 255)));
}
ret = 0xffffff80;
if (((unsigned long)((unsigned int)(var2)) == 0xff000000)) {
return ret;
}
var6 = (int)((signed char)((arg1 & 255)));
var8 = ((int)(var5) >> 24);
ret = (unsigned long)((unsigned int)(var8));
t5 = ((short)(var8) >> 15);
var11 = (t5 & 0xffff);
t69 = ((unsigned long)((unsigned int)(var6)) & 0xffff);
t70 = (var11 & 0xffff);
t71 = ((unsigned long)((unsigned int)(var8)) & 0xffff);
t73 = ((short)((((int)(short)(t70) * (((int)1) << 16)) + (unsigned short)(t71)) / (short)(t69)));
var13 = (t73 & 0xffff);
return (int)((signed char)((var13 & 255)));
} divide_signed_shorts pass 32 lines
// glaurung: divide_signed_shorts @ 0x1170
int32_t divide_signed_shorts(int32_t arg0, int32_t arg1) {
long ret;
int var1;
long var11;
long var2;
long var5;
int var6;
int var8;
var1 = ((unsigned long)((unsigned int)(arg1)) << 16);
var2 = (unsigned long)((unsigned int)(var1));
if (((unsigned long)((unsigned int)(var1)) == 0)) {
return 0;
}
var5 = (unsigned long)((unsigned int)((arg0 << 16)));
if (((unsigned long)((unsigned int)(var5)) != 0x80000000)) {
var6 = (int)((short)((arg1 & 0xffff)));
var8 = ((int)(var5) >> 16);
var11 = (((unsigned long)((long)((int)(var8))) >> 32) & 0xffffffff);
ret = ((int)((((long long)(int)(var11) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)((unsigned long)((unsigned int)(var8)))))) / (int)(var6)));
return (int)((short)(ret));
}
ret = 0xffff8000;
if (((unsigned long)((unsigned int)(var2)) == 0xffff0000)) {
return ret;
}
var6 = (int)((short)((arg1 & 0xffff)));
var8 = ((int)(var5) >> 16);
var11 = (((unsigned long)((long)((int)(var8))) >> 32) & 0xffffffff);
ret = ((int)((((long long)(int)(var11) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)((unsigned long)((unsigned int)(var8)))))) / (int)(var6)));
return (int)((short)(ret));
} divide_unsigned_bytes pass 15 lines
// glaurung: divide_unsigned_bytes @ 0x11d0
int32_t divide_unsigned_bytes(int32_t arg0, int32_t arg1) {
long t136;
long t71;
long t72;
int var1;
if (((unsigned long)((unsigned char)((arg1 & 255))) == 0)) {
return 0;
}
var1 = (unsigned int)((unsigned char)((arg0 & 255)));
t136 = (((unsigned long)((unsigned int)(var1)) >> 8) & 255);
t71 = ((unsigned long)((unsigned int)(var1)) & 255);
t72 = ((unsigned long)((unsigned int)(arg1)) & 255);
return (unsigned int)((unsigned char)((((((unsigned char)(((((unsigned short)(unsigned char)(t136) << 8) | (unsigned char)(t71)) / (unsigned char)(t72)))) & 255) | ((((unsigned char)(((((unsigned short)(unsigned char)(t136) << 8) | (unsigned char)(t71)) % (unsigned char)(t72)))) & 255) << 8)) & 255)));
} divide_unsigned_shorts pass 7 lines
// glaurung: divide_unsigned_shorts @ 0x11f0
int32_t divide_unsigned_shorts(int32_t arg0, int32_t arg1) {
if (((unsigned long)((unsigned short)((arg1 & 0xffff))) == 0)) {
return 0;
}
return (unsigned int)((unsigned short)((((unsigned short)(((((unsigned int)(unsigned short)(((unsigned long)((unsigned int)(0)) & 0xffff)) << 16) | (unsigned short)(((unsigned long)((unsigned int)(arg0)) & 0xffff))) / (unsigned short)((arg1 & 0xffff))))) & 0xffff)));
} remainder_signed_bytes pass 49 lines
// glaurung: remainder_signed_bytes @ 0x1140
int32_t remainder_signed_bytes(int32_t arg0, int32_t arg1) {
long ret;
long t5;
long t69;
long t70;
long t71;
long t74;
long var11;
long var15;
int var2;
long var3;
long var5;
int var6;
int var8;
ret = 0;
var2 = ((unsigned long)((unsigned int)(arg1)) << 24);
var3 = (unsigned long)((unsigned int)(var2));
if (((unsigned long)((unsigned int)(var2)) != 0)) {
var5 = (unsigned long)((unsigned int)((arg0 << 24)));
if (((unsigned long)((unsigned int)(var5)) != 0x80000000)) {
var6 = (int)((signed char)((arg1 & 255)));
var8 = ((int)(var5) >> 24);
ret = (unsigned long)((unsigned int)(var8));
t5 = ((short)(var8) >> 15);
var11 = (t5 & 0xffff);
t69 = ((unsigned long)((unsigned int)(var6)) & 0xffff);
t70 = (var11 & 0xffff);
t71 = ((unsigned long)((unsigned int)(var8)) & 0xffff);
t74 = ((short)((((int)(short)(t70) * (((int)1) << 16)) + (unsigned short)(t71)) % (short)(t69)));
var15 = (t74 & 0xffff);
return (int)((short)((var15 & 0xffff)));
}
if (((unsigned long)((unsigned int)(var3)) != 0xff000000)) {
var6 = (int)((signed char)((arg1 & 255)));
var8 = ((int)(var5) >> 24);
ret = (unsigned long)((unsigned int)(var8));
t5 = ((short)(var8) >> 15);
var11 = (t5 & 0xffff);
t69 = ((unsigned long)((unsigned int)(var6)) & 0xffff);
t70 = (var11 & 0xffff);
t71 = ((unsigned long)((unsigned int)(var8)) & 0xffff);
t74 = ((short)((((int)(short)(t70) * (((int)1) << 16)) + (unsigned short)(t71)) % (short)(t69)));
var15 = (t74 & 0xffff);
return (int)((short)((var15 & 0xffff)));
}
}
return ret;
} remainder_signed_shorts pass 32 lines
// glaurung: remainder_signed_shorts @ 0x11a0
int32_t remainder_signed_shorts(int32_t arg0, int32_t arg1) {
long ret;
long var11;
int var13;
int var2;
long var3;
long var5;
int var6;
int var8;
ret = 0;
var2 = ((unsigned long)((unsigned int)(arg1)) << 16);
var3 = (unsigned long)((unsigned int)(var2));
if (((unsigned long)((unsigned int)(var2)) != 0)) {
var5 = (unsigned long)((unsigned int)((arg0 << 16)));
if (((unsigned long)((unsigned int)(var5)) != 0x80000000)) {
var6 = (int)((short)((arg1 & 0xffff)));
var8 = ((int)(var5) >> 16);
var11 = (((unsigned long)((long)((int)(var8))) >> 32) & 0xffffffff);
var13 = ((int)((((long long)(int)(var11) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)((unsigned long)((unsigned int)(var8)))))) % (int)(var6)));
return (unsigned int)(var13);
}
if (((unsigned long)((unsigned int)(var3)) != 0xffff0000)) {
var6 = (int)((short)((arg1 & 0xffff)));
var8 = ((int)(var5) >> 16);
var11 = (((unsigned long)((long)((int)(var8))) >> 32) & 0xffffffff);
var13 = ((int)((((long long)(int)(var11) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)((unsigned long)((unsigned int)(var8)))))) % (int)(var6)));
return (unsigned int)(var13);
}
}
return ret;
} gcc -O0
7/7divide_short_by_seven pass 10 lines
// glaurung: divide_short_by_seven @ 0x129f
int32_t divide_short_by_seven(int32_t arg0) {
short dividend;
long var6;
// x86-64 prologue: save rbp
dividend = arg0;
var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((int)((short)(((unsigned int)((unsigned short)(dividend)) & 0xffff))) * 0x4925))) >> 16)));
// x86-64 epilogue: restore rbp
return (int)((short)(((unsigned long)((unsigned int)(((var6 & -0x10000LL) | (((short)((var6 & 0xffff)) >> 1) & 0xffff)))) - (unsigned long)((unsigned int)((((unsigned int)((unsigned short)(dividend)) & -0x10000LL) | (((short)(((unsigned int)((unsigned short)(dividend)) & 0xffff)) >> 15) & 0xffff)))))));
} divide_signed_bytes pass 27 lines
// glaurung: divide_signed_bytes @ 0x10f9
int32_t divide_signed_bytes(int32_t arg0, int32_t arg1) {
signed char dividend;
signed char divisor;
long var4;
long var5;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned char)(divisor)) != 0)) {
if (((unsigned long)((unsigned char)(dividend)) != 128)) {
var4 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var5 = ((int)((((long long)(int)(var4) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)));
// x86-64 epilogue: restore rbp
return (int)((signed char)((var5 & 255)));
}
if (((unsigned long)((unsigned char)(divisor)) != 255)) {
var4 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var5 = ((int)((((long long)(int)(var4) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)));
// x86-64 epilogue: restore rbp
return (int)((signed char)((var5 & 255)));
}
return 0xffffff80;
} else {
return 0;
}
} divide_signed_shorts pass 27 lines
// glaurung: divide_signed_shorts @ 0x118f
int32_t divide_signed_shorts(int32_t arg0, int32_t arg1) {
short dividend;
short divisor;
long ret;
long var4;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned short)(divisor)) != 0)) {
if (((unsigned long)((unsigned short)(dividend)) != 0x8000)) {
var4 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
ret = (int)((short)(((int)((((long long)(int)(var4) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)))));
// x86-64 epilogue: restore rbp
return (int)((short)(ret));
}
if (((unsigned long)((unsigned short)(divisor)) != 0xffff)) {
var4 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
ret = (int)((short)(((int)((((long long)(int)(var4) * (((long long)1) << 32)) + (unsigned int)(dividend)) / (int)(divisor)))));
// x86-64 epilogue: restore rbp
return (int)((short)(ret));
}
return 0xffff8000;
} else {
return 0;
}
} divide_unsigned_bytes pass 19 lines
// glaurung: divide_unsigned_bytes @ 0x122d
int32_t divide_unsigned_bytes(int32_t arg0, int32_t arg1) {
unsigned char dividend;
unsigned char divisor;
long t144;
long t71;
int var3;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if ((divisor != 0)) {
var3 = (unsigned int)((unsigned char)((dividend & 255)));
t144 = (((unsigned long)((unsigned int)(var3)) >> 8) & 255);
t71 = ((unsigned long)((unsigned int)(var3)) & 255);
return (unsigned int)((unsigned char)((((((unsigned char)(((((unsigned short)(unsigned char)(t144) << 8) | (unsigned char)(t71)) / (unsigned char)(divisor)))) & 255) | ((((unsigned char)(((((unsigned short)(unsigned char)(t144) << 8) | (unsigned char)(t71)) % (unsigned char)(divisor)))) & 255) << 8)) & 255)));
} else {
return 0;
}
} divide_unsigned_shorts pass 13 lines
// glaurung: divide_unsigned_shorts @ 0x1263
int32_t divide_unsigned_shorts(int32_t arg0, int32_t arg1) {
unsigned short dividend;
unsigned short divisor;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if ((divisor != 0)) {
return (unsigned int)((unsigned short)((((unsigned short)(((((unsigned int)(unsigned short)((0 & 0xffff)) << 16) | (unsigned short)(((unsigned int)(dividend) & 0xffff))) / (unsigned short)(divisor)))) & 0xffff)));
} else {
return 0;
}
} remainder_signed_bytes pass 27 lines
// glaurung: remainder_signed_bytes @ 0x1143
int32_t remainder_signed_bytes(int32_t arg0, int32_t arg1) {
signed char dividend;
signed char divisor;
long var4;
int var6;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned char)(divisor)) != 0)) {
if (((unsigned long)((unsigned char)(dividend)) != 128)) {
var4 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var6 = ((int)((((long long)(int)(var4) * (((long long)1) << 32)) + (unsigned int)(dividend)) % (int)(divisor)));
// x86-64 epilogue: restore rbp
return (int)((signed char)(((unsigned long)((unsigned int)(var6)) & 255)));
}
if (((unsigned long)((unsigned char)(divisor)) != 255)) {
var4 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var6 = ((int)((((long long)(int)(var4) * (((long long)1) << 32)) + (unsigned int)(dividend)) % (int)(divisor)));
// x86-64 epilogue: restore rbp
return (int)((signed char)(((unsigned long)((unsigned int)(var6)) & 255)));
}
return 0;
} else {
return 0;
}
} remainder_signed_shorts pass 27 lines
// glaurung: remainder_signed_shorts @ 0x11dd
int32_t remainder_signed_shorts(int32_t arg0, int32_t arg1) {
short dividend;
short divisor;
long var4;
int var6;
// x86-64 prologue: save rbp
dividend = arg0;
divisor = arg1;
if (((unsigned long)((unsigned short)(divisor)) != 0)) {
if (((unsigned long)((unsigned short)(dividend)) != 0x8000)) {
var4 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var6 = ((int)((((long long)(int)(var4) * (((long long)1) << 32)) + (unsigned int)(dividend)) % (int)(divisor)));
// x86-64 epilogue: restore rbp
return (int)((short)(var6));
}
if (((unsigned long)((unsigned short)(divisor)) != 0xffff)) {
var4 = (((unsigned long)((long)(dividend)) >> 32) & 0xffffffff);
var6 = ((int)((((long long)(int)(var4) * (((long long)1) << 32)) + (unsigned int)(dividend)) % (int)(divisor)));
// x86-64 epilogue: restore rbp
return (int)((short)(var6));
}
return 0;
} else {
return 0;
}
} gcc -O2
7/7divide_short_by_seven pass 4 lines
// glaurung: divide_short_by_seven @ 0x1200
int32_t divide_short_by_seven(int32_t arg0) {
return (int)((short)(((unsigned long)((unsigned int)(((int)(((int)((short)((arg0 & 0xffff))) * 0x4925)) >> 17))) - ((arg0 & -0x10000LL) | (((short)((arg0 & 0xffff)) >> 15) & 0xffff)))));
} divide_signed_bytes pass 27 lines
// glaurung: divide_signed_bytes @ 0x1100
int32_t divide_signed_bytes(int32_t arg0, int32_t arg1) {
long ret;
int var1;
int var2;
long var3;
long var4;
ret = 0;
if (((unsigned long)((unsigned char)((arg1 & 255))) == 0)) {
return ret;
}
if (((unsigned long)((unsigned char)((arg0 & 255))) != 128)) {
var1 = (int)((signed char)((arg0 & 255)));
var2 = (int)((signed char)((arg1 & 255)));
var3 = (((unsigned long)((long)((int)(var1))) >> 32) & 0xffffffff);
var4 = ((int)((((long long)(int)(var3) * (((long long)1) << 32)) + (unsigned int)(var1)) / (int)(var2)));
return (int)((signed char)((var4 & 255)));
}
if (((unsigned long)((unsigned char)((arg1 & 255))) != 255)) {
var1 = (int)((signed char)((arg0 & 255)));
var2 = (int)((signed char)((arg1 & 255)));
var3 = (((unsigned long)((long)((int)(var1))) >> 32) & 0xffffffff);
var4 = ((int)((((long long)(int)(var3) * (((long long)1) << 32)) + (unsigned int)(var1)) / (int)(var2)));
return (int)((signed char)((var4 & 255)));
}
return 0xffffff80;
} divide_signed_shorts pass 26 lines
// glaurung: divide_signed_shorts @ 0x1160
int32_t divide_signed_shorts(int32_t arg0, int32_t arg1) {
long ret;
int var1;
int var2;
long var3;
ret = 0;
if (((unsigned long)((unsigned short)((arg1 & 0xffff))) == 0)) {
return ret;
}
if (((unsigned long)((unsigned short)((arg0 & 0xffff))) != 0x8000)) {
var1 = (int)((short)((arg0 & 0xffff)));
var2 = (int)((short)((arg1 & 0xffff)));
var3 = (((unsigned long)((long)((int)(var1))) >> 32) & 0xffffffff);
ret = ((int)((((long long)(int)(var3) * (((long long)1) << 32)) + (unsigned int)(var1)) / (int)(var2)));
return (int)((short)(ret));
}
if (((unsigned long)((unsigned short)((arg1 & 0xffff))) != 0xffff)) {
var1 = (int)((short)((arg0 & 0xffff)));
var2 = (int)((short)((arg1 & 0xffff)));
var3 = (((unsigned long)((long)((int)(var1))) >> 32) & 0xffffffff);
ret = ((int)((((long long)(int)(var3) * (((long long)1) << 32)) + (unsigned int)(var1)) / (int)(var2)));
return (int)((short)(ret));
}
return 0xffff8000;
} divide_unsigned_bytes pass 17 lines
// glaurung: divide_unsigned_bytes @ 0x11c0
int32_t divide_unsigned_bytes(int32_t arg0, int32_t arg1) {
long ret;
long t136;
long t71;
long t72;
int var2;
ret = 0;
if (((unsigned long)((unsigned char)((arg1 & 255))) != 0)) {
var2 = (unsigned int)((unsigned char)((arg0 & 255)));
t136 = (((unsigned long)((unsigned int)(var2)) >> 8) & 255);
t71 = ((unsigned long)((unsigned int)(var2)) & 255);
t72 = ((unsigned long)((unsigned int)(arg1)) & 255);
ret = (unsigned int)((unsigned char)((((((unsigned char)(((((unsigned short)(unsigned char)(t136) << 8) | (unsigned char)(t71)) / (unsigned char)(t72)))) & 255) | ((((unsigned char)(((((unsigned short)(unsigned char)(t136) << 8) | (unsigned char)(t71)) % (unsigned char)(t72)))) & 255) << 8)) & 255)));
}
return ret;
} divide_unsigned_shorts pass 12 lines
// glaurung: divide_unsigned_shorts @ 0x11e0
int32_t divide_unsigned_shorts(int32_t arg0, int32_t arg1) {
unsigned short dividend;
long var0;
long var3;
var0 = (unsigned long)((unsigned int)(arg0));
var3 = 0;
if (((unsigned long)((unsigned short)((arg1 & 0xffff))) != 0)) {
var3 = (unsigned int)((unsigned short)((((unsigned short)(((((unsigned int)(unsigned short)(((unsigned long)((unsigned int)(0)) & 0xffff)) << 16) | (unsigned short)((var0 & 0xffff))) / (unsigned short)((arg1 & 0xffff))))) & 0xffff)));
}
return (unsigned int)(var3);
} remainder_signed_bytes pass 19 lines
// glaurung: remainder_signed_bytes @ 0x1130
int32_t remainder_signed_bytes(int32_t arg0, int32_t arg1) {
long var1;
int var2;
var1 = 0;
if (((unsigned long)((unsigned char)((arg1 & 255))) != 0)) {
if (((unsigned long)((unsigned char)((arg0 & 255))) != 128)) {
var2 = (int)((signed char)((arg0 & 255)));
var1 = (unsigned long)((unsigned int)(((int)((((long long)(int)((((unsigned long)((long)((int)(var2))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var2)) % (int)((int)((signed char)((arg1 & 255))))))));
return (unsigned int)(var1);
}
if (((unsigned long)((unsigned char)((arg1 & 255))) == 255)) {
return (unsigned int)(var1);
}
var2 = (int)((signed char)((arg0 & 255)));
var1 = (unsigned long)((unsigned int)(((int)((((long long)(int)((((unsigned long)((long)((int)(var2))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var2)) % (int)((int)((signed char)((arg1 & 255))))))));
}
return (unsigned int)(var1);
} remainder_signed_shorts pass 19 lines
// glaurung: remainder_signed_shorts @ 0x1190
int32_t remainder_signed_shorts(int32_t arg0, int32_t arg1) {
long var1;
int var2;
var1 = 0;
if (((unsigned long)((unsigned short)((arg1 & 0xffff))) != 0)) {
if (((unsigned long)((unsigned short)((arg0 & 0xffff))) != 0x8000)) {
var2 = (int)((short)((arg0 & 0xffff)));
var1 = (unsigned long)((unsigned int)(((int)((((long long)(int)((((unsigned long)((long)((int)(var2))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var2)) % (int)((int)((short)((arg1 & 0xffff))))))));
return (unsigned int)(var1);
}
if (((unsigned long)((unsigned short)((arg1 & 0xffff))) == 0xffff)) {
return (unsigned int)(var1);
}
var2 = (int)((short)((arg0 & 0xffff)));
var1 = (unsigned long)((unsigned int)(((int)((((long long)(int)((((unsigned long)((long)((int)(var2))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var2)) % (int)((int)((short)((arg1 & 0xffff))))))));
}
return (unsigned int)(var1);
}