Commit 714e525b authored by whesse@chromium.org's avatar whesse@chromium.org

Improve register allocation of left shift operation. Add tests

for all shift operations.
Review URL: http://codereview.chromium.org/101016

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1825 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 328dc180
...@@ -5902,10 +5902,10 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, ...@@ -5902,10 +5902,10 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left,
// Right operand must be in register cl because x86 likes it that way. // Right operand must be in register cl because x86 likes it that way.
if (right->reg().is(ecx)) { if (right->reg().is(ecx)) {
// Right is already in the right place. Left may be in the // Right is already in the right place. Left may be in the
// same register, which causes problems. Use answer instead. // same register, which causes problems. Always use answer
if (left->reg().is(ecx)) { // instead of left, even if left is not ecx, since this avoids
// spilling left.
*left = answer; *left = answer;
}
} else if (left->reg().is(ecx)) { } else if (left->reg().is(ecx)) {
generator()->frame()->Spill(left->reg()); generator()->frame()->Spill(left->reg());
__ mov(left->reg(), right->reg()); __ mov(left->reg(), right->reg());
...@@ -5919,6 +5919,9 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, ...@@ -5919,6 +5919,9 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left,
ASSERT(reg_ecx.is_valid()); ASSERT(reg_ecx.is_valid());
__ mov(ecx, right->reg()); __ mov(ecx, right->reg());
*right = reg_ecx; *right = reg_ecx;
// Answer and left both contain the left operand. Use answer, so
// left is not spilled.
*left = answer;
} }
ASSERT(left->reg().is_valid()); ASSERT(left->reg().is_valid());
ASSERT(!left->reg().is(ecx)); ASSERT(!left->reg().is(ecx));
...@@ -5968,16 +5971,10 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, ...@@ -5968,16 +5971,10 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left,
case Token::SHL: { case Token::SHL: {
__ shl(left->reg()); __ shl(left->reg());
// Check that the *signed* result fits in a smi. // Check that the *signed* result fits in a smi.
//
// TODO(207): Can reduce registers from 4 to 3 by
// preallocating ecx.
JumpTarget result_ok(generator()); JumpTarget result_ok(generator());
Result smi_test_reg = generator()->allocator()->Allocate(); __ cmp(left->reg(), 0xc0000000);
ASSERT(smi_test_reg.is_valid()); result_ok.Branch(positive, left, taken);
__ lea(smi_test_reg.reg(), Operand(left->reg(), 0x40000000));
__ test(smi_test_reg.reg(), Immediate(0x80000000));
smi_test_reg.Unuse();
result_ok.Branch(zero, left, taken);
__ shr(left->reg()); __ shr(left->reg());
ASSERT(kSmiTag == 0); ASSERT(kSmiTag == 0);
__ shl(left->reg(), kSmiTagSize); __ shl(left->reg(), kSmiTagSize);
...@@ -6277,11 +6274,15 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) { ...@@ -6277,11 +6274,15 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
case Token::SHR: __ shr(eax); break; case Token::SHR: __ shr(eax); break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
if (op_ == Token::SHR) {
// Check if result is non-negative and fits in a smi. // Check if result is non-negative and fits in a smi.
__ test(eax, Immediate(0xc0000000)); __ test(eax, Immediate(0xc0000000));
__ j(not_zero, &non_smi_result); __ j(not_zero, &non_smi_result);
} else {
// Check if result fits in a smi.
__ cmp(eax, 0xc0000000);
__ j(negative, &non_smi_result);
}
// Tag smi result and return. // Tag smi result and return.
ASSERT(kSmiTagSize == times_2); // adjust code if not the case ASSERT(kSmiTagSize == times_2); // adjust code if not the case
__ lea(eax, Operand(eax, eax, times_1, kSmiTag)); __ lea(eax, Operand(eax, eax, times_1, kSmiTag));
......
...@@ -195,3 +195,393 @@ assertEquals(78, Xor100Reversed(OBJ_42)); ...@@ -195,3 +195,393 @@ assertEquals(78, Xor100Reversed(OBJ_42));
var x = 0x23; var y = 0x35; var x = 0x23; var y = 0x35;
assertEquals(0x16, x ^ y); assertEquals(0x16, x ^ y);
// Test shift operators on non-smi inputs, giving smi and non-smi results.
function testShiftNonSmis() {
var pos_non_smi = 2000000000;
var neg_non_smi = -pos_non_smi;
var pos_smi = 1000000000;
var neg_smi = -pos_smi;
// Begin block A
assertEquals(pos_non_smi, (pos_non_smi) >> 0);
assertEquals(pos_non_smi, (pos_non_smi) >>> 0);
assertEquals(pos_non_smi, (pos_non_smi) << 0);
assertEquals(neg_non_smi, (neg_non_smi) >> 0);
assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> 0);
assertEquals(neg_non_smi, (neg_non_smi) << 0);
assertEquals(pos_smi, (pos_smi) >> 0);
assertEquals(pos_smi, (pos_smi) >>> 0);
assertEquals(pos_smi, (pos_smi) << 0);
assertEquals(neg_smi, (neg_smi) >> 0);
assertEquals(neg_smi + 0x100000000, (neg_smi) >>> 0);
assertEquals(neg_smi, (neg_smi) << 0);
assertEquals(pos_non_smi / 2, (pos_non_smi) >> 1);
assertEquals(pos_non_smi / 2, (pos_non_smi) >>> 1);
assertEquals(-0x1194D800, (pos_non_smi) << 1);
assertEquals(pos_non_smi / 8, (pos_non_smi) >> 3);
assertEquals(pos_non_smi / 8, (pos_non_smi) >>> 3);
assertEquals(-0x46536000, (pos_non_smi) << 3);
assertEquals(0x73594000, (pos_non_smi) << 4);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> 0);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> 0);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) << 0);
assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> 1);
assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> 1);
assertEquals(-0x1194D800, (pos_non_smi + 0.5) << 1);
assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> 3);
assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> 3);
assertEquals(-0x46536000, (pos_non_smi + 0.5) << 3);
assertEquals(0x73594000, (pos_non_smi + 0.5) << 4);
assertEquals(neg_non_smi / 2, (neg_non_smi) >> 1);
assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> 1);
assertEquals(0x1194D800, (neg_non_smi) << 1);
assertEquals(neg_non_smi / 8, (neg_non_smi) >> 3);
assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> 3);
assertEquals(0x46536000, (neg_non_smi) << 3);
assertEquals(-0x73594000, (neg_non_smi) << 4);
assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> 0);
assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> 0);
assertEquals(neg_non_smi, (neg_non_smi - 0.5) << 0);
assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> 1);
assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> 1);
assertEquals(0x1194D800, (neg_non_smi - 0.5) << 1);
assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> 3);
assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5) >>> 3);
assertEquals(0x46536000, (neg_non_smi - 0.5) << 3);
assertEquals(-0x73594000, (neg_non_smi - 0.5) << 4);
assertEquals(pos_smi / 2, (pos_smi) >> 1);
assertEquals(pos_smi / 2, (pos_smi) >>> 1);
assertEquals(pos_non_smi, (pos_smi) << 1);
assertEquals(pos_smi / 8, (pos_smi) >> 3);
assertEquals(pos_smi / 8, (pos_smi) >>> 3);
assertEquals(-0x2329b000, (pos_smi) << 3);
assertEquals(0x73594000, (pos_smi) << 5);
assertEquals(pos_smi, (pos_smi + 0.5) >> 0);
assertEquals(pos_smi, (pos_smi + 0.5) >>> 0);
assertEquals(pos_smi, (pos_smi + 0.5) << 0);
assertEquals(pos_smi / 2, (pos_smi + 0.5) >> 1);
assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> 1);
assertEquals(pos_non_smi, (pos_smi + 0.5) << 1);
assertEquals(pos_smi / 8, (pos_smi + 0.5) >> 3);
assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> 3);
assertEquals(-0x2329b000, (pos_smi + 0.5) << 3);
assertEquals(0x73594000, (pos_smi + 0.5) << 5);
assertEquals(neg_smi / 2, (neg_smi) >> 1);
assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> 1);
assertEquals(neg_non_smi, (neg_smi) << 1);
assertEquals(neg_smi / 8, (neg_smi) >> 3);
assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> 3);
assertEquals(0x46536000, (neg_smi) << 4);
assertEquals(-0x73594000, (neg_smi) << 5);
assertEquals(neg_smi, (neg_smi - 0.5) >> 0);
assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> 0);
assertEquals(neg_smi, (neg_smi - 0.5) << 0);
assertEquals(neg_smi / 2, (neg_smi - 0.5) >> 1);
assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> 1);
assertEquals(neg_non_smi, (neg_smi - 0.5) << 1);
assertEquals(neg_smi / 8, (neg_smi - 0.5) >> 3);
assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> 3);
assertEquals(0x46536000, (neg_smi - 0.5) << 4);
assertEquals(-0x73594000, (neg_smi - 0.5) << 5);
// End block A
// Repeat block A with 2^32 added to positive numbers and
// 2^32 subtracted from negative numbers.
// Begin block A repeat 1
var two_32 = 0x100000000;
var neg_32 = -two_32;
assertEquals(pos_non_smi, (two_32 + pos_non_smi) >> 0);
assertEquals(pos_non_smi, (two_32 + pos_non_smi) >>> 0);
assertEquals(pos_non_smi, (two_32 + pos_non_smi) << 0);
assertEquals(neg_non_smi, (neg_32 + neg_non_smi) >> 0);
assertEquals(neg_non_smi + 0x100000000, (neg_32 + neg_non_smi) >>> 0);
assertEquals(neg_non_smi, (neg_32 + neg_non_smi) << 0);
assertEquals(pos_smi, (two_32 + pos_smi) >> 0);
assertEquals(pos_smi, (two_32 + pos_smi) >>> 0);
assertEquals(pos_smi, (two_32 + pos_smi) << 0);
assertEquals(neg_smi, (neg_32 + neg_smi) >> 0);
assertEquals(neg_smi + 0x100000000, (neg_32 + neg_smi) >>> 0);
assertEquals(neg_smi, (neg_32 + neg_smi) << 0);
assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi) >> 1);
assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi) >>> 1);
assertEquals(-0x1194D800, (two_32 + pos_non_smi) << 1);
assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi) >> 3);
assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi) >>> 3);
assertEquals(-0x46536000, (two_32 + pos_non_smi) << 3);
assertEquals(0x73594000, (two_32 + pos_non_smi) << 4);
assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) >> 0);
assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) >>> 0);
assertEquals(pos_non_smi, (two_32 + pos_non_smi + 0.5) << 0);
assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi + 0.5) >> 1);
assertEquals(pos_non_smi / 2, (two_32 + pos_non_smi + 0.5) >>> 1);
assertEquals(-0x1194D800, (two_32 + pos_non_smi + 0.5) << 1);
assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi + 0.5) >> 3);
assertEquals(pos_non_smi / 8, (two_32 + pos_non_smi + 0.5) >>> 3);
assertEquals(-0x46536000, (two_32 + pos_non_smi + 0.5) << 3);
assertEquals(0x73594000, (two_32 + pos_non_smi + 0.5) << 4);
assertEquals(neg_non_smi / 2, (neg_32 + neg_non_smi) >> 1);
assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_32 + neg_non_smi) >>> 1);
assertEquals(0x1194D800, (neg_32 + neg_non_smi) << 1);
assertEquals(neg_non_smi / 8, (neg_32 + neg_non_smi) >> 3);
assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_32 + neg_non_smi) >>> 3);
assertEquals(0x46536000, (neg_32 + neg_non_smi) << 3);
assertEquals(-0x73594000, (neg_32 + neg_non_smi) << 4);
assertEquals(neg_non_smi, (neg_32 + neg_non_smi - 0.5) >> 0);
assertEquals(neg_non_smi + 0x100000000, (neg_32 + neg_non_smi - 0.5) >>> 0);
assertEquals(neg_non_smi, (neg_32 + neg_non_smi - 0.5) << 0);
assertEquals(neg_non_smi / 2, (neg_32 + neg_non_smi - 0.5) >> 1);
assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_32 + neg_non_smi - 0.5)
>>> 1);
assertEquals(0x1194D800, (neg_32 + neg_non_smi - 0.5) << 1);
assertEquals(neg_non_smi / 8, (neg_32 + neg_non_smi - 0.5) >> 3);
assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_32 + neg_non_smi - 0.5)
>>> 3);
assertEquals(0x46536000, (neg_32 + neg_non_smi - 0.5) << 3);
assertEquals(-0x73594000, (neg_32 + neg_non_smi - 0.5) << 4);
assertEquals(pos_smi / 2, (two_32 + pos_smi) >> 1);
assertEquals(pos_smi / 2, (two_32 + pos_smi) >>> 1);
assertEquals(pos_non_smi, (two_32 + pos_smi) << 1);
assertEquals(pos_smi / 8, (two_32 + pos_smi) >> 3);
assertEquals(pos_smi / 8, (two_32 + pos_smi) >>> 3);
assertEquals(-0x2329b000, (two_32 + pos_smi) << 3);
assertEquals(0x73594000, (two_32 + pos_smi) << 5);
assertEquals(pos_smi, (two_32 + pos_smi + 0.5) >> 0);
assertEquals(pos_smi, (two_32 + pos_smi + 0.5) >>> 0);
assertEquals(pos_smi, (two_32 + pos_smi + 0.5) << 0);
assertEquals(pos_smi / 2, (two_32 + pos_smi + 0.5) >> 1);
assertEquals(pos_smi / 2, (two_32 + pos_smi + 0.5) >>> 1);
assertEquals(pos_non_smi, (two_32 + pos_smi + 0.5) << 1);
assertEquals(pos_smi / 8, (two_32 + pos_smi + 0.5) >> 3);
assertEquals(pos_smi / 8, (two_32 + pos_smi + 0.5) >>> 3);
assertEquals(-0x2329b000, (two_32 + pos_smi + 0.5) << 3);
assertEquals(0x73594000, (two_32 + pos_smi + 0.5) << 5);
assertEquals(neg_smi / 2, (neg_32 + neg_smi) >> 1);
assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_32 + neg_smi) >>> 1);
assertEquals(neg_non_smi, (neg_32 + neg_smi) << 1);
assertEquals(neg_smi / 8, (neg_32 + neg_smi) >> 3);
assertEquals((neg_smi + 0x100000000) / 8, (neg_32 + neg_smi) >>> 3);
assertEquals(0x46536000, (neg_32 + neg_smi) << 4);
assertEquals(-0x73594000, (neg_32 + neg_smi) << 5);
assertEquals(neg_smi, (neg_32 + neg_smi - 0.5) >> 0);
assertEquals(neg_smi + 0x100000000, (neg_32 + neg_smi - 0.5) >>> 0);
assertEquals(neg_smi, (neg_32 + neg_smi - 0.5) << 0);
assertEquals(neg_smi / 2, (neg_32 + neg_smi - 0.5) >> 1);
assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_32 + neg_smi - 0.5) >>> 1);
assertEquals(neg_non_smi, (neg_32 + neg_smi - 0.5) << 1);
assertEquals(neg_smi / 8, (neg_32 + neg_smi - 0.5) >> 3);
assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_32 + neg_smi - 0.5) >>> 3);
assertEquals(0x46536000, (neg_32 + neg_smi - 0.5) << 4);
assertEquals(-0x73594000, (neg_32 + neg_smi - 0.5) << 5);
// End block A repeat 1
// Repeat block A with shift amounts in variables intialized with
// a constant.
var zero = 0;
var one = 1;
var three = 3;
var four = 4;
var five = 5;
// Begin block A repeat 2
assertEquals(pos_non_smi, (pos_non_smi) >> zero);
assertEquals(pos_non_smi, (pos_non_smi) >>> zero);
assertEquals(pos_non_smi, (pos_non_smi) << zero);
assertEquals(neg_non_smi, (neg_non_smi) >> zero);
assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> zero);
assertEquals(neg_non_smi, (neg_non_smi) << zero);
assertEquals(pos_smi, (pos_smi) >> zero);
assertEquals(pos_smi, (pos_smi) >>> zero);
assertEquals(pos_smi, (pos_smi) << zero);
assertEquals(neg_smi, (neg_smi) >> zero);
assertEquals(neg_smi + 0x100000000, (neg_smi) >>> zero);
assertEquals(neg_smi, (neg_smi) << zero);
assertEquals(pos_non_smi / 2, (pos_non_smi) >> one);
assertEquals(pos_non_smi / 2, (pos_non_smi) >>> one);
assertEquals(-0x1194D800, (pos_non_smi) << one);
assertEquals(pos_non_smi / 8, (pos_non_smi) >> three);
assertEquals(pos_non_smi / 8, (pos_non_smi) >>> three);
assertEquals(-0x46536000, (pos_non_smi) << three);
assertEquals(0x73594000, (pos_non_smi) << four);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> zero);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> zero);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) << zero);
assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> one);
assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> one);
assertEquals(-0x1194D800, (pos_non_smi + 0.5) << one);
assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> three);
assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> three);
assertEquals(-0x46536000, (pos_non_smi + 0.5) << three);
assertEquals(0x73594000, (pos_non_smi + 0.5) << four);
assertEquals(neg_non_smi / 2, (neg_non_smi) >> one);
assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> one);
assertEquals(0x1194D800, (neg_non_smi) << one);
assertEquals(neg_non_smi / 8, (neg_non_smi) >> three);
assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> three);
assertEquals(0x46536000, (neg_non_smi) << three);
assertEquals(-0x73594000, (neg_non_smi) << four);
assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> zero);
assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> zero);
assertEquals(neg_non_smi, (neg_non_smi - 0.5) << zero);
assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> one);
assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> one);
assertEquals(0x1194D800, (neg_non_smi - 0.5) << one);
assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> three);
assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5)
>>> three);
assertEquals(0x46536000, (neg_non_smi - 0.5) << three);
assertEquals(-0x73594000, (neg_non_smi - 0.5) << four);
assertEquals(pos_smi / 2, (pos_smi) >> one);
assertEquals(pos_smi / 2, (pos_smi) >>> one);
assertEquals(pos_non_smi, (pos_smi) << one);
assertEquals(pos_smi / 8, (pos_smi) >> three);
assertEquals(pos_smi / 8, (pos_smi) >>> three);
assertEquals(-0x2329b000, (pos_smi) << three);
assertEquals(0x73594000, (pos_smi) << five);
assertEquals(pos_smi, (pos_smi + 0.5) >> zero);
assertEquals(pos_smi, (pos_smi + 0.5) >>> zero);
assertEquals(pos_smi, (pos_smi + 0.5) << zero);
assertEquals(pos_smi / 2, (pos_smi + 0.5) >> one);
assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> one);
assertEquals(pos_non_smi, (pos_smi + 0.5) << one);
assertEquals(pos_smi / 8, (pos_smi + 0.5) >> three);
assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> three);
assertEquals(-0x2329b000, (pos_smi + 0.5) << three);
assertEquals(0x73594000, (pos_smi + 0.5) << five);
assertEquals(neg_smi / 2, (neg_smi) >> one);
assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> one);
assertEquals(neg_non_smi, (neg_smi) << one);
assertEquals(neg_smi / 8, (neg_smi) >> three);
assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> three);
assertEquals(0x46536000, (neg_smi) << four);
assertEquals(-0x73594000, (neg_smi) << five);
assertEquals(neg_smi, (neg_smi - 0.5) >> zero);
assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> zero);
assertEquals(neg_smi, (neg_smi - 0.5) << zero);
assertEquals(neg_smi / 2, (neg_smi - 0.5) >> one);
assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> one);
assertEquals(neg_non_smi, (neg_smi - 0.5) << one);
assertEquals(neg_smi / 8, (neg_smi - 0.5) >> three);
assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> three);
assertEquals(0x46536000, (neg_smi - 0.5) << four);
assertEquals(-0x73594000, (neg_smi - 0.5) << five);
// End block A repeat 2
// Repeat previous block, with computed values in the shift variables.
five = 0;
while (five < 5 ) ++five;
four = five - one;
three = four - one;
one = four - three;
zero = one - one;
// Begin block A repeat 3
assertEquals(pos_non_smi, (pos_non_smi) >> zero);
assertEquals(pos_non_smi, (pos_non_smi) >>> zero);
assertEquals(pos_non_smi, (pos_non_smi) << zero);
assertEquals(neg_non_smi, (neg_non_smi) >> zero);
assertEquals(neg_non_smi + 0x100000000, (neg_non_smi) >>> zero);
assertEquals(neg_non_smi, (neg_non_smi) << zero);
assertEquals(pos_smi, (pos_smi) >> zero);
assertEquals(pos_smi, (pos_smi) >>> zero);
assertEquals(pos_smi, (pos_smi) << zero);
assertEquals(neg_smi, (neg_smi) >> zero);
assertEquals(neg_smi + 0x100000000, (neg_smi) >>> zero);
assertEquals(neg_smi, (neg_smi) << zero);
assertEquals(pos_non_smi / 2, (pos_non_smi) >> one);
assertEquals(pos_non_smi / 2, (pos_non_smi) >>> one);
assertEquals(-0x1194D800, (pos_non_smi) << one);
assertEquals(pos_non_smi / 8, (pos_non_smi) >> three);
assertEquals(pos_non_smi / 8, (pos_non_smi) >>> three);
assertEquals(-0x46536000, (pos_non_smi) << three);
assertEquals(0x73594000, (pos_non_smi) << four);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) >> zero);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) >>> zero);
assertEquals(pos_non_smi, (pos_non_smi + 0.5) << zero);
assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >> one);
assertEquals(pos_non_smi / 2, (pos_non_smi + 0.5) >>> one);
assertEquals(-0x1194D800, (pos_non_smi + 0.5) << one);
assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >> three);
assertEquals(pos_non_smi / 8, (pos_non_smi + 0.5) >>> three);
assertEquals(-0x46536000, (pos_non_smi + 0.5) << three);
assertEquals(0x73594000, (pos_non_smi + 0.5) << four);
assertEquals(neg_non_smi / 2, (neg_non_smi) >> one);
assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi) >>> one);
assertEquals(0x1194D800, (neg_non_smi) << one);
assertEquals(neg_non_smi / 8, (neg_non_smi) >> three);
assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi) >>> three);
assertEquals(0x46536000, (neg_non_smi) << three);
assertEquals(-0x73594000, (neg_non_smi) << four);
assertEquals(neg_non_smi, (neg_non_smi - 0.5) >> zero);
assertEquals(neg_non_smi + 0x100000000, (neg_non_smi - 0.5) >>> zero);
assertEquals(neg_non_smi, (neg_non_smi - 0.5) << zero);
assertEquals(neg_non_smi / 2, (neg_non_smi - 0.5) >> one);
assertEquals(neg_non_smi / 2 + 0x100000000 / 2, (neg_non_smi - 0.5) >>> one);
assertEquals(0x1194D800, (neg_non_smi - 0.5) << one);
assertEquals(neg_non_smi / 8, (neg_non_smi - 0.5) >> three);
assertEquals(neg_non_smi / 8 + 0x100000000 / 8, (neg_non_smi - 0.5)
>>> three);
assertEquals(0x46536000, (neg_non_smi - 0.5) << three);
assertEquals(-0x73594000, (neg_non_smi - 0.5) << four);
assertEquals(pos_smi / 2, (pos_smi) >> one);
assertEquals(pos_smi / 2, (pos_smi) >>> one);
assertEquals(pos_non_smi, (pos_smi) << one);
assertEquals(pos_smi / 8, (pos_smi) >> three);
assertEquals(pos_smi / 8, (pos_smi) >>> three);
assertEquals(-0x2329b000, (pos_smi) << three);
assertEquals(0x73594000, (pos_smi) << five);
assertEquals(pos_smi, (pos_smi + 0.5) >> zero);
assertEquals(pos_smi, (pos_smi + 0.5) >>> zero);
assertEquals(pos_smi, (pos_smi + 0.5) << zero);
assertEquals(pos_smi / 2, (pos_smi + 0.5) >> one);
assertEquals(pos_smi / 2, (pos_smi + 0.5) >>> one);
assertEquals(pos_non_smi, (pos_smi + 0.5) << one);
assertEquals(pos_smi / 8, (pos_smi + 0.5) >> three);
assertEquals(pos_smi / 8, (pos_smi + 0.5) >>> three);
assertEquals(-0x2329b000, (pos_smi + 0.5) << three);
assertEquals(0x73594000, (pos_smi + 0.5) << five);
assertEquals(neg_smi / 2, (neg_smi) >> one);
assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi) >>> one);
assertEquals(neg_non_smi, (neg_smi) << one);
assertEquals(neg_smi / 8, (neg_smi) >> three);
assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi) >>> three);
assertEquals(0x46536000, (neg_smi) << four);
assertEquals(-0x73594000, (neg_smi) << five);
assertEquals(neg_smi, (neg_smi - 0.5) >> zero);
assertEquals(neg_smi + 0x100000000, (neg_smi - 0.5) >>> zero);
assertEquals(neg_smi, (neg_smi - 0.5) << zero);
assertEquals(neg_smi / 2, (neg_smi - 0.5) >> one);
assertEquals(neg_smi / 2 + 0x100000000 / 2, (neg_smi - 0.5) >>> one);
assertEquals(neg_non_smi, (neg_smi - 0.5) << one);
assertEquals(neg_smi / 8, (neg_smi - 0.5) >> three);
assertEquals(neg_smi / 8 + 0x100000000 / 8, (neg_smi - 0.5) >>> three);
assertEquals(0x46536000, (neg_smi - 0.5) << four);
assertEquals(-0x73594000, (neg_smi - 0.5) << five);
// End block A repeat 3
// Test non-integer shift value
assertEquals(5, 20.5 >> 2.4);
assertEquals(5, 20.5 >> 2.7);
var shift = 2.4;
assertEquals(5, 20.5 >> shift);
assertEquals(5, 20.5 >> shift + 0.3);
shift = shift + zero;
assertEquals(5, 20.5 >> shift);
assertEquals(5, 20.5 >> shift + 0.3);
}
testShiftNonSmis();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment