| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 75ba04e48170f0ed94975dc180d28f5cd9625ae3..3af6b9f68d8c2ed4c26d315f9e89d976bd31b89e 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -431,8 +431,17 @@ bool LCodeGen::IsSmiConstant(LConstantOperand* op) const {
|
|
|
|
|
| int32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
|
| + return ToRepresentation(op, Representation::Integer32());
|
| +}
|
| +
|
| +
|
| +int32_t LCodeGen::ToRepresentation(LConstantOperand* op,
|
| + const Representation& r) const {
|
| HConstant* constant = chunk_->LookupConstant(op);
|
| - return constant->Integer32Value();
|
| + int32_t value = constant->Integer32Value();
|
| + if (r.IsInteger32()) return value;
|
| + ASSERT(SmiValuesAre31Bits() && r.IsSmiOrTagged());
|
| + return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value)));
|
| }
|
|
|
|
|
| @@ -1457,8 +1466,11 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
| }
|
| __ j(not_zero, &done, Label::kNear);
|
| if (right->IsConstantOperand()) {
|
| - // Constant can't be represented as Smi due to immediate size limit.
|
| - ASSERT(!instr->hydrogen_value()->representation().IsSmi());
|
| + // Constant can't be represented as 32-bit Smi due to immediate size
|
| + // limit.
|
| + ASSERT(SmiValuesAre32Bits()
|
| + ? !instr->hydrogen_value()->representation().IsSmi()
|
| + : SmiValuesAre31Bits());
|
| if (ToInteger32(LConstantOperand::cast(right)) < 0) {
|
| DeoptimizeIf(no_condition, instr->environment());
|
| } else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
|
| @@ -1493,7 +1505,9 @@ void LCodeGen::DoBitI(LBitI* instr) {
|
| ASSERT(left->IsRegister());
|
|
|
| if (right->IsConstantOperand()) {
|
| - int32_t right_operand = ToInteger32(LConstantOperand::cast(right));
|
| + int32_t right_operand =
|
| + ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->right()->representation());
|
| switch (instr->op()) {
|
| case Token::BIT_AND:
|
| __ andl(ToRegister(left), Immediate(right_operand));
|
| @@ -1625,7 +1639,20 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
|
| case Token::SHL:
|
| if (shift_count != 0) {
|
| if (instr->hydrogen_value()->representation().IsSmi()) {
|
| - __ shlp(ToRegister(left), Immediate(shift_count));
|
| + if (SmiValuesAre32Bits()) {
|
| + __ shlp(ToRegister(left), Immediate(shift_count));
|
| + } else {
|
| + ASSERT(SmiValuesAre31Bits());
|
| + if (instr->can_deopt()) {
|
| + if (shift_count != 1) {
|
| + __ shll(ToRegister(left), Immediate(shift_count - 1));
|
| + }
|
| + __ Integer32ToSmi(ToRegister(left), ToRegister(left));
|
| + DeoptimizeIf(overflow, instr->environment());
|
| + } else {
|
| + __ shll(ToRegister(left), Immediate(shift_count));
|
| + }
|
| + }
|
| } else {
|
| __ shll(ToRegister(left), Immediate(shift_count));
|
| }
|
| @@ -1645,8 +1672,10 @@ void LCodeGen::DoSubI(LSubI* instr) {
|
| ASSERT(left->Equals(instr->result()));
|
|
|
| if (right->IsConstantOperand()) {
|
| - __ subl(ToRegister(left),
|
| - Immediate(ToInteger32(LConstantOperand::cast(right))));
|
| + int32_t right_operand =
|
| + ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->right()->representation());
|
| + __ subl(ToRegister(left), Immediate(right_operand));
|
| } else if (right->IsRegister()) {
|
| if (instr->hydrogen_value()->representation().IsSmi()) {
|
| __ subp(ToRegister(left), ToRegister(right));
|
| @@ -1847,8 +1876,11 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
|
|
| if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
|
| if (right->IsConstantOperand()) {
|
| - ASSERT(!target_rep.IsSmi()); // No support for smi-immediates.
|
| - int32_t offset = ToInteger32(LConstantOperand::cast(right));
|
| + // No support for smi-immediates for 32-bit SMI.
|
| + ASSERT(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits());
|
| + int32_t offset =
|
| + ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->right()->representation());
|
| if (is_p) {
|
| __ leap(ToRegister(instr->result()),
|
| MemOperand(ToRegister(left), offset));
|
| @@ -1866,13 +1898,15 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
| }
|
| } else {
|
| if (right->IsConstantOperand()) {
|
| - ASSERT(!target_rep.IsSmi()); // No support for smi-immediates.
|
| + // No support for smi-immediates for 32-bit SMI.
|
| + ASSERT(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits());
|
| + int32_t right_operand =
|
| + ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->right()->representation());
|
| if (is_p) {
|
| - __ addp(ToRegister(left),
|
| - Immediate(ToInteger32(LConstantOperand::cast(right))));
|
| + __ addp(ToRegister(left), Immediate(right_operand));
|
| } else {
|
| - __ addl(ToRegister(left),
|
| - Immediate(ToInteger32(LConstantOperand::cast(right))));
|
| + __ addl(ToRegister(left), Immediate(right_operand));
|
| }
|
| } else if (right->IsRegister()) {
|
| if (is_p) {
|
| @@ -1906,9 +1940,12 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
|
| : greater_equal;
|
| Register left_reg = ToRegister(left);
|
| if (right->IsConstantOperand()) {
|
| - Immediate right_imm =
|
| - Immediate(ToInteger32(LConstantOperand::cast(right)));
|
| - ASSERT(!instr->hydrogen_value()->representation().IsSmi());
|
| + Immediate right_imm = Immediate(
|
| + ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->right()->representation()));
|
| + ASSERT(SmiValuesAre32Bits()
|
| + ? !instr->hydrogen()->representation().IsSmi()
|
| + : SmiValuesAre31Bits());
|
| __ cmpl(left_reg, right_imm);
|
| __ j(condition, &return_left, Label::kNear);
|
| __ movp(left_reg, right_imm);
|
| @@ -4698,8 +4735,8 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
| Register output = ToRegister(instr->result());
|
| if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
| hchange->value()->CheckFlag(HValue::kUint32)) {
|
| - __ testl(input, input);
|
| - DeoptimizeIf(sign, instr->environment());
|
| + Condition is_smi = __ CheckUInteger32ValidSmiValue(input);
|
| + DeoptimizeIf(NegateCondition(is_smi), instr->environment());
|
| }
|
| __ Integer32ToSmi(output, input);
|
| if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
|
|