Commit 883a5671 authored by ager@chromium.org's avatar ager@chromium.org

ARM: Implement DoIsObject and DoIsObjectAndBranch in the lithium code generator.

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/6308012

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6438 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 36506015
...@@ -1018,11 +1018,8 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) { ...@@ -1018,11 +1018,8 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) {
HIsObject* compare = HIsObject::cast(v); HIsObject* compare = HIsObject::cast(v);
ASSERT(compare->value()->representation().IsTagged()); ASSERT(compare->value()->representation().IsTagged());
LOperand* temp1 = TempRegister(); LOperand* temp = TempRegister();
LOperand* temp2 = TempRegister(); return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp);
return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()),
temp1,
temp2);
} else if (v->IsCompareJSObjectEq()) { } else if (v->IsCompareJSObjectEq()) {
HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
...@@ -1404,7 +1401,7 @@ LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { ...@@ -1404,7 +1401,7 @@ LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
ASSERT(instr->value()->representation().IsTagged()); ASSERT(instr->value()->representation().IsTagged());
LOperand* value = UseRegisterAtStart(instr->value()); LOperand* value = UseRegisterAtStart(instr->value());
return DefineAsRegister(new LIsObject(value, TempRegister())); return DefineAsRegister(new LIsObject(value));
} }
......
...@@ -734,9 +734,8 @@ class LIsNullAndBranch: public LControlInstruction<1, 0> { ...@@ -734,9 +734,8 @@ class LIsNullAndBranch: public LControlInstruction<1, 0> {
class LIsObject: public LTemplateInstruction<1, 1, 1> { class LIsObject: public LTemplateInstruction<1, 1, 1> {
public: public:
LIsObject(LOperand* value, LOperand* temp) { explicit LIsObject(LOperand* value) {
inputs_[0] = value; inputs_[0] = value;
temps_[0] = temp;
} }
DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object") DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
...@@ -745,10 +744,9 @@ class LIsObject: public LTemplateInstruction<1, 1, 1> { ...@@ -745,10 +744,9 @@ class LIsObject: public LTemplateInstruction<1, 1, 1> {
class LIsObjectAndBranch: public LControlInstruction<1, 2> { class LIsObjectAndBranch: public LControlInstruction<1, 2> {
public: public:
LIsObjectAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) { LIsObjectAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value; inputs_[0] = value;
temps_[0] = temp; temps_[0] = temp;
temps_[1] = temp2;
} }
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch") DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
......
...@@ -1730,18 +1730,62 @@ Condition LCodeGen::EmitIsObject(Register input, ...@@ -1730,18 +1730,62 @@ Condition LCodeGen::EmitIsObject(Register input,
Register temp2, Register temp2,
Label* is_not_object, Label* is_not_object,
Label* is_object) { Label* is_object) {
Abort("EmitIsObject unimplemented."); __ BranchOnSmi(input, is_not_object);
return ne;
__ LoadRoot(temp1, Heap::kNullValueRootIndex);
__ cmp(input, temp1);
__ b(eq, is_object);
// Load map.
__ ldr(temp1, FieldMemOperand(input, HeapObject::kMapOffset));
// Undetectable objects behave like undefined.
__ ldrb(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset));
__ tst(temp2, Operand(1 << Map::kIsUndetectable));
__ b(ne, is_not_object);
// Load instance type and check that it is in object type range.
__ 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 le;
} }
void LCodeGen::DoIsObject(LIsObject* instr) { void LCodeGen::DoIsObject(LIsObject* instr) {
Abort("DoIsObject unimplemented."); Register reg = ToRegister(instr->InputAt(0));
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(&done);
__ bind(&is_true);
__ LoadRoot(result, Heap::kTrueValueRootIndex);
__ bind(&done);
} }
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Abort("DoIsObjectAndBranch unimplemented."); Register reg = ToRegister(instr->InputAt(0));
Register temp1 = ToRegister(instr->TempAt(0));
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);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment