Commit f2eda210 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Some assembler-level optimizations on ARM.

Review URL: https://chromiumcodereview.appspot.com/9223011

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10541 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 74feaa6c
This diff is collapsed.
// 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 // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -104,10 +104,10 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( ...@@ -104,10 +104,10 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
__ add(lr, lr, Operand(r5, LSL, 2)); __ add(lr, lr, Operand(r5, LSL, 2));
__ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); __ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS);
// r6: destination FixedDoubleArray, not tagged as heap object // r6: destination FixedDoubleArray, not tagged as heap object
// Set destination FixedDoubleArray's length and map.
__ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex); __ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex);
__ str(r9, MemOperand(r6, HeapObject::kMapOffset));
// Set destination FixedDoubleArray's length.
__ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset));
__ str(r9, MemOperand(r6, HeapObject::kMapOffset));
// Update receiver's map. // Update receiver's map.
__ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
...@@ -155,10 +155,9 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( ...@@ -155,10 +155,9 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
__ bind(&loop); __ bind(&loop);
__ ldr(r9, MemOperand(r3, 4, PostIndex)); __ ldr(r9, MemOperand(r3, 4, PostIndex));
// r9: current element // r9: current element
__ JumpIfNotSmi(r9, &convert_hole); __ UntagAndJumpIfNotSmi(r9, r9, &convert_hole);
// Normal smi, convert to double and store. // Normal smi, convert to double and store.
__ SmiUntag(r9);
if (vfp3_supported) { if (vfp3_supported) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
__ vmov(s0, r9); __ vmov(s0, r9);
...@@ -181,6 +180,9 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( ...@@ -181,6 +180,9 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
// Hole found, store the-hole NaN. // Hole found, store the-hole NaN.
__ bind(&convert_hole); __ bind(&convert_hole);
if (FLAG_debug_code) { if (FLAG_debug_code) {
// Restore a "smi-untagged" heap object.
__ SmiTag(r9);
__ orr(r9, r9, Operand(1));
__ CompareRoot(r9, Heap::kTheHoleValueRootIndex); __ CompareRoot(r9, Heap::kTheHoleValueRootIndex);
__ Assert(eq, "object found in smi-only array"); __ Assert(eq, "object found in smi-only array");
} }
...@@ -208,9 +210,8 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( ...@@ -208,9 +210,8 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
Label entry, loop, convert_hole, gc_required; Label entry, loop, convert_hole, gc_required;
__ push(lr); __ push(lr);
__ Push(r3, r2, r1, r0);
__ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset));
__ Push(r3, r2, r1, r0);
__ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset));
// r4: source FixedDoubleArray // r4: source FixedDoubleArray
// r5: number of elements (smi-tagged) // r5: number of elements (smi-tagged)
...@@ -220,10 +221,10 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( ...@@ -220,10 +221,10 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
__ add(r0, r0, Operand(r5, LSL, 1)); __ add(r0, r0, Operand(r5, LSL, 1));
__ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS);
// r6: destination FixedArray, not tagged as heap object // r6: destination FixedArray, not tagged as heap object
// Set destination FixedDoubleArray's length and map.
__ LoadRoot(r9, Heap::kFixedArrayMapRootIndex); __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex);
__ str(r9, MemOperand(r6, HeapObject::kMapOffset));
// Set destination FixedDoubleArray's length.
__ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset));
__ str(r9, MemOperand(r6, HeapObject::kMapOffset));
// Prepare for conversion loop. // Prepare for conversion loop.
__ add(r4, r4, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4)); __ add(r4, r4, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
...@@ -325,8 +326,8 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -325,8 +326,8 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
// Handle slices. // Handle slices.
Label indirect_string_loaded; Label indirect_string_loaded;
__ ldr(result, FieldMemOperand(string, SlicedString::kOffsetOffset)); __ ldr(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
__ add(index, index, Operand(result, ASR, kSmiTagSize));
__ ldr(string, FieldMemOperand(string, SlicedString::kParentOffset)); __ ldr(string, FieldMemOperand(string, SlicedString::kParentOffset));
__ add(index, index, Operand(result, ASR, kSmiTagSize));
__ jmp(&indirect_string_loaded); __ jmp(&indirect_string_loaded);
// Handle cons strings. // Handle cons strings.
...@@ -336,8 +337,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -336,8 +337,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
// the string. // the string.
__ bind(&cons_string); __ bind(&cons_string);
__ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset)); __ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset));
__ LoadRoot(ip, Heap::kEmptyStringRootIndex); __ CompareRoot(result, Heap::kEmptyStringRootIndex);
__ cmp(result, ip);
__ b(ne, call_runtime); __ b(ne, call_runtime);
// Get the first of the two strings and load its instance type. // Get the first of the two strings and load its instance type.
__ ldr(string, FieldMemOperand(string, ConsString::kFirstOffset)); __ ldr(string, FieldMemOperand(string, ConsString::kFirstOffset));
......
...@@ -3929,7 +3929,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, ...@@ -3929,7 +3929,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
Label load_smi, heap_number, done; Label load_smi, heap_number, done;
// Smi check. // Smi check.
__ JumpIfSmi(input_reg, &load_smi); __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
// Heap number map check. // Heap number map check.
__ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
...@@ -3968,7 +3968,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, ...@@ -3968,7 +3968,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
// Smi to double register conversion // Smi to double register conversion
__ bind(&load_smi); __ bind(&load_smi);
__ SmiUntag(scratch, input_reg); // Untag smi before converting to float. // scratch: untagged value of input_reg
__ vmov(flt_scratch, scratch); __ vmov(flt_scratch, scratch);
__ vcvt_f64_s32(result_reg, flt_scratch); __ vcvt_f64_s32(result_reg, flt_scratch);
__ bind(&done); __ bind(&done);
...@@ -4256,7 +4256,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { ...@@ -4256,7 +4256,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
Label is_smi, done, heap_number; Label is_smi, done, heap_number;
// Both smi and heap number cases are handled. // Both smi and heap number cases are handled.
__ JumpIfSmi(input_reg, &is_smi); __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi);
// Check for heap number // Check for heap number
__ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
...@@ -4279,7 +4279,6 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { ...@@ -4279,7 +4279,6 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
// smi // smi
__ bind(&is_smi); __ bind(&is_smi);
__ SmiUntag(result_reg, input_reg);
__ ClampUint8(result_reg, result_reg); __ ClampUint8(result_reg, result_reg);
__ bind(&done); __ bind(&done);
......
...@@ -2965,6 +2965,22 @@ void MacroAssembler::JumpIfNotBothSmi(Register reg1, ...@@ -2965,6 +2965,22 @@ void MacroAssembler::JumpIfNotBothSmi(Register reg1,
} }
void MacroAssembler::UntagAndJumpIfSmi(
Register dst, Register src, Label* smi_case) {
STATIC_ASSERT(kSmiTag == 0);
mov(dst, Operand(src, ASR, kSmiTagSize), SetCC);
b(cc, smi_case); // Shifter carry is not set for a smi.
}
void MacroAssembler::UntagAndJumpIfNotSmi(
Register dst, Register src, Label* non_smi_case) {
STATIC_ASSERT(kSmiTag == 0);
mov(dst, Operand(src, ASR, kSmiTagSize), SetCC);
b(cs, non_smi_case); // Shifter carry is set for a non-smi.
}
void MacroAssembler::JumpIfEitherSmi(Register reg1, void MacroAssembler::JumpIfEitherSmi(Register reg1,
Register reg2, Register reg2,
Label* on_either_smi) { Label* on_either_smi) {
......
...@@ -1149,6 +1149,14 @@ class MacroAssembler: public Assembler { ...@@ -1149,6 +1149,14 @@ class MacroAssembler: public Assembler {
mov(dst, Operand(src, ASR, kSmiTagSize), s); mov(dst, Operand(src, ASR, kSmiTagSize), s);
} }
// 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. // Jump the register contains a smi.
inline void JumpIfSmi(Register value, Label* smi_label) { inline void JumpIfSmi(Register value, Label* smi_label) {
tst(value, Operand(kSmiTagMask)); tst(value, Operand(kSmiTagMask));
......
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