From: haitao.feng@intel.com Date: Tue, 10 Jun 2014 04:03:51 +0000 (+0000) Subject: Update SmiShiftLeft, SmiShiftLogicalRight, SmiShiftArithmeticRight and SmiDiv to... X-Git-Tag: upstream/4.7.83~8772 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=87df0b0eb7b4f4a1fcd5cd3656eaa7696e263165;p=platform%2Fupstream%2Fv8.git Update SmiShiftLeft, SmiShiftLogicalRight, SmiShiftArithmeticRight and SmiDiv to support x32 port. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/264973011 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21725 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index b5b0090..8de4226 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -2294,7 +2294,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, __ SmiShiftArithmeticRight(rax, rdx, rcx); break; case Token::SHL: - __ SmiShiftLeft(rax, rdx, rcx); + __ SmiShiftLeft(rax, rdx, rcx, &stub_call); break; case Token::SHR: __ SmiShiftLogicalRight(rax, rdx, rcx, &stub_call); diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index f5145da..39acf80 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(isolate()->heap()->NewSpaceMask()))); + ASSERT(kPointerSize == kInt64Size + ? is_int32(static_cast(isolate()->heap()->NewSpaceMask())) + : kPointerSize == kInt32Size); intptr_t new_space_start = reinterpret_cast(isolate()->heap()->NewSpaceStart()); Move(kScratchRegister, reinterpret_cast
(-new_space_start), @@ -1494,6 +1496,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) { @@ -1502,6 +1512,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) { @@ -1982,7 +2000,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)) { @@ -2175,12 +2193,27 @@ 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 { + SmiToInteger32(dst, src); + shll(dst, Immediate(shift_value)); + JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump); + Integer32ToSmi(dst, dst); + } } } @@ -2192,29 +2225,73 @@ void MacroAssembler::SmiShiftLogicalRightConstant( if (dst.is(src)) { UNIMPLEMENTED(); // Not used. } else { - movp(dst, src); if (shift_value == 0) { - testp(dst, dst); + testp(src, src); j(negative, on_not_smi_result, near_jump); } - shrq(dst, Immediate(shift_value + kSmiShift)); - shlq(dst, Immediate(kSmiShift)); + if (SmiValuesAre32Bits()) { + movp(dst, src); + shrp(dst, Immediate(shift_value + kSmiShift)); + shlp(dst, Immediate(kSmiShift)); + } else { + ASSERT(SmiValuesAre31Bits()); + SmiToInteger32(dst, src); + 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)); + if (!dst.is(src1)) { + movp(dst, src1); + } + // Untag shift amount. + SmiToInteger32(rcx, src2); + // 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)) { + movq(kScratchRegister, rcx); + } + if (dst.is(src1)) { + UNIMPLEMENTED(); // Not used. + } else { + Label valid_result; + SmiToInteger32(dst, src1); + SmiToInteger32(rcx, src2); + shll_cl(dst); + 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)) { + movq(src1, kScratchRegister); + } else { + movq(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); } @@ -2226,33 +2303,31 @@ 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); } - 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; + SmiToInteger32(dst, src1); + SmiToInteger32(rcx, src2); + 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)) { + movq(src1, kScratchRegister); + } else { + movq(src2, kScratchRegister); + } + } + jmp(on_not_smi_result, near_jump); + bind(&valid_result); + Integer32ToSmi(dst, dst); } } @@ -2264,23 +2339,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); } diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h index 6635289..e6d5191 100644 --- a/src/x64/macro-assembler-x64.h +++ b/src/x64/macro-assembler-x64.h @@ -489,10 +489,18 @@ class MacroAssembler: public Assembler { // Test-and-jump functions. Typically combines a check function // above with a conditional jump. + // Jump if the value can be represented by a smi. + void JumpIfValidSmiValue(Register src, Label* on_valid, + Label::Distance near_jump = Label::kFar); + // Jump if the value cannot be represented by a smi. void JumpIfNotValidSmiValue(Register src, Label* on_invalid, Label::Distance near_jump = Label::kFar); + // Jump if the unsigned integer value can be represented by a smi. + void JumpIfUIntValidSmiValue(Register src, Label* on_valid, + Label::Distance near_jump = Label::kFar); + // Jump if the unsigned integer value cannot be represented by a smi. void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid, Label::Distance near_jump = Label::kFar); @@ -650,7 +658,9 @@ class MacroAssembler: public Assembler { void SmiShiftLeftConstant(Register dst, Register src, - int shift_value); + int shift_value, + Label* on_not_smi_result = NULL, + Label::Distance near_jump = Label::kFar); void SmiShiftLogicalRightConstant(Register dst, Register src, int shift_value, @@ -664,7 +674,9 @@ class MacroAssembler: public Assembler { // Uses and clobbers rcx, so dst may not be rcx. void SmiShiftLeft(Register dst, Register src1, - Register src2); + Register src2, + Label* on_not_smi_result = NULL, + Label::Distance near_jump = Label::kFar); // Shifts a smi value to the right, shifting in zero bits at the top, and // returns the unsigned intepretation of the result if that is a smi. // Uses and clobbers rcx, so dst may not be rcx.