Revision: 10568
Author:   [email protected]
Date:     Tue Jan 31 04:45:27 2012
Log:      MIPS: Some assembler-level optimizations on ARM.

Port r10541 (0aab14ba).

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9296046
Patch from Daniel Kalmar <[email protected]>.
http://code.google.com/p/v8/source/detail?r=10568

Modified:
 /branches/bleeding_edge/src/mips/code-stubs-mips.cc
 /branches/bleeding_edge/src/mips/codegen-mips.cc
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
 /branches/bleeding_edge/src/mips/macro-assembler-mips.cc
 /branches/bleeding_edge/src/mips/macro-assembler-mips.h

=======================================
--- /branches/bleeding_edge/src/mips/code-stubs-mips.cc Mon Jan 30 02:58:22 2012 +++ /branches/bleeding_edge/src/mips/code-stubs-mips.cc Tue Jan 31 04:45:27 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -158,20 +158,18 @@
   __ lw(a3, MemOperand(sp, 0));

   // Set up the object header.
-  __ LoadRoot(a2, Heap::kFunctionContextMapRootIndex);
-  __ sw(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
+  __ LoadRoot(a1, Heap::kFunctionContextMapRootIndex);
   __ li(a2, Operand(Smi::FromInt(length)));
   __ sw(a2, FieldMemOperand(v0, FixedArray::kLengthOffset));
-
-  // Set up the fixed slots.
+  __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
+
+ // Set up the fixed slots, copy the global object from the previous context.
+  __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ li(a1, Operand(Smi::FromInt(0)));
   __ sw(a3, MemOperand(v0, Context::SlotOffset(Context::CLOSURE_INDEX)));
   __ sw(cp, MemOperand(v0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
   __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::EXTENSION_INDEX)));
-
-  // Copy the global object from the previous context.
-  __ lw(a1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  __ sw(a2, MemOperand(v0, Context::SlotOffset(Context::GLOBAL_INDEX)));

   // Initialize the rest of the slots to undefined.
   __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
@@ -229,14 +227,12 @@
   __ lw(a3, ContextOperand(a3, Context::CLOSURE_INDEX));
   __ bind(&after_sentinel);

-  // Set up the fixed slots.
+ // Set up the fixed slots, copy the global object from the previous context.
+  __ lw(a2, ContextOperand(cp, Context::GLOBAL_INDEX));
   __ sw(a3, ContextOperand(v0, Context::CLOSURE_INDEX));
   __ sw(cp, ContextOperand(v0, Context::PREVIOUS_INDEX));
   __ sw(a1, ContextOperand(v0, Context::EXTENSION_INDEX));
-
-  // Copy the global object from the previous context.
-  __ lw(a1, ContextOperand(cp, Context::GLOBAL_INDEX));
-  __ sw(a1, ContextOperand(v0, Context::GLOBAL_INDEX));
+  __ sw(a2, ContextOperand(v0, Context::GLOBAL_INDEX));

   // Initialize the rest of the slots to the hole value.
   __ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
@@ -592,7 +588,9 @@

   Label is_smi, done;

-  __ JumpIfSmi(object, &is_smi);
+  // Smi-check
+  __ UntagAndJumpIfSmi(scratch1, object, &is_smi);
+  // Heap number check
   __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);

   // Handle loading a double from a heap number.
@@ -619,7 +617,6 @@
   if (CpuFeatures::IsSupported(FPU)) {
     CpuFeatures::Scope scope(FPU);
     // Convert smi to double using FPU instructions.
-    __ SmiUntag(scratch1, object);
     __ mtc1(scratch1, dst);
     __ cvt_d_w(dst, dst);
     if (destination == kCoreRegisters) {
@@ -654,11 +651,10 @@
                            Heap::kHeapNumberMapRootIndex,
                            "HeapNumberMap register clobbered.");
   }
-  Label is_smi;
   Label done;
   Label not_in_int32_range;

-  __ JumpIfSmi(object, &is_smi);
+  __ UntagAndJumpIfSmi(dst, object, &done);
   __ lw(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset));
   __ Branch(not_number, ne, scratch1, Operand(heap_number_map));
   __ ConvertToInt32(object,
@@ -678,10 +674,6 @@
                                  scratch2,
                                  scratch3);

-  __ jmp(&done);
-
-  __ bind(&is_smi);
-  __ SmiUntag(dst, object);
   __ bind(&done);
 }

@@ -863,10 +855,7 @@

   Label done;

-  // Untag the object into the destination register.
-  __ SmiUntag(dst, object);
-  // Just return if the object is a smi.
-  __ JumpIfSmi(object, &done);
+  __ UntagAndJumpIfSmi(dst, object, &done);

   if (FLAG_debug_code) {
     __ AbortIfNotRootValue(heap_number_map,
@@ -3605,7 +3594,7 @@
   const Register scratch = t5;
   const Register scratch2 = t3;

-  Label call_runtime, done, exponent_not_smi, int_exponent;
+  Label call_runtime, done, int_exponent;
   if (exponent_type_ == ON_STACK) {
     Label base_is_smi, unpack_exponent;
     // The exponent and base are supplied as arguments on the stack.
@@ -3616,7 +3605,7 @@

     __ LoadRoot(heapnumbermap, Heap::kHeapNumberMapRootIndex);

-    __ JumpIfSmi(base, &base_is_smi);
+    __ UntagAndJumpIfSmi(scratch, base, &base_is_smi);
     __ lw(scratch, FieldMemOperand(base, JSObject::kMapOffset));
     __ Branch(&call_runtime, ne, scratch, Operand(heapnumbermap));

@@ -3624,27 +3613,20 @@
     __ jmp(&unpack_exponent);

     __ bind(&base_is_smi);
-    __ SmiUntag(base);
-    __ mtc1(base, single_scratch);
+    __ mtc1(scratch, single_scratch);
     __ cvt_d_w(double_base, single_scratch);
     __ bind(&unpack_exponent);

-    __ JumpIfNotSmi(exponent, &exponent_not_smi);
-    __ SmiUntag(exponent);
-    __ jmp(&int_exponent);
-
-    __ bind(&exponent_not_smi);
+    __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
+
     __ lw(scratch, FieldMemOperand(exponent, JSObject::kMapOffset));
     __ Branch(&call_runtime, ne, scratch, Operand(heapnumbermap));
     __ ldc1(double_exponent,
             FieldMemOperand(exponent, HeapNumber::kValueOffset));
   } else if (exponent_type_ == TAGGED) {
     // Base is already in double_base.
-    __ JumpIfNotSmi(exponent, &exponent_not_smi);
-    __ SmiUntag(exponent);
-    __ jmp(&int_exponent);
-
-    __ bind(&exponent_not_smi);
+    __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
+
     __ ldc1(double_exponent,
             FieldMemOperand(exponent, HeapNumber::kValueOffset));
   }
@@ -3724,13 +3706,20 @@
     __ jmp(&done);

     __ bind(&int_exponent_convert);
-    __ mfc1(exponent, single_scratch);
+    __ mfc1(scratch, single_scratch);
   }

   // Calculate power with integer exponent.
   __ bind(&int_exponent);

-  __ mov(scratch, exponent);  // Back up exponent.
+  // Get two copies of exponent in the registers scratch and exponent.
+  if (exponent_type_ == INTEGER) {
+    __ mov(scratch, exponent);
+  } else {
+ // Exponent has previously been stored into scratch as untagged integer.
+    __ mov(exponent, scratch);
+  }
+
   __ mov_d(double_scratch, double_base);  // Back up base.
   __ Move(double_result, 1.0);

@@ -5298,11 +5287,11 @@

   // Set input, index and length fields from arguments.
   __ lw(a1, MemOperand(sp, kPointerSize * 0));
+  __ lw(a2, MemOperand(sp, kPointerSize * 1));
+  __ lw(t2, MemOperand(sp, kPointerSize * 2));
   __ sw(a1, FieldMemOperand(v0, JSRegExpResult::kInputOffset));
-  __ lw(a1, MemOperand(sp, kPointerSize * 1));
-  __ sw(a1, FieldMemOperand(v0, JSRegExpResult::kIndexOffset));
-  __ lw(a1, MemOperand(sp, kPointerSize * 2));
-  __ sw(a1, FieldMemOperand(v0, JSArray::kLengthOffset));
+  __ sw(a2, FieldMemOperand(v0, JSRegExpResult::kIndexOffset));
+  __ sw(t2, FieldMemOperand(v0, JSArray::kLengthOffset));

   // Fill out the elements FixedArray.
   // v0: JSArray, tagged.
@@ -6069,10 +6058,8 @@

   // Utilize delay slots. SmiUntag doesn't emit a jump, everything else is
   // safe in this case.
-  __ JumpIfSmi(a2, &runtime, at, USE_DELAY_SLOT);
-  __ SmiUntag(a2);
-  __ JumpIfSmi(a3, &runtime, at, USE_DELAY_SLOT);
-  __ SmiUntag(a3);
+  __ UntagAndJumpIfSmi(a2, a2, &runtime);
+  __ UntagAndJumpIfSmi(a3, a3, &runtime);

   // Both a2 and a3 are untagged integers.

@@ -6156,10 +6143,10 @@

   __ bind(&sliced_string);
   // Sliced string.  Fetch parent and correct start index by offset.
-  __ lw(t1, FieldMemOperand(v0, SlicedString::kOffsetOffset));
-  __ sra(t1, t1, 1);
-  __ Addu(a3, a3, t1);
+  __ lw(t0, FieldMemOperand(v0, SlicedString::kOffsetOffset));
   __ lw(t1, FieldMemOperand(v0, SlicedString::kParentOffset));
+  __ sra(t0, t0, 1);  // Add offset to index.
+  __ Addu(a3, a3, t0);
   // Update instance type.
   __ lw(a1, FieldMemOperand(t1, HeapObject::kMapOffset));
   __ lbu(a1, FieldMemOperand(a1, Map::kInstanceTypeOffset));
=======================================
--- /branches/bleeding_edge/src/mips/codegen-mips.cc Thu Dec 1 00:31:09 2011 +++ /branches/bleeding_edge/src/mips/codegen-mips.cc Tue Jan 31 04:45:27 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -105,10 +105,10 @@
   __ Addu(scratch, scratch, FixedDoubleArray::kHeaderSize);
__ AllocateInNewSpace(scratch, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS);
   // t2: destination FixedDoubleArray, not tagged as heap object
+  // Set destination FixedDoubleArray's length and map.
   __ LoadRoot(t5, Heap::kFixedDoubleArrayMapRootIndex);
-  __ sw(t5, MemOperand(t2, HeapObject::kMapOffset));
-  // Set destination FixedDoubleArray's length.
   __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset));
+  __ sw(t5, MemOperand(t2, HeapObject::kMapOffset));
   // Update receiver's map.

   __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
@@ -159,10 +159,9 @@
   __ lw(t5, MemOperand(a3));
   __ Addu(a3, a3, kIntSize);
   // t5: current element
-  __ JumpIfNotSmi(t5, &convert_hole);
+  __ UntagAndJumpIfNotSmi(t5, t5, &convert_hole);

   // Normal smi, convert to double and store.
-  __ SmiUntag(t5);
   if (fpu_supported) {
     CpuFeatures::Scope scope(FPU);
     __ mtc1(t5, f0);
@@ -187,6 +186,9 @@
   // Hole found, store the-hole NaN.
   __ bind(&convert_hole);
   if (FLAG_debug_code) {
+    // Restore a "smi-untagged" heap object.
+    __ SmiTag(t5);
+    __ Or(t5, t5, Operand(1));
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
     __ Assert(eq, "object found in smi-only array", at, Operand(t5));
   }
@@ -225,10 +227,10 @@
   __ Addu(a0, a0, FixedDoubleArray::kHeaderSize);
   __ AllocateInNewSpace(a0, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS);
   // t2: destination FixedArray, not tagged as heap object
+  // Set destination FixedDoubleArray's length and map.
   __ LoadRoot(t5, Heap::kFixedArrayMapRootIndex);
-  __ sw(t5, MemOperand(t2, HeapObject::kMapOffset));
-  // Set destination FixedDoubleArray's length.
   __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset));
+  __ sw(t5, MemOperand(t2, HeapObject::kMapOffset));

   // Prepare for conversion loop.
__ Addu(t0, t0, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
@@ -333,9 +335,9 @@
   // Handle slices.
   Label indirect_string_loaded;
   __ lw(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
+  __ lw(string, FieldMemOperand(string, SlicedString::kParentOffset));
   __ sra(at, result, kSmiTagSize);
   __ Addu(index, index, at);
-  __ lw(string, FieldMemOperand(string, SlicedString::kParentOffset));
   __ jmp(&indirect_string_loaded);

   // Handle cons strings.
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Tue Jan 31 04:33:46 2012 +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Tue Jan 31 04:45:27 2012
@@ -3844,7 +3844,7 @@
   Label load_smi, heap_number, done;

   // Smi check.
-  __ JumpIfSmi(input_reg, &load_smi);
+  __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);

   // Heap number map check.
   __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
@@ -3877,7 +3877,7 @@

   // Smi to double register conversion
   __ bind(&load_smi);
- __ SmiUntag(scratch, input_reg); // Untag smi before converting to float.
+  // scratch: untagged value of input_reg
   __ mtc1(scratch, result_reg);
   __ cvt_d_w(result_reg, result_reg);
   __ bind(&done);
@@ -4160,7 +4160,7 @@
   Label is_smi, done, heap_number;

   // Both smi and heap number cases are handled.
-  __ JumpIfSmi(input_reg, &is_smi);
+  __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi);

   // Check for heap number
   __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
@@ -4180,9 +4180,7 @@
   __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg);
   __ jmp(&done);

-  // smi
   __ bind(&is_smi);
-  __ SmiUntag(scratch, input_reg);
   __ ClampUint8(result_reg, scratch);

   __ bind(&done);
=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Tue Jan 31 04:33:46 2012 +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Tue Jan 31 04:45:27 2012
@@ -4539,6 +4539,40 @@
     xor_(overflow, dst, src);  // Overflow if (value ^ 2 * value) < 0.
   }
 }
+
+
+void MacroAssembler::UntagAndJumpIfSmi(Register dst,
+                                       Register src,
+                                       Label* smi_case) {
+  JumpIfSmi(src, smi_case, at, USE_DELAY_SLOT);
+  SmiUntag(dst, src);
+}
+
+
+void MacroAssembler::UntagAndJumpIfNotSmi(Register dst,
+                                          Register src,
+                                          Label* non_smi_case) {
+  JumpIfNotSmi(src, non_smi_case, at, USE_DELAY_SLOT);
+  SmiUntag(dst, src);
+}
+
+void MacroAssembler::JumpIfSmi(Register value,
+                               Label* smi_label,
+                               Register scratch,
+                               BranchDelaySlot bd) {
+  ASSERT_EQ(0, kSmiTag);
+  andi(scratch, value, kSmiTagMask);
+  Branch(bd, smi_label, eq, scratch, Operand(zero_reg));
+}
+
+void MacroAssembler::JumpIfNotSmi(Register value,
+                                  Label* not_smi_label,
+                                  Register scratch,
+                                  BranchDelaySlot bd) {
+  ASSERT_EQ(0, kSmiTag);
+  andi(scratch, value, kSmiTagMask);
+  Branch(bd, not_smi_label, ne, scratch, Operand(zero_reg));
+}


 void MacroAssembler::JumpIfNotBothSmi(Register reg1,
=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.h Tue Jan 31 04:33:46 2012 +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.h Tue Jan 31 04:45:27 2012
@@ -1241,23 +1241,26 @@
   void SmiUntag(Register dst, Register src) {
     sra(dst, src, kSmiTagSize);
   }
+
+  // Untag the source value into destination and jump if source is a smi.
+  // Souce and destination can be the same register.
+  void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
+
+ // Untag the source value into destination and jump if source is not a smi.
+  // Souce and destination can be the same register.
+ void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case);

   // Jump the register contains a smi.
-  inline void JumpIfSmi(Register value, Label* smi_label,
-                        Register scratch = at,
-                        BranchDelaySlot bd = PROTECT) {
-    ASSERT_EQ(0, kSmiTag);
-    andi(scratch, value, kSmiTagMask);
-    Branch(bd, smi_label, eq, scratch, Operand(zero_reg));
-  }
+  void JumpIfSmi(Register value,
+                 Label* smi_label,
+                 Register scratch = at,
+                 BranchDelaySlot bd = PROTECT);

   // Jump if the register contains a non-smi.
-  inline void JumpIfNotSmi(Register value, Label* not_smi_label,
-                           Register scratch = at) {
-    ASSERT_EQ(0, kSmiTag);
-    andi(scratch, value, kSmiTagMask);
-    Branch(not_smi_label, ne, scratch, Operand(zero_reg));
-  }
+  void JumpIfNotSmi(Register value,
+                    Label* not_smi_label,
+                    Register scratch = at,
+                    BranchDelaySlot bd = PROTECT);

   // Jump if either of the registers contain a non-smi.
void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);

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

Reply via email to