ARM: VFP cleanup now that VFP2 is the baseline.

BUG=none
TEST=none

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14382 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0c634a1d
This diff is collapsed.
...@@ -588,142 +588,6 @@ class DirectCEntryStub: public PlatformCodeStub { ...@@ -588,142 +588,6 @@ class DirectCEntryStub: public PlatformCodeStub {
}; };
class FloatingPointHelper : public AllStatic {
public:
enum Destination {
kVFPRegisters,
kCoreRegisters
};
// Loads smis from r0 and r1 (right and left in binary operations) into
// floating point registers. Depending on the destination the values ends up
// either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is
// floating point registers VFP3 must be supported. If core registers are
// requested when VFP3 is supported d6 and d7 will be scratched.
static void LoadSmis(MacroAssembler* masm,
Destination destination,
Register scratch1,
Register scratch2);
// Convert the smi or heap number in object to an int32 using the rules
// for ToInt32 as described in ECMAScript 9.5.: the value is truncated
// and brought into the range -2^31 .. +2^31 - 1.
static void ConvertNumberToInt32(MacroAssembler* masm,
Register object,
Register dst,
Register heap_number_map,
Register scratch1,
Register scratch2,
Register scratch3,
DwVfpRegister double_scratch1,
DwVfpRegister double_scratch2,
Label* not_int32);
// Converts the integer (untagged smi) in |int_scratch| to a double, storing
// the result either in |double_dst| or |dst2:dst1|, depending on
// |destination|.
// Warning: The value in |int_scratch| will be changed in the process!
static void ConvertIntToDouble(MacroAssembler* masm,
Register int_scratch,
Destination destination,
DwVfpRegister double_dst,
Register dst1,
Register dst2,
Register scratch2,
SwVfpRegister single_scratch);
// Load the number from object into double_dst in the double format.
// Control will jump to not_int32 if the value cannot be exactly represented
// by a 32-bit integer.
// Floating point value in the 32-bit integer range that are not exact integer
// won't be loaded.
static void LoadNumberAsInt32Double(MacroAssembler* masm,
Register object,
Destination destination,
DwVfpRegister double_dst,
DwVfpRegister double_scratch,
Register dst1,
Register dst2,
Register heap_number_map,
Register scratch1,
Register scratch2,
SwVfpRegister single_scratch,
Label* not_int32);
// Loads the number from object into dst as a 32-bit integer.
// Control will jump to not_int32 if the object cannot be exactly represented
// by a 32-bit integer.
// Floating point value in the 32-bit integer range that are not exact integer
// won't be converted.
// scratch3 is not used when VFP3 is supported.
static void LoadNumberAsInt32(MacroAssembler* masm,
Register object,
Register dst,
Register heap_number_map,
Register scratch1,
Register scratch2,
Register scratch3,
DwVfpRegister double_scratch0,
DwVfpRegister double_scratch1,
Label* not_int32);
// Generate non VFP3 code to check if a double can be exactly represented by a
// 32-bit integer. This does not check for 0 or -0, which need
// to be checked for separately.
// Control jumps to not_int32 if the value is not a 32-bit integer, and falls
// through otherwise.
// src1 and src2 will be cloberred.
//
// Expected input:
// - src1: higher (exponent) part of the double value.
// - src2: lower (mantissa) part of the double value.
// Output status:
// - dst: 32 higher bits of the mantissa. (mantissa[51:20])
// - src2: contains 1.
// - other registers are clobbered.
static void DoubleIs32BitInteger(MacroAssembler* masm,
Register src1,
Register src2,
Register dst,
Register scratch,
Label* not_int32);
// Generates code to call a C function to do a double operation using core
// registers. (Used when VFP3 is not supported.)
// This code never falls through, but returns with a heap number containing
// the result in r0.
// Register heapnumber_result must be a heap number in which the
// result of the operation will be stored.
// Requires the following layout on entry:
// r0: Left value (least significant part of mantissa).
// r1: Left value (sign, exponent, top of mantissa).
// r2: Right value (least significant part of mantissa).
// r3: Right value (sign, exponent, top of mantissa).
static void CallCCodeForDoubleOperation(MacroAssembler* masm,
Token::Value op,
Register heap_number_result,
Register scratch);
// Loads the objects from |object| into floating point registers.
// Depending on |destination| the value ends up either in |dst| or
// in |dst1|/|dst2|. If |destination| is kVFPRegisters, then VFP3
// must be supported. If kCoreRegisters are requested and VFP3 is
// supported, |dst| will be scratched. If |object| is neither smi nor
// heap number, |not_number| is jumped to with |object| still intact.
static void LoadNumber(MacroAssembler* masm,
FloatingPointHelper::Destination destination,
Register object,
DwVfpRegister dst,
Register dst1,
Register dst2,
Register heap_number_map,
Register scratch1,
Register scratch2,
Label* not_number);
};
class NameDictionaryLookupStub: public PlatformCodeStub { class NameDictionaryLookupStub: public PlatformCodeStub {
public: public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
......
...@@ -1340,13 +1340,7 @@ static void KeyedStoreGenerateGenericHelper( ...@@ -1340,13 +1340,7 @@ static void KeyedStoreGenerateGenericHelper(
__ b(ne, slow); __ b(ne, slow);
} }
__ bind(&fast_double_without_map_check); __ bind(&fast_double_without_map_check);
__ StoreNumberToDoubleElements(value, __ StoreNumberToDoubleElements(value, key, elements, r3,
key,
elements, // Overwritten.
r3, // Scratch regs...
r4,
r5,
r6,
&transition_double_elements); &transition_double_elements);
if (increment_length == kIncrementLength) { if (increment_length == kIncrementLength) {
// Add 1 to receiver->length. // Add 1 to receiver->length.
......
...@@ -5040,8 +5040,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { ...@@ -5040,8 +5040,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
__ sub(scratch1, input_reg, Operand(kHeapObjectTag)); __ sub(scratch1, input_reg, Operand(kHeapObjectTag));
__ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset); __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset);
__ ECMAToInt32(input_reg, double_scratch2, double_scratch, __ ECMAToInt32(input_reg, double_scratch2,
scratch1, scratch2, scratch3); scratch1, scratch2, scratch3, double_scratch);
} else { } else {
// Deoptimize if we don't have a heap number. // Deoptimize if we don't have a heap number.
...@@ -5138,8 +5138,8 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { ...@@ -5138,8 +5138,8 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
if (instr->truncating()) { if (instr->truncating()) {
Register scratch3 = ToRegister(instr->temp2()); Register scratch3 = ToRegister(instr->temp2());
__ ECMAToInt32(result_reg, double_input, double_scratch, __ ECMAToInt32(result_reg, double_input,
scratch1, scratch2, scratch3); scratch1, scratch2, scratch3, double_scratch);
} else { } else {
__ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
// Deoptimize if the input wasn't a int32 (inside a double). // Deoptimize if the input wasn't a int32 (inside a double).
......
This diff is collapsed.
...@@ -495,6 +495,54 @@ class MacroAssembler: public Assembler { ...@@ -495,6 +495,54 @@ class MacroAssembler: public Assembler {
const double imm, const double imm,
const Register scratch = no_reg); const Register scratch = no_reg);
// Converts the smi or heap number in object to an int32 using the rules
// for ToInt32 as described in ECMAScript 9.5.: the value is truncated
// and brought into the range -2^31 .. +2^31 - 1.
void ConvertNumberToInt32(Register object,
Register dst,
Register heap_number_map,
Register scratch1,
Register scratch2,
Register scratch3,
DwVfpRegister double_scratch1,
DwVfpRegister double_scratch2,
Label* not_int32);
// Loads the number from object into dst register.
// If |object| is neither smi nor heap number, |not_number| is jumped to
// with |object| still intact.
void LoadNumber(Register object,
DwVfpRegister dst,
Register heap_number_map,
Register scratch,
Label* not_number);
// Loads the number from object into double_dst in the double format.
// Control will jump to not_int32 if the value cannot be exactly represented
// by a 32-bit integer.
// Floating point value in the 32-bit integer range that are not exact integer
// won't be loaded.
void LoadNumberAsInt32Double(Register object,
DwVfpRegister double_dst,
Register heap_number_map,
Register scratch,
DwVfpRegister double_scratch,
Label* not_int32);
// Loads the number from object into dst as a 32-bit integer.
// Control will jump to not_int32 if the object cannot be exactly represented
// by a 32-bit integer.
// Floating point value in the 32-bit integer range that are not exact integer
// won't be converted.
void LoadNumberAsInt32(Register object,
Register dst,
Register heap_number_map,
Register scratch,
DwVfpRegister double_scratch0,
DwVfpRegister double_scratch1,
Label* not_int32);
// Enter exit frame. // Enter exit frame.
// stack_space - extra stack space, used for alignment before call to C. // stack_space - extra stack space, used for alignment before call to C.
void EnterExitFrame(bool save_doubles, int stack_space = 0); void EnterExitFrame(bool save_doubles, int stack_space = 0);
...@@ -831,16 +879,11 @@ class MacroAssembler: public Assembler { ...@@ -831,16 +879,11 @@ class MacroAssembler: public Assembler {
// Check to see if maybe_number can be stored as a double in // Check to see if maybe_number can be stored as a double in
// FastDoubleElements. If it can, store it at the index specified by key in // FastDoubleElements. If it can, store it at the index specified by key in
// the FastDoubleElements array elements. Otherwise jump to fail, in which // the FastDoubleElements array elements. Otherwise jump to fail.
// case scratch2, scratch3 and scratch4 are unmodified.
void StoreNumberToDoubleElements(Register value_reg, void StoreNumberToDoubleElements(Register value_reg,
Register key_reg, Register key_reg,
// All regs below here overwritten.
Register elements_reg, Register elements_reg,
Register scratch1, Register scratch1,
Register scratch2,
Register scratch3,
Register scratch4,
Label* fail, Label* fail,
int elements_offset = 0); int elements_offset = 0);
...@@ -972,26 +1015,16 @@ class MacroAssembler: public Assembler { ...@@ -972,26 +1015,16 @@ class MacroAssembler: public Assembler {
Label* done, Label* done,
Label* exact); Label* exact);
// Performs a truncating conversion of a heap floating point number as used by
// the JS bitwise operations. See ECMA-262 9.5: ToInt32.
// Exits with 'result' holding the answer.
void ECMAConvertNumberToInt32(Register source,
Register result,
Register input_low,
Register input_high,
Register scratch,
DwVfpRegister double_scratch1,
DwVfpRegister double_scratch2);
// Performs a truncating conversion of a floating point number as used by // Performs a truncating conversion of a floating point number as used by
// the JS bitwise operations. See ECMA-262 9.5: ToInt32. // the JS bitwise operations. See ECMA-262 9.5: ToInt32.
// Double_scratch must be between d0 and d15.
// Exits with 'result' holding the answer and all other registers clobbered. // Exits with 'result' holding the answer and all other registers clobbered.
void ECMAToInt32(Register result, void ECMAToInt32(Register result,
DwVfpRegister double_input, DwVfpRegister double_input,
DwVfpRegister double_scratch,
Register scratch, Register scratch,
Register input_high, Register scratch_high,
Register input_low); Register scratch_low,
DwVfpRegister double_scratch);
// Check whether d16-d31 are available on the CPU. The result is given by the // Check whether d16-d31 are available on the CPU. The result is given by the
// Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise. // Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise.
...@@ -1127,7 +1160,6 @@ class MacroAssembler: public Assembler { ...@@ -1127,7 +1160,6 @@ class MacroAssembler: public Assembler {
// Calls Abort(msg) if the condition cond is not satisfied. // Calls Abort(msg) if the condition cond is not satisfied.
// Use --debug_code to enable. // Use --debug_code to enable.
void Assert(Condition cond, const char* msg); void Assert(Condition cond, const char* msg);
void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index);
void AssertFastElements(Register elements); void AssertFastElements(Register elements);
// Like Assert(), but always enabled. // Like Assert(), but always enabled.
...@@ -1237,11 +1269,9 @@ class MacroAssembler: public Assembler { ...@@ -1237,11 +1269,9 @@ class MacroAssembler: public Assembler {
// Abort execution if argument is not a name, enabled via --debug-code. // Abort execution if argument is not a name, enabled via --debug-code.
void AssertName(Register object); void AssertName(Register object);
// Abort execution if argument is not the root value with the given index, // Abort execution if reg is not the root value with the given index,
// enabled via --debug-code. // enabled via --debug-code.
void AssertRootValue(Register src, void AssertIsRoot(Register reg, Heap::RootListIndex index);
Heap::RootListIndex root_value_index,
const char* message);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// HeapNumber utilities // HeapNumber utilities
...@@ -1372,16 +1402,6 @@ class MacroAssembler: public Assembler { ...@@ -1372,16 +1402,6 @@ class MacroAssembler: public Assembler {
// it. See the implementation for register usage. // it. See the implementation for register usage.
void JumpToHandlerEntry(); void JumpToHandlerEntry();
// Helper for ECMAToInt32VFP and ECMAToInt32NoVFP.
// It is expected that 31 <= exponent <= 83, and scratch is exponent - 1.
void ECMAToInt32Tail(Register result,
Register scratch,
Register input_high,
Register input_low,
Label* out_of_range,
Label* negate,
Label* done);
// Compute memory operands for safepoint stack slots. // Compute memory operands for safepoint stack slots.
static int SafepointRegisterStackIndex(int reg_code); static int SafepointRegisterStackIndex(int reg_code);
MemOperand SafepointRegisterSlot(Register reg); MemOperand SafepointRegisterSlot(Register reg);
......
...@@ -1620,8 +1620,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall( ...@@ -1620,8 +1620,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
__ b(gt, &call_builtin); __ b(gt, &call_builtin);
__ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
__ StoreNumberToDoubleElements( __ StoreNumberToDoubleElements(r4, r0, elements, r5,
r4, r0, elements, r5, r2, r3, r9,
&call_builtin, argc * kDoubleSize); &call_builtin, argc * kDoubleSize);
// Save new length. // Save new length.
...@@ -3246,14 +3245,10 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( ...@@ -3246,14 +3245,10 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
StoreIntAsFloat(masm, r3, r4, r5, r7); StoreIntAsFloat(masm, r3, r4, r5, r7);
break; break;
case EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
__ vmov(s2, r5);
__ vcvt_f64_s32(d0, s2);
__ add(r3, r3, Operand(key, LSL, 2)); __ add(r3, r3, Operand(key, LSL, 2));
// r3: effective address of the double element // r3: effective address of the double element
FloatingPointHelper::Destination destination;
destination = FloatingPointHelper::kVFPRegisters;
FloatingPointHelper::ConvertIntToDouble(
masm, r5, destination,
d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent.
r4, s2); // These are: scratch2, single_scratch.
__ vstr(d0, r3, 0); __ vstr(d0, r3, 0);
break; break;
case FAST_ELEMENTS: case FAST_ELEMENTS:
...@@ -3303,7 +3298,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( ...@@ -3303,7 +3298,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// not include -kHeapObjectTag into it. // not include -kHeapObjectTag into it.
__ sub(r5, value, Operand(kHeapObjectTag)); __ sub(r5, value, Operand(kHeapObjectTag));
__ vldr(d0, r5, HeapNumber::kValueOffset); __ vldr(d0, r5, HeapNumber::kValueOffset);
__ ECMAToInt32(r5, d0, d1, r6, r7, r9); __ ECMAToInt32(r5, d0, r6, r7, r9, d1);
switch (elements_kind) { switch (elements_kind) {
case EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
...@@ -3537,9 +3532,6 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( ...@@ -3537,9 +3532,6 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
// -- r3 : scratch (elements backing store) // -- r3 : scratch (elements backing store)
// -- r4 : scratch // -- r4 : scratch
// -- r5 : scratch // -- r5 : scratch
// -- r6 : scratch
// -- r7 : scratch
// -- r9 : scratch
// ----------------------------------- // -----------------------------------
Label miss_force_generic, transition_elements_kind, grow, slow; Label miss_force_generic, transition_elements_kind, grow, slow;
Label finish_store, check_capacity; Label finish_store, check_capacity;
...@@ -3550,9 +3542,6 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( ...@@ -3550,9 +3542,6 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
Register elements_reg = r3; Register elements_reg = r3;
Register scratch1 = r4; Register scratch1 = r4;
Register scratch2 = r5; Register scratch2 = r5;
Register scratch3 = r6;
Register scratch4 = r7;
Register scratch5 = r9;
Register length_reg = r7; Register length_reg = r7;
// This stub is meant to be tail-jumped to, the receiver must already // This stub is meant to be tail-jumped to, the receiver must already
...@@ -3581,15 +3570,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( ...@@ -3581,15 +3570,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
} }
__ bind(&finish_store); __ bind(&finish_store);
__ StoreNumberToDoubleElements(value_reg, __ StoreNumberToDoubleElements(value_reg, key_reg, elements_reg,
key_reg, scratch1, &transition_elements_kind);
// All registers after this are overwritten.
elements_reg,
scratch1,
scratch3,
scratch4,
scratch2,
&transition_elements_kind);
__ Ret(); __ Ret();
// Handle store cache miss, replacing the ic with the generic stub. // Handle store cache miss, replacing the ic with the generic stub.
...@@ -3636,15 +3618,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( ...@@ -3636,15 +3618,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset)); FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset));
__ mov(scratch1, elements_reg); __ mov(scratch1, elements_reg);
__ StoreNumberToDoubleElements(value_reg, __ StoreNumberToDoubleElements(value_reg, key_reg, scratch1,
key_reg, scratch2, &transition_elements_kind);
// All registers after this are overwritten.
scratch1,
scratch2,
scratch3,
scratch4,
scratch5,
&transition_elements_kind);
__ mov(scratch1, Operand(kHoleNanLower32)); __ mov(scratch1, Operand(kHoleNanLower32));
__ mov(scratch2, Operand(kHoleNanUpper32)); __ mov(scratch2, Operand(kHoleNanUpper32));
......
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