Reviewers: Søren Gjesse,
Description:
ARM: Implement DoIsObject and DoIsObjectAndBranch in the lithium code
generator.
BUG=none
TEST=none
Please review this at http://codereview.chromium.org/6308012/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge/test
Affected files:
M src/arm/lithium-arm.h
M src/arm/lithium-arm.cc
M src/arm/lithium-codegen-arm.cc
Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index
8d839caa1c059d2b9d5834f12f73861fe0063a10..431684555bafd92c4a9230aff84ed7685f55e731
100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1017,11 +1017,9 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) {
HIsObject* compare = HIsObject::cast(v);
ASSERT(compare->value()->representation().IsTagged());
- LOperand* temp1 = TempRegister();
- LOperand* temp2 = TempRegister();
+ LOperand* temp = TempRegister();
return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()),
- temp1,
- temp2,
+ temp,
first_id,
second_id);
} else if (v->IsCompareJSObjectEq()) {
@@ -1411,7 +1409,7 @@ LInstruction* LChunkBuilder::DoIsObject(HIsObject*
instr) {
ASSERT(instr->value()->representation().IsTagged());
LOperand* value = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LIsObject(value, TempRegister()));
+ return DefineAsRegister(new LIsObject(value));
}
Index: src/arm/lithium-arm.h
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index
1cf9898f6c4090696810a15b82ba81c2bd35906e..9ffdc036c9f82175d2626689efd96e90860ec599
100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -708,15 +708,9 @@ class LIsNullAndBranch: public LIsNull {
class LIsObject: public LUnaryOperation {
public:
- LIsObject(LOperand* value, LOperand* temp)
- : LUnaryOperation(value), temp_(temp) {}
+ explicit LIsObject(LOperand* value) : LUnaryOperation(value) { }
DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
-
- LOperand* temp() const { return temp_; }
-
- private:
- LOperand* temp_;
};
@@ -724,11 +718,10 @@ class LIsObjectAndBranch: public LIsObject {
public:
LIsObjectAndBranch(LOperand* value,
LOperand* temp,
- LOperand* temp2,
int true_block_id,
int false_block_id)
- : LIsObject(value, temp),
- temp2_(temp2),
+ : LIsObject(value),
+ temp_(temp),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
@@ -739,10 +732,10 @@ class LIsObjectAndBranch: public LIsObject {
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
- LOperand* temp2() const { return temp2_; }
+ LOperand* temp() const { return temp_; }
private:
- LOperand* temp2_;
+ LOperand* temp_;
int true_block_id_;
int false_block_id_;
};
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
2d1e7ba6247ad1330a60cd3e2022315f189b1dfc..807601ffc94ccc58599b26aefbb5e0699b9cc302
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1729,18 +1729,58 @@ Condition LCodeGen::EmitIsObject(Register input,
Register temp2,
Label* is_not_object,
Label* is_object) {
- Abort("EmitIsObject unimplemented.");
- return ne;
+ __ BranchOnSmi(input, is_not_object);
+
+ __ LoadRoot(temp1, Heap::kNullValueRootIndex);
+ __ cmp(input, temp1);
+ __ b(eq, is_object);
+
+ __ ldr(temp1, FieldMemOperand(input, HeapObject::kMapOffset));
+ __ ldrb(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset));
+ __ tst(temp2, Operand(1 << Map::kIsUndetectable));
+ __ b(ne, is_not_object);
+
+ __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
+ __ cmp(temp2, Operand(FIRST_JS_OBJECT_TYPE));
+ __ b(lt, is_not_object);
+ __ cmp(temp2, Operand(LAST_JS_OBJECT_TYPE));
+ return gt;
}
void LCodeGen::DoIsObject(LIsObject* instr) {
- Abort("DoIsObject unimplemented.");
+ Register reg = ToRegister(instr->input());
+ Register result = ToRegister(instr->result());
+ Register temp = scratch0();
+ Label is_false, is_true, done;
+
+ Condition true_cond = EmitIsObject(reg, result, temp, &is_false,
&is_true);
+ __ b(true_cond, &is_true);
+
+ __ bind(&is_false);
+ __ LoadRoot(result, Heap::kFalseValueRootIndex);
+ __ b(al, &done);
+
+ __ bind(&is_true);
+ __ LoadRoot(result, Heap::kTrueValueRootIndex, true_cond);
+
+ __ bind(&done);
}
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
- Abort("DoIsObjectAndBranch unimplemented.");
+ Register reg = ToRegister(instr->input());
+ Register temp1 = ToRegister(instr->temp());
+ Register temp2 = scratch0();
+
+ int true_block = chunk_->LookupDestination(instr->true_block_id());
+ int false_block = chunk_->LookupDestination(instr->false_block_id());
+ Label* true_label = chunk_->GetAssemblyLabel(true_block);
+ Label* false_label = chunk_->GetAssemblyLabel(false_block);
+
+ Condition true_cond = EmitIsObject(reg, temp1, temp2, false_label,
true_label);
+
+ EmitBranch(true_block, false_block, true_cond);
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev