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

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

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again Created 7 years, 2 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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
3068 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3055 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3069 __ CallRuntime(Runtime::kTraceExit, 1); 3056 __ CallRuntime(Runtime::kTraceExit, 1);
3070 } 3057 }
3071 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { 3058 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) {
3072 ASSERT(NeedsEagerFrame()); 3059 ASSERT(NeedsEagerFrame());
3073 CpuFeatureScope scope(masm(), SSE2); 3060 CpuFeatureScope scope(masm(), SSE2);
3074 BitVector* doubles = chunk()->allocated_double_registers(); 3061 BitVector* doubles = chunk()->allocated_double_registers();
3075 BitVector::Iterator save_iterator(doubles); 3062 BitVector::Iterator save_iterator(doubles);
3076 int count = 0; 3063 int count = 0;
3077 while (!save_iterator.Done()) { 3064 while (!save_iterator.Done()) {
3078 __ movdbl(XMMRegister::FromAllocationIndex(save_iterator.Current()), 3065 __ movsd(XMMRegister::FromAllocationIndex(save_iterator.Current()),
3079 MemOperand(esp, count * kDoubleSize)); 3066 MemOperand(esp, count * kDoubleSize));
3080 save_iterator.Advance(); 3067 save_iterator.Advance();
3081 count++; 3068 count++;
3082 } 3069 }
3083 } 3070 }
3084 if (dynamic_frame_alignment_) { 3071 if (dynamic_frame_alignment_) {
3085 // Fetch the state of the dynamic frame alignment. 3072 // Fetch the state of the dynamic frame alignment.
3086 __ mov(edx, Operand(ebp, 3073 __ mov(edx, Operand(ebp,
3087 JavaScriptFrameConstants::kDynamicAlignmentStateOffset)); 3074 JavaScriptFrameConstants::kDynamicAlignmentStateOffset));
3088 } 3075 }
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
3236 } 3223 }
3237 return; 3224 return;
3238 } 3225 }
3239 3226
3240 Register object = ToRegister(instr->object()); 3227 Register object = ToRegister(instr->object());
3241 if (FLAG_track_double_fields && 3228 if (FLAG_track_double_fields &&
3242 instr->hydrogen()->representation().IsDouble()) { 3229 instr->hydrogen()->representation().IsDouble()) {
3243 if (CpuFeatures::IsSupported(SSE2)) { 3230 if (CpuFeatures::IsSupported(SSE2)) {
3244 CpuFeatureScope scope(masm(), SSE2); 3231 CpuFeatureScope scope(masm(), SSE2);
3245 XMMRegister result = ToDoubleRegister(instr->result()); 3232 XMMRegister result = ToDoubleRegister(instr->result());
3246 __ movdbl(result, FieldOperand(object, offset)); 3233 __ movsd(result, FieldOperand(object, offset));
3247 } else { 3234 } else {
3248 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); 3235 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset));
3249 } 3236 }
3250 return; 3237 return;
3251 } 3238 }
3252 3239
3253 Register result = ToRegister(instr->result()); 3240 Register result = ToRegister(instr->result());
3254 if (!access.IsInobject()) { 3241 if (!access.IsInobject()) {
3255 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); 3242 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
3256 object = result; 3243 object = result;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
3390 CpuFeatureScope scope(masm(), SSE2); 3377 CpuFeatureScope scope(masm(), SSE2);
3391 XMMRegister result(ToDoubleRegister(instr->result())); 3378 XMMRegister result(ToDoubleRegister(instr->result()));
3392 __ movss(result, operand); 3379 __ movss(result, operand);
3393 __ cvtss2sd(result, result); 3380 __ cvtss2sd(result, result);
3394 } else { 3381 } else {
3395 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); 3382 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand);
3396 } 3383 }
3397 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3384 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3398 if (CpuFeatures::IsSupported(SSE2)) { 3385 if (CpuFeatures::IsSupported(SSE2)) {
3399 CpuFeatureScope scope(masm(), SSE2); 3386 CpuFeatureScope scope(masm(), SSE2);
3400 __ movdbl(ToDoubleRegister(instr->result()), operand); 3387 __ movsd(ToDoubleRegister(instr->result()), operand);
3401 } else { 3388 } else {
3402 X87Mov(ToX87Register(instr->result()), operand); 3389 X87Mov(ToX87Register(instr->result()), operand);
3403 } 3390 }
3404 } else { 3391 } else {
3405 Register result(ToRegister(instr->result())); 3392 Register result(ToRegister(instr->result()));
3406 switch (elements_kind) { 3393 switch (elements_kind) {
3407 case EXTERNAL_BYTE_ELEMENTS: 3394 case EXTERNAL_BYTE_ELEMENTS:
3408 __ movsx_b(result, operand); 3395 __ movsx_b(result, operand);
3409 break; 3396 break;
3410 case EXTERNAL_PIXEL_ELEMENTS: 3397 case EXTERNAL_PIXEL_ELEMENTS:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3461 Operand double_load_operand = BuildFastArrayOperand( 3448 Operand double_load_operand = BuildFastArrayOperand(
3462 instr->elements(), 3449 instr->elements(),
3463 instr->key(), 3450 instr->key(),
3464 instr->hydrogen()->key()->representation(), 3451 instr->hydrogen()->key()->representation(),
3465 FAST_DOUBLE_ELEMENTS, 3452 FAST_DOUBLE_ELEMENTS,
3466 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 3453 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3467 instr->additional_index()); 3454 instr->additional_index());
3468 if (CpuFeatures::IsSupported(SSE2)) { 3455 if (CpuFeatures::IsSupported(SSE2)) {
3469 CpuFeatureScope scope(masm(), SSE2); 3456 CpuFeatureScope scope(masm(), SSE2);
3470 XMMRegister result = ToDoubleRegister(instr->result()); 3457 XMMRegister result = ToDoubleRegister(instr->result());
3471 __ movdbl(result, double_load_operand); 3458 __ movsd(result, double_load_operand);
3472 } else { 3459 } else {
3473 X87Mov(ToX87Register(instr->result()), double_load_operand); 3460 X87Mov(ToX87Register(instr->result()), double_load_operand);
3474 } 3461 }
3475 } 3462 }
3476 3463
3477 3464
3478 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3465 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3479 Register result = ToRegister(instr->result()); 3466 Register result = ToRegister(instr->result());
3480 3467
3481 // Load the result. 3468 // Load the result.
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
3678 __ j(zero, &invoke, Label::kNear); 3665 __ j(zero, &invoke, Label::kNear);
3679 __ bind(&loop); 3666 __ bind(&loop);
3680 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); 3667 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
3681 __ dec(length); 3668 __ dec(length);
3682 __ j(not_zero, &loop); 3669 __ j(not_zero, &loop);
3683 3670
3684 // Invoke the function. 3671 // Invoke the function.
3685 __ bind(&invoke); 3672 __ bind(&invoke);
3686 ASSERT(instr->HasPointerMap()); 3673 ASSERT(instr->HasPointerMap());
3687 LPointerMap* pointers = instr->pointer_map(); 3674 LPointerMap* pointers = instr->pointer_map();
3688 RecordPosition(pointers->position());
3689 SafepointGenerator safepoint_generator( 3675 SafepointGenerator safepoint_generator(
3690 this, pointers, Safepoint::kLazyDeopt); 3676 this, pointers, Safepoint::kLazyDeopt);
3691 ParameterCount actual(eax); 3677 ParameterCount actual(eax);
3692 __ InvokeFunction(function, actual, CALL_FUNCTION, 3678 __ InvokeFunction(function, actual, CALL_FUNCTION,
3693 safepoint_generator, CALL_AS_METHOD); 3679 safepoint_generator, CALL_AS_METHOD);
3694 } 3680 }
3695 3681
3696 3682
3697 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 3683 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
3698 __ int3(); 3684 __ int3();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3763 int formal_parameter_count, 3749 int formal_parameter_count,
3764 int arity, 3750 int arity,
3765 LInstruction* instr, 3751 LInstruction* instr,
3766 CallKind call_kind, 3752 CallKind call_kind,
3767 EDIState edi_state) { 3753 EDIState edi_state) {
3768 bool dont_adapt_arguments = 3754 bool dont_adapt_arguments =
3769 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3755 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3770 bool can_invoke_directly = 3756 bool can_invoke_directly =
3771 dont_adapt_arguments || formal_parameter_count == arity; 3757 dont_adapt_arguments || formal_parameter_count == arity;
3772 3758
3773 LPointerMap* pointers = instr->pointer_map();
3774 RecordPosition(pointers->position());
3775
3776 if (can_invoke_directly) { 3759 if (can_invoke_directly) {
3777 if (edi_state == EDI_UNINITIALIZED) { 3760 if (edi_state == EDI_UNINITIALIZED) {
3778 __ LoadHeapObject(edi, function); 3761 __ LoadHeapObject(edi, function);
3779 } 3762 }
3780 3763
3781 // Change context. 3764 // Change context.
3782 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 3765 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
3783 3766
3784 // 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
3785 // is available to write to at this point. 3768 // is available to write to at this point.
3786 if (dont_adapt_arguments) { 3769 if (dont_adapt_arguments) {
3787 __ mov(eax, arity); 3770 __ mov(eax, arity);
3788 } 3771 }
3789 3772
3790 // Invoke function directly. 3773 // Invoke function directly.
3791 __ SetCallKind(ecx, call_kind); 3774 __ SetCallKind(ecx, call_kind);
3792 if (function.is_identical_to(info()->closure())) { 3775 if (function.is_identical_to(info()->closure())) {
3793 __ CallSelf(); 3776 __ CallSelf();
3794 } else { 3777 } else {
3795 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); 3778 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset));
3796 } 3779 }
3797 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 3780 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3798 } else { 3781 } else {
3799 // We need to adapt arguments. 3782 // We need to adapt arguments.
3783 LPointerMap* pointers = instr->pointer_map();
3800 SafepointGenerator generator( 3784 SafepointGenerator generator(
3801 this, pointers, Safepoint::kLazyDeopt); 3785 this, pointers, Safepoint::kLazyDeopt);
3802 ParameterCount count(arity); 3786 ParameterCount count(arity);
3803 ParameterCount expected(formal_parameter_count); 3787 ParameterCount expected(formal_parameter_count);
3804 __ InvokeFunction( 3788 __ InvokeFunction(
3805 function, expected, count, CALL_FUNCTION, generator, call_kind); 3789 function, expected, count, CALL_FUNCTION, generator, call_kind);
3806 } 3790 }
3807 } 3791 }
3808 3792
3809 3793
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
3984 CpuFeatureScope scope(masm(), SSE2); 3968 CpuFeatureScope scope(masm(), SSE2);
3985 Register output_reg = ToRegister(instr->result()); 3969 Register output_reg = ToRegister(instr->result());
3986 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3970 XMMRegister input_reg = ToDoubleRegister(instr->value());
3987 XMMRegister xmm_scratch = double_scratch0(); 3971 XMMRegister xmm_scratch = double_scratch0();
3988 XMMRegister input_temp = ToDoubleRegister(instr->temp()); 3972 XMMRegister input_temp = ToDoubleRegister(instr->temp());
3989 ExternalReference one_half = ExternalReference::address_of_one_half(); 3973 ExternalReference one_half = ExternalReference::address_of_one_half();
3990 ExternalReference minus_one_half = 3974 ExternalReference minus_one_half =
3991 ExternalReference::address_of_minus_one_half(); 3975 ExternalReference::address_of_minus_one_half();
3992 3976
3993 Label done, round_to_zero, below_one_half, do_not_compensate; 3977 Label done, round_to_zero, below_one_half, do_not_compensate;
3994 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 3978 __ movsd(xmm_scratch, Operand::StaticVariable(one_half));
3995 __ ucomisd(xmm_scratch, input_reg); 3979 __ ucomisd(xmm_scratch, input_reg);
3996 __ j(above, &below_one_half); 3980 __ j(above, &below_one_half);
3997 3981
3998 // 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).
3999 __ addsd(xmm_scratch, input_reg); 3983 __ addsd(xmm_scratch, input_reg);
4000 __ cvttsd2si(output_reg, Operand(xmm_scratch)); 3984 __ cvttsd2si(output_reg, Operand(xmm_scratch));
4001 // Overflow is signalled with minint. 3985 // Overflow is signalled with minint.
4002 __ cmp(output_reg, 0x80000000u); 3986 __ cmp(output_reg, 0x80000000u);
4003 __ RecordComment("D2I conversion overflow"); 3987 __ RecordComment("D2I conversion overflow");
4004 DeoptimizeIf(equal, instr->environment()); 3988 DeoptimizeIf(equal, instr->environment());
4005 __ jmp(&done); 3989 __ jmp(&done);
4006 3990
4007 __ bind(&below_one_half); 3991 __ bind(&below_one_half);
4008 __ movdbl(xmm_scratch, Operand::StaticVariable(minus_one_half)); 3992 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half));
4009 __ ucomisd(xmm_scratch, input_reg); 3993 __ ucomisd(xmm_scratch, input_reg);
4010 __ j(below_equal, &round_to_zero); 3994 __ j(below_equal, &round_to_zero);
4011 3995
4012 // 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
4013 // compare and compensate. 3997 // compare and compensate.
4014 __ movsd(input_temp, input_reg); // Do not alter input_reg. 3998 __ movsd(input_temp, input_reg); // Do not alter input_reg.
4015 __ subsd(input_temp, xmm_scratch); 3999 __ subsd(input_temp, xmm_scratch);
4016 __ cvttsd2si(output_reg, Operand(input_temp)); 4000 __ cvttsd2si(output_reg, Operand(input_temp));
4017 // Catch minint due to overflow, and to prevent overflow when compensating. 4001 // Catch minint due to overflow, and to prevent overflow when compensating.
4018 __ cmp(output_reg, 0x80000000u); 4002 __ cmp(output_reg, 0x80000000u);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
4185 ASSERT(instr->value()->Equals(instr->result())); 4169 ASSERT(instr->value()->Equals(instr->result()));
4186 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4170 XMMRegister input_reg = ToDoubleRegister(instr->value());
4187 XMMRegister xmm_scratch = double_scratch0(); 4171 XMMRegister xmm_scratch = double_scratch0();
4188 Label positive, done, zero; 4172 Label positive, done, zero;
4189 __ xorps(xmm_scratch, xmm_scratch); 4173 __ xorps(xmm_scratch, xmm_scratch);
4190 __ ucomisd(input_reg, xmm_scratch); 4174 __ ucomisd(input_reg, xmm_scratch);
4191 __ j(above, &positive, Label::kNear); 4175 __ j(above, &positive, Label::kNear);
4192 __ j(equal, &zero, Label::kNear); 4176 __ j(equal, &zero, Label::kNear);
4193 ExternalReference nan = 4177 ExternalReference nan =
4194 ExternalReference::address_of_canonical_non_hole_nan(); 4178 ExternalReference::address_of_canonical_non_hole_nan();
4195 __ movdbl(input_reg, Operand::StaticVariable(nan)); 4179 __ movsd(input_reg, Operand::StaticVariable(nan));
4196 __ jmp(&done, Label::kNear); 4180 __ jmp(&done, Label::kNear);
4197 __ bind(&zero); 4181 __ bind(&zero);
4198 __ push(Immediate(0xFFF00000)); 4182 ExternalReference ninf =
4199 __ push(Immediate(0)); 4183 ExternalReference::address_of_negative_infinity();
4200 __ movdbl(input_reg, Operand(esp, 0)); 4184 __ movsd(input_reg, Operand::StaticVariable(ninf));
4201 __ add(Operand(esp), Immediate(kDoubleSize));
4202 __ jmp(&done, Label::kNear); 4185 __ jmp(&done, Label::kNear);
4203 __ bind(&positive); 4186 __ bind(&positive);
4204 __ fldln2(); 4187 __ fldln2();
4205 __ sub(Operand(esp), Immediate(kDoubleSize)); 4188 __ sub(Operand(esp), Immediate(kDoubleSize));
4206 __ movdbl(Operand(esp, 0), input_reg); 4189 __ movsd(Operand(esp, 0), input_reg);
4207 __ fld_d(Operand(esp, 0)); 4190 __ fld_d(Operand(esp, 0));
4208 __ fyl2x(); 4191 __ fyl2x();
4209 __ fstp_d(Operand(esp, 0)); 4192 __ fstp_d(Operand(esp, 0));
4210 __ movdbl(input_reg, Operand(esp, 0)); 4193 __ movsd(input_reg, Operand(esp, 0));
4211 __ add(Operand(esp), Immediate(kDoubleSize)); 4194 __ add(Operand(esp), Immediate(kDoubleSize));
4212 __ bind(&done); 4195 __ bind(&done);
4213 } 4196 }
4214 4197
4215 4198
4216 void LCodeGen::DoMathExp(LMathExp* instr) { 4199 void LCodeGen::DoMathExp(LMathExp* instr) {
4217 CpuFeatureScope scope(masm(), SSE2); 4200 CpuFeatureScope scope(masm(), SSE2);
4218 XMMRegister input = ToDoubleRegister(instr->value()); 4201 XMMRegister input = ToDoubleRegister(instr->value());
4219 XMMRegister result = ToDoubleRegister(instr->result()); 4202 XMMRegister result = ToDoubleRegister(instr->result());
4220 XMMRegister temp0 = double_scratch0(); 4203 XMMRegister temp0 = double_scratch0();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4259 4242
4260 4243
4261 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 4244 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
4262 ASSERT(ToRegister(instr->context()).is(esi)); 4245 ASSERT(ToRegister(instr->context()).is(esi));
4263 ASSERT(ToRegister(instr->function()).is(edi)); 4246 ASSERT(ToRegister(instr->function()).is(edi));
4264 ASSERT(instr->HasPointerMap()); 4247 ASSERT(instr->HasPointerMap());
4265 4248
4266 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 4249 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
4267 if (known_function.is_null()) { 4250 if (known_function.is_null()) {
4268 LPointerMap* pointers = instr->pointer_map(); 4251 LPointerMap* pointers = instr->pointer_map();
4269 RecordPosition(pointers->position());
4270 SafepointGenerator generator( 4252 SafepointGenerator generator(
4271 this, pointers, Safepoint::kLazyDeopt); 4253 this, pointers, Safepoint::kLazyDeopt);
4272 ParameterCount count(instr->arity()); 4254 ParameterCount count(instr->arity());
4273 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 4255 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
4274 } else { 4256 } else {
4275 CallKnownFunction(known_function, 4257 CallKnownFunction(known_function,
4276 instr->hydrogen()->formal_parameter_count(), 4258 instr->hydrogen()->formal_parameter_count(),
4277 instr->arity(), 4259 instr->arity(),
4278 instr, 4260 instr,
4279 CALL_AS_METHOD, 4261 CALL_AS_METHOD,
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
4471 DeoptimizeIf(zero, instr->environment()); 4453 DeoptimizeIf(zero, instr->environment());
4472 } 4454 }
4473 } 4455 }
4474 } else if (FLAG_track_double_fields && representation.IsDouble()) { 4456 } else if (FLAG_track_double_fields && representation.IsDouble()) {
4475 ASSERT(transition.is_null()); 4457 ASSERT(transition.is_null());
4476 ASSERT(access.IsInobject()); 4458 ASSERT(access.IsInobject());
4477 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4459 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4478 if (CpuFeatures::IsSupported(SSE2)) { 4460 if (CpuFeatures::IsSupported(SSE2)) {
4479 CpuFeatureScope scope(masm(), SSE2); 4461 CpuFeatureScope scope(masm(), SSE2);
4480 XMMRegister value = ToDoubleRegister(instr->value()); 4462 XMMRegister value = ToDoubleRegister(instr->value());
4481 __ movdbl(FieldOperand(object, offset), value); 4463 __ movsd(FieldOperand(object, offset), value);
4482 } else { 4464 } else {
4483 X87Register value = ToX87Register(instr->value()); 4465 X87Register value = ToX87Register(instr->value());
4484 X87Mov(FieldOperand(object, offset), value); 4466 X87Mov(FieldOperand(object, offset), value);
4485 } 4467 }
4486 return; 4468 return;
4487 } 4469 }
4488 4470
4489 if (!transition.is_null()) { 4471 if (!transition.is_null()) {
4490 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 4472 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
4491 __ 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
4621 XMMRegister xmm_scratch = double_scratch0(); 4603 XMMRegister xmm_scratch = double_scratch0();
4622 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); 4604 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value()));
4623 __ movss(operand, xmm_scratch); 4605 __ movss(operand, xmm_scratch);
4624 } else { 4606 } else {
4625 __ fld(0); 4607 __ fld(0);
4626 __ fstp_s(operand); 4608 __ fstp_s(operand);
4627 } 4609 }
4628 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4610 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4629 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4611 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4630 CpuFeatureScope scope(masm(), SSE2); 4612 CpuFeatureScope scope(masm(), SSE2);
4631 __ movdbl(operand, ToDoubleRegister(instr->value())); 4613 __ movsd(operand, ToDoubleRegister(instr->value()));
4632 } else { 4614 } else {
4633 X87Mov(operand, ToX87Register(instr->value())); 4615 X87Mov(operand, ToX87Register(instr->value()));
4634 } 4616 }
4635 } else { 4617 } else {
4636 Register value = ToRegister(instr->value()); 4618 Register value = ToRegister(instr->value());
4637 switch (elements_kind) { 4619 switch (elements_kind) {
4638 case EXTERNAL_PIXEL_ELEMENTS: 4620 case EXTERNAL_PIXEL_ELEMENTS:
4639 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4621 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4640 case EXTERNAL_BYTE_ELEMENTS: 4622 case EXTERNAL_BYTE_ELEMENTS:
4641 __ mov_b(operand, value); 4623 __ mov_b(operand, value);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4679 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4661 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4680 CpuFeatureScope scope(masm(), SSE2); 4662 CpuFeatureScope scope(masm(), SSE2);
4681 XMMRegister value = ToDoubleRegister(instr->value()); 4663 XMMRegister value = ToDoubleRegister(instr->value());
4682 4664
4683 if (instr->NeedsCanonicalization()) { 4665 if (instr->NeedsCanonicalization()) {
4684 Label have_value; 4666 Label have_value;
4685 4667
4686 __ ucomisd(value, value); 4668 __ ucomisd(value, value);
4687 __ j(parity_odd, &have_value); // NaN. 4669 __ j(parity_odd, &have_value); // NaN.
4688 4670
4689 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); 4671 __ movsd(value, Operand::StaticVariable(canonical_nan_reference));
4690 __ bind(&have_value); 4672 __ bind(&have_value);
4691 } 4673 }
4692 4674
4693 __ movdbl(double_store_operand, value); 4675 __ movsd(double_store_operand, value);
4694 } else { 4676 } else {
4695 // Can't use SSE2 in the serializer 4677 // Can't use SSE2 in the serializer
4696 if (instr->hydrogen()->IsConstantHoleStore()) { 4678 if (instr->hydrogen()->IsConstantHoleStore()) {
4697 // This means we should store the (double) hole. No floating point 4679 // This means we should store the (double) hole. No floating point
4698 // registers required. 4680 // registers required.
4699 double nan_double = FixedDoubleArray::hole_nan_as_double(); 4681 double nan_double = FixedDoubleArray::hole_nan_as_double();
4700 uint64_t int_val = BitCast<uint64_t, double>(nan_double); 4682 uint64_t int_val = BitCast<uint64_t, double>(nan_double);
4701 int32_t lower = static_cast<int32_t>(int_val); 4683 int32_t lower = static_cast<int32_t>(int_val);
4702 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 4684 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
4703 4685
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
4806 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4788 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4807 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 4789 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
4808 : isolate()->builtins()->KeyedStoreIC_Initialize(); 4790 : isolate()->builtins()->KeyedStoreIC_Initialize();
4809 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4791 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4810 } 4792 }
4811 4793
4812 4794
4813 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4795 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4814 Register object = ToRegister(instr->object()); 4796 Register object = ToRegister(instr->object());
4815 Register temp = ToRegister(instr->temp()); 4797 Register temp = ToRegister(instr->temp());
4816 __ TestJSArrayForAllocationMemento(object, temp); 4798 Label no_memento_found;
4799 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
4817 DeoptimizeIf(equal, instr->environment()); 4800 DeoptimizeIf(equal, instr->environment());
4801 __ bind(&no_memento_found);
4818 } 4802 }
4819 4803
4820 4804
4821 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4805 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4822 Register object_reg = ToRegister(instr->object()); 4806 Register object_reg = ToRegister(instr->object());
4823 4807
4824 Handle<Map> from_map = instr->original_map(); 4808 Handle<Map> from_map = instr->original_map();
4825 Handle<Map> to_map = instr->transitioned_map(); 4809 Handle<Map> to_map = instr->transitioned_map();
4826 ElementsKind from_kind = instr->from_kind(); 4810 ElementsKind from_kind = instr->from_kind();
4827 ElementsKind to_kind = instr->to_kind(); 4811 ElementsKind to_kind = instr->to_kind();
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
5147 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 5131 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
5148 RecordSafepointWithRegisters( 5132 RecordSafepointWithRegisters(
5149 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 5133 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5150 if (!reg.is(eax)) __ mov(reg, eax); 5134 if (!reg.is(eax)) __ mov(reg, eax);
5151 5135
5152 // Done. Put the value in xmm_scratch into the value of the allocated heap 5136 // Done. Put the value in xmm_scratch into the value of the allocated heap
5153 // number. 5137 // number.
5154 __ bind(&done); 5138 __ bind(&done);
5155 if (CpuFeatures::IsSupported(SSE2)) { 5139 if (CpuFeatures::IsSupported(SSE2)) {
5156 CpuFeatureScope feature_scope(masm(), SSE2); 5140 CpuFeatureScope feature_scope(masm(), SSE2);
5157 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch); 5141 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch);
5158 } else { 5142 } else {
5159 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5143 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
5160 } 5144 }
5161 __ StoreToSafepointRegisterSlot(reg, reg); 5145 __ StoreToSafepointRegisterSlot(reg, reg);
5162 } 5146 }
5163 5147
5164 5148
5165 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 5149 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
5166 class DeferredNumberTagD V8_FINAL : public LDeferredCode { 5150 class DeferredNumberTagD V8_FINAL : public LDeferredCode {
5167 public: 5151 public:
(...skipping 23 matching lines...) Expand all
5191 if (FLAG_inline_new) { 5175 if (FLAG_inline_new) {
5192 Register tmp = ToRegister(instr->temp()); 5176 Register tmp = ToRegister(instr->temp());
5193 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 5177 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
5194 } else { 5178 } else {
5195 __ jmp(deferred->entry()); 5179 __ jmp(deferred->entry());
5196 } 5180 }
5197 __ bind(deferred->exit()); 5181 __ bind(deferred->exit());
5198 if (use_sse2) { 5182 if (use_sse2) {
5199 CpuFeatureScope scope(masm(), SSE2); 5183 CpuFeatureScope scope(masm(), SSE2);
5200 XMMRegister input_reg = ToDoubleRegister(instr->value()); 5184 XMMRegister input_reg = ToDoubleRegister(instr->value());
5201 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 5185 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
5202 } else { 5186 } else {
5203 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5187 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
5204 } 5188 }
5205 } 5189 }
5206 5190
5207 5191
5208 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 5192 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
5209 // TODO(3095996): Get rid of this. For now, we need to make the 5193 // TODO(3095996): Get rid of this. For now, we need to make the
5210 // result register contain a valid pointer because it is already 5194 // result register contain a valid pointer because it is already
5211 // contained in the register pointer map. 5195 // contained in the register pointer map.
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
5334 // Heap number map check. 5318 // Heap number map check.
5335 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5319 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5336 factory()->heap_number_map()); 5320 factory()->heap_number_map());
5337 if (can_convert_undefined_to_nan) { 5321 if (can_convert_undefined_to_nan) {
5338 __ j(not_equal, &convert, Label::kNear); 5322 __ j(not_equal, &convert, Label::kNear);
5339 } else { 5323 } else {
5340 DeoptimizeIf(not_equal, env); 5324 DeoptimizeIf(not_equal, env);
5341 } 5325 }
5342 5326
5343 // Heap number to XMM conversion. 5327 // Heap number to XMM conversion.
5344 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5328 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
5345 5329
5346 if (deoptimize_on_minus_zero) { 5330 if (deoptimize_on_minus_zero) {
5347 XMMRegister xmm_scratch = double_scratch0(); 5331 XMMRegister xmm_scratch = double_scratch0();
5348 __ xorps(xmm_scratch, xmm_scratch); 5332 __ xorps(xmm_scratch, xmm_scratch);
5349 __ ucomisd(result_reg, xmm_scratch); 5333 __ ucomisd(result_reg, xmm_scratch);
5350 __ j(not_zero, &done, Label::kNear); 5334 __ j(not_zero, &done, Label::kNear);
5351 __ movmskpd(temp_reg, result_reg); 5335 __ movmskpd(temp_reg, result_reg);
5352 __ test_b(temp_reg, 1); 5336 __ test_b(temp_reg, 1);
5353 DeoptimizeIf(not_zero, env); 5337 DeoptimizeIf(not_zero, env);
5354 } 5338 }
5355 __ jmp(&done, Label::kNear); 5339 __ jmp(&done, Label::kNear);
5356 5340
5357 if (can_convert_undefined_to_nan) { 5341 if (can_convert_undefined_to_nan) {
5358 __ bind(&convert); 5342 __ bind(&convert);
5359 5343
5360 // Convert undefined (and hole) to NaN. 5344 // Convert undefined (and hole) to NaN.
5361 __ cmp(input_reg, factory()->undefined_value()); 5345 __ cmp(input_reg, factory()->undefined_value());
5362 DeoptimizeIf(not_equal, env); 5346 DeoptimizeIf(not_equal, env);
5363 5347
5364 ExternalReference nan = 5348 ExternalReference nan =
5365 ExternalReference::address_of_canonical_non_hole_nan(); 5349 ExternalReference::address_of_canonical_non_hole_nan();
5366 __ movdbl(result_reg, Operand::StaticVariable(nan)); 5350 __ movsd(result_reg, Operand::StaticVariable(nan));
5367 __ jmp(&done, Label::kNear); 5351 __ jmp(&done, Label::kNear);
5368 } 5352 }
5369 } else { 5353 } else {
5370 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 5354 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
5371 } 5355 }
5372 5356
5373 __ bind(&load_smi); 5357 __ bind(&load_smi);
5374 // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the 5358 // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the
5375 // input register since we avoid dependencies. 5359 // input register since we avoid dependencies.
5376 __ mov(temp_reg, input_reg); 5360 __ mov(temp_reg, input_reg);
5377 __ SmiUntag(temp_reg); // Untag smi before converting to float. 5361 __ SmiUntag(temp_reg); // Untag smi before converting to float.
5378 __ Cvtsi2sd(result_reg, Operand(temp_reg)); 5362 __ Cvtsi2sd(result_reg, Operand(temp_reg));
5379 __ bind(&done); 5363 __ bind(&done);
5380 } 5364 }
5381 5365
5382 5366
5383 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) { 5367 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
5384 Register input_reg = ToRegister(instr->value()); 5368 Register input_reg = ToRegister(instr->value());
5385 5369
5386
5387 if (instr->truncating()) { 5370 if (instr->truncating()) {
5388 Label heap_number, slow_case; 5371 Label no_heap_number, check_bools, check_false;
5389 5372
5390 // Heap number map check. 5373 // Heap number map check.
5391 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5374 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5392 factory()->heap_number_map()); 5375 factory()->heap_number_map());
5393 __ j(equal, &heap_number, Label::kNear); 5376 __ j(not_equal, &no_heap_number, Label::kNear);
5377 __ TruncateHeapNumberToI(input_reg, input_reg);
5378 __ jmp(done);
5394 5379
5395 // Check for undefined. Undefined is converted to zero for truncating 5380 __ bind(&no_heap_number);
5396 // conversions. 5381 // Check for Oddballs. Undefined/False is converted to zero and True to one
5382 // for truncating conversions.
5397 __ cmp(input_reg, factory()->undefined_value()); 5383 __ cmp(input_reg, factory()->undefined_value());
5384 __ j(not_equal, &check_bools, Label::kNear);
5385 __ Set(input_reg, Immediate(0));
5386 __ jmp(done);
5387
5388 __ bind(&check_bools);
5389 __ cmp(input_reg, factory()->true_value());
5390 __ j(not_equal, &check_false, Label::kNear);
5391 __ Set(input_reg, Immediate(1));
5392 __ jmp(done);
5393
5394 __ bind(&check_false);
5395 __ cmp(input_reg, factory()->false_value());
5398 __ RecordComment("Deferred TaggedToI: cannot truncate"); 5396 __ RecordComment("Deferred TaggedToI: cannot truncate");
5399 DeoptimizeIf(not_equal, instr->environment()); 5397 DeoptimizeIf(not_equal, instr->environment());
5400 __ mov(input_reg, 0); 5398 __ Set(input_reg, Immediate(0));
5401 __ jmp(done); 5399 __ jmp(done);
5402
5403 __ bind(&heap_number);
5404 __ TruncateHeapNumberToI(input_reg, input_reg);
5405 } else { 5400 } else {
5406 Label bailout; 5401 Label bailout;
5407 XMMRegister scratch = (instr->temp() != NULL) 5402 XMMRegister scratch = (instr->temp() != NULL)
5408 ? ToDoubleRegister(instr->temp()) 5403 ? ToDoubleRegister(instr->temp())
5409 : no_xmm_reg; 5404 : no_xmm_reg;
5410 __ TaggedToI(input_reg, input_reg, scratch, 5405 __ TaggedToI(input_reg, input_reg, scratch,
5411 instr->hydrogen()->GetMinusZeroMode(), &bailout); 5406 instr->hydrogen()->GetMinusZeroMode(), &bailout);
5412 __ jmp(done); 5407 __ jmp(done);
5413 __ bind(&bailout); 5408 __ bind(&bailout);
5414 DeoptimizeIf(no_condition, instr->environment()); 5409 DeoptimizeIf(no_condition, instr->environment());
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
5734 5729
5735 // Check for undefined. Undefined is converted to zero for clamping 5730 // Check for undefined. Undefined is converted to zero for clamping
5736 // conversions. 5731 // conversions.
5737 __ cmp(input_reg, factory()->undefined_value()); 5732 __ cmp(input_reg, factory()->undefined_value());
5738 DeoptimizeIf(not_equal, instr->environment()); 5733 DeoptimizeIf(not_equal, instr->environment());
5739 __ mov(input_reg, 0); 5734 __ mov(input_reg, 0);
5740 __ jmp(&done, Label::kNear); 5735 __ jmp(&done, Label::kNear);
5741 5736
5742 // Heap number 5737 // Heap number
5743 __ bind(&heap_number); 5738 __ bind(&heap_number);
5744 __ movdbl(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5739 __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset));
5745 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); 5740 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg);
5746 __ jmp(&done, Label::kNear); 5741 __ jmp(&done, Label::kNear);
5747 5742
5748 // smi 5743 // smi
5749 __ bind(&is_smi); 5744 __ bind(&is_smi);
5750 __ SmiUntag(input_reg); 5745 __ SmiUntag(input_reg);
5751 __ ClampUint8(input_reg); 5746 __ ClampUint8(input_reg);
5752 __ bind(&done); 5747 __ bind(&done);
5753 } 5748 }
5754 5749
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
6383 FixedArray::kHeaderSize - kPointerSize)); 6378 FixedArray::kHeaderSize - kPointerSize));
6384 __ bind(&done); 6379 __ bind(&done);
6385 } 6380 }
6386 6381
6387 6382
6388 #undef __ 6383 #undef __
6389 6384
6390 } } // namespace v8::internal 6385 } } // namespace v8::internal
6391 6386
6392 #endif // V8_TARGET_ARCH_IA32 6387 #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