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

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

Issue 23156006: [v8-dev] ARM: Improve Lithium register constraints. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 9ec80f819a062dbf3078fc4a0487b765177a19cb..e5baef2503ab62c5c4434db9a8c001c6d5a3f5fd 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -417,72 +417,12 @@ Register LCodeGen::ToRegister(LOperand* op) const {
}
-Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
- if (op->IsRegister()) {
- return ToRegister(op->index());
- } else if (op->IsConstantOperand()) {
- LConstantOperand* const_op = LConstantOperand::cast(op);
- HConstant* constant = chunk_->LookupConstant(const_op);
- Handle<Object> literal = constant->handle();
- Representation r = chunk_->LookupLiteralRepresentation(const_op);
- if (r.IsInteger32()) {
- ASSERT(literal->IsNumber());
- __ mov(scratch, Operand(static_cast<int32_t>(literal->Number())));
- } else if (r.IsDouble()) {
- Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
- } else {
- ASSERT(r.IsTagged());
- __ LoadObject(scratch, literal);
- }
- return scratch;
- } else if (op->IsStackSlot() || op->IsArgument()) {
- __ ldr(scratch, ToMemOperand(op));
- return scratch;
- }
- UNREACHABLE();
- return scratch;
-}
-
-
DwVfpRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
ASSERT(op->IsDoubleRegister());
return ToDoubleRegister(op->index());
}
-DwVfpRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
- SwVfpRegister flt_scratch,
- DwVfpRegister dbl_scratch) {
- if (op->IsDoubleRegister()) {
- return ToDoubleRegister(op->index());
- } else if (op->IsConstantOperand()) {
- LConstantOperand* const_op = LConstantOperand::cast(op);
- HConstant* constant = chunk_->LookupConstant(const_op);
- Handle<Object> literal = constant->handle();
- Representation r = chunk_->LookupLiteralRepresentation(const_op);
- if (r.IsInteger32()) {
- ASSERT(literal->IsNumber());
- __ mov(ip, Operand(static_cast<int32_t>(literal->Number())));
- __ vmov(flt_scratch, ip);
- __ vcvt_f64_s32(dbl_scratch, flt_scratch);
- return dbl_scratch;
- } else if (r.IsDouble()) {
- Abort(kUnsupportedDoubleImmediate);
- } else if (r.IsTagged()) {
- Abort(kUnsupportedTaggedImmediate);
- }
- } else if (op->IsStackSlot() || op->IsArgument()) {
- // TODO(regis): Why is vldr not taking a MemOperand?
- // __ vldr(dbl_scratch, ToMemOperand(op));
- MemOperand mem_op = ToMemOperand(op);
- __ vldr(dbl_scratch, mem_op.rn(), mem_op.offset());
- return dbl_scratch;
- }
- UNREACHABLE();
- return dbl_scratch;
-}
-
-
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
HConstant* constant = chunk_->LookupConstant(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
@@ -1368,7 +1308,8 @@ void LCodeGen::EmitSignedIntegerDivisionByConstant(
void LCodeGen::DoDivI(LDivI* instr) {
if (instr->hydrogen()->HasPowerOf2Divisor()) {
- Register dividend = ToRegister(instr->left());
+ const Register dividend = ToRegister(instr->left());
+ const Register result = ToRegister(instr->result());
int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant();
int32_t test_value = 0;
int32_t power = 0;
@@ -1379,7 +1320,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
} else {
// Check for (0 / -x) that will produce negative zero.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- __ tst(dividend, Operand(dividend));
+ __ cmp(dividend, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
// Check for (kMinInt / -1).
@@ -1394,19 +1335,22 @@ void LCodeGen::DoDivI(LDivI* instr) {
if (test_value != 0) {
if (instr->hydrogen()->CheckFlag(
HInstruction::kAllUsesTruncatingToInt32)) {
- __ cmp(dividend, Operand(0));
- __ rsb(dividend, dividend, Operand(0), LeaveCC, lt);
- __ mov(dividend, Operand(dividend, ASR, power));
- if (divisor > 0) __ rsb(dividend, dividend, Operand(0), LeaveCC, lt);
+ __ sub(result, dividend, Operand::Zero(), SetCC);
+ __ rsb(result, result, Operand::Zero(), LeaveCC, lt);
+ __ mov(result, Operand(result, ASR, power));
+ if (divisor > 0) __ rsb(result, result, Operand::Zero(), LeaveCC, lt);
return; // Don't fall through to "__ rsb" below.
} else {
// Deoptimize if remainder is not 0.
__ tst(dividend, Operand(test_value));
DeoptimizeIf(ne, instr->environment());
- __ mov(dividend, Operand(dividend, ASR, power));
+ __ mov(result, Operand(dividend, ASR, power));
}
+ } else {
+ __ Move(result, dividend);
}
- if (divisor < 0) __ rsb(dividend, dividend, Operand(0));
+
+ if (divisor < 0) __ rsb(result, result, Operand::Zero());
return;
}
@@ -1572,17 +1516,15 @@ void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
void LCodeGen::DoMulI(LMulI* instr) {
- Register scratch = scratch0();
Register result = ToRegister(instr->result());
// Note that result may alias left.
Register left = ToRegister(instr->left());
LOperand* right_op = instr->right();
- bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
bool bailout_on_minus_zero =
instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
- if (right_op->IsConstantOperand() && !can_overflow) {
+ if (right_op->IsConstantOperand()) {
// Use optimized code for specific constants.
int32_t constant = ToRepresentation(
LConstantOperand::cast(right_op),
@@ -1643,12 +1585,11 @@ void LCodeGen::DoMulI(LMulI* instr) {
}
} else {
- Register right = EmitLoadRegister(right_op, scratch);
- if (bailout_on_minus_zero) {
- __ orr(ToRegister(instr->temp()), left, right);
- }
+ ASSERT(right_op->IsRegister());
+ Register right = ToRegister(right_op);
- if (can_overflow) {
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ Register scratch = scratch0();
// scratch:result = left * right.
if (instr->hydrogen()->representation().IsSmi()) {
__ SmiUntag(result, left);
@@ -1668,12 +1609,12 @@ void LCodeGen::DoMulI(LMulI* instr) {
}
if (bailout_on_minus_zero) {
- // Bail out if the result is supposed to be negative zero.
Label done;
+ __ teq(left, Operand(right));
+ __ b(pl, &done);
+ // Bail out if the result is minus zero.
__ cmp(result, Operand::Zero());
- __ b(ne, &done);
- __ cmp(ToRegister(instr->temp()), Operand::Zero());
- DeoptimizeIf(mi, instr->environment());
+ DeoptimizeIf(eq, instr->environment());
__ bind(&done);
}
}
@@ -1686,32 +1627,40 @@ void LCodeGen::DoBitI(LBitI* instr) {
ASSERT(left_op->IsRegister());
Register left = ToRegister(left_op);
Register result = ToRegister(instr->result());
- Operand right(no_reg);
- if (right_op->IsStackSlot() || right_op->IsArgument()) {
- right = Operand(EmitLoadRegister(right_op, ip));
+ if (right_op->IsStackSlot()) {
+ MemOperand right(ToMemOperand(right_op));
+ switch (instr->op()) {
+ case Token::BIT_AND:
+ __ AndMemOperand(result, left, right);
+ break;
+ case Token::BIT_OR:
+ __ OrrMemOperand(result, left, right);
+ break;
+ case Token::BIT_XOR:
+ __ EorMemOperand(result, left, right);
+ break;
+ default: UNREACHABLE();
+ }
} else {
- ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
- right = ToOperand(right_op);
- }
-
- switch (instr->op()) {
- case Token::BIT_AND:
- __ and_(result, left, right);
- break;
- case Token::BIT_OR:
- __ orr(result, left, right);
- break;
- case Token::BIT_XOR:
- if (right_op->IsConstantOperand() && right.immediate() == int32_t(~0)) {
- __ mvn(result, Operand(left));
- } else {
- __ eor(result, left, right);
- }
- break;
- default:
- UNREACHABLE();
- break;
+ Operand right(ToOperand(right_op));
+ switch (instr->op()) {
+ case Token::BIT_AND:
+ __ and_(result, left, right);
+ break;
+ case Token::BIT_OR:
+ __ orr(result, left, right);
+ break;
+ case Token::BIT_XOR:
+ if (right_op->IsConstantOperand()
+ && right.immediate() == int32_t(~0)) {
+ __ mvn(result, Operand(left));
+ } else {
+ __ eor(result, left, right);
+ }
+ break;
+ default: UNREACHABLE();
+ }
}
}
@@ -1805,18 +1754,17 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
void LCodeGen::DoSubI(LSubI* instr) {
- LOperand* left = instr->left();
- LOperand* right = instr->right();
- LOperand* result = instr->result();
+ Register left = ToRegister(instr->left());
+ LOperand* right_op = instr->right();
+ Register result = ToRegister(instr->result());
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
SBit set_cond = can_overflow ? SetCC : LeaveCC;
- if (right->IsStackSlot() || right->IsArgument()) {
- Register right_reg = EmitLoadRegister(right, ip);
- __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
+ if (right_op->IsStackSlot()) {
+ __ SubMemOperand(result, left, ToMemOperand(right_op), set_cond);
} else {
- ASSERT(right->IsRegister() || right->IsConstantOperand());
- __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
+ ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
+ __ sub(result, left, ToOperand(right_op), set_cond);
}
if (can_overflow) {
@@ -1826,18 +1774,16 @@ void LCodeGen::DoSubI(LSubI* instr) {
void LCodeGen::DoRSubI(LRSubI* instr) {
- LOperand* left = instr->left();
- LOperand* right = instr->right();
- LOperand* result = instr->result();
+ Register left = ToRegister(instr->left());
+ LOperand* right_op = instr->right();
+ Register result = ToRegister(instr->result());
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
SBit set_cond = can_overflow ? SetCC : LeaveCC;
- if (right->IsStackSlot() || right->IsArgument()) {
- Register right_reg = EmitLoadRegister(right, ip);
- __ rsb(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
+ if (right_op->IsStackSlot()) {
+ __ RsbMemOperand(result, left, ToMemOperand(right_op), set_cond);
} else {
- ASSERT(right->IsRegister() || right->IsConstantOperand());
- __ rsb(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
+ __ rsb(result, left, ToOperand(right_op), set_cond);
}
if (can_overflow) {
@@ -1961,38 +1907,50 @@ void LCodeGen::DoDateField(LDateField* instr) {
void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
Register string = ToRegister(instr->string());
- Register index = ToRegister(instr->index());
Register value = ToRegister(instr->value());
+ Register scratch = scratch0();
+ LOperand* index_op = instr->index();
String::Encoding encoding = instr->encoding();
if (FLAG_debug_code) {
- __ ldr(ip, FieldMemOperand(string, HeapObject::kMapOffset));
- __ ldrb(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset));
+ __ ldr(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
+ __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
- __ and_(ip, ip, Operand(kStringRepresentationMask | kStringEncodingMask));
+ __ and_(scratch, scratch,
+ Operand(kStringRepresentationMask | kStringEncodingMask));
static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- __ cmp(ip, Operand(encoding == String::ONE_BYTE_ENCODING
- ? one_byte_seq_type : two_byte_seq_type));
+ __ cmp(scratch, Operand(encoding == String::ONE_BYTE_ENCODING
+ ? one_byte_seq_type : two_byte_seq_type));
__ Check(eq, kUnexpectedStringType);
}
- __ add(ip,
- string,
- Operand(SeqString::kHeaderSize - kHeapObjectTag));
- if (encoding == String::ONE_BYTE_ENCODING) {
- __ strb(value, MemOperand(ip, index));
+ if (index_op->IsConstantOperand()) {
+ int constant_index = ToInteger32(LConstantOperand::cast(index_op));
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ __ strb(value,
+ FieldMemOperand(string,
+ SeqString::kHeaderSize + constant_index));
+ } else {
+ __ strh(value,
+ FieldMemOperand(string,
+ SeqString::kHeaderSize + constant_index * 2));
+ }
} else {
- // MemOperand with ip as the base register is not allowed for strh, so
- // we do the address calculation explicitly.
- __ add(ip, ip, Operand(index, LSL, 1));
- __ strh(value, MemOperand(ip));
+ Register index = ToRegister(index_op);
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ __ add(scratch, string, Operand(index));
+ __ strb(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
+ } else {
+ __ add(scratch, string, Operand(index, LSL, 1));
+ __ strh(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
+ }
}
}
void LCodeGen::DoThrow(LThrow* instr) {
- Register input_reg = EmitLoadRegister(instr->value(), ip);
+ Register input_reg = ToRegister(instr->value());
__ push(input_reg);
CallRuntime(Runtime::kThrow, 1, instr);
@@ -2003,18 +1961,17 @@ void LCodeGen::DoThrow(LThrow* instr) {
void LCodeGen::DoAddI(LAddI* instr) {
- LOperand* left = instr->left();
- LOperand* right = instr->right();
- LOperand* result = instr->result();
+ Register left = ToRegister(instr->left());
+ LOperand* right_op = instr->right();
+ Register result = ToRegister(instr->result());
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
SBit set_cond = can_overflow ? SetCC : LeaveCC;
- if (right->IsStackSlot() || right->IsArgument()) {
- Register right_reg = EmitLoadRegister(right, ip);
- __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
+ if (right_op->IsStackSlot()) {
+ __ AddMemOperand(result, left, ToMemOperand(right_op), set_cond);
} else {
- ASSERT(right->IsRegister() || right->IsConstantOperand());
- __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
+ ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
+ __ add(result, left, ToOperand(right_op), set_cond);
}
if (can_overflow) {
@@ -2030,9 +1987,7 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
Register left_reg = ToRegister(left);
- Operand right_op = (right->IsRegister() || right->IsConstantOperand())
- ? ToOperand(right)
- : Operand(EmitLoadRegister(right, ip));
+ Operand right_op = ToOperand(right);
Register result_reg = ToRegister(instr->result());
__ cmp(left_reg, right_op);
__ Move(result_reg, left_reg, condition);
@@ -2040,7 +1995,13 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
} else {
ASSERT(instr->hydrogen()->representation().IsDouble());
DwVfpRegister left_reg = ToDoubleRegister(left);
- DwVfpRegister right_reg = ToDoubleRegister(right);
+ DwVfpRegister right_reg ;
+ if (right->IsDoubleStackSlot()) {
+ __ vldr(double_scratch0(), ToMemOperand(right));
+ right_reg = double_scratch0();
+ } else {
+ right_reg = ToDoubleRegister(right);
+ }
DwVfpRegister result_reg = ToDoubleRegister(instr->result());
Label result_is_nan, return_left, return_right, check_zero, done;
__ VFPCompareAndSetFlags(left_reg, right_reg);
@@ -2092,7 +2053,14 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
DwVfpRegister left = ToDoubleRegister(instr->left());
- DwVfpRegister right = ToDoubleRegister(instr->right());
+ DwVfpRegister right;
+ if (instr->right()->IsDoubleStackSlot()) {
+ __ vldr(double_scratch0(), ToMemOperand(instr->right()));
+ right = double_scratch0();
+ } else {
+ ASSERT(instr->right()->IsDoubleRegister());
+ right = ToDoubleRegister(instr->right());
+ }
DwVfpRegister result = ToDoubleRegister(instr->result());
switch (instr->op()) {
case Token::ADD:
@@ -2520,8 +2488,7 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
- Register input_reg = EmitLoadRegister(instr->value(), ip);
- __ SmiTst(input_reg);
+ __ SmiTst(ToRegister(instr->value()));
EmitBranch(instr, eq);
}
@@ -3146,20 +3113,35 @@ void LCodeGen::DoLoadExternalArrayPointer(
void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
Register arguments = ToRegister(instr->arguments());
Register result = ToRegister(instr->result());
- if (instr->length()->IsConstantOperand() &&
- instr->index()->IsConstantOperand()) {
- int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+ // There are two words between the frame pointer and the last argument.
+ // Subtracting from length accounts for one of them add one more.
+ if (instr->length()->IsConstantOperand()) {
int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
- int index = (const_length - const_index) + 1;
- __ ldr(result, MemOperand(arguments, index * kPointerSize));
+ if (instr->index()->IsConstantOperand()) {
+ int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+ int index = (const_length - const_index) + 1;
+ __ ldr(result, MemOperand(arguments, index * kPointerSize));
+ } else {
+ Register index = ToRegister(instr->index());
+ __ rsb(result, index, Operand(const_length + 1));
+ __ ldr(result, MemOperand(arguments, result, LSL, kPointerSizeLog2));
+ }
+ } else if (instr->index()->IsConstantOperand()) {
+ Register length = ToRegister(instr->length());
+ int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+ int loc = const_index - 1;
+ if (loc != 0) {
+ __ sub(result, length, Operand(loc));
+ __ ldr(result, MemOperand(arguments, result, LSL, kPointerSizeLog2));
+ } else {
+ __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
+ }
} else {
Register length = ToRegister(instr->length());
Register index = ToRegister(instr->index());
- // There are two words between the frame pointer and the last argument.
- // Subtracting from length accounts for one of them add one more.
- __ sub(length, length, index);
- __ add(length, length, Operand(1));
- __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
+ __ sub(result, length, index);
+ __ add(result, result, Operand(1));
+ __ ldr(result, MemOperand(arguments, result, LSL, kPointerSizeLog2));
}
}
@@ -3253,25 +3235,25 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
? (element_size_shift - kSmiTagSize) : element_size_shift;
- int constant_key = 0;
if (key_is_constant) {
- constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+ int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
if (constant_key & 0xF0000000) {
Abort(kArrayIndexConstantValueTooBig);
}
+ int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
+ ((constant_key + instr->additional_index()) << element_size_shift);
+ __ add(scratch, elements, Operand(base_offset));
} else {
+ int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
+ ((instr->additional_index()) << element_size_shift);
key = ToRegister(instr->key());
+ __ add(scratch, elements, Operand(base_offset));
+ __ add(scratch, scratch, Operand(key, LSL, shift_size));
}
- int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
- ((constant_key + instr->additional_index()) << element_size_shift);
- if (!key_is_constant) {
- __ add(elements, elements, Operand(key, LSL, shift_size));
- }
- __ add(elements, elements, Operand(base_offset));
- __ vldr(result, elements, 0);
+ __ vldr(result, scratch, 0);
if (instr->hydrogen()->RequiresHoleCheck()) {
- __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
+ __ ldr(scratch, MemOperand(scratch, sizeof(kHoleNanLower32)));
__ cmp(scratch, Operand(kHoleNanUpper32));
DeoptimizeIf(eq, instr->environment());
}
@@ -3291,7 +3273,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
instr->additional_index());
store_base = elements;
} else {
- Register key = EmitLoadRegister(instr->key(), scratch0());
+ Register key = ToRegister(instr->key());
// Even though the HLoadKeyed instruction forces the input
// representation for the key to be an integer, the input gets replaced
// during bound check elimination with the index argument to the bounds
@@ -3516,13 +3498,8 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
void LCodeGen::DoPushArgument(LPushArgument* instr) {
- LOperand* argument = instr->value();
- if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
- Abort(kDoPushArgumentNotImplementedForDoubleType);
- } else {
- Register argument_reg = EmitLoadRegister(argument, ip);
- __ push(argument_reg);
- }
+ ASSERT(instr->value()->IsRegister());
+ __ push(ToRegister(instr->value()));
}
@@ -3961,10 +3938,11 @@ void LCodeGen::DoMathExp(LMathExp* instr) {
DwVfpRegister double_scratch2 = double_scratch0();
Register temp1 = ToRegister(instr->temp1());
Register temp2 = ToRegister(instr->temp2());
+ Register temp3 = scratch0();
MathExpGenerator::EmitMathExp(
masm(), input, result, double_scratch1, double_scratch2,
- temp1, temp2, scratch0());
+ temp1, temp2, temp3);
}
@@ -4304,16 +4282,23 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
+ Register address = scratch0();
DwVfpRegister value(ToDoubleRegister(instr->value()));
- Operand operand(key_is_constant
- ? Operand(constant_key << element_size_shift)
- : Operand(key, LSL, shift_size));
- __ add(scratch0(), external_pointer, operand);
+ if (key_is_constant) {
+ if (constant_key != 0) {
+ __ add(address, external_pointer,
+ Operand(constant_key << element_size_shift)) ;
+ } else {
+ address = external_pointer;
+ }
+ } else {
+ __ add(address, external_pointer, Operand(key, LSL, shift_size));
+ }
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ vcvt_f32_f64(double_scratch0().low(), value);
- __ vstr(double_scratch0().low(), scratch0(), additional_offset);
+ __ vstr(double_scratch0().low(), address, additional_offset);
} else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
- __ vstr(value, scratch0(), additional_offset);
+ __ vstr(value, address, additional_offset);
}
} else {
Register value(ToRegister(instr->value()));
@@ -4355,32 +4340,28 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
DwVfpRegister value = ToDoubleRegister(instr->value());
Register elements = ToRegister(instr->elements());
- Register key = no_reg;
Register scratch = scratch0();
+ DwVfpRegister double_scratch = double_scratch0();
bool key_is_constant = instr->key()->IsConstantOperand();
- int constant_key = 0;
// Calculate the effective address of the slot in the array to store the
// double value.
+ int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
if (key_is_constant) {
- constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+ int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
if (constant_key & 0xF0000000) {
Abort(kArrayIndexConstantValueTooBig);
}
+ __ add(scratch, elements,
+ Operand((constant_key << element_size_shift) +
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
- key = ToRegister(instr->key());
- }
- int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
- int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
- ? (element_size_shift - kSmiTagSize) : element_size_shift;
- Operand operand = key_is_constant
- ? Operand((constant_key << element_size_shift) +
- FixedDoubleArray::kHeaderSize - kHeapObjectTag)
- : Operand(key, LSL, shift_size);
- __ add(scratch, elements, operand);
- if (!key_is_constant) {
- __ add(scratch, scratch,
+ int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
+ ? (element_size_shift - kSmiTagSize) : element_size_shift;
+ __ add(scratch, elements,
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ __ add(scratch, scratch,
+ Operand(ToRegister(instr->key()), LSL, shift_size));
}
if (instr->NeedsCanonicalization()) {
@@ -4390,9 +4371,13 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
__ tst(ip, Operand(kVFPDefaultNaNModeControlBit));
__ Assert(ne, kDefaultNaNModeNotSet);
}
- __ VFPCanonicalizeNaN(value);
+ __ VFPCanonicalizeNaN(double_scratch, value);
+ __ vstr(double_scratch, scratch,
+ instr->additional_index() << element_size_shift);
+ } else {
+ __ vstr(value, scratch,
+ instr->additional_index() << element_size_shift);
}
- __ vstr(value, scratch, instr->additional_index() << element_size_shift);
}
@@ -4621,17 +4606,11 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
LOperand* input = instr->value();
- ASSERT(input->IsRegister() || input->IsStackSlot());
LOperand* output = instr->result();
+ ASSERT(input->IsRegister());
ASSERT(output->IsDoubleRegister());
SwVfpRegister single_scratch = double_scratch0().low();
- if (input->IsStackSlot()) {
- Register scratch = scratch0();
- __ ldr(scratch, ToMemOperand(input));
- __ vmov(single_scratch, scratch);
- } else {
- __ vmov(single_scratch, ToRegister(input));
- }
+ __ vmov(single_scratch, ToRegister(input));
__ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
}
@@ -5313,11 +5292,11 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
if (instr->hydrogen()->MustPrefillWithFiller()) {
if (instr->size()->IsConstantOperand()) {
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
- __ mov(scratch, Operand(size));
+ __ mov(scratch, Operand(size - kPointerSize));
} else {
- scratch = ToRegister(instr->size());
+ Register size = ToRegister(instr->size());
+ __ sub(scratch, size, Operand(kPointerSize));
}
- __ sub(scratch, scratch, Operand(kPointerSize));
__ sub(result, result, Operand(kHeapObjectTag));
Label loop;
__ bind(&loop);
@@ -5462,22 +5441,21 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
Register scratch = scratch0();
if (type_name->Equals(heap()->number_string())) {
__ JumpIfSmi(input, true_label);
- __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset));
- __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
- __ cmp(input, Operand(ip));
+ __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
+ __ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
final_branch_condition = eq;
} else if (type_name->Equals(heap()->string_string())) {
__ JumpIfSmi(input, false_label);
- __ CompareObjectType(input, input, scratch, FIRST_NONSTRING_TYPE);
+ __ CompareObjectType(input, scratch, no_reg, FIRST_NONSTRING_TYPE);
__ b(ge, false_label);
- __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
- __ tst(ip, Operand(1 << Map::kIsUndetectable));
+ __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+ __ tst(scratch, Operand(1 << Map::kIsUndetectable));
final_branch_condition = eq;
} else if (type_name->Equals(heap()->symbol_string())) {
__ JumpIfSmi(input, false_label);
- __ CompareObjectType(input, input, scratch, SYMBOL_TYPE);
+ __ CompareObjectType(input, scratch, no_reg, SYMBOL_TYPE);
final_branch_condition = eq;
} else if (type_name->Equals(heap()->boolean_string())) {
@@ -5495,17 +5473,18 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ b(eq, true_label);
__ JumpIfSmi(input, false_label);
// Check for undetectable objects => true.
- __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset));
- __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
- __ tst(ip, Operand(1 << Map::kIsUndetectable));
+ __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
+ __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+ __ tst(scratch, Operand(1 << Map::kIsUndetectable));
final_branch_condition = ne;
} else if (type_name->Equals(heap()->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
+ Register type_reg = scratch;
__ JumpIfSmi(input, false_label);
- __ CompareObjectType(input, scratch, input, JS_FUNCTION_TYPE);
+ __ CompareObjectType(input, scratch, type_reg, JS_FUNCTION_TYPE);
__ b(eq, true_label);
- __ cmp(input, Operand(JS_FUNCTION_PROXY_TYPE));
+ __ cmp(type_reg, Operand(JS_FUNCTION_PROXY_TYPE));
final_branch_condition = eq;
} else if (type_name->Equals(heap()->object_string())) {
@@ -5514,14 +5493,14 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ CompareRoot(input, Heap::kNullValueRootIndex);
__ b(eq, true_label);
}
- __ CompareObjectType(input, input, scratch,
- FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
- __ b(lt, false_label);
- __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
- __ b(gt, false_label);
+ __ CheckObjectTypeRange(input,
+ scratch,
+ FIRST_NONCALLABLE_SPEC_OBJECT_TYPE,
+ LAST_NONCALLABLE_SPEC_OBJECT_TYPE,
+ false_label);
// Check for undetectable objects => false.
- __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
- __ tst(ip, Operand(1 << Map::kIsUndetectable));
+ __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+ __ tst(scratch, Operand(1 << Map::kIsUndetectable));
final_branch_condition = eq;
} else {

Powered by Google App Engine
This is Rietveld 408576698