Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(623)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 133443009: A64: Synchronize with r17441. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-gap-resolver-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-gap-resolver-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698