Chromium Code Reviews| Index: src/x64/macro-assembler-x64.cc |
| diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
| index 2eb74e55f0c9f71103c351cb92c7fac06028e659..ab748029cbc4ba61562b6fdf67cfc737c711bbcf 100644 |
| --- a/src/x64/macro-assembler-x64.cc |
| +++ b/src/x64/macro-assembler-x64.cc |
| @@ -268,7 +268,9 @@ void MacroAssembler::InNewSpace(Register object, |
| cmpp(scratch, kScratchRegister); |
| j(cc, branch, distance); |
| } else { |
| - ASSERT(is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask()))); |
| + ASSERT(kPointerSize == kInt64Size |
| + ? is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask())) |
| + : kPointerSize == kInt32Size); |
| intptr_t new_space_start = |
| reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart()); |
| Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start), |
| @@ -1429,6 +1431,14 @@ void MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) { |
| } |
| +void MacroAssembler::JumpIfValidSmiValue(Register src, |
| + Label* on_valid, |
| + Label::Distance near_jump) { |
| + Condition is_valid = CheckInteger32ValidSmiValue(src); |
| + j(is_valid, on_valid, near_jump); |
| +} |
| + |
| + |
| void MacroAssembler::JumpIfNotValidSmiValue(Register src, |
| Label* on_invalid, |
| Label::Distance near_jump) { |
| @@ -1437,6 +1447,14 @@ void MacroAssembler::JumpIfNotValidSmiValue(Register src, |
| } |
| +void MacroAssembler::JumpIfUIntValidSmiValue(Register src, |
| + Label* on_valid, |
| + Label::Distance near_jump) { |
| + Condition is_valid = CheckUInteger32ValidSmiValue(src); |
| + j(is_valid, on_valid, near_jump); |
| +} |
| + |
| + |
| void MacroAssembler::JumpIfUIntNotValidSmiValue(Register src, |
| Label* on_invalid, |
| Label::Distance near_jump) { |
| @@ -1917,7 +1935,7 @@ void MacroAssembler::SmiDiv(Register dst, |
| // We overshoot a little and go to slow case if we divide min-value |
| // by any negative value, not just -1. |
| Label safe_div; |
| - testl(rax, Immediate(0x7fffffff)); |
| + testl(rax, Immediate(~Smi::kMinValue)); |
| j(not_zero, &safe_div, Label::kNear); |
| testp(src2, src2); |
| if (src1.is(rax)) { |
| @@ -2110,12 +2128,28 @@ void MacroAssembler::SmiShiftArithmeticRightConstant(Register dst, |
| void MacroAssembler::SmiShiftLeftConstant(Register dst, |
| Register src, |
| - int shift_value) { |
| - if (!dst.is(src)) { |
| - movp(dst, src); |
| - } |
| - if (shift_value > 0) { |
| - shlp(dst, Immediate(shift_value)); |
| + int shift_value, |
| + Label* on_not_smi_result, |
| + Label::Distance near_jump) { |
| + if (SmiValuesAre32Bits()) { |
| + if (!dst.is(src)) { |
| + movp(dst, src); |
| + } |
| + if (shift_value > 0) { |
| + // Shift amount specified by lower 5 bits, not six as the shl opcode. |
| + shlq(dst, Immediate(shift_value & 0x1f)); |
| + } |
| + } else { |
| + ASSERT(SmiValuesAre31Bits()); |
| + if (dst.is(src)) { |
| + UNIMPLEMENTED(); // Not used. |
| + } else { |
| + movp(dst, src); |
| + SmiToInteger32(dst, dst); |
|
Toon Verwaest
2014/06/02 09:49:08
Why not just SmiToInteger32(dst, src) ?
haitao.feng
2014/06/03 03:14:30
Done.
|
| + shll(dst, Immediate(shift_value)); |
| + JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump); |
| + Integer32ToSmi(dst, dst); |
| + } |
| } |
| } |
| @@ -2132,24 +2166,69 @@ void MacroAssembler::SmiShiftLogicalRightConstant( |
| testp(dst, dst); |
| j(negative, on_not_smi_result, near_jump); |
| } |
| - shrq(dst, Immediate(shift_value + kSmiShift)); |
| - shlq(dst, Immediate(kSmiShift)); |
| + if (SmiValuesAre32Bits()) { |
| + shrp(dst, Immediate(shift_value + kSmiShift)); |
| + shlp(dst, Immediate(kSmiShift)); |
| + } else { |
| + ASSERT(SmiValuesAre31Bits()); |
| + SmiToInteger32(dst, dst); |
|
Toon Verwaest
2014/06/02 09:49:08
Same here
haitao.feng
2014/06/03 03:14:30
Done.
|
| + shrp(dst, Immediate(shift_value)); |
| + JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump); |
| + Integer32ToSmi(dst, dst); |
| + } |
| } |
| } |
| void MacroAssembler::SmiShiftLeft(Register dst, |
| Register src1, |
| - Register src2) { |
| - ASSERT(!dst.is(rcx)); |
| - // Untag shift amount. |
| - if (!dst.is(src1)) { |
| - movq(dst, src1); |
| + Register src2, |
| + Label* on_not_smi_result, |
| + Label::Distance near_jump) { |
| + if (SmiValuesAre32Bits()) { |
| + ASSERT(!dst.is(rcx)); |
| + // Untag shift amount. |
| + SmiToInteger32(rcx, src2); |
| + if (!dst.is(src1)) { |
|
Toon Verwaest
2014/06/02 09:49:08
If src1 is rcx, doing SmiToInteger32 first will de
haitao.feng
2014/06/03 03:14:30
Done.
|
| + movp(dst, src1); |
| + } |
| + // Shift amount specified by lower 5 bits, not six as the shl opcode. |
| + andp(rcx, Immediate(0x1f)); |
| + shlq_cl(dst); |
| + } else { |
| + ASSERT(SmiValuesAre31Bits()); |
| + ASSERT(!dst.is(kScratchRegister)); |
| + ASSERT(!src1.is(kScratchRegister)); |
| + ASSERT(!src2.is(kScratchRegister)); |
| + ASSERT(!dst.is(src2)); |
| + ASSERT(!dst.is(rcx)); |
| + |
| + if (src1.is(rcx) || src2.is(rcx)) { |
| + movp(kScratchRegister, rcx); |
| + } |
| + if (dst.is(src1)) { |
| + UNIMPLEMENTED(); // Not used. |
| + } else { |
| + Label valid_result; |
| + movp(dst, src1); |
| + SmiToInteger32(dst, dst); |
| + SmiToInteger32(rcx, src2); |
| + shll_cl(dst); |
|
Toon Verwaest
2014/06/02 09:49:08
Seems like this code could be simplified? Why didn
haitao.feng
2014/06/03 03:14:30
For 31-bit SMI, we might need to jump to the on_no
|
| + JumpIfValidSmiValue(dst, &valid_result, Label::kNear); |
| + // As src1 or src2 could not be dst, we do not need to restore them for |
| + // clobbering dst. |
| + if (src1.is(rcx) || src2.is(rcx)) { |
| + if (src1.is(rcx)) { |
| + movp(src1, kScratchRegister); |
| + } else { |
| + movp(src2, kScratchRegister); |
| + } |
| + } |
| + jmp(on_not_smi_result, near_jump); |
| + bind(&valid_result); |
| + Integer32ToSmi(dst, dst); |
| + } |
| } |
| - SmiToInteger32(rcx, src2); |
| - // Shift amount specified by lower 5 bits, not six as the shl opcode. |
| - andq(rcx, Immediate(0x1f)); |
| - shlq_cl(dst); |
| } |
| @@ -2161,33 +2240,32 @@ void MacroAssembler::SmiShiftLogicalRight(Register dst, |
| ASSERT(!dst.is(kScratchRegister)); |
| ASSERT(!src1.is(kScratchRegister)); |
| ASSERT(!src2.is(kScratchRegister)); |
| + ASSERT(!dst.is(src2)); |
| ASSERT(!dst.is(rcx)); |
| - // dst and src1 can be the same, because the one case that bails out |
| - // is a shift by 0, which leaves dst, and therefore src1, unchanged. |
| if (src1.is(rcx) || src2.is(rcx)) { |
| - movq(kScratchRegister, rcx); |
| + movp(kScratchRegister, rcx); |
| } |
| - if (!dst.is(src1)) { |
| - movq(dst, src1); |
| - } |
| - SmiToInteger32(rcx, src2); |
| - orl(rcx, Immediate(kSmiShift)); |
| - shrq_cl(dst); // Shift is rcx modulo 0x1f + 32. |
| - shlq(dst, Immediate(kSmiShift)); |
| - testq(dst, dst); |
| - if (src1.is(rcx) || src2.is(rcx)) { |
| - Label positive_result; |
| - j(positive, &positive_result, Label::kNear); |
| - if (src1.is(rcx)) { |
| - movq(src1, kScratchRegister); |
| - } else { |
| - movq(src2, kScratchRegister); |
| - } |
| - jmp(on_not_smi_result, near_jump); |
| - bind(&positive_result); |
| + if (dst.is(src1)) { |
| + UNIMPLEMENTED(); // Not used. |
| } else { |
| - // src2 was zero and src1 negative. |
| - j(negative, on_not_smi_result, near_jump); |
| + Label valid_result; |
| + movp(dst, src1); |
|
Toon Verwaest
2014/06/02 09:49:08
SmiToInteger32(dst, src1);
haitao.feng
2014/06/03 03:14:30
Done.
|
| + SmiToInteger32(rcx, src2); |
| + SmiToInteger32(dst, dst); |
| + shrl_cl(dst); |
| + JumpIfUIntValidSmiValue(dst, &valid_result, Label::kNear); |
| + // As src1 or src2 could not be dst, we do not need to restore them for |
| + // clobbering dst. |
| + if (src1.is(rcx) || src2.is(rcx)) { |
| + if (src1.is(rcx)) { |
| + movp(src1, kScratchRegister); |
| + } else { |
| + movp(src2, kScratchRegister); |
| + } |
| + } |
| + jmp(on_not_smi_result, near_jump); |
| + bind(&valid_result); |
| + Integer32ToSmi(dst, dst); |
| } |
| } |
| @@ -2199,23 +2277,14 @@ void MacroAssembler::SmiShiftArithmeticRight(Register dst, |
| ASSERT(!src1.is(kScratchRegister)); |
| ASSERT(!src2.is(kScratchRegister)); |
| ASSERT(!dst.is(rcx)); |
| - if (src1.is(rcx)) { |
| - movp(kScratchRegister, src1); |
| - } else if (src2.is(rcx)) { |
| - movp(kScratchRegister, src2); |
| - } |
| + |
| + SmiToInteger32(rcx, src2); |
| if (!dst.is(src1)) { |
| movp(dst, src1); |
| } |
| - SmiToInteger32(rcx, src2); |
| - orl(rcx, Immediate(kSmiShift)); |
| - sarp_cl(dst); // Shift 32 + original rcx & 0x1f. |
| - shlp(dst, Immediate(kSmiShift)); |
| - if (src1.is(rcx)) { |
| - movp(src1, kScratchRegister); |
| - } else if (src2.is(rcx)) { |
| - movp(src2, kScratchRegister); |
| - } |
| + SmiToInteger32(dst, dst); |
| + sarl_cl(dst); |
| + Integer32ToSmi(dst, dst); |
| } |