Revision: 6771
Author: [email protected]
Date: Mon Feb 14 04:34:11 2011
Log: More x64 work.

x64: Implement DoArgumentsElements, DoNumberUntagD, DoArgumentsLength,
DoAccessArgumentsAt, DoStringLength in lithium x64 backend.

Fix a bug in DoConstantD where only 32-bits of a double was loaded to
an xmm register.

Review URL: http://codereview.chromium.org/6474039
http://code.google.com/p/v8/source/detail?r=6771

Modified:
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Feb 14 03:42:06 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Feb 14 04:34:11 2011
@@ -888,21 +888,15 @@
   ASSERT(instr->result()->IsDoubleRegister());
   XMMRegister res = ToDoubleRegister(instr->result());
   double v = instr->value();
+  uint64_t int_val = BitCast<uint64_t, double>(v);
   // Use xor to produce +0.0 in a fast and compact way, but avoid to
   // do so if the constant is -0.0.
-  if (BitCast<uint64_t, double>(v) == 0) {
+  if (int_val == 0) {
     __ xorpd(res, res);
   } else {
     Register tmp = ToRegister(instr->TempAt(0));
-    int32_t v_int32 = static_cast<int32_t>(v);
-    if (static_cast<double>(v_int32) == v) {
-      __ movl(tmp, Immediate(v_int32));
-      __ cvtlsi2sd(res, tmp);
-    } else {
-      uint64_t int_val = BitCast<uint64_t, double>(v);
-      __ Set(tmp, int_val);
-      __ movd(res, tmp);
-    }
+    __ Set(tmp, int_val);
+    __ movq(res, tmp);
   }
 }

@@ -1820,7 +1814,20 @@


 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
-  Abort("Unimplemented: %s", "DoAccessArgumentsAt");
+  Register arguments = ToRegister(instr->arguments());
+  Register length = ToRegister(instr->length());
+  Register result = ToRegister(instr->result());
+
+  if (instr->index()->IsRegister()) {
+    __ subl(length, ToRegister(instr->index()));
+  } else {
+    __ subl(length, ToOperand(instr->index()));
+  }
+  DeoptimizeIf(below_equal, instr->environment());
+
+  // There are two words between the frame pointer and the last argument.
+  // Subtracting from length accounts for one of them add one more.
+ __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
 }


@@ -1859,12 +1866,51 @@


 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
-  Abort("Unimplemented: %s", "DoArgumentsElements");
+  Register result = ToRegister(instr->result());
+
+  // Check for arguments adapter frame.
+  NearLabel done, adapted;
+  __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
+  __ SmiCompare(Operand(result, StandardFrameConstants::kContextOffset),
+                Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
+  __ j(equal, &adapted);
+
+  // No arguments adaptor frame.
+  __ movq(result, rbp);
+  __ jmp(&done);
+
+  // Arguments adaptor frame present.
+  __ bind(&adapted);
+  __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
+
+ // Result is the frame pointer for the frame if not adapted and for the real
+  // frame below the adaptor frame if adapted.
+  __ bind(&done);
 }


 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
-  Abort("Unimplemented: %s", "DoArgumentsLength");
+  Register result = ToRegister(instr->result());
+
+  NearLabel done;
+
+  // If no arguments adaptor frame the number of arguments is fixed.
+  if (instr->InputAt(0)->IsRegister()) {
+    __ cmpq(rbp, ToRegister(instr->InputAt(0)));
+  } else {
+    __ cmpq(rbp, ToOperand(instr->InputAt(0)));
+  }
+  __ movq(result, Immediate(scope()->num_parameters()));
+  __ j(equal, &done);
+
+  // Arguments adaptor frame present. Get argument length from there.
+  __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
+  __ movq(result, Operand(result,
+                          ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ SmiToInteger32(result, result);
+
+  // Argument length is in result register.
+  __ bind(&done);
 }


@@ -2146,6 +2192,13 @@
 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
   Abort("Unimplemented: %s", "DoStoreKeyedGeneric");
 }
+
+
+void LCodeGen::DoStringLength(LStringLength* instr) {
+  Register string = ToRegister(instr->string());
+  Register result = ToRegister(instr->result());
+  __ movq(result, FieldOperand(string, String::kLengthOffset));
+}


 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
@@ -2260,7 +2313,7 @@

   // Smi to XMM conversion
   __ bind(&load_smi);
-  __ SmiToInteger32(kScratchRegister, input_reg);  // Untag smi first.
+  __ SmiToInteger32(kScratchRegister, input_reg);
   __ cvtlsi2sd(result_reg, kScratchRegister);
   __ bind(&done);
 }
@@ -2337,7 +2390,15 @@


 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
-  Abort("Unimplemented: %s", "DoNumberUntagD");
+  LOperand* input = instr->InputAt(0);
+  ASSERT(input->IsRegister());
+  LOperand* result = instr->result();
+  ASSERT(result->IsDoubleRegister());
+
+  Register input_reg = ToRegister(input);
+  XMMRegister result_reg = ToDoubleRegister(result);
+
+  EmitNumberUntagD(input_reg, result_reg, instr->environment());
 }


=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Mon Feb 14 03:42:06 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Mon Feb 14 04:34:11 2011
@@ -1114,14 +1114,12 @@


 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
-  Abort("Unimplemented: %s", "DoArgumentsLength");
-  return NULL;
+  return DefineAsRegister(new LArgumentsLength(Use(length->value())));
 }


LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
-  Abort("Unimplemented: %s", "DoArgumentsElements");
-  return NULL;
+  return DefineAsRegister(new LArgumentsElements);
 }


@@ -1343,7 +1341,7 @@
     }
     return result;
   } else if (instr->representation().IsDouble()) {
-    Abort("Unimplemented: %s", "DoAdd on Doubles");
+    return DoArithmeticD(Token::ADD, instr);
   } else {
     ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::ADD, instr);
@@ -1750,8 +1748,8 @@


 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
-  Abort("Unimplemented: %s", "DoStringLength");
-  return NULL;
+  LOperand* string = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new LStringLength(string));
 }


@@ -1813,8 +1811,11 @@


LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
-  Abort("Unimplemented: %s", "DoAccessArgumentsAt");
-  return NULL;
+  LOperand* arguments = UseRegister(instr->arguments());
+  LOperand* length = UseTempRegister(instr->length());
+  LOperand* index = Use(instr->index());
+ LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
+  return AssignEnvironment(DefineAsRegister(result));
 }


=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Thu Feb 10 08:33:01 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Mon Feb 14 04:34:11 2011
@@ -146,6 +146,7 @@
   V(StoreKeyedGeneric)                          \
   V(StoreNamedField)                            \
   V(StoreNamedGeneric)                          \
+  V(StringLength)                               \
   V(SubI)                                       \
   V(TaggedToI)                                  \
   V(Throw)                                      \
@@ -1550,6 +1551,19 @@
 };


+class LStringLength: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LStringLength(LOperand* string) {
+    inputs_[0] = string;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
+  DECLARE_HYDROGEN_ACCESSOR(StringLength)
+
+  LOperand* string() { return inputs_[0]; }
+};
+
+
 class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
  public:
   explicit LCheckFunction(LOperand* value) {

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to