Fixture 207
scaled index addressing
C · 6 functions · 4 lanes · 22 of 24 function-lanes behave identically
One lane has a function that returns a different result after decompilation: clang-O2 (4/6).
An index register SCALED by the element width, at every stride the machine encodes, plus the controls that prove the scale is read rather than assumed.
THE DEFECT THIS EXISTS FOR. Capstone carries an ARM/AArch64 shift on the OPERAND (ArmOperand::shift), not inside the memory-operand struct (ArmOpMem), so a reader that inspects only the mem struct sees [base, index] where the encoding says [base, index, lsl #2]. Both of our ARM arms did exactly that — let scale = None — for as long as they existed. Every effective address in the analysis layer was therefore base + index instead of base + index * 2^n: for lsl #2, wrong by a factor of four, silently, with no diagnostic anywhere. analysis::dispatch, analysis::xrefs and the memory-bound guards all consume that field.
It survived because the ARM lifter compensates locally (lift_arm32:: scaled_memop re-derives the shift from the instruction), so the DECOMPILED C was right while the analysis was wrong — which is invisible to a fixture that only diffs execution. That is why the assertions here are about the recovered subscript arithmetic on every architecture, and why the fixture spans all three element widths rather than testing one.
NOT COVERED BY 109_subscript_commutativity (which spelling produced a subscript), 110_pointer_arithmetic (pointer displacement), or 187_constant_bias_index (a constant added to the index). None of those vary the ELEMENT WIDTH, which is the only thing that changes the encoded scale.
The last two functions are the controls. byte_stride_unscaled indexes a byte array, where the scale is 1 and no shift is encoded at all — a reader that fabricated a scale would break it. shift_as_value shifts the loaded VALUE rather than the index, which must not be folded into an address.
#include <stdint.h>
/* An index register SCALED by the element width, at every stride the machine
* encodes, plus the controls that prove the scale is read rather than assumed.
*
* THE DEFECT THIS EXISTS FOR. Capstone carries an ARM/AArch64 shift on the
* OPERAND (`ArmOperand::shift`), not inside the memory-operand struct
* (`ArmOpMem`), so a reader that inspects only the mem struct sees `[base,
* index]` where the encoding says `[base, index, lsl #2]`. Both of our ARM arms
* did exactly that — `let scale = None` — for as long as they existed. Every
* effective address in the analysis layer was therefore `base + index` instead
* of `base + index * 2^n`: for `lsl #2`, wrong by a factor of four, silently,
* with no diagnostic anywhere. `analysis::dispatch`, `analysis::xrefs` and the
* memory-bound guards all consume that field.
*
* It survived because the ARM lifter compensates locally (`lift_arm32::
* scaled_memop` re-derives the shift from the instruction), so the DECOMPILED C
* was right while the analysis was wrong — which is invisible to a fixture that
* only diffs execution. That is why the assertions here are about the recovered
* subscript arithmetic on every architecture, and why the fixture spans all
* three element widths rather than testing one.
*
* NOT COVERED BY `109_subscript_commutativity` (which spelling produced a
* subscript), `110_pointer_arithmetic` (pointer displacement), or
* `187_constant_bias_index` (a constant added to the index). None of those vary
* the ELEMENT WIDTH, which is the only thing that changes the encoded scale.
*
* The last two functions are the controls. `byte_stride_unscaled` indexes a
* byte array, where the scale is 1 and no shift is encoded at all — a reader
* that fabricated a scale would break it. `shift_as_value` shifts the loaded
* VALUE rather than the index, which must not be folded into an address.
*/
__attribute__((noinline)) int32_t word_stride_sum(const int32_t *values,
int32_t count) {
int32_t total = 0;
if (values == 0 || count < 0 || count > 16) {
return -1;
}
/* 4-byte elements: `lsl #2` on ARM/AArch64, `(,%r,4)` on x86. */
for (int32_t i = 0; i < count; i++) {
total += values[i];
}
return total;
}
__attribute__((noinline)) int64_t quad_stride_sum(const int64_t *values,
int32_t count) {
int64_t total = 0;
if (values == 0 || count < 0 || count > 16) {
return -1;
}
/* 8-byte elements: `lsl #3` / `(,%r,8)`. */
for (int32_t i = 0; i < count; i++) {
total += values[i];
}
return total;
}
/* One scaled load at a computed index, with no loop, so the addressing mode is
* the entire function body and nothing can hide it. */
__attribute__((noinline)) int32_t word_at_index(const int32_t *values,
int32_t index) {
if (values == 0 || index < 0 || index > 15) {
return -1;
}
return values[index] + 7;
}
/* A scaled STORE, so the write path is covered as well as the read path. */
__attribute__((noinline)) int32_t word_store_at_index(int32_t *values,
int32_t index,
int32_t value) {
if (values == 0 || index < 0 || index > 15) {
return -1;
}
values[index] = value * 3;
return values[index];
}
/* CONTROL: byte elements. Scale is 1 and no shift is encoded; a fabricated
* scale changes the answer. */
__attribute__((noinline)) int32_t byte_stride_unscaled(const uint8_t *bytes,
int32_t count) {
int32_t total = 0;
if (bytes == 0 || count < 0 || count > 16) {
return -1;
}
for (int32_t i = 0; i < count; i++) {
total += (int32_t)bytes[i];
}
return total;
}
/* CONTROL: the shift is applied to the loaded VALUE, not to the index. Folding
* it into an address scale would be wrong in a way that still compiles and
* still looks plausible. */
__attribute__((noinline)) int32_t shift_as_value(const int32_t *values,
int32_t index) {
if (values == 0 || index < 0 || index > 15) {
return -1;
}
return values[index] << 2;
} 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 -O2
4/6byte_stride_unscaled fail 93 lines
// glaurung: byte_stride_unscaled @ 0x12f0
int32_t byte_stride_unscaled(const uint8_t * arg0, int32_t arg1) {
extern long __unknown(long, ...);
int total;
int i;
long ret;
int var11;
int var12;
int var15;
int var16;
int var19;
long var2;
int var20;
int var21;
int var22;
int var27;
int var28;
int var41;
int var42;
int var45;
int var46;
long var5;
int var58;
int var59;
long var83;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
ret = 0xffffffff;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & -4)));
var11 = 0;
var12 = 0;
var15 = __unknown(0);
var16 = __unknown(0);
var19 = ((unsigned int)((unsigned short)(var15)) | ((unsigned int)(0) << 16));
var20 = ((unsigned int)((unsigned short)((((unsigned int)(var15) >> 16) & 0xffff))) | ((unsigned int)(0) << 16));
var21 = ((unsigned int)((unsigned short)(var16)) | ((unsigned int)(0) << 16));
var22 = ((unsigned int)((unsigned short)((((unsigned int)(var16) >> 16) & 0xffff))) | ((unsigned int)(0) << 16));
if ((var5 != 4)) {
var27 = __unknown(0);
var28 = __unknown(0);
var19 = (var19 + ((unsigned int)((unsigned short)(var27)) | ((unsigned int)((unsigned short)(var11)) << 16)));
var20 = (var20 + ((unsigned int)((unsigned short)((((unsigned int)(var27) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)((((unsigned int)(var11) >> 16) & 0xffff))) << 16)));
var21 = (var21 + ((unsigned int)((unsigned short)(var28)) | ((unsigned int)((unsigned short)(var12)) << 16)));
var22 = (var22 + ((unsigned int)((unsigned short)((((unsigned int)(var28) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)((((unsigned int)(var12) >> 16) & 0xffff))) << 16)));
if (((unsigned long)((unsigned int)(var5)) != 8)) {
var41 = 0;
var42 = 0;
var45 = __unknown(0);
var46 = __unknown(0);
var19 = (var19 + ((unsigned int)((unsigned short)(var45)) | ((unsigned int)(0) << 16)));
var20 = (var20 + ((unsigned int)((unsigned short)((((unsigned int)(var45) >> 16) & 0xffff))) | ((unsigned int)(0) << 16)));
var21 = (var21 + ((unsigned int)((unsigned short)(var46)) | ((unsigned int)(0) << 16)));
var22 = (var22 + ((unsigned int)((unsigned short)((((unsigned int)(var46) >> 16) & 0xffff))) | ((unsigned int)(0) << 16)));
if (((unsigned long)((unsigned int)(var5)) != 12)) {
var58 = __unknown(0);
var59 = __unknown(0);
var19 = (var19 + ((unsigned int)((unsigned short)(var58)) | ((unsigned int)((unsigned short)(var41)) << 16)));
var20 = (var20 + ((unsigned int)((unsigned short)((((unsigned int)(var58) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)((((unsigned int)(var41) >> 16) & 0xffff))) << 16)));
var21 = (var21 + ((unsigned int)((unsigned short)(var59)) | ((unsigned int)((unsigned short)(var42)) << 16)));
var22 = (var22 + ((unsigned int)((unsigned short)((((unsigned int)(var59) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)((((unsigned int)(var42) >> 16) & 0xffff))) << 16)));
}
}
}
var83 = (unsigned long)((unsigned int)(((var22 + var20) + (var21 + var19))));
ret = var83;
if ((var5 == var2)) {
return ret;
}
L_13a0: ;
do {
total = (var83 + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + var5)))));
i = (var5 + 1);
var83 = (unsigned long)((unsigned int)(total));
var5 = (unsigned long)((unsigned int)(i));
ret = (unsigned long)((unsigned int)(total));
} while ((var2 != i));
} else {
var83 = 0;
var5 = 0;
goto L_13a0;
}
return ret;
} quad_stride_sum fail 152 lines
// glaurung: quad_stride_sum @ 0x1190
int64_t quad_stride_sum(const int64_t * arg0, int32_t arg1) {
long total;
int i;
long ret;
long t110;
long t113;
long t214;
long t215;
long t216;
long t217;
long t218;
long t219;
long t220;
long t221;
long t222;
long t241;
long t242;
long t243;
long t244;
long t245;
long t246;
long t247;
long t248;
long var110;
long var12;
long var13;
int var15;
int var16;
int var17;
int var18;
long var2;
long var20;
long var5;
long var6;
long var81;
int var82;
int var83;
int var84;
int var85;
int var88;
int var89;
long var9;
int var90;
int var91;
long var92;
long var93;
long var95;
ret = -1;
if ((arg0 == 0)) {
return ret;
}
ret = -1;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)((unsigned int)(arg1)) != 1)) {
var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & -2)));
var6 = (var5 - 2);
var9 = (((unsigned long)(var6) >> 1) + 1);
var12 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var9)) & 7)));
if (((unsigned long)(14) <= (unsigned long)(var6))) {
var13 = (var9 & -8);
var15 = 0;
var16 = 0;
var17 = 0;
var18 = 0;
var20 = 0;
do {
t110 = ((*(int *)(((long)arg0 + var20 * 8 + 0x4)) | *(int *)(((long)arg0 + var20 * 8))) + ((unsigned long)((unsigned int)(var16)) | (unsigned long)((unsigned int)(var15))));
t113 = ((*(int *)(((long)arg0 + var20 * 8 + 0xc)) | *(int *)(((long)arg0 + var20 * 8 + 0x8))) + ((unsigned long)((unsigned int)(var18)) | (unsigned long)((unsigned int)(var17))));
t214 = ((*(int *)(((long)arg0 + var20 * 8 + 0x24)) | *(int *)(((long)arg0 + var20 * 8 + 0x20))) + (*(int *)(((long)arg0 + var20 * 8 + 0x14)) | *(int *)(((long)arg0 + var20 * 8 + 0x10))));
t241 = ((*(int *)(((long)arg0 + var20 * 8 + 0x2c)) | *(int *)(((long)arg0 + var20 * 8 + 0x28))) + (*(int *)(((long)arg0 + var20 * 8 + 0x1c)) | *(int *)(((long)arg0 + var20 * 8 + 0x18))));
t215 = (((((unsigned long)(t214) >> 32) & 0xffffffff) | (unsigned int)(t214)) + ((((unsigned long)(t110) >> 32) & 0xffffffff) | (unsigned int)(t110)));
t242 = (((((unsigned long)(t241) >> 32) & 0xffffffff) | (unsigned int)(t241)) + ((((unsigned long)(t113) >> 32) & 0xffffffff) | (unsigned int)(t113)));
t216 = ((*(int *)(((long)arg0 + var20 * 8 + 0x44)) | *(int *)(((long)arg0 + var20 * 8 + 0x40))) + (*(int *)(((long)arg0 + var20 * 8 + 0x34)) | *(int *)(((long)arg0 + var20 * 8 + 0x30))));
t243 = ((*(int *)(((long)arg0 + var20 * 8 + 0x4c)) | *(int *)(((long)arg0 + var20 * 8 + 0x48))) + (*(int *)(((long)arg0 + var20 * 8 + 0x3c)) | *(int *)(((long)arg0 + var20 * 8 + 0x38))));
t217 = ((*(int *)(((long)arg0 + var20 * 8 + 0x54)) | *(int *)(((long)arg0 + var20 * 8 + 0x50))) + ((((unsigned long)(t216) >> 32) & 0xffffffff) | (unsigned int)(t216)));
t244 = ((*(int *)(((long)arg0 + var20 * 8 + 0x5c)) | *(int *)(((long)arg0 + var20 * 8 + 0x58))) + ((((unsigned long)(t243) >> 32) & 0xffffffff) | (unsigned int)(t243)));
t218 = (((((unsigned long)(t217) >> 32) & 0xffffffff) | (unsigned int)(t217)) + ((((unsigned long)(t215) >> 32) & 0xffffffff) | (unsigned int)(t215)));
t245 = (((((unsigned long)(t244) >> 32) & 0xffffffff) | (unsigned int)(t244)) + ((((unsigned long)(t242) >> 32) & 0xffffffff) | (unsigned int)(t242)));
t219 = ((*(int *)(((long)arg0 + var20 * 8 + 0x74)) | *(int *)(((long)arg0 + var20 * 8 + 0x70))) + (*(int *)(((long)arg0 + var20 * 8 + 0x64)) | *(int *)(((long)arg0 + var20 * 8 + 0x60))));
t246 = ((*(int *)(((long)arg0 + var20 * 8 + 0x7c)) | *(int *)(((long)arg0 + var20 * 8 + 0x78))) + (*(int *)(((long)arg0 + var20 * 8 + 0x6c)) | *(int *)(((long)arg0 + var20 * 8 + 0x68))));
t220 = (((((unsigned long)(t219) >> 32) & 0xffffffff) | (unsigned int)(t219)) + ((((unsigned long)(t218) >> 32) & 0xffffffff) | (unsigned int)(t218)));
var15 = (unsigned int)(t220);
var16 = (((unsigned long)(t220) >> 32) & 0xffffffff);
t247 = (((((unsigned long)(t246) >> 32) & 0xffffffff) | (unsigned int)(t246)) + ((((unsigned long)(t245) >> 32) & 0xffffffff) | (unsigned int)(t245)));
var17 = (unsigned int)(t247);
var18 = (((unsigned long)(t247) >> 32) & 0xffffffff);
ret = ((unsigned long)((unsigned int)(var16)) | (unsigned int)(t220));
var20 = (var20 + 16);
var13 = (var13 - 8);
var81 = var20;
var82 = (unsigned int)(t220);
var83 = var16;
var84 = (unsigned int)(t247);
var85 = var18;
} while ((var13 != 0));
} else {
var82 = 0;
var83 = 0;
var84 = 0;
var85 = 0;
var81 = 0;
}
var88 = var82;
var89 = var83;
var90 = var84;
var91 = var85;
if ((var12 != 0)) {
var92 = (long)(((long)arg0 + (var81 * 8)));
var93 = (var12 << 4);
var95 = 0;
do {
t221 = (((unsigned long)((unsigned int)(var83)) | (unsigned long)((unsigned int)(var82))) + (*(int *)((var92 + var95 + 0x4)) | *(int *)((var92 + var95))));
var82 = (unsigned int)(t221);
var83 = (((unsigned long)(t221) >> 32) & 0xffffffff);
t248 = (((unsigned long)((unsigned int)(var85)) | (unsigned long)((unsigned int)(var84))) + (*(int *)((var92 + var95 + 0xc)) | *(int *)((var92 + var95 + 0x8))));
var84 = (unsigned int)(t248);
var85 = (((unsigned long)(t248) >> 32) & 0xffffffff);
var95 = (var95 + 16);
var88 = (unsigned int)(t221);
var89 = var83;
var90 = (unsigned int)(t248);
var91 = var85;
} while ((var93 != var95));
}
t222 = (((unsigned long)((unsigned int)(var91)) | (unsigned long)((unsigned int)(var90))) + ((unsigned long)((unsigned int)(var89)) | (unsigned long)((unsigned int)(var88))));
var110 = ((((unsigned long)(t222) >> 32) & 0xffffffff) | (unsigned int)(t222));
ret = var110;
if ((var5 == var2)) {
return ret;
}
L_12a0: ;
do {
total = (var110 + *(long *)(((long)arg0 + var5 * 8)));
i = (var5 + 1);
var110 = total;
var5 = (unsigned long)((unsigned int)(i));
ret = total;
} while ((var2 != i));
} else {
var110 = 0;
var5 = 0;
goto L_12a0;
}
return ret;
} shift_as_value pass 11 lines
// glaurung: shift_as_value @ 0x13b0
int32_t shift_as_value(const int32_t * arg0, int32_t arg1) {
long ret;
ret = 0xffffffff;
if ((arg0 != 0)) {
if (((unsigned long)((unsigned long)((unsigned int)(arg1))) <= (unsigned long)(15))) {
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(unsigned long)((unsigned int)(arg1))])) << 2)));
}
}
return ret;
} word_at_index pass 11 lines
// glaurung: word_at_index @ 0x12b0
int32_t word_at_index(const int32_t * arg0, int32_t arg1) {
long ret;
ret = 0xffffffff;
if ((arg0 != 0)) {
if (((unsigned long)((unsigned long)((unsigned int)(arg1))) <= (unsigned long)(15))) {
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(unsigned long)((unsigned int)(arg1))])) + 7)));
}
}
return ret;
} word_store_at_index pass 12 lines
// glaurung: word_store_at_index @ 0x12d0
int32_t word_store_at_index(int32_t * arg0, int32_t arg1, int32_t arg2) {
long ret;
ret = 0xffffffff;
if ((arg0 != 0)) {
if (((unsigned long)((unsigned long)((unsigned int)(arg1))) <= (unsigned long)(15))) {
ret = (unsigned long)((unsigned int)((arg2 + (arg2 * 2))));
arg0[(unsigned long)((unsigned int)(arg1))] = ret;
}
}
return ret;
} word_stride_sum pass 68 lines
// glaurung: word_stride_sum @ 0x1100
int32_t word_stride_sum(const int32_t * arg0, int32_t arg1) {
int total;
int i;
long ret;
long var2;
long var41;
long var5;
int var6;
int var7;
int var8;
int var9;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
ret = 0xffffffff;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & -4)));
var6 = *(int *)(((long)arg0));
var7 = *(int *)(((long)arg0 + 0x4));
var8 = *(int *)(((long)arg0 + 0x8));
var9 = *(int *)(((long)arg0 + 0xc));
if ((var5 != 4)) {
var6 = (var6 + *(int *)(((long)arg0 + 0x10)));
var7 = (var7 + *(int *)(((long)arg0 + 0x14)));
var8 = (var8 + *(int *)(((long)arg0 + 0x18)));
var9 = (var9 + *(int *)(((long)arg0 + 0x1c)));
if (((unsigned long)((unsigned int)(var5)) != 8)) {
var6 = (var6 + *(int *)(((long)arg0 + 0x20)));
var7 = (var7 + *(int *)(((long)arg0 + 0x24)));
var8 = (var8 + *(int *)(((long)arg0 + 0x28)));
var9 = (var9 + *(int *)(((long)arg0 + 0x2c)));
if (((unsigned long)((unsigned int)(var5)) != 12)) {
var6 = (var6 + *(int *)(((long)arg0 + 0x30)));
var7 = (var7 + *(int *)(((long)arg0 + 0x34)));
var8 = (var8 + *(int *)(((long)arg0 + 0x38)));
var9 = (var9 + *(int *)(((long)arg0 + 0x3c)));
}
}
}
var41 = (unsigned long)((unsigned int)(((var9 + var7) + (var8 + var6))));
ret = var41;
if ((var5 == var2)) {
return ret;
}
L_1180: ;
do {
total = (var41 + *(int *)(((long)arg0 + var5 * 4)));
i = (var5 + 1);
var41 = (unsigned long)((unsigned int)(total));
var5 = (unsigned long)((unsigned int)(i));
ret = (unsigned long)((unsigned int)(total));
} while ((var2 != i));
} else {
var41 = 0;
var5 = 0;
goto L_1180;
}
return ret;
} clang -O0
6/6byte_stride_unscaled pass 29 lines
// glaurung: byte_stride_unscaled @ 0x12c0
int32_t byte_stride_unscaled(const uint8_t * arg0, int32_t arg1) {
int total;
int i;
int local_4;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 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 (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
for (i = 0; (i < arg1); i++) {
total = ((unsigned int)((unsigned char)(arg0[i])) + total);
}
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} quad_stride_sum pass 29 lines
// glaurung: quad_stride_sum @ 0x1180
int64_t quad_stride_sum(const int64_t * arg0, int32_t arg1) {
long total;
int i;
long local_8;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 0)) {
local_8 = -1;
// x86-64 epilogue: restore rbp
return local_8;
}
if (((long)(arg1) < 0)) {
local_8 = -1;
// x86-64 epilogue: restore rbp
return local_8;
}
if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
local_8 = -1;
// x86-64 epilogue: restore rbp
return local_8;
}
for (i = 0; (i < arg1); i++) {
total = (arg0[(long)(i)] + total);
}
local_8 = total;
// x86-64 epilogue: restore rbp
return local_8;
} shift_as_value pass 23 lines
// glaurung: shift_as_value @ 0x1340
int32_t shift_as_value(const int32_t * arg0, int32_t arg1) {
int local_4;
// x86-64 prologue: save rbp
if ((arg0 == 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 (((((unsigned long)((unsigned int)(arg1)) == 15) | ((long)(arg1) < 15)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_4 = ((unsigned long)((unsigned int)(arg0[(long)(arg1)])) << 2);
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} word_at_index pass 23 lines
// glaurung: word_at_index @ 0x1210
int32_t word_at_index(const int32_t * arg0, int32_t arg1) {
int local_4;
// x86-64 prologue: save rbp
if ((arg0 == 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 (((((unsigned long)((unsigned int)(arg1)) == 15) | ((long)(arg1) < 15)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_4 = ((unsigned int)(arg0[(long)(arg1)]) + 7);
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} word_store_at_index pass 24 lines
// glaurung: word_store_at_index @ 0x1260
int32_t word_store_at_index(int32_t * arg0, int32_t arg1, int32_t arg2) {
int local_4;
// x86-64 prologue: save rbp
if ((arg0 == 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 (((((unsigned long)((unsigned int)(arg1)) == 15) | ((long)(arg1) < 15)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
arg0[(long)(arg1)] = (arg2 * 3);
local_4 = arg0[(long)(arg1)];
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} word_stride_sum pass 29 lines
// glaurung: word_stride_sum @ 0x1100
int32_t word_stride_sum(const int32_t * arg0, int32_t arg1) {
int total;
int i;
int local_4;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 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 (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
for (i = 0; (i < arg1); i++) {
total = ((unsigned int)(arg0[(long)(i)]) + total);
}
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} gcc -O0
6/6byte_stride_unscaled pass 24 lines
// glaurung: byte_stride_unscaled @ 0x126d
int32_t byte_stride_unscaled(const uint8_t * arg0, int32_t arg1) {
int total;
int i;
// x86-64 prologue: save rbp
total = 0;
if ((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)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
for (i = 0; (i < arg1); i++) {
total = (total + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[i])) & 255))));
}
// x86-64 epilogue: restore rbp
return (unsigned int)(total);
} quad_stride_sum pass 24 lines
// glaurung: quad_stride_sum @ 0x115c
int64_t quad_stride_sum(const int64_t * arg0, int32_t arg1) {
long total;
int i;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return -1;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return -1;
}
if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return -1;
}
for (i = 0; (i < arg1); i++) {
total = (total + arg0[(long)(i)]);
}
// x86-64 epilogue: restore rbp
return total;
} shift_as_value pass 18 lines
// glaurung: shift_as_value @ 0x12cd
int32_t shift_as_value(const int32_t * arg0, int32_t arg1) {
// x86-64 prologue: save rbp
if ((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)(arg1)) == 15) | ((long)(arg1) < 15)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(arg1)])) << 2));
} word_at_index pass 18 lines
// glaurung: word_at_index @ 0x11c5
int32_t word_at_index(const int32_t * arg0, int32_t arg1) {
// x86-64 prologue: save rbp
if ((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)(arg1)) == 15) | ((long)(arg1) < 15)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(arg1)])) + 7));
} word_store_at_index pass 19 lines
// glaurung: word_store_at_index @ 0x1209
int32_t word_store_at_index(int32_t * arg0, int32_t arg1, int32_t arg2) {
// x86-64 prologue: save rbp
if ((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)(arg1)) == 15) | ((long)(arg1) < 15)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
arg0[(long)(arg1)] = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) + (unsigned long)((unsigned int)(arg2))))) + (unsigned long)((unsigned int)(arg2)));
// x86-64 epilogue: restore rbp
return (unsigned int)(arg0[(long)(arg1)]);
} word_stride_sum pass 24 lines
// glaurung: word_stride_sum @ 0x10f9
int32_t word_stride_sum(const int32_t * arg0, int32_t arg1) {
int total;
int i;
// x86-64 prologue: save rbp
total = 0;
if ((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)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
for (i = 0; (i < arg1); i++) {
total = (total + (unsigned int)(arg0[(long)(i)]));
}
// x86-64 epilogue: restore rbp
return (unsigned int)(total);
} gcc -O2
6/6byte_stride_unscaled pass 27 lines
// glaurung: byte_stride_unscaled @ 0x11e0
int32_t byte_stride_unscaled(const uint8_t * arg0, int32_t arg1) {
int i;
int total;
long ret;
long var2;
long var5;
int var6;
if ((arg0 == 0)) {
return 0xffffffff;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (long)((((long)arg0 + (unsigned long)((unsigned int)((arg1 - 1)))) + 1));
ret = 0;
var5 = (long)arg0;
do {
var6 = (unsigned int)((unsigned char)(*(char *)((var5))));
var5 = (var5 + 1);
ret = (unsigned long)((unsigned int)((ret + var6)));
} while ((var5 != var2));
return ret;
} quad_stride_sum pass 24 lines
// glaurung: quad_stride_sum @ 0x1140
int64_t quad_stride_sum(const int64_t * arg0, int32_t arg1) {
long total;
int i;
long var2;
long var5;
if ((arg0 == 0)) {
return -1;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return -1;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 8)) + 8));
total = 0;
var5 = (long)arg0;
do {
total = (total + *(long *)((var5)));
var5 = (var5 + 8);
} while ((var5 != var2));
return total;
} shift_as_value pass 7 lines
// glaurung: shift_as_value @ 0x1220
int32_t shift_as_value(const int32_t * arg0, int32_t arg1) {
if (((arg0 == 0) || ((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)(arg1)))))) {
return 0xffffffff;
}
return (unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(arg1)])) << 2));
} word_at_index pass 7 lines
// glaurung: word_at_index @ 0x1180
int32_t word_at_index(const int32_t * arg0, int32_t arg1) {
if (((arg0 == 0) || ((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)(arg1)))))) {
return 0xffffffff;
}
return (unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(arg1)])) + 7));
} word_store_at_index pass 12 lines
// glaurung: word_store_at_index @ 0x11b0
int32_t word_store_at_index(int32_t * arg0, int32_t arg1, int32_t arg2) {
long ret;
if ((arg0 != 0)) {
if (((unsigned long)((unsigned long)((unsigned int)(arg1))) <= (unsigned long)(15))) {
ret = (unsigned long)((unsigned int)((arg2 + (arg2 * 2))));
arg0[(long)(arg1)] = ret;
return ret;
}
}
return 0xffffffff;
} word_stride_sum pass 25 lines
// glaurung: word_stride_sum @ 0x1100
int32_t word_stride_sum(const int32_t * arg0, int32_t arg1) {
int i;
int total;
long ret;
long var2;
long var5;
if ((arg0 == 0)) {
return 0xffffffff;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
ret = 0;
var5 = (long)arg0;
do {
ret = (unsigned long)((unsigned int)((ret + *(int *)((var5)))));
var5 = (var5 + 4);
} while ((var5 != var2));
return ret;
}