| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 6f45b81082a93fe5eda2d44901872425a49f215c..646dafbafa786f05e03b33f820a5d339fee2aee4 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -410,10 +410,26 @@ bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const {
|
| }
|
|
|
|
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| int32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
|
| HConstant* constant = chunk_->LookupConstant(op);
|
| return constant->Integer32Value();
|
| }
|
| +#else
|
| +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);
|
| + int32_t value = constant->Integer32Value();
|
| + if (r.IsInteger32()) return value;
|
| + ASSERT(r.IsSmiOrTagged());
|
| + return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value)));
|
| +}
|
| +#endif
|
|
|
|
|
| Smi* LCodeGen::ToSmi(LConstantOperand* op) const {
|
| @@ -1301,14 +1317,22 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
| } else if (right->IsStackSlot()) {
|
| if (instr->hydrogen_value()->representation().IsSmi()) {
|
| __ SmiToInteger32(left, left);
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ imul(left, ToOperand(right));
|
| +#else
|
| + __ imull(left, ToOperand(right));
|
| +#endif
|
| } else {
|
| __ imull(left, ToOperand(right));
|
| }
|
| } else {
|
| if (instr->hydrogen_value()->representation().IsSmi()) {
|
| __ SmiToInteger32(left, left);
|
| - __ imul(left, ToRegister(right));
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| + __ imul(left, ToOperand(right));
|
| +#else
|
| + __ imull(left, ToOperand(right));
|
| +#endif
|
| } else {
|
| __ imull(left, ToRegister(right));
|
| }
|
| @@ -1318,6 +1342,12 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
| DeoptimizeIf(overflow, instr->environment());
|
| }
|
|
|
| +#if V8_USE_31_BITS_SMI_VALUE
|
| + if (instr->hydrogen_value()->representation().IsSmi()) {
|
| + __ movsxlq(left, left);
|
| + }
|
| +#endif
|
| +
|
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| // Bail out if the result is supposed to be negative zero.
|
| Label done;
|
| @@ -1350,16 +1380,45 @@ void LCodeGen::DoBitI(LBitI* instr) {
|
| ASSERT(left->IsRegister());
|
|
|
| if (right->IsConstantOperand()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| int right_operand = ToInteger32(LConstantOperand::cast(right));
|
| +#else
|
| + int right_operand = ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->representation());
|
| +#endif
|
| switch (instr->op()) {
|
| case Token::BIT_AND:
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ andl(ToRegister(left), Immediate(right_operand));
|
| +#else
|
| + if (instr->hydrogen()->representation().IsSmi()) {
|
| + __ and_(ToRegister(left), Immediate(right_operand));
|
| + } else {
|
| + __ andl(ToRegister(left), Immediate(right_operand));
|
| + }
|
| +#endif
|
| break;
|
| case Token::BIT_OR:
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ orl(ToRegister(left), Immediate(right_operand));
|
| +#else
|
| + if (instr->hydrogen()->representation().IsSmi()) {
|
| + __ or_(ToRegister(left), Immediate(right_operand));
|
| + } else {
|
| + __ orl(ToRegister(left), Immediate(right_operand));
|
| + }
|
| +#endif
|
| break;
|
| case Token::BIT_XOR:
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ xorl(ToRegister(left), Immediate(right_operand));
|
| +#else
|
| + if (instr->hydrogen()->representation().IsSmi()) {
|
| + __ xor_(ToRegister(left), Immediate(right_operand));
|
| + } else {
|
| + __ xorl(ToRegister(left), Immediate(right_operand));
|
| + }
|
| +#endif
|
| break;
|
| default:
|
| UNREACHABLE();
|
| @@ -1474,17 +1533,31 @@ void LCodeGen::DoSubI(LSubI* instr) {
|
| ASSERT(left->Equals(instr->result()));
|
|
|
| if (right->IsConstantOperand()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ subl(ToRegister(left),
|
| Immediate(ToInteger32(LConstantOperand::cast(right))));
|
| +#else
|
| + __ subl(ToRegister(left),
|
| + Immediate(ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->representation())));
|
| +#endif
|
| } else if (right->IsRegister()) {
|
| if (instr->hydrogen_value()->representation().IsSmi()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ subq(ToRegister(left), ToRegister(right));
|
| +#else
|
| + __ subl(ToRegister(left), ToRegister(right));
|
| +#endif
|
| } else {
|
| __ subl(ToRegister(left), ToRegister(right));
|
| }
|
| } else {
|
| if (instr->hydrogen_value()->representation().IsSmi()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ subq(ToRegister(left), ToOperand(right));
|
| +#else
|
| + __ subl(ToRegister(left), ToOperand(right));
|
| +#endif
|
| } else {
|
| __ subl(ToRegister(left), ToOperand(right));
|
| }
|
| @@ -1493,6 +1566,12 @@ void LCodeGen::DoSubI(LSubI* instr) {
|
| if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
|
| DeoptimizeIf(overflow, instr->environment());
|
| }
|
| +
|
| +#if V8_USE_31_BITS_SMI_VALUE
|
| + if (instr->hydrogen_value()->representation().IsSmi()) {
|
| + __ movsxlq(ToRegister(left), ToRegister(left));
|
| + }
|
| +#endif
|
| }
|
|
|
|
|
| @@ -1663,9 +1742,21 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
|
|
| if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
|
| if (right->IsConstantOperand()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| int32_t offset = ToInteger32(LConstantOperand::cast(right));
|
| __ leal(ToRegister(instr->result()),
|
| MemOperand(ToRegister(left), offset));
|
| +#else
|
| + int32_t offset = ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->representation());
|
| + if (instr->hydrogen()->representation().IsSmi()) {
|
| + __ lea(ToRegister(instr->result()),
|
| + MemOperand(ToRegister(left), offset));
|
| + } else {
|
| + __ leal(ToRegister(instr->result()),
|
| + MemOperand(ToRegister(left), offset));
|
| + }
|
| +#endif
|
| } else {
|
| Operand address(ToRegister(left), ToRegister(right), times_1, 0);
|
| if (instr->hydrogen()->representation().IsSmi()) {
|
| @@ -1676,17 +1767,31 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
| }
|
| } else {
|
| if (right->IsConstantOperand()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ addl(ToRegister(left),
|
| Immediate(ToInteger32(LConstantOperand::cast(right))));
|
| +#else
|
| + __ addl(ToRegister(left),
|
| + Immediate(ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->representation())));
|
| +#endif
|
| } else if (right->IsRegister()) {
|
| if (instr->hydrogen_value()->representation().IsSmi()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ addq(ToRegister(left), ToRegister(right));
|
| +#else
|
| + __ addl(ToRegister(left), ToRegister(right));
|
| +#endif
|
| } else {
|
| __ addl(ToRegister(left), ToRegister(right));
|
| }
|
| } else {
|
| if (instr->hydrogen_value()->representation().IsSmi()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| __ addq(ToRegister(left), ToOperand(right));
|
| +#else
|
| + __ addl(ToRegister(left), ToOperand(right));
|
| +#endif
|
| } else {
|
| __ addl(ToRegister(left), ToOperand(right));
|
| }
|
| @@ -1694,6 +1799,11 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
| if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
|
| DeoptimizeIf(overflow, instr->environment());
|
| }
|
| +#if V8_USE_31_BITS_SMI_VALUE
|
| + if (instr->hydrogen_value()->representation().IsSmi()) {
|
| + __ movsxlq(ToRegister(left), ToRegister(left));
|
| + }
|
| +#endif
|
| }
|
| }
|
|
|
| @@ -1710,9 +1820,15 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
|
| : greater_equal;
|
| Register left_reg = ToRegister(left);
|
| if (right->IsConstantOperand()) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| Immediate right_imm =
|
| Immediate(ToInteger32(LConstantOperand::cast(right)));
|
| ASSERT(!instr->hydrogen_value()->representation().IsSmi());
|
| +#else
|
| + Immediate right_imm =
|
| + Immediate(ToRepresentation(LConstantOperand::cast(right),
|
| + instr->hydrogen()->representation()));
|
| +#endif
|
| __ cmpl(left_reg, right_imm);
|
| __ j(condition, &return_left, Label::kNear);
|
| __ movq(left_reg, right_imm);
|
| @@ -2910,7 +3026,13 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
|
| // gets replaced during bound check elimination with the index argument
|
| // to the bounds check, which can be tagged, so that case must be
|
| // handled here, too.
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| if (instr->hydrogen()->IsDehoisted()) {
|
| +#else
|
| + if (instr->hydrogen()->key()->representation().IsSmi()) {
|
| + __ SmiToInteger64(key_reg, key_reg);
|
| + } else if (instr->hydrogen()->IsDehoisted()) {
|
| +#endif
|
| // Sign extend key because it could be a 32 bit negative value
|
| // and the dehoisted address computation happens in 64 bits
|
| __ movsxlq(key_reg, key_reg);
|
| @@ -2981,7 +3103,13 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
|
| // representation for the key to be an integer, the input gets replaced
|
| // during bound check elimination with the index argument to the bounds
|
| // check, which can be tagged, so that case must be handled here, too.
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| if (instr->hydrogen()->IsDehoisted()) {
|
| +#else
|
| + if (instr->hydrogen()->key()->representation().IsSmi()) {
|
| + __ SmiToInteger64(key_reg, key_reg);
|
| + } else if (instr->hydrogen()->IsDehoisted()) {
|
| +#endif
|
| // Sign extend key because it could be a 32 bit negative value
|
| // and the dehoisted address computation happens in 64 bits
|
| __ movsxlq(key_reg, key_reg);
|
| @@ -3021,7 +3149,13 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
|
| // gets replaced during bound check elimination with the index
|
| // argument to the bounds check, which can be tagged, so that
|
| // case must be handled here, too.
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| if (instr->hydrogen()->IsDehoisted()) {
|
| +#else
|
| + if (instr->hydrogen()->key()->representation().IsSmi()) {
|
| + __ SmiToInteger64(key_reg, key_reg);
|
| + } else if (instr->hydrogen()->IsDehoisted()) {
|
| +#endif
|
| // Sign extend key because it could be a 32 bit negative value
|
| // and the dehoisted address computation happens in 64 bits
|
| __ movsxlq(key_reg, key_reg);
|
| @@ -4097,7 +4231,13 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
|
| // gets replaced during bound check elimination with the index
|
| // argument to the bounds check, which can be tagged, so that case
|
| // must be handled here, too.
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| if (instr->hydrogen()->IsDehoisted()) {
|
| +#else
|
| + if (instr->hydrogen()->key()->representation().IsSmi()) {
|
| + __ SmiToInteger64(key_reg, key_reg);
|
| + } else if (instr->hydrogen()->IsDehoisted()) {
|
| +#endif
|
| // Sign extend key because it could be a 32 bit negative value
|
| // and the dehoisted address computation happens in 64 bits
|
| __ movsxlq(key_reg, key_reg);
|
| @@ -4159,7 +4299,13 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
|
| // input gets replaced during bound check elimination with the index
|
| // argument to the bounds check, which can be tagged, so that case
|
| // must be handled here, too.
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| if (instr->hydrogen()->IsDehoisted()) {
|
| +#else
|
| + if (instr->hydrogen()->key()->representation().IsSmi()) {
|
| + __ SmiToInteger64(key_reg, key_reg);
|
| + } else if (instr->hydrogen()->IsDehoisted()) {
|
| +#endif
|
| // Sign extend key because it could be a 32 bit negative value
|
| // and the dehoisted address computation happens in 64 bits
|
| __ movsxlq(key_reg, key_reg);
|
| @@ -4200,7 +4346,13 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| // input gets replaced during bound check elimination with the index
|
| // argument to the bounds check, which can be tagged, so that case
|
| // must be handled here, too.
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| if (instr->hydrogen()->IsDehoisted()) {
|
| +#else
|
| + if (instr->hydrogen()->key()->representation().IsSmi()) {
|
| + __ SmiToInteger64(key_reg, key_reg);
|
| + } else if (instr->hydrogen()->IsDehoisted()) {
|
| +#endif
|
| // Sign extend key because it could be a 32 bit negative value
|
| // and the dehoisted address computation happens in 64 bits
|
| __ movsxlq(key_reg, key_reg);
|
| @@ -4486,14 +4638,80 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
|
|
|
|
| void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
|
| +#if !V8_USE_31_BITS_SMI_VALUE
|
| LOperand* input = instr->value();
|
| ASSERT(input->IsRegister() && input->Equals(instr->result()));
|
| Register reg = ToRegister(input);
|
|
|
| __ Integer32ToSmi(reg, reg);
|
| +#else
|
| + class DeferredNumberTagI: public LDeferredCode {
|
| + public:
|
| + DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
|
| + : LDeferredCode(codegen), instr_(instr) { }
|
| + virtual void Generate() {
|
| + codegen()->DoDeferredNumberTagI(instr_);
|
| + }
|
| + virtual LInstruction* instr() { return instr_; }
|
| + private:
|
| + LNumberTagI* instr_;
|
| + };
|
| +
|
| + LOperand* input = instr->value();
|
| + ASSERT(input->IsRegister() && input->Equals(instr->result()));
|
| + Register reg = ToRegister(input);
|
| +
|
| + DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
|
| + __ shll(reg, Immediate(kSmiTagSize + kSmiShiftSize));
|
| + __ j(overflow, deferred->entry());
|
| + __ movsxlq(reg, reg);
|
| + __ bind(deferred->exit());
|
| +#endif
|
| }
|
|
|
|
|
| +#if V8_USE_31_BITS_SMI_VALUE
|
| +void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
|
| + Label slow;
|
| + Register reg = ToRegister(instr->value());
|
| + Register tmp = reg.is(rax) ? kScratchRegister : rax;
|
| +
|
| + // Preserve the value of all registers.
|
| + PushSafepointRegistersScope scope(this);
|
| +
|
| + Label done;
|
| + // There was overflow, so bits 30 and 31 of the original integer
|
| + // disagree. Try to allocate a heap number in new space and store
|
| + // the value in there. If that fails, call the runtime system.
|
| + __ SmiToInteger32(reg, reg);
|
| + __ xorl(reg, Immediate(0x80000000));
|
| + __ cvtlsi2sd(xmm1, reg);
|
| +
|
| + if (FLAG_inline_new) {
|
| + __ AllocateHeapNumber(reg, tmp, &slow);
|
| + __ jmp(&done, Label::kNear);
|
| + }
|
| +
|
| + // Slow case: Call the runtime system to do the number allocation.
|
| + __ bind(&slow);
|
| +
|
| + // Put a valid pointer value in the stack slot where the result
|
| + // register is stored, as this register is in the pointer map, but contains an
|
| + // integer value.
|
| + __ StoreToSafepointRegisterSlot(reg, Immediate(0));
|
| + CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
|
| + // Set the pointer to the new heap number in tmp.
|
| + if (!reg.is(rax)) __ movq(reg, rax);
|
| +
|
| + // Heap number allocated. Put the value in xmm0 into the value of the
|
| + // allocated heap number.
|
| + __ bind(&done);
|
| + __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1);
|
| + __ StoreToSafepointRegisterSlot(reg, reg);
|
| +}
|
| +#endif
|
| +
|
| +
|
| void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
|
| class DeferredNumberTagU: public LDeferredCode {
|
| public:
|
|
|