Source code

Revision control

Copy as Markdown

Other Tools

// Int32 add, sub and bitwise ops whose operand is a constant shift.
const values = [
0, 1, -1, 2, 7, 0x1234, -0x5678, 0x7fffffff, -0x80000000, 0x40000000,
0x3fffffff, -0x40000001, 0x55555555, -0x2aaaaaab,
];
for (const op of ["+", "-", "&", "|", "^"]) {
for (const shift of ["<<", ">>", ">>>"]) {
for (const amount of [1, 13, 31, 32, 33]) {
for (const shiftedRhs of [true, false]) {
for (const truncate of [true, false]) {
const shifted = `(x ${shift} ${amount})`;
let expr = shiftedRhs ? `y ${op} ${shifted}` : `${shifted} ${op} y`;
if (truncate) {
expr = `(${expr}) | 0`;
}
const f = new Function("x", "y", `return ${expr};`);
const ref = new Function("x", "y", `with ({}) {} return ${expr};`);
for (let i = 0; i < 100; i++) {
const x = values[i % 3];
const y = values[(i + 1) % 3];
assertEq(f(x, y), ref(x, y));
}
for (const x of values) {
for (const y of values) {
assertEq(f(x, y), ref(x, y));
}
}
}
}
}
}
}
function hash(s) {
let h = 0;
for (let i = 0; i < s.length; i++) {
h = ((h << 5) + s.charCodeAt(i)) | 0;
}
return h;
}
function hashRef(s) {
with ({}) {}
let h = 0;
for (let i = 0; i < s.length; i++) {
h = ((h << 5) + s.charCodeAt(i)) | 0;
}
return h;
}
for (let i = 0; i < 200; i++) {
const s = "shifted operand " + i;
assertEq(hash(s), hashRef(s));
}
function twoShifts(x, y) {
return ((x << 3) + (y >>> 5)) | 0;
}
function sameShift(x) {
const t = x << 7;
return t ^ t;
}
function shiftUsedTwice(x, y) {
const t = x >> 4;
return ((y + t) | 0) - t;
}
for (let i = 0; i < 200; i++) {
const x = values[i % values.length];
const y = values[(i * 7) % values.length];
assertEq(twoShifts(x, y), ((x * 8) + Math.floor((y >>> 0) / 32)) | 0);
assertEq(sameShift(x), 0);
assertEq(shiftUsedTwice(x, y), ((y + (x >> 4)) | 0) - (x >> 4));
}