Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1224)

Unified Diff: src/x64/lithium-codegen-x64.cc

Issue 21014003: Optionally use 31-bits SMI value for 64-bit system (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use (kSmiValueSize == 31) or (kSmiValueSize == 32) for SMI functions in macro assembler" Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..7115f37091bc924dbd4a56eecb757549d7dcbb9e 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -411,8 +411,17 @@ bool LCodeGen::IsTaggedConstant(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(r.IsSmiOrTagged());
+ return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value)));
}
@@ -1301,14 +1310,24 @@ void LCodeGen::DoMulI(LMulI* instr) {
} else if (right->IsStackSlot()) {
if (instr->hydrogen_value()->representation().IsSmi()) {
__ SmiToInteger32(left, left);
- __ imul(left, ToOperand(right));
+ if (kSmiValueSize == 32) {
+ __ imul(left, ToOperand(right));
danno 2013/08/01 16:45:41 Move this switching into the macro assembler, you
+ } else {
+ ASSERT(kSmiValueSize == 31);
+ __ imull(left, ToOperand(right));
+ }
} else {
__ imull(left, ToOperand(right));
}
} else {
if (instr->hydrogen_value()->representation().IsSmi()) {
__ SmiToInteger32(left, left);
- __ imul(left, ToRegister(right));
+ if (kSmiValueSize == 32) {
+ __ imul(left, ToOperand(right));
+ } else {
+ ASSERT(kSmiValueSize == 31);
+ __ imull(left, ToOperand(right));
+ }
} else {
__ imull(left, ToRegister(right));
}
@@ -1318,6 +1337,11 @@ void LCodeGen::DoMulI(LMulI* instr) {
DeoptimizeIf(overflow, instr->environment());
}
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen_value()->representation().IsSmi()) {
+ __ movsxlq(left, left);
+ }
+
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Bail out if the result is supposed to be negative zero.
Label done;
@@ -1350,16 +1374,29 @@ void LCodeGen::DoBitI(LBitI* instr) {
ASSERT(left->IsRegister());
if (right->IsConstantOperand()) {
- int right_operand = ToInteger32(LConstantOperand::cast(right));
+ int right_operand = ToRepresentation(LConstantOperand::cast(right),
+ instr->hydrogen()->representation());
switch (instr->op()) {
case Token::BIT_AND:
- __ andl(ToRegister(left), Immediate(right_operand));
+ if (instr->hydrogen()->representation().IsSmi()) {
+ __ and_(ToRegister(left), Immediate(right_operand));
+ } else {
+ __ andl(ToRegister(left), Immediate(right_operand));
+ }
break;
case Token::BIT_OR:
- __ orl(ToRegister(left), Immediate(right_operand));
+ if (instr->hydrogen()->representation().IsSmi()) {
+ __ or_(ToRegister(left), Immediate(right_operand));
+ } else {
+ __ orl(ToRegister(left), Immediate(right_operand));
+ }
break;
case Token::BIT_XOR:
- __ xorl(ToRegister(left), Immediate(right_operand));
+ if (instr->hydrogen()->representation().IsSmi()) {
+ __ xor_(ToRegister(left), Immediate(right_operand));
+ } else {
+ __ xorl(ToRegister(left), Immediate(right_operand));
+ }
break;
default:
UNREACHABLE();
@@ -1475,16 +1512,27 @@ void LCodeGen::DoSubI(LSubI* instr) {
if (right->IsConstantOperand()) {
__ subl(ToRegister(left),
- Immediate(ToInteger32(LConstantOperand::cast(right))));
+ Immediate(ToRepresentation(LConstantOperand::cast(right),
+ instr->hydrogen()->representation())));
} else if (right->IsRegister()) {
if (instr->hydrogen_value()->representation().IsSmi()) {
- __ subq(ToRegister(left), ToRegister(right));
+ if (kSmiValueSize == 32) {
+ __ subq(ToRegister(left), ToRegister(right));
+ } else {
+ ASSERT(kSmiValueSize == 31);
+ __ subl(ToRegister(left), ToRegister(right));
+ }
} else {
__ subl(ToRegister(left), ToRegister(right));
}
} else {
if (instr->hydrogen_value()->representation().IsSmi()) {
- __ subq(ToRegister(left), ToOperand(right));
+ if (kSmiValueSize == 32) {
+ __ subq(ToRegister(left), ToOperand(right));
+ } else {
+ ASSERT(kSmiValueSize == 31);
+ __ subl(ToRegister(left), ToOperand(right));
+ }
} else {
__ subl(ToRegister(left), ToOperand(right));
}
@@ -1493,6 +1541,11 @@ void LCodeGen::DoSubI(LSubI* instr) {
if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
DeoptimizeIf(overflow, instr->environment());
}
+
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen_value()->representation().IsSmi()) {
+ __ movsxlq(ToRegister(left), ToRegister(left));
+ }
}
@@ -1663,9 +1716,15 @@ void LCodeGen::DoAddI(LAddI* instr) {
if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
if (right->IsConstantOperand()) {
- int32_t offset = ToInteger32(LConstantOperand::cast(right));
- __ leal(ToRegister(instr->result()),
- MemOperand(ToRegister(left), offset));
+ 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));
+ }
} else {
Operand address(ToRegister(left), ToRegister(right), times_1, 0);
if (instr->hydrogen()->representation().IsSmi()) {
@@ -1677,16 +1736,27 @@ void LCodeGen::DoAddI(LAddI* instr) {
} else {
if (right->IsConstantOperand()) {
__ addl(ToRegister(left),
- Immediate(ToInteger32(LConstantOperand::cast(right))));
+ Immediate(ToRepresentation(LConstantOperand::cast(right),
+ instr->hydrogen()->representation())));
} else if (right->IsRegister()) {
if (instr->hydrogen_value()->representation().IsSmi()) {
- __ addq(ToRegister(left), ToRegister(right));
+ if (kSmiValueSize == 32) {
+ __ addq(ToRegister(left), ToRegister(right));
+ } else {
+ ASSERT(kSmiValueSize == 31);
+ __ addl(ToRegister(left), ToRegister(right));
+ }
} else {
__ addl(ToRegister(left), ToRegister(right));
}
} else {
if (instr->hydrogen_value()->representation().IsSmi()) {
- __ addq(ToRegister(left), ToOperand(right));
+ if (kSmiValueSize == 32) {
+ __ addq(ToRegister(left), ToOperand(right));
+ } else {
+ ASSERT(kSmiValueSize == 31);
+ __ addl(ToRegister(left), ToOperand(right));
+ }
} else {
__ addl(ToRegister(left), ToOperand(right));
}
@@ -1694,6 +1764,11 @@ void LCodeGen::DoAddI(LAddI* instr) {
if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
DeoptimizeIf(overflow, instr->environment());
}
+
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen_value()->representation().IsSmi()) {
+ __ movsxlq(ToRegister(left), ToRegister(left));
+ }
}
}
@@ -1711,8 +1786,8 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
Register left_reg = ToRegister(left);
if (right->IsConstantOperand()) {
Immediate right_imm =
- Immediate(ToInteger32(LConstantOperand::cast(right)));
- ASSERT(!instr->hydrogen_value()->representation().IsSmi());
+ Immediate(ToRepresentation(LConstantOperand::cast(right),
+ instr->hydrogen()->representation()));
__ cmpl(left_reg, right_imm);
__ j(condition, &return_left, Label::kNear);
__ movq(left_reg, right_imm);
@@ -2910,7 +2985,10 @@ 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 (instr->hydrogen()->IsDehoisted()) {
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen()->key()->representation().IsSmi()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
// 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 +3059,10 @@ 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 (instr->hydrogen()->IsDehoisted()) {
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen()->key()->representation().IsSmi()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
// 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 +3102,10 @@ 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 (instr->hydrogen()->IsDehoisted()) {
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen()->key()->representation().IsSmi()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
// 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 +4181,10 @@ 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 (instr->hydrogen()->IsDehoisted()) {
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen()->key()->representation().IsSmi()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
// 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 +4246,10 @@ 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 (instr->hydrogen()->IsDehoisted()) {
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen()->key()->representation().IsSmi()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
// 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 +4290,10 @@ 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 (instr->hydrogen()->IsDehoisted()) {
+ if (kSmiValueSize == 31 &&
+ instr->hydrogen()->key()->representation().IsSmi()) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (instr->hydrogen()->IsDehoisted()) {
// 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,11 +4579,76 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
- LOperand* input = instr->value();
- ASSERT(input->IsRegister() && input->Equals(instr->result()));
- Register reg = ToRegister(input);
+ if (kSmiValueSize == 32) {
+ LOperand* input = instr->value();
+ ASSERT(input->IsRegister() && input->Equals(instr->result()));
+ Register reg = ToRegister(input);
- __ Integer32ToSmi(reg, reg);
+ __ Integer32ToSmi(reg, reg);
+ } else {
+ ASSERT(kSmiValueSize == 31);
+ 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());
+ }
+}
+
+
+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);
}

Powered by Google App Engine
This is Rietveld 408576698