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

Reply via email to