| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 __ j(not_zero, &align_loop, Label::kNear); | 181 __ j(not_zero, &align_loop, Label::kNear); |
| 182 __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue)); | 182 __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue)); |
| 183 __ bind(&do_not_pad); | 183 __ bind(&do_not_pad); |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 | 186 |
| 187 info()->set_prologue_offset(masm_->pc_offset()); | 187 info()->set_prologue_offset(masm_->pc_offset()); |
| 188 if (NeedsEagerFrame()) { | 188 if (NeedsEagerFrame()) { |
| 189 ASSERT(!frame_is_built_); | 189 ASSERT(!frame_is_built_); |
| 190 frame_is_built_ = true; | 190 frame_is_built_ = true; |
| 191 __ push(ebp); // Caller's frame pointer. | 191 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); |
| 192 __ mov(ebp, esp); | |
| 193 info()->AddNoFrameRange(0, masm_->pc_offset()); | 192 info()->AddNoFrameRange(0, masm_->pc_offset()); |
| 194 __ push(esi); // Callee's context. | |
| 195 if (info()->IsStub()) { | |
| 196 __ push(Immediate(Smi::FromInt(StackFrame::STUB))); | |
| 197 } else { | |
| 198 __ push(edi); // Callee's JS function. | |
| 199 } | |
| 200 } | 193 } |
| 201 | 194 |
| 202 if (info()->IsOptimizing() && | 195 if (info()->IsOptimizing() && |
| 203 dynamic_frame_alignment_ && | 196 dynamic_frame_alignment_ && |
| 204 FLAG_debug_code) { | 197 FLAG_debug_code) { |
| 205 __ test(esp, Immediate(kPointerSize)); | 198 __ test(esp, Immediate(kPointerSize)); |
| 206 __ Assert(zero, kFrameIsExpectedToBeAligned); | 199 __ Assert(zero, kFrameIsExpectedToBeAligned); |
| 207 } | 200 } |
| 208 | 201 |
| 209 // Reserve space for the stack slots needed by the code. | 202 // Reserve space for the stack slots needed by the code. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 } | 243 } |
| 251 } | 244 } |
| 252 | 245 |
| 253 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { | 246 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { |
| 254 Comment(";;; Save clobbered callee double registers"); | 247 Comment(";;; Save clobbered callee double registers"); |
| 255 CpuFeatureScope scope(masm(), SSE2); | 248 CpuFeatureScope scope(masm(), SSE2); |
| 256 int count = 0; | 249 int count = 0; |
| 257 BitVector* doubles = chunk()->allocated_double_registers(); | 250 BitVector* doubles = chunk()->allocated_double_registers(); |
| 258 BitVector::Iterator save_iterator(doubles); | 251 BitVector::Iterator save_iterator(doubles); |
| 259 while (!save_iterator.Done()) { | 252 while (!save_iterator.Done()) { |
| 260 __ movdbl(MemOperand(esp, count * kDoubleSize), | 253 __ movsd(MemOperand(esp, count * kDoubleSize), |
| 261 XMMRegister::FromAllocationIndex(save_iterator.Current())); | 254 XMMRegister::FromAllocationIndex(save_iterator.Current())); |
| 262 save_iterator.Advance(); | 255 save_iterator.Advance(); |
| 263 count++; | 256 count++; |
| 264 } | 257 } |
| 265 } | 258 } |
| 266 } | 259 } |
| 267 | 260 |
| 268 // Possibly allocate a local context. | 261 // Possibly allocate a local context. |
| 269 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 262 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 270 if (heap_slots > 0) { | 263 if (heap_slots > 0) { |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 | 433 |
| 441 | 434 |
| 442 bool LCodeGen::GenerateDeferredCode() { | 435 bool LCodeGen::GenerateDeferredCode() { |
| 443 ASSERT(is_generating()); | 436 ASSERT(is_generating()); |
| 444 if (deferred_.length() > 0) { | 437 if (deferred_.length() > 0) { |
| 445 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 438 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
| 446 LDeferredCode* code = deferred_[i]; | 439 LDeferredCode* code = deferred_[i]; |
| 447 X87Stack copy(code->x87_stack()); | 440 X87Stack copy(code->x87_stack()); |
| 448 x87_stack_ = copy; | 441 x87_stack_ = copy; |
| 449 | 442 |
| 450 int pos = instructions_->at(code->instruction_index())->position(); | 443 HValue* value = |
| 451 RecordAndUpdatePosition(pos); | 444 instructions_->at(code->instruction_index())->hydrogen_value(); |
| 445 RecordAndWritePosition(value->position()); |
| 452 | 446 |
| 453 Comment(";;; <@%d,#%d> " | 447 Comment(";;; <@%d,#%d> " |
| 454 "-------------------- Deferred %s --------------------", | 448 "-------------------- Deferred %s --------------------", |
| 455 code->instruction_index(), | 449 code->instruction_index(), |
| 456 code->instr()->hydrogen_value()->id(), | 450 code->instr()->hydrogen_value()->id(), |
| 457 code->instr()->Mnemonic()); | 451 code->instr()->Mnemonic()); |
| 458 __ bind(code->entry()); | 452 __ bind(code->entry()); |
| 459 if (NeedsDeferredFrame()) { | 453 if (NeedsDeferredFrame()) { |
| 460 Comment(";;; Build frame"); | 454 Comment(";;; Build frame"); |
| 461 ASSERT(!frame_is_built_); | 455 ASSERT(!frame_is_built_); |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 UNREACHABLE(); | 922 UNREACHABLE(); |
| 929 } | 923 } |
| 930 } | 924 } |
| 931 | 925 |
| 932 | 926 |
| 933 void LCodeGen::CallCodeGeneric(Handle<Code> code, | 927 void LCodeGen::CallCodeGeneric(Handle<Code> code, |
| 934 RelocInfo::Mode mode, | 928 RelocInfo::Mode mode, |
| 935 LInstruction* instr, | 929 LInstruction* instr, |
| 936 SafepointMode safepoint_mode) { | 930 SafepointMode safepoint_mode) { |
| 937 ASSERT(instr != NULL); | 931 ASSERT(instr != NULL); |
| 938 LPointerMap* pointers = instr->pointer_map(); | |
| 939 RecordPosition(pointers->position()); | |
| 940 __ call(code, mode); | 932 __ call(code, mode); |
| 941 RecordSafepointWithLazyDeopt(instr, safepoint_mode); | 933 RecordSafepointWithLazyDeopt(instr, safepoint_mode); |
| 942 | 934 |
| 943 // Signal that we don't inline smi code before these stubs in the | 935 // Signal that we don't inline smi code before these stubs in the |
| 944 // optimizing code generator. | 936 // optimizing code generator. |
| 945 if (code->kind() == Code::BINARY_OP_IC || | 937 if (code->kind() == Code::BINARY_OP_IC || |
| 946 code->kind() == Code::COMPARE_IC) { | 938 code->kind() == Code::COMPARE_IC) { |
| 947 __ nop(); | 939 __ nop(); |
| 948 } | 940 } |
| 949 } | 941 } |
| 950 | 942 |
| 951 | 943 |
| 952 void LCodeGen::CallCode(Handle<Code> code, | 944 void LCodeGen::CallCode(Handle<Code> code, |
| 953 RelocInfo::Mode mode, | 945 RelocInfo::Mode mode, |
| 954 LInstruction* instr) { | 946 LInstruction* instr) { |
| 955 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); | 947 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); |
| 956 } | 948 } |
| 957 | 949 |
| 958 | 950 |
| 959 void LCodeGen::CallRuntime(const Runtime::Function* fun, | 951 void LCodeGen::CallRuntime(const Runtime::Function* fun, |
| 960 int argc, | 952 int argc, |
| 961 LInstruction* instr, | 953 LInstruction* instr, |
| 962 SaveFPRegsMode save_doubles) { | 954 SaveFPRegsMode save_doubles) { |
| 963 ASSERT(instr != NULL); | 955 ASSERT(instr != NULL); |
| 964 ASSERT(instr->HasPointerMap()); | 956 ASSERT(instr->HasPointerMap()); |
| 965 LPointerMap* pointers = instr->pointer_map(); | |
| 966 RecordPosition(pointers->position()); | |
| 967 | 957 |
| 968 __ CallRuntime(fun, argc, save_doubles); | 958 __ CallRuntime(fun, argc, save_doubles); |
| 969 | 959 |
| 970 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 960 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
| 971 | 961 |
| 972 ASSERT(info()->is_calling()); | 962 ASSERT(info()->is_calling()); |
| 973 } | 963 } |
| 974 | 964 |
| 975 | 965 |
| 976 void LCodeGen::LoadContextFromDeferred(LOperand* context) { | 966 void LCodeGen::LoadContextFromDeferred(LOperand* context) { |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 } | 1239 } |
| 1250 | 1240 |
| 1251 | 1241 |
| 1252 void LCodeGen::RecordSafepoint(LPointerMap* pointers, | 1242 void LCodeGen::RecordSafepoint(LPointerMap* pointers, |
| 1253 Safepoint::DeoptMode mode) { | 1243 Safepoint::DeoptMode mode) { |
| 1254 RecordSafepoint(pointers, Safepoint::kSimple, 0, mode); | 1244 RecordSafepoint(pointers, Safepoint::kSimple, 0, mode); |
| 1255 } | 1245 } |
| 1256 | 1246 |
| 1257 | 1247 |
| 1258 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode mode) { | 1248 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode mode) { |
| 1259 LPointerMap empty_pointers(RelocInfo::kNoPosition, zone()); | 1249 LPointerMap empty_pointers(zone()); |
| 1260 RecordSafepoint(&empty_pointers, mode); | 1250 RecordSafepoint(&empty_pointers, mode); |
| 1261 } | 1251 } |
| 1262 | 1252 |
| 1263 | 1253 |
| 1264 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, | 1254 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, |
| 1265 int arguments, | 1255 int arguments, |
| 1266 Safepoint::DeoptMode mode) { | 1256 Safepoint::DeoptMode mode) { |
| 1267 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, mode); | 1257 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, mode); |
| 1268 } | 1258 } |
| 1269 | 1259 |
| 1270 | 1260 |
| 1271 void LCodeGen::RecordPosition(int position) { | 1261 void LCodeGen::RecordAndWritePosition(int position) { |
| 1272 if (position == RelocInfo::kNoPosition) return; | 1262 if (position == RelocInfo::kNoPosition) return; |
| 1273 masm()->positions_recorder()->RecordPosition(position); | 1263 masm()->positions_recorder()->RecordPosition(position); |
| 1264 masm()->positions_recorder()->WriteRecordedPositions(); |
| 1274 } | 1265 } |
| 1275 | 1266 |
| 1276 | 1267 |
| 1277 void LCodeGen::RecordAndUpdatePosition(int position) { | |
| 1278 if (position >= 0 && position != old_position_) { | |
| 1279 masm()->positions_recorder()->RecordPosition(position); | |
| 1280 old_position_ = position; | |
| 1281 } | |
| 1282 } | |
| 1283 | |
| 1284 | |
| 1285 static const char* LabelType(LLabel* label) { | 1268 static const char* LabelType(LLabel* label) { |
| 1286 if (label->is_loop_header()) return " (loop header)"; | 1269 if (label->is_loop_header()) return " (loop header)"; |
| 1287 if (label->is_osr_entry()) return " (OSR entry)"; | 1270 if (label->is_osr_entry()) return " (OSR entry)"; |
| 1288 return ""; | 1271 return ""; |
| 1289 } | 1272 } |
| 1290 | 1273 |
| 1291 | 1274 |
| 1292 void LCodeGen::DoLabel(LLabel* label) { | 1275 void LCodeGen::DoLabel(LLabel* label) { |
| 1293 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", | 1276 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", |
| 1294 current_instruction_, | 1277 current_instruction_, |
| (...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 break; | 2209 break; |
| 2227 case Token::DIV: | 2210 case Token::DIV: |
| 2228 __ divsd(left, right); | 2211 __ divsd(left, right); |
| 2229 // Don't delete this mov. It may improve performance on some CPUs, | 2212 // Don't delete this mov. It may improve performance on some CPUs, |
| 2230 // when there is a mulsd depending on the result | 2213 // when there is a mulsd depending on the result |
| 2231 __ movaps(left, left); | 2214 __ movaps(left, left); |
| 2232 break; | 2215 break; |
| 2233 case Token::MOD: { | 2216 case Token::MOD: { |
| 2234 // Pass two doubles as arguments on the stack. | 2217 // Pass two doubles as arguments on the stack. |
| 2235 __ PrepareCallCFunction(4, eax); | 2218 __ PrepareCallCFunction(4, eax); |
| 2236 __ movdbl(Operand(esp, 0 * kDoubleSize), left); | 2219 __ movsd(Operand(esp, 0 * kDoubleSize), left); |
| 2237 __ movdbl(Operand(esp, 1 * kDoubleSize), right); | 2220 __ movsd(Operand(esp, 1 * kDoubleSize), right); |
| 2238 __ CallCFunction( | 2221 __ CallCFunction( |
| 2239 ExternalReference::double_fp_operation(Token::MOD, isolate()), | 2222 ExternalReference::double_fp_operation(Token::MOD, isolate()), |
| 2240 4); | 2223 4); |
| 2241 | 2224 |
| 2242 // Return value is in st(0) on ia32. | 2225 // Return value is in st(0) on ia32. |
| 2243 // Store it into the result register. | 2226 // Store it into the result register. |
| 2244 __ sub(Operand(esp), Immediate(kDoubleSize)); | 2227 __ sub(Operand(esp), Immediate(kDoubleSize)); |
| 2245 __ fstp_d(Operand(esp, 0)); | 2228 __ fstp_d(Operand(esp, 0)); |
| 2246 __ movdbl(result, Operand(esp, 0)); | 2229 __ movsd(result, Operand(esp, 0)); |
| 2247 __ add(Operand(esp), Immediate(kDoubleSize)); | 2230 __ add(Operand(esp), Immediate(kDoubleSize)); |
| 2248 break; | 2231 break; |
| 2249 } | 2232 } |
| 2250 default: | 2233 default: |
| 2251 UNREACHABLE(); | 2234 UNREACHABLE(); |
| 2252 break; | 2235 break; |
| 2253 } | 2236 } |
| 2254 } else { | 2237 } else { |
| 2255 X87Register left = ToX87Register(instr->left()); | 2238 X87Register left = ToX87Register(instr->left()); |
| 2256 X87Register right = ToX87Register(instr->right()); | 2239 X87Register right = ToX87Register(instr->right()); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2496 } | 2479 } |
| 2497 | 2480 |
| 2498 | 2481 |
| 2499 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { | 2482 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { |
| 2500 Condition cond = no_condition; | 2483 Condition cond = no_condition; |
| 2501 switch (op) { | 2484 switch (op) { |
| 2502 case Token::EQ: | 2485 case Token::EQ: |
| 2503 case Token::EQ_STRICT: | 2486 case Token::EQ_STRICT: |
| 2504 cond = equal; | 2487 cond = equal; |
| 2505 break; | 2488 break; |
| 2489 case Token::NE: |
| 2490 case Token::NE_STRICT: |
| 2491 cond = not_equal; |
| 2492 break; |
| 2506 case Token::LT: | 2493 case Token::LT: |
| 2507 cond = is_unsigned ? below : less; | 2494 cond = is_unsigned ? below : less; |
| 2508 break; | 2495 break; |
| 2509 case Token::GT: | 2496 case Token::GT: |
| 2510 cond = is_unsigned ? above : greater; | 2497 cond = is_unsigned ? above : greater; |
| 2511 break; | 2498 break; |
| 2512 case Token::LTE: | 2499 case Token::LTE: |
| 2513 cond = is_unsigned ? below_equal : less_equal; | 2500 cond = is_unsigned ? below_equal : less_equal; |
| 2514 break; | 2501 break; |
| 2515 case Token::GTE: | 2502 case Token::GTE: |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2606 __ fstp(0); | 2593 __ fstp(0); |
| 2607 EmitFalseBranch(instr, no_condition); | 2594 EmitFalseBranch(instr, no_condition); |
| 2608 __ bind(&ok); | 2595 __ bind(&ok); |
| 2609 } | 2596 } |
| 2610 | 2597 |
| 2611 | 2598 |
| 2612 __ sub(esp, Immediate(kDoubleSize)); | 2599 __ sub(esp, Immediate(kDoubleSize)); |
| 2613 if (use_sse2) { | 2600 if (use_sse2) { |
| 2614 CpuFeatureScope scope(masm(), SSE2); | 2601 CpuFeatureScope scope(masm(), SSE2); |
| 2615 XMMRegister input_reg = ToDoubleRegister(instr->object()); | 2602 XMMRegister input_reg = ToDoubleRegister(instr->object()); |
| 2616 __ movdbl(MemOperand(esp, 0), input_reg); | 2603 __ movsd(MemOperand(esp, 0), input_reg); |
| 2617 } else { | 2604 } else { |
| 2618 __ fstp_d(MemOperand(esp, 0)); | 2605 __ fstp_d(MemOperand(esp, 0)); |
| 2619 } | 2606 } |
| 2620 | 2607 |
| 2621 __ add(esp, Immediate(kDoubleSize)); | 2608 __ add(esp, Immediate(kDoubleSize)); |
| 2622 int offset = sizeof(kHoleNanUpper32); | 2609 int offset = sizeof(kHoleNanUpper32); |
| 2623 __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32)); | 2610 __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32)); |
| 2624 EmitBranch(instr, equal); | 2611 EmitBranch(instr, equal); |
| 2625 } | 2612 } |
| 2626 | 2613 |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2996 // Get the deoptimization index of the LLazyBailout-environment that | 2983 // Get the deoptimization index of the LLazyBailout-environment that |
| 2997 // corresponds to this instruction. | 2984 // corresponds to this instruction. |
| 2998 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); | 2985 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); |
| 2999 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 2986 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
| 3000 | 2987 |
| 3001 // Put the result value into the eax slot and restore all registers. | 2988 // Put the result value into the eax slot and restore all registers. |
| 3002 __ StoreToSafepointRegisterSlot(eax, eax); | 2989 __ StoreToSafepointRegisterSlot(eax, eax); |
| 3003 } | 2990 } |
| 3004 | 2991 |
| 3005 | 2992 |
| 3006 void LCodeGen::DoInstanceSize(LInstanceSize* instr) { | |
| 3007 Register object = ToRegister(instr->object()); | |
| 3008 Register result = ToRegister(instr->result()); | |
| 3009 __ mov(result, FieldOperand(object, HeapObject::kMapOffset)); | |
| 3010 __ movzx_b(result, FieldOperand(result, Map::kInstanceSizeOffset)); | |
| 3011 } | |
| 3012 | |
| 3013 | |
| 3014 void LCodeGen::DoCmpT(LCmpT* instr) { | 2993 void LCodeGen::DoCmpT(LCmpT* instr) { |
| 3015 Token::Value op = instr->op(); | 2994 Token::Value op = instr->op(); |
| 3016 | 2995 |
| 3017 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 2996 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
| 3018 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2997 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3019 | 2998 |
| 3020 Condition condition = ComputeCompareCondition(op); | 2999 Condition condition = ComputeCompareCondition(op); |
| 3021 Label true_value, done; | 3000 Label true_value, done; |
| 3022 __ test(eax, Operand(eax)); | 3001 __ test(eax, Operand(eax)); |
| 3023 __ j(condition, &true_value, Label::kNear); | 3002 __ j(condition, &true_value, Label::kNear); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3076 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3055 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 3077 __ CallRuntime(Runtime::kTraceExit, 1); | 3056 __ CallRuntime(Runtime::kTraceExit, 1); |
| 3078 } | 3057 } |
| 3079 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { | 3058 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { |
| 3080 ASSERT(NeedsEagerFrame()); | 3059 ASSERT(NeedsEagerFrame()); |
| 3081 CpuFeatureScope scope(masm(), SSE2); | 3060 CpuFeatureScope scope(masm(), SSE2); |
| 3082 BitVector* doubles = chunk()->allocated_double_registers(); | 3061 BitVector* doubles = chunk()->allocated_double_registers(); |
| 3083 BitVector::Iterator save_iterator(doubles); | 3062 BitVector::Iterator save_iterator(doubles); |
| 3084 int count = 0; | 3063 int count = 0; |
| 3085 while (!save_iterator.Done()) { | 3064 while (!save_iterator.Done()) { |
| 3086 __ movdbl(XMMRegister::FromAllocationIndex(save_iterator.Current()), | 3065 __ movsd(XMMRegister::FromAllocationIndex(save_iterator.Current()), |
| 3087 MemOperand(esp, count * kDoubleSize)); | 3066 MemOperand(esp, count * kDoubleSize)); |
| 3088 save_iterator.Advance(); | 3067 save_iterator.Advance(); |
| 3089 count++; | 3068 count++; |
| 3090 } | 3069 } |
| 3091 } | 3070 } |
| 3092 if (dynamic_frame_alignment_) { | 3071 if (dynamic_frame_alignment_) { |
| 3093 // Fetch the state of the dynamic frame alignment. | 3072 // Fetch the state of the dynamic frame alignment. |
| 3094 __ mov(edx, Operand(ebp, | 3073 __ mov(edx, Operand(ebp, |
| 3095 JavaScriptFrameConstants::kDynamicAlignmentStateOffset)); | 3074 JavaScriptFrameConstants::kDynamicAlignmentStateOffset)); |
| 3096 } | 3075 } |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3244 } | 3223 } |
| 3245 return; | 3224 return; |
| 3246 } | 3225 } |
| 3247 | 3226 |
| 3248 Register object = ToRegister(instr->object()); | 3227 Register object = ToRegister(instr->object()); |
| 3249 if (FLAG_track_double_fields && | 3228 if (FLAG_track_double_fields && |
| 3250 instr->hydrogen()->representation().IsDouble()) { | 3229 instr->hydrogen()->representation().IsDouble()) { |
| 3251 if (CpuFeatures::IsSupported(SSE2)) { | 3230 if (CpuFeatures::IsSupported(SSE2)) { |
| 3252 CpuFeatureScope scope(masm(), SSE2); | 3231 CpuFeatureScope scope(masm(), SSE2); |
| 3253 XMMRegister result = ToDoubleRegister(instr->result()); | 3232 XMMRegister result = ToDoubleRegister(instr->result()); |
| 3254 __ movdbl(result, FieldOperand(object, offset)); | 3233 __ movsd(result, FieldOperand(object, offset)); |
| 3255 } else { | 3234 } else { |
| 3256 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); | 3235 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); |
| 3257 } | 3236 } |
| 3258 return; | 3237 return; |
| 3259 } | 3238 } |
| 3260 | 3239 |
| 3261 Register result = ToRegister(instr->result()); | 3240 Register result = ToRegister(instr->result()); |
| 3262 if (!access.IsInobject()) { | 3241 if (!access.IsInobject()) { |
| 3263 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 3242 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 3264 object = result; | 3243 object = result; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3398 CpuFeatureScope scope(masm(), SSE2); | 3377 CpuFeatureScope scope(masm(), SSE2); |
| 3399 XMMRegister result(ToDoubleRegister(instr->result())); | 3378 XMMRegister result(ToDoubleRegister(instr->result())); |
| 3400 __ movss(result, operand); | 3379 __ movss(result, operand); |
| 3401 __ cvtss2sd(result, result); | 3380 __ cvtss2sd(result, result); |
| 3402 } else { | 3381 } else { |
| 3403 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); | 3382 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); |
| 3404 } | 3383 } |
| 3405 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3384 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 3406 if (CpuFeatures::IsSupported(SSE2)) { | 3385 if (CpuFeatures::IsSupported(SSE2)) { |
| 3407 CpuFeatureScope scope(masm(), SSE2); | 3386 CpuFeatureScope scope(masm(), SSE2); |
| 3408 __ movdbl(ToDoubleRegister(instr->result()), operand); | 3387 __ movsd(ToDoubleRegister(instr->result()), operand); |
| 3409 } else { | 3388 } else { |
| 3410 X87Mov(ToX87Register(instr->result()), operand); | 3389 X87Mov(ToX87Register(instr->result()), operand); |
| 3411 } | 3390 } |
| 3412 } else { | 3391 } else { |
| 3413 Register result(ToRegister(instr->result())); | 3392 Register result(ToRegister(instr->result())); |
| 3414 switch (elements_kind) { | 3393 switch (elements_kind) { |
| 3415 case EXTERNAL_BYTE_ELEMENTS: | 3394 case EXTERNAL_BYTE_ELEMENTS: |
| 3416 __ movsx_b(result, operand); | 3395 __ movsx_b(result, operand); |
| 3417 break; | 3396 break; |
| 3418 case EXTERNAL_PIXEL_ELEMENTS: | 3397 case EXTERNAL_PIXEL_ELEMENTS: |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3469 Operand double_load_operand = BuildFastArrayOperand( | 3448 Operand double_load_operand = BuildFastArrayOperand( |
| 3470 instr->elements(), | 3449 instr->elements(), |
| 3471 instr->key(), | 3450 instr->key(), |
| 3472 instr->hydrogen()->key()->representation(), | 3451 instr->hydrogen()->key()->representation(), |
| 3473 FAST_DOUBLE_ELEMENTS, | 3452 FAST_DOUBLE_ELEMENTS, |
| 3474 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3453 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 3475 instr->additional_index()); | 3454 instr->additional_index()); |
| 3476 if (CpuFeatures::IsSupported(SSE2)) { | 3455 if (CpuFeatures::IsSupported(SSE2)) { |
| 3477 CpuFeatureScope scope(masm(), SSE2); | 3456 CpuFeatureScope scope(masm(), SSE2); |
| 3478 XMMRegister result = ToDoubleRegister(instr->result()); | 3457 XMMRegister result = ToDoubleRegister(instr->result()); |
| 3479 __ movdbl(result, double_load_operand); | 3458 __ movsd(result, double_load_operand); |
| 3480 } else { | 3459 } else { |
| 3481 X87Mov(ToX87Register(instr->result()), double_load_operand); | 3460 X87Mov(ToX87Register(instr->result()), double_load_operand); |
| 3482 } | 3461 } |
| 3483 } | 3462 } |
| 3484 | 3463 |
| 3485 | 3464 |
| 3486 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3465 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3487 Register result = ToRegister(instr->result()); | 3466 Register result = ToRegister(instr->result()); |
| 3488 | 3467 |
| 3489 // Load the result. | 3468 // Load the result. |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3686 __ j(zero, &invoke, Label::kNear); | 3665 __ j(zero, &invoke, Label::kNear); |
| 3687 __ bind(&loop); | 3666 __ bind(&loop); |
| 3688 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); | 3667 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); |
| 3689 __ dec(length); | 3668 __ dec(length); |
| 3690 __ j(not_zero, &loop); | 3669 __ j(not_zero, &loop); |
| 3691 | 3670 |
| 3692 // Invoke the function. | 3671 // Invoke the function. |
| 3693 __ bind(&invoke); | 3672 __ bind(&invoke); |
| 3694 ASSERT(instr->HasPointerMap()); | 3673 ASSERT(instr->HasPointerMap()); |
| 3695 LPointerMap* pointers = instr->pointer_map(); | 3674 LPointerMap* pointers = instr->pointer_map(); |
| 3696 RecordPosition(pointers->position()); | |
| 3697 SafepointGenerator safepoint_generator( | 3675 SafepointGenerator safepoint_generator( |
| 3698 this, pointers, Safepoint::kLazyDeopt); | 3676 this, pointers, Safepoint::kLazyDeopt); |
| 3699 ParameterCount actual(eax); | 3677 ParameterCount actual(eax); |
| 3700 __ InvokeFunction(function, actual, CALL_FUNCTION, | 3678 __ InvokeFunction(function, actual, CALL_FUNCTION, |
| 3701 safepoint_generator, CALL_AS_METHOD); | 3679 safepoint_generator, CALL_AS_METHOD); |
| 3702 } | 3680 } |
| 3703 | 3681 |
| 3704 | 3682 |
| 3705 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 3683 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
| 3706 __ int3(); | 3684 __ int3(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3771 int formal_parameter_count, | 3749 int formal_parameter_count, |
| 3772 int arity, | 3750 int arity, |
| 3773 LInstruction* instr, | 3751 LInstruction* instr, |
| 3774 CallKind call_kind, | 3752 CallKind call_kind, |
| 3775 EDIState edi_state) { | 3753 EDIState edi_state) { |
| 3776 bool dont_adapt_arguments = | 3754 bool dont_adapt_arguments = |
| 3777 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3755 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 3778 bool can_invoke_directly = | 3756 bool can_invoke_directly = |
| 3779 dont_adapt_arguments || formal_parameter_count == arity; | 3757 dont_adapt_arguments || formal_parameter_count == arity; |
| 3780 | 3758 |
| 3781 LPointerMap* pointers = instr->pointer_map(); | |
| 3782 RecordPosition(pointers->position()); | |
| 3783 | |
| 3784 if (can_invoke_directly) { | 3759 if (can_invoke_directly) { |
| 3785 if (edi_state == EDI_UNINITIALIZED) { | 3760 if (edi_state == EDI_UNINITIALIZED) { |
| 3786 __ LoadHeapObject(edi, function); | 3761 __ LoadHeapObject(edi, function); |
| 3787 } | 3762 } |
| 3788 | 3763 |
| 3789 // Change context. | 3764 // Change context. |
| 3790 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 3765 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 3791 | 3766 |
| 3792 // Set eax to arguments count if adaption is not needed. Assumes that eax | 3767 // Set eax to arguments count if adaption is not needed. Assumes that eax |
| 3793 // is available to write to at this point. | 3768 // is available to write to at this point. |
| 3794 if (dont_adapt_arguments) { | 3769 if (dont_adapt_arguments) { |
| 3795 __ mov(eax, arity); | 3770 __ mov(eax, arity); |
| 3796 } | 3771 } |
| 3797 | 3772 |
| 3798 // Invoke function directly. | 3773 // Invoke function directly. |
| 3799 __ SetCallKind(ecx, call_kind); | 3774 __ SetCallKind(ecx, call_kind); |
| 3800 if (function.is_identical_to(info()->closure())) { | 3775 if (function.is_identical_to(info()->closure())) { |
| 3801 __ CallSelf(); | 3776 __ CallSelf(); |
| 3802 } else { | 3777 } else { |
| 3803 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 3778 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
| 3804 } | 3779 } |
| 3805 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 3780 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
| 3806 } else { | 3781 } else { |
| 3807 // We need to adapt arguments. | 3782 // We need to adapt arguments. |
| 3783 LPointerMap* pointers = instr->pointer_map(); |
| 3808 SafepointGenerator generator( | 3784 SafepointGenerator generator( |
| 3809 this, pointers, Safepoint::kLazyDeopt); | 3785 this, pointers, Safepoint::kLazyDeopt); |
| 3810 ParameterCount count(arity); | 3786 ParameterCount count(arity); |
| 3811 ParameterCount expected(formal_parameter_count); | 3787 ParameterCount expected(formal_parameter_count); |
| 3812 __ InvokeFunction( | 3788 __ InvokeFunction( |
| 3813 function, expected, count, CALL_FUNCTION, generator, call_kind); | 3789 function, expected, count, CALL_FUNCTION, generator, call_kind); |
| 3814 } | 3790 } |
| 3815 } | 3791 } |
| 3816 | 3792 |
| 3817 | 3793 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3900 | 3876 |
| 3901 ASSERT(instr->value()->Equals(instr->result())); | 3877 ASSERT(instr->value()->Equals(instr->result())); |
| 3902 Representation r = instr->hydrogen()->value()->representation(); | 3878 Representation r = instr->hydrogen()->value()->representation(); |
| 3903 | 3879 |
| 3904 CpuFeatureScope scope(masm(), SSE2); | 3880 CpuFeatureScope scope(masm(), SSE2); |
| 3905 if (r.IsDouble()) { | 3881 if (r.IsDouble()) { |
| 3906 XMMRegister scratch = double_scratch0(); | 3882 XMMRegister scratch = double_scratch0(); |
| 3907 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3883 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3908 __ xorps(scratch, scratch); | 3884 __ xorps(scratch, scratch); |
| 3909 __ subsd(scratch, input_reg); | 3885 __ subsd(scratch, input_reg); |
| 3910 __ pand(input_reg, scratch); | 3886 __ andps(input_reg, scratch); |
| 3911 } else if (r.IsSmiOrInteger32()) { | 3887 } else if (r.IsSmiOrInteger32()) { |
| 3912 EmitIntegerMathAbs(instr); | 3888 EmitIntegerMathAbs(instr); |
| 3913 } else { // Tagged case. | 3889 } else { // Tagged case. |
| 3914 DeferredMathAbsTaggedHeapNumber* deferred = | 3890 DeferredMathAbsTaggedHeapNumber* deferred = |
| 3915 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_); | 3891 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_); |
| 3916 Register input_reg = ToRegister(instr->value()); | 3892 Register input_reg = ToRegister(instr->value()); |
| 3917 // Smi check. | 3893 // Smi check. |
| 3918 __ JumpIfNotSmi(input_reg, deferred->entry()); | 3894 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 3919 EmitIntegerMathAbs(instr); | 3895 EmitIntegerMathAbs(instr); |
| 3920 __ bind(deferred->exit()); | 3896 __ bind(deferred->exit()); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3992 CpuFeatureScope scope(masm(), SSE2); | 3968 CpuFeatureScope scope(masm(), SSE2); |
| 3993 Register output_reg = ToRegister(instr->result()); | 3969 Register output_reg = ToRegister(instr->result()); |
| 3994 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3970 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3995 XMMRegister xmm_scratch = double_scratch0(); | 3971 XMMRegister xmm_scratch = double_scratch0(); |
| 3996 XMMRegister input_temp = ToDoubleRegister(instr->temp()); | 3972 XMMRegister input_temp = ToDoubleRegister(instr->temp()); |
| 3997 ExternalReference one_half = ExternalReference::address_of_one_half(); | 3973 ExternalReference one_half = ExternalReference::address_of_one_half(); |
| 3998 ExternalReference minus_one_half = | 3974 ExternalReference minus_one_half = |
| 3999 ExternalReference::address_of_minus_one_half(); | 3975 ExternalReference::address_of_minus_one_half(); |
| 4000 | 3976 |
| 4001 Label done, round_to_zero, below_one_half, do_not_compensate; | 3977 Label done, round_to_zero, below_one_half, do_not_compensate; |
| 4002 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); | 3978 __ movsd(xmm_scratch, Operand::StaticVariable(one_half)); |
| 4003 __ ucomisd(xmm_scratch, input_reg); | 3979 __ ucomisd(xmm_scratch, input_reg); |
| 4004 __ j(above, &below_one_half); | 3980 __ j(above, &below_one_half); |
| 4005 | 3981 |
| 4006 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). | 3982 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). |
| 4007 __ addsd(xmm_scratch, input_reg); | 3983 __ addsd(xmm_scratch, input_reg); |
| 4008 __ cvttsd2si(output_reg, Operand(xmm_scratch)); | 3984 __ cvttsd2si(output_reg, Operand(xmm_scratch)); |
| 4009 // Overflow is signalled with minint. | 3985 // Overflow is signalled with minint. |
| 4010 __ cmp(output_reg, 0x80000000u); | 3986 __ cmp(output_reg, 0x80000000u); |
| 4011 __ RecordComment("D2I conversion overflow"); | 3987 __ RecordComment("D2I conversion overflow"); |
| 4012 DeoptimizeIf(equal, instr->environment()); | 3988 DeoptimizeIf(equal, instr->environment()); |
| 4013 __ jmp(&done); | 3989 __ jmp(&done); |
| 4014 | 3990 |
| 4015 __ bind(&below_one_half); | 3991 __ bind(&below_one_half); |
| 4016 __ movdbl(xmm_scratch, Operand::StaticVariable(minus_one_half)); | 3992 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half)); |
| 4017 __ ucomisd(xmm_scratch, input_reg); | 3993 __ ucomisd(xmm_scratch, input_reg); |
| 4018 __ j(below_equal, &round_to_zero); | 3994 __ j(below_equal, &round_to_zero); |
| 4019 | 3995 |
| 4020 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then | 3996 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then |
| 4021 // compare and compensate. | 3997 // compare and compensate. |
| 4022 __ movsd(input_temp, input_reg); // Do not alter input_reg. | 3998 __ movsd(input_temp, input_reg); // Do not alter input_reg. |
| 4023 __ subsd(input_temp, xmm_scratch); | 3999 __ subsd(input_temp, xmm_scratch); |
| 4024 __ cvttsd2si(output_reg, Operand(input_temp)); | 4000 __ cvttsd2si(output_reg, Operand(input_temp)); |
| 4025 // Catch minint due to overflow, and to prevent overflow when compensating. | 4001 // Catch minint due to overflow, and to prevent overflow when compensating. |
| 4026 __ cmp(output_reg, 0x80000000u); | 4002 __ cmp(output_reg, 0x80000000u); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4193 ASSERT(instr->value()->Equals(instr->result())); | 4169 ASSERT(instr->value()->Equals(instr->result())); |
| 4194 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4170 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 4195 XMMRegister xmm_scratch = double_scratch0(); | 4171 XMMRegister xmm_scratch = double_scratch0(); |
| 4196 Label positive, done, zero; | 4172 Label positive, done, zero; |
| 4197 __ xorps(xmm_scratch, xmm_scratch); | 4173 __ xorps(xmm_scratch, xmm_scratch); |
| 4198 __ ucomisd(input_reg, xmm_scratch); | 4174 __ ucomisd(input_reg, xmm_scratch); |
| 4199 __ j(above, &positive, Label::kNear); | 4175 __ j(above, &positive, Label::kNear); |
| 4200 __ j(equal, &zero, Label::kNear); | 4176 __ j(equal, &zero, Label::kNear); |
| 4201 ExternalReference nan = | 4177 ExternalReference nan = |
| 4202 ExternalReference::address_of_canonical_non_hole_nan(); | 4178 ExternalReference::address_of_canonical_non_hole_nan(); |
| 4203 __ movdbl(input_reg, Operand::StaticVariable(nan)); | 4179 __ movsd(input_reg, Operand::StaticVariable(nan)); |
| 4204 __ jmp(&done, Label::kNear); | 4180 __ jmp(&done, Label::kNear); |
| 4205 __ bind(&zero); | 4181 __ bind(&zero); |
| 4206 __ push(Immediate(0xFFF00000)); | 4182 ExternalReference ninf = |
| 4207 __ push(Immediate(0)); | 4183 ExternalReference::address_of_negative_infinity(); |
| 4208 __ movdbl(input_reg, Operand(esp, 0)); | 4184 __ movsd(input_reg, Operand::StaticVariable(ninf)); |
| 4209 __ add(Operand(esp), Immediate(kDoubleSize)); | |
| 4210 __ jmp(&done, Label::kNear); | 4185 __ jmp(&done, Label::kNear); |
| 4211 __ bind(&positive); | 4186 __ bind(&positive); |
| 4212 __ fldln2(); | 4187 __ fldln2(); |
| 4213 __ sub(Operand(esp), Immediate(kDoubleSize)); | 4188 __ sub(Operand(esp), Immediate(kDoubleSize)); |
| 4214 __ movdbl(Operand(esp, 0), input_reg); | 4189 __ movsd(Operand(esp, 0), input_reg); |
| 4215 __ fld_d(Operand(esp, 0)); | 4190 __ fld_d(Operand(esp, 0)); |
| 4216 __ fyl2x(); | 4191 __ fyl2x(); |
| 4217 __ fstp_d(Operand(esp, 0)); | 4192 __ fstp_d(Operand(esp, 0)); |
| 4218 __ movdbl(input_reg, Operand(esp, 0)); | 4193 __ movsd(input_reg, Operand(esp, 0)); |
| 4219 __ add(Operand(esp), Immediate(kDoubleSize)); | 4194 __ add(Operand(esp), Immediate(kDoubleSize)); |
| 4220 __ bind(&done); | 4195 __ bind(&done); |
| 4221 } | 4196 } |
| 4222 | 4197 |
| 4223 | 4198 |
| 4224 void LCodeGen::DoMathExp(LMathExp* instr) { | 4199 void LCodeGen::DoMathExp(LMathExp* instr) { |
| 4225 CpuFeatureScope scope(masm(), SSE2); | 4200 CpuFeatureScope scope(masm(), SSE2); |
| 4226 XMMRegister input = ToDoubleRegister(instr->value()); | 4201 XMMRegister input = ToDoubleRegister(instr->value()); |
| 4227 XMMRegister result = ToDoubleRegister(instr->result()); | 4202 XMMRegister result = ToDoubleRegister(instr->result()); |
| 4228 XMMRegister temp0 = double_scratch0(); | 4203 XMMRegister temp0 = double_scratch0(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4267 | 4242 |
| 4268 | 4243 |
| 4269 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 4244 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 4270 ASSERT(ToRegister(instr->context()).is(esi)); | 4245 ASSERT(ToRegister(instr->context()).is(esi)); |
| 4271 ASSERT(ToRegister(instr->function()).is(edi)); | 4246 ASSERT(ToRegister(instr->function()).is(edi)); |
| 4272 ASSERT(instr->HasPointerMap()); | 4247 ASSERT(instr->HasPointerMap()); |
| 4273 | 4248 |
| 4274 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 4249 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 4275 if (known_function.is_null()) { | 4250 if (known_function.is_null()) { |
| 4276 LPointerMap* pointers = instr->pointer_map(); | 4251 LPointerMap* pointers = instr->pointer_map(); |
| 4277 RecordPosition(pointers->position()); | |
| 4278 SafepointGenerator generator( | 4252 SafepointGenerator generator( |
| 4279 this, pointers, Safepoint::kLazyDeopt); | 4253 this, pointers, Safepoint::kLazyDeopt); |
| 4280 ParameterCount count(instr->arity()); | 4254 ParameterCount count(instr->arity()); |
| 4281 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 4255 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
| 4282 } else { | 4256 } else { |
| 4283 CallKnownFunction(known_function, | 4257 CallKnownFunction(known_function, |
| 4284 instr->hydrogen()->formal_parameter_count(), | 4258 instr->hydrogen()->formal_parameter_count(), |
| 4285 instr->arity(), | 4259 instr->arity(), |
| 4286 instr, | 4260 instr, |
| 4287 CALL_AS_METHOD, | 4261 CALL_AS_METHOD, |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4479 DeoptimizeIf(zero, instr->environment()); | 4453 DeoptimizeIf(zero, instr->environment()); |
| 4480 } | 4454 } |
| 4481 } | 4455 } |
| 4482 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 4456 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 4483 ASSERT(transition.is_null()); | 4457 ASSERT(transition.is_null()); |
| 4484 ASSERT(access.IsInobject()); | 4458 ASSERT(access.IsInobject()); |
| 4485 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4459 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
| 4486 if (CpuFeatures::IsSupported(SSE2)) { | 4460 if (CpuFeatures::IsSupported(SSE2)) { |
| 4487 CpuFeatureScope scope(masm(), SSE2); | 4461 CpuFeatureScope scope(masm(), SSE2); |
| 4488 XMMRegister value = ToDoubleRegister(instr->value()); | 4462 XMMRegister value = ToDoubleRegister(instr->value()); |
| 4489 __ movdbl(FieldOperand(object, offset), value); | 4463 __ movsd(FieldOperand(object, offset), value); |
| 4490 } else { | 4464 } else { |
| 4491 X87Register value = ToX87Register(instr->value()); | 4465 X87Register value = ToX87Register(instr->value()); |
| 4492 X87Mov(FieldOperand(object, offset), value); | 4466 X87Mov(FieldOperand(object, offset), value); |
| 4493 } | 4467 } |
| 4494 return; | 4468 return; |
| 4495 } | 4469 } |
| 4496 | 4470 |
| 4497 if (!transition.is_null()) { | 4471 if (!transition.is_null()) { |
| 4498 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { | 4472 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { |
| 4499 __ mov(FieldOperand(object, HeapObject::kMapOffset), transition); | 4473 __ mov(FieldOperand(object, HeapObject::kMapOffset), transition); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4629 XMMRegister xmm_scratch = double_scratch0(); | 4603 XMMRegister xmm_scratch = double_scratch0(); |
| 4630 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); | 4604 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); |
| 4631 __ movss(operand, xmm_scratch); | 4605 __ movss(operand, xmm_scratch); |
| 4632 } else { | 4606 } else { |
| 4633 __ fld(0); | 4607 __ fld(0); |
| 4634 __ fstp_s(operand); | 4608 __ fstp_s(operand); |
| 4635 } | 4609 } |
| 4636 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4610 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 4637 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4611 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 4638 CpuFeatureScope scope(masm(), SSE2); | 4612 CpuFeatureScope scope(masm(), SSE2); |
| 4639 __ movdbl(operand, ToDoubleRegister(instr->value())); | 4613 __ movsd(operand, ToDoubleRegister(instr->value())); |
| 4640 } else { | 4614 } else { |
| 4641 X87Mov(operand, ToX87Register(instr->value())); | 4615 X87Mov(operand, ToX87Register(instr->value())); |
| 4642 } | 4616 } |
| 4643 } else { | 4617 } else { |
| 4644 Register value = ToRegister(instr->value()); | 4618 Register value = ToRegister(instr->value()); |
| 4645 switch (elements_kind) { | 4619 switch (elements_kind) { |
| 4646 case EXTERNAL_PIXEL_ELEMENTS: | 4620 case EXTERNAL_PIXEL_ELEMENTS: |
| 4647 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 4621 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 4648 case EXTERNAL_BYTE_ELEMENTS: | 4622 case EXTERNAL_BYTE_ELEMENTS: |
| 4649 __ mov_b(operand, value); | 4623 __ mov_b(operand, value); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4687 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4661 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 4688 CpuFeatureScope scope(masm(), SSE2); | 4662 CpuFeatureScope scope(masm(), SSE2); |
| 4689 XMMRegister value = ToDoubleRegister(instr->value()); | 4663 XMMRegister value = ToDoubleRegister(instr->value()); |
| 4690 | 4664 |
| 4691 if (instr->NeedsCanonicalization()) { | 4665 if (instr->NeedsCanonicalization()) { |
| 4692 Label have_value; | 4666 Label have_value; |
| 4693 | 4667 |
| 4694 __ ucomisd(value, value); | 4668 __ ucomisd(value, value); |
| 4695 __ j(parity_odd, &have_value); // NaN. | 4669 __ j(parity_odd, &have_value); // NaN. |
| 4696 | 4670 |
| 4697 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); | 4671 __ movsd(value, Operand::StaticVariable(canonical_nan_reference)); |
| 4698 __ bind(&have_value); | 4672 __ bind(&have_value); |
| 4699 } | 4673 } |
| 4700 | 4674 |
| 4701 __ movdbl(double_store_operand, value); | 4675 __ movsd(double_store_operand, value); |
| 4702 } else { | 4676 } else { |
| 4703 // Can't use SSE2 in the serializer | 4677 // Can't use SSE2 in the serializer |
| 4704 if (instr->hydrogen()->IsConstantHoleStore()) { | 4678 if (instr->hydrogen()->IsConstantHoleStore()) { |
| 4705 // This means we should store the (double) hole. No floating point | 4679 // This means we should store the (double) hole. No floating point |
| 4706 // registers required. | 4680 // registers required. |
| 4707 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 4681 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
| 4708 uint64_t int_val = BitCast<uint64_t, double>(nan_double); | 4682 uint64_t int_val = BitCast<uint64_t, double>(nan_double); |
| 4709 int32_t lower = static_cast<int32_t>(int_val); | 4683 int32_t lower = static_cast<int32_t>(int_val); |
| 4710 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); | 4684 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); |
| 4711 | 4685 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4814 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 4788 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| 4815 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 4789 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 4816 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 4790 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 4817 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4791 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 4818 } | 4792 } |
| 4819 | 4793 |
| 4820 | 4794 |
| 4821 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { | 4795 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { |
| 4822 Register object = ToRegister(instr->object()); | 4796 Register object = ToRegister(instr->object()); |
| 4823 Register temp = ToRegister(instr->temp()); | 4797 Register temp = ToRegister(instr->temp()); |
| 4824 __ TestJSArrayForAllocationMemento(object, temp); | 4798 Label no_memento_found; |
| 4799 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); |
| 4825 DeoptimizeIf(equal, instr->environment()); | 4800 DeoptimizeIf(equal, instr->environment()); |
| 4801 __ bind(&no_memento_found); |
| 4826 } | 4802 } |
| 4827 | 4803 |
| 4828 | 4804 |
| 4829 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { | 4805 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
| 4830 Register object_reg = ToRegister(instr->object()); | 4806 Register object_reg = ToRegister(instr->object()); |
| 4831 | 4807 |
| 4832 Handle<Map> from_map = instr->original_map(); | 4808 Handle<Map> from_map = instr->original_map(); |
| 4833 Handle<Map> to_map = instr->transitioned_map(); | 4809 Handle<Map> to_map = instr->transitioned_map(); |
| 4834 ElementsKind from_kind = instr->from_kind(); | 4810 ElementsKind from_kind = instr->from_kind(); |
| 4835 ElementsKind to_kind = instr->to_kind(); | 4811 ElementsKind to_kind = instr->to_kind(); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5029 ToDoubleRegister(temp)); | 5005 ToDoubleRegister(temp)); |
| 5030 } else { | 5006 } else { |
| 5031 X87Register res = ToX87Register(output); | 5007 X87Register res = ToX87Register(output); |
| 5032 X87PrepareToWrite(res); | 5008 X87PrepareToWrite(res); |
| 5033 __ LoadUint32NoSSE2(ToRegister(input)); | 5009 __ LoadUint32NoSSE2(ToRegister(input)); |
| 5034 X87CommitWrite(res); | 5010 X87CommitWrite(res); |
| 5035 } | 5011 } |
| 5036 } | 5012 } |
| 5037 | 5013 |
| 5038 | 5014 |
| 5015 void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) { |
| 5016 Register input = ToRegister(instr->value()); |
| 5017 if (!instr->hydrogen()->value()->HasRange() || |
| 5018 !instr->hydrogen()->value()->range()->IsInSmiRange()) { |
| 5019 __ test(input, Immediate(0xc0000000)); |
| 5020 DeoptimizeIf(not_zero, instr->environment()); |
| 5021 } |
| 5022 __ SmiTag(input); |
| 5023 } |
| 5024 |
| 5025 |
| 5039 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 5026 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| 5040 class DeferredNumberTagI V8_FINAL : public LDeferredCode { | 5027 class DeferredNumberTagI V8_FINAL : public LDeferredCode { |
| 5041 public: | 5028 public: |
| 5042 DeferredNumberTagI(LCodeGen* codegen, | 5029 DeferredNumberTagI(LCodeGen* codegen, |
| 5043 LNumberTagI* instr, | 5030 LNumberTagI* instr, |
| 5044 const X87Stack& x87_stack) | 5031 const X87Stack& x87_stack) |
| 5045 : LDeferredCode(codegen, x87_stack), instr_(instr) { } | 5032 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
| 5046 virtual void Generate() V8_OVERRIDE { | 5033 virtual void Generate() V8_OVERRIDE { |
| 5047 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32); | 5034 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32); |
| 5048 } | 5035 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5155 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 5142 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 5156 RecordSafepointWithRegisters( | 5143 RecordSafepointWithRegisters( |
| 5157 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 5144 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 5158 if (!reg.is(eax)) __ mov(reg, eax); | 5145 if (!reg.is(eax)) __ mov(reg, eax); |
| 5159 | 5146 |
| 5160 // Done. Put the value in xmm_scratch into the value of the allocated heap | 5147 // Done. Put the value in xmm_scratch into the value of the allocated heap |
| 5161 // number. | 5148 // number. |
| 5162 __ bind(&done); | 5149 __ bind(&done); |
| 5163 if (CpuFeatures::IsSupported(SSE2)) { | 5150 if (CpuFeatures::IsSupported(SSE2)) { |
| 5164 CpuFeatureScope feature_scope(masm(), SSE2); | 5151 CpuFeatureScope feature_scope(masm(), SSE2); |
| 5165 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch); | 5152 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch); |
| 5166 } else { | 5153 } else { |
| 5167 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 5154 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
| 5168 } | 5155 } |
| 5169 __ StoreToSafepointRegisterSlot(reg, reg); | 5156 __ StoreToSafepointRegisterSlot(reg, reg); |
| 5170 } | 5157 } |
| 5171 | 5158 |
| 5172 | 5159 |
| 5173 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 5160 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
| 5174 class DeferredNumberTagD V8_FINAL : public LDeferredCode { | 5161 class DeferredNumberTagD V8_FINAL : public LDeferredCode { |
| 5175 public: | 5162 public: |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5199 if (FLAG_inline_new) { | 5186 if (FLAG_inline_new) { |
| 5200 Register tmp = ToRegister(instr->temp()); | 5187 Register tmp = ToRegister(instr->temp()); |
| 5201 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); | 5188 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); |
| 5202 } else { | 5189 } else { |
| 5203 __ jmp(deferred->entry()); | 5190 __ jmp(deferred->entry()); |
| 5204 } | 5191 } |
| 5205 __ bind(deferred->exit()); | 5192 __ bind(deferred->exit()); |
| 5206 if (use_sse2) { | 5193 if (use_sse2) { |
| 5207 CpuFeatureScope scope(masm(), SSE2); | 5194 CpuFeatureScope scope(masm(), SSE2); |
| 5208 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 5195 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 5209 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); | 5196 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); |
| 5210 } else { | 5197 } else { |
| 5211 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 5198 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
| 5212 } | 5199 } |
| 5213 } | 5200 } |
| 5214 | 5201 |
| 5215 | 5202 |
| 5216 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 5203 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
| 5217 // TODO(3095996): Get rid of this. For now, we need to make the | 5204 // TODO(3095996): Get rid of this. For now, we need to make the |
| 5218 // result register contain a valid pointer because it is already | 5205 // result register contain a valid pointer because it is already |
| 5219 // contained in the register pointer map. | 5206 // contained in the register pointer map. |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5342 // Heap number map check. | 5329 // Heap number map check. |
| 5343 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 5330 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 5344 factory()->heap_number_map()); | 5331 factory()->heap_number_map()); |
| 5345 if (can_convert_undefined_to_nan) { | 5332 if (can_convert_undefined_to_nan) { |
| 5346 __ j(not_equal, &convert, Label::kNear); | 5333 __ j(not_equal, &convert, Label::kNear); |
| 5347 } else { | 5334 } else { |
| 5348 DeoptimizeIf(not_equal, env); | 5335 DeoptimizeIf(not_equal, env); |
| 5349 } | 5336 } |
| 5350 | 5337 |
| 5351 // Heap number to XMM conversion. | 5338 // Heap number to XMM conversion. |
| 5352 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 5339 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 5353 | 5340 |
| 5354 if (deoptimize_on_minus_zero) { | 5341 if (deoptimize_on_minus_zero) { |
| 5355 XMMRegister xmm_scratch = double_scratch0(); | 5342 XMMRegister xmm_scratch = double_scratch0(); |
| 5356 __ xorps(xmm_scratch, xmm_scratch); | 5343 __ xorps(xmm_scratch, xmm_scratch); |
| 5357 __ ucomisd(result_reg, xmm_scratch); | 5344 __ ucomisd(result_reg, xmm_scratch); |
| 5358 __ j(not_zero, &done, Label::kNear); | 5345 __ j(not_zero, &done, Label::kNear); |
| 5359 __ movmskpd(temp_reg, result_reg); | 5346 __ movmskpd(temp_reg, result_reg); |
| 5360 __ test_b(temp_reg, 1); | 5347 __ test_b(temp_reg, 1); |
| 5361 DeoptimizeIf(not_zero, env); | 5348 DeoptimizeIf(not_zero, env); |
| 5362 } | 5349 } |
| 5363 __ jmp(&done, Label::kNear); | 5350 __ jmp(&done, Label::kNear); |
| 5364 | 5351 |
| 5365 if (can_convert_undefined_to_nan) { | 5352 if (can_convert_undefined_to_nan) { |
| 5366 __ bind(&convert); | 5353 __ bind(&convert); |
| 5367 | 5354 |
| 5368 // Convert undefined (and hole) to NaN. | 5355 // Convert undefined (and hole) to NaN. |
| 5369 __ cmp(input_reg, factory()->undefined_value()); | 5356 __ cmp(input_reg, factory()->undefined_value()); |
| 5370 DeoptimizeIf(not_equal, env); | 5357 DeoptimizeIf(not_equal, env); |
| 5371 | 5358 |
| 5372 ExternalReference nan = | 5359 ExternalReference nan = |
| 5373 ExternalReference::address_of_canonical_non_hole_nan(); | 5360 ExternalReference::address_of_canonical_non_hole_nan(); |
| 5374 __ movdbl(result_reg, Operand::StaticVariable(nan)); | 5361 __ movsd(result_reg, Operand::StaticVariable(nan)); |
| 5375 __ jmp(&done, Label::kNear); | 5362 __ jmp(&done, Label::kNear); |
| 5376 } | 5363 } |
| 5377 } else { | 5364 } else { |
| 5378 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); | 5365 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); |
| 5379 } | 5366 } |
| 5380 | 5367 |
| 5381 __ bind(&load_smi); | 5368 __ bind(&load_smi); |
| 5382 // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the | 5369 // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the |
| 5383 // input register since we avoid dependencies. | 5370 // input register since we avoid dependencies. |
| 5384 __ mov(temp_reg, input_reg); | 5371 __ mov(temp_reg, input_reg); |
| 5385 __ SmiUntag(temp_reg); // Untag smi before converting to float. | 5372 __ SmiUntag(temp_reg); // Untag smi before converting to float. |
| 5386 __ Cvtsi2sd(result_reg, Operand(temp_reg)); | 5373 __ Cvtsi2sd(result_reg, Operand(temp_reg)); |
| 5387 __ bind(&done); | 5374 __ bind(&done); |
| 5388 } | 5375 } |
| 5389 | 5376 |
| 5390 | 5377 |
| 5391 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) { | 5378 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) { |
| 5392 Register input_reg = ToRegister(instr->value()); | 5379 Register input_reg = ToRegister(instr->value()); |
| 5393 | 5380 |
| 5394 | |
| 5395 if (instr->truncating()) { | 5381 if (instr->truncating()) { |
| 5396 Label heap_number, slow_case; | 5382 Label no_heap_number, check_bools, check_false; |
| 5397 | 5383 |
| 5398 // Heap number map check. | 5384 // Heap number map check. |
| 5399 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 5385 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 5400 factory()->heap_number_map()); | 5386 factory()->heap_number_map()); |
| 5401 __ j(equal, &heap_number, Label::kNear); | 5387 __ j(not_equal, &no_heap_number, Label::kNear); |
| 5388 __ TruncateHeapNumberToI(input_reg, input_reg); |
| 5389 __ jmp(done); |
| 5402 | 5390 |
| 5403 // Check for undefined. Undefined is converted to zero for truncating | 5391 __ bind(&no_heap_number); |
| 5404 // conversions. | 5392 // Check for Oddballs. Undefined/False is converted to zero and True to one |
| 5393 // for truncating conversions. |
| 5405 __ cmp(input_reg, factory()->undefined_value()); | 5394 __ cmp(input_reg, factory()->undefined_value()); |
| 5395 __ j(not_equal, &check_bools, Label::kNear); |
| 5396 __ Set(input_reg, Immediate(0)); |
| 5397 __ jmp(done); |
| 5398 |
| 5399 __ bind(&check_bools); |
| 5400 __ cmp(input_reg, factory()->true_value()); |
| 5401 __ j(not_equal, &check_false, Label::kNear); |
| 5402 __ Set(input_reg, Immediate(1)); |
| 5403 __ jmp(done); |
| 5404 |
| 5405 __ bind(&check_false); |
| 5406 __ cmp(input_reg, factory()->false_value()); |
| 5406 __ RecordComment("Deferred TaggedToI: cannot truncate"); | 5407 __ RecordComment("Deferred TaggedToI: cannot truncate"); |
| 5407 DeoptimizeIf(not_equal, instr->environment()); | 5408 DeoptimizeIf(not_equal, instr->environment()); |
| 5408 __ mov(input_reg, 0); | 5409 __ Set(input_reg, Immediate(0)); |
| 5409 __ jmp(done); | 5410 __ jmp(done); |
| 5410 | |
| 5411 __ bind(&heap_number); | |
| 5412 __ TruncateHeapNumberToI(input_reg, input_reg); | |
| 5413 } else { | 5411 } else { |
| 5414 Label bailout; | 5412 Label bailout; |
| 5415 XMMRegister scratch = (instr->temp() != NULL) | 5413 XMMRegister scratch = (instr->temp() != NULL) |
| 5416 ? ToDoubleRegister(instr->temp()) | 5414 ? ToDoubleRegister(instr->temp()) |
| 5417 : no_xmm_reg; | 5415 : no_xmm_reg; |
| 5418 __ TaggedToI(input_reg, input_reg, scratch, | 5416 __ TaggedToI(input_reg, input_reg, scratch, |
| 5419 instr->hydrogen()->GetMinusZeroMode(), &bailout); | 5417 instr->hydrogen()->GetMinusZeroMode(), &bailout); |
| 5420 __ jmp(done); | 5418 __ jmp(done); |
| 5421 __ bind(&bailout); | 5419 __ bind(&bailout); |
| 5422 DeoptimizeIf(no_condition, instr->environment()); | 5420 DeoptimizeIf(no_condition, instr->environment()); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5742 | 5740 |
| 5743 // Check for undefined. Undefined is converted to zero for clamping | 5741 // Check for undefined. Undefined is converted to zero for clamping |
| 5744 // conversions. | 5742 // conversions. |
| 5745 __ cmp(input_reg, factory()->undefined_value()); | 5743 __ cmp(input_reg, factory()->undefined_value()); |
| 5746 DeoptimizeIf(not_equal, instr->environment()); | 5744 DeoptimizeIf(not_equal, instr->environment()); |
| 5747 __ mov(input_reg, 0); | 5745 __ mov(input_reg, 0); |
| 5748 __ jmp(&done, Label::kNear); | 5746 __ jmp(&done, Label::kNear); |
| 5749 | 5747 |
| 5750 // Heap number | 5748 // Heap number |
| 5751 __ bind(&heap_number); | 5749 __ bind(&heap_number); |
| 5752 __ movdbl(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 5750 __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 5753 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); | 5751 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); |
| 5754 __ jmp(&done, Label::kNear); | 5752 __ jmp(&done, Label::kNear); |
| 5755 | 5753 |
| 5756 // smi | 5754 // smi |
| 5757 __ bind(&is_smi); | 5755 __ bind(&is_smi); |
| 5758 __ SmiUntag(input_reg); | 5756 __ SmiUntag(input_reg); |
| 5759 __ ClampUint8(input_reg); | 5757 __ ClampUint8(input_reg); |
| 5760 __ bind(&done); | 5758 __ bind(&done); |
| 5761 } | 5759 } |
| 5762 | 5760 |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6391 FixedArray::kHeaderSize - kPointerSize)); | 6389 FixedArray::kHeaderSize - kPointerSize)); |
| 6392 __ bind(&done); | 6390 __ bind(&done); |
| 6393 } | 6391 } |
| 6394 | 6392 |
| 6395 | 6393 |
| 6396 #undef __ | 6394 #undef __ |
| 6397 | 6395 |
| 6398 } } // namespace v8::internal | 6396 } } // namespace v8::internal |
| 6399 | 6397 |
| 6400 #endif // V8_TARGET_ARCH_IA32 | 6398 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |