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

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

Issue 7277081: Straight-line code in DeferredTaggedToI (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 5 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 } 252 }
253 } 253 }
254 254
255 255
256 bool LCodeGen::GenerateDeferredCode() { 256 bool LCodeGen::GenerateDeferredCode() {
257 ASSERT(is_generating()); 257 ASSERT(is_generating());
258 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 258 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
259 LDeferredCode* code = deferred_[i]; 259 LDeferredCode* code = deferred_[i];
260 __ bind(code->entry()); 260 __ bind(code->entry());
261 code->Generate(); 261 code->Generate();
262 __ jmp(code->exit());
263 } 262 }
264 263
265 // Deferred code is the last part of the instruction sequence. Mark 264 // Deferred code is the last part of the instruction sequence. Mark
266 // the generated code as done unless we bailed out. 265 // the generated code as done unless we bailed out.
267 if (!is_aborted()) status_ = DONE; 266 if (!is_aborted()) status_ = DONE;
268 return !is_aborted(); 267 return !is_aborted();
269 } 268 }
270 269
271 270
272 bool LCodeGen::GenerateSafepointTable() { 271 bool LCodeGen::GenerateSafepointTable() {
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 break; 1457 break;
1459 case Token::IN: 1458 case Token::IN:
1460 case Token::INSTANCEOF: 1459 case Token::INSTANCEOF:
1461 default: 1460 default:
1462 UNREACHABLE(); 1461 UNREACHABLE();
1463 } 1462 }
1464 return cond; 1463 return cond;
1465 } 1464 }
1466 1465
1467 1466
1467 void LCodeGen::EmitPush(LOperand* operand) {
1468 if (operand->IsRegister()) {
1469 __ push(ToRegister(operand));
1470 } else if (operand->IsConstantOperand()) {
1471 __ push(ToImmediate(operand));
1472 } else {
1473 __ push(ToOperand(operand));
1474 }
1475 }
1476
1477
1468 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { 1478 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) {
1469 if (right->IsConstantOperand()) { 1479 if (right->IsConstantOperand()) {
1470 __ cmp(ToOperand(left), ToImmediate(right)); 1480 __ cmp(ToOperand(left), ToImmediate(right));
1471 } else { 1481 } else {
1472 __ cmp(ToRegister(left), ToOperand(right)); 1482 __ cmp(ToRegister(left), ToOperand(right));
1473 } 1483 }
1474 } 1484 }
1475 1485
1476 1486
1477 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1487 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1781 1791
1782 1792
1783 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 1793 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
1784 class DeferredInstanceOfKnownGlobal: public LDeferredCode { 1794 class DeferredInstanceOfKnownGlobal: public LDeferredCode {
1785 public: 1795 public:
1786 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 1796 DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
1787 LInstanceOfKnownGlobal* instr) 1797 LInstanceOfKnownGlobal* instr)
1788 : LDeferredCode(codegen), instr_(instr) { } 1798 : LDeferredCode(codegen), instr_(instr) { }
1789 virtual void Generate() { 1799 virtual void Generate() {
1790 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); 1800 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_);
1801 __ jmp(exit());
1791 } 1802 }
1792 1803
1793 Label* map_check() { return &map_check_; } 1804 Label* map_check() { return &map_check_; }
1794 1805
1795 private: 1806 private:
1796 LInstanceOfKnownGlobal* instr_; 1807 LInstanceOfKnownGlobal* instr_;
1797 Label map_check_; 1808 Label map_check_;
1798 }; 1809 };
1799 1810
1800 DeferredInstanceOfKnownGlobal* deferred; 1811 DeferredInstanceOfKnownGlobal* deferred;
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 pointers, 2438 pointers,
2428 env->deoptimization_index()); 2439 env->deoptimization_index());
2429 ParameterCount actual(eax); 2440 ParameterCount actual(eax);
2430 __ InvokeFunction(function, actual, CALL_FUNCTION, 2441 __ InvokeFunction(function, actual, CALL_FUNCTION,
2431 safepoint_generator, CALL_AS_METHOD); 2442 safepoint_generator, CALL_AS_METHOD);
2432 } 2443 }
2433 2444
2434 2445
2435 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2446 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2436 LOperand* argument = instr->InputAt(0); 2447 LOperand* argument = instr->InputAt(0);
2437 if (argument->IsConstantOperand()) { 2448 EmitPush(argument);
2438 __ push(ToImmediate(argument));
2439 } else {
2440 __ push(ToOperand(argument));
2441 }
2442 } 2449 }
2443 2450
2444 2451
2445 void LCodeGen::DoThisFunction(LThisFunction* instr) { 2452 void LCodeGen::DoThisFunction(LThisFunction* instr) {
2446 Register result = ToRegister(instr->result()); 2453 Register result = ToRegister(instr->result());
2447 __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 2454 __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2448 } 2455 }
2449 2456
2450 2457
2451 void LCodeGen::DoContext(LContext* instr) { 2458 void LCodeGen::DoContext(LContext* instr) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2589 2596
2590 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 2597 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
2591 // Class for deferred case. 2598 // Class for deferred case.
2592 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 2599 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
2593 public: 2600 public:
2594 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2601 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2595 LUnaryMathOperation* instr) 2602 LUnaryMathOperation* instr)
2596 : LDeferredCode(codegen), instr_(instr) { } 2603 : LDeferredCode(codegen), instr_(instr) { }
2597 virtual void Generate() { 2604 virtual void Generate() {
2598 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 2605 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2606 __ jmp(exit());
2599 } 2607 }
2600 private: 2608 private:
2601 LUnaryMathOperation* instr_; 2609 LUnaryMathOperation* instr_;
2602 }; 2610 };
2603 2611
2604 ASSERT(instr->InputAt(0)->Equals(instr->result())); 2612 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2605 Representation r = instr->hydrogen()->value()->representation(); 2613 Representation r = instr->hydrogen()->value()->representation();
2606 2614
2607 if (r.IsDouble()) { 2615 if (r.IsDouble()) {
2608 XMMRegister scratch = xmm0; 2616 XMMRegister scratch = xmm0;
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3074 : isolate()->builtins()->KeyedStoreIC_Initialize();
3067 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 3075 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
3068 } 3076 }
3069 3077
3070 3078
3071 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 3079 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
3072 class DeferredStringCharCodeAt: public LDeferredCode { 3080 class DeferredStringCharCodeAt: public LDeferredCode {
3073 public: 3081 public:
3074 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 3082 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
3075 : LDeferredCode(codegen), instr_(instr) { } 3083 : LDeferredCode(codegen), instr_(instr) { }
3076 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 3084 virtual void Generate() {
3085 codegen()->DoDeferredStringCharCodeAt(instr_);
3086 __ jmp(exit());
3087 }
3077 private: 3088 private:
3078 LStringCharCodeAt* instr_; 3089 LStringCharCodeAt* instr_;
3079 }; 3090 };
3080 3091
3081 Register string = ToRegister(instr->string()); 3092 Register string = ToRegister(instr->string());
3082 Register index = no_reg; 3093 Register index = no_reg;
3083 int const_index = -1; 3094 int const_index = -1;
3084 if (instr->index()->IsConstantOperand()) { 3095 if (instr->index()->IsConstantOperand()) {
3085 const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3096 const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3086 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 3097 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
3202 __ SmiUntag(eax); 3213 __ SmiUntag(eax);
3203 __ StoreToSafepointRegisterSlot(result, eax); 3214 __ StoreToSafepointRegisterSlot(result, eax);
3204 } 3215 }
3205 3216
3206 3217
3207 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 3218 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
3208 class DeferredStringCharFromCode: public LDeferredCode { 3219 class DeferredStringCharFromCode: public LDeferredCode {
3209 public: 3220 public:
3210 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 3221 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
3211 : LDeferredCode(codegen), instr_(instr) { } 3222 : LDeferredCode(codegen), instr_(instr) { }
3212 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 3223 virtual void Generate() {
3224 codegen()->DoDeferredStringCharFromCode(instr_);
3225 __ jmp(exit());
3226 }
3213 private: 3227 private:
3214 LStringCharFromCode* instr_; 3228 LStringCharFromCode* instr_;
3215 }; 3229 };
3216 3230
3217 DeferredStringCharFromCode* deferred = 3231 DeferredStringCharFromCode* deferred =
3218 new DeferredStringCharFromCode(this, instr); 3232 new DeferredStringCharFromCode(this, instr);
3219 3233
3220 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); 3234 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
3221 Register char_code = ToRegister(instr->char_code()); 3235 Register char_code = ToRegister(instr->char_code());
3222 Register result = ToRegister(instr->result()); 3236 Register result = ToRegister(instr->result());
(...skipping 29 matching lines...) Expand all
3252 3266
3253 3267
3254 void LCodeGen::DoStringLength(LStringLength* instr) { 3268 void LCodeGen::DoStringLength(LStringLength* instr) {
3255 Register string = ToRegister(instr->string()); 3269 Register string = ToRegister(instr->string());
3256 Register result = ToRegister(instr->result()); 3270 Register result = ToRegister(instr->result());
3257 __ mov(result, FieldOperand(string, String::kLengthOffset)); 3271 __ mov(result, FieldOperand(string, String::kLengthOffset));
3258 } 3272 }
3259 3273
3260 3274
3261 void LCodeGen::DoStringAdd(LStringAdd* instr) { 3275 void LCodeGen::DoStringAdd(LStringAdd* instr) {
3262 if (instr->left()->IsConstantOperand()) { 3276 EmitPush(instr->left());
3263 __ push(ToImmediate(instr->left())); 3277 EmitPush(instr->right());
3264 } else {
3265 __ push(ToOperand(instr->left()));
3266 }
3267 if (instr->right()->IsConstantOperand()) {
3268 __ push(ToImmediate(instr->right()));
3269 } else {
3270 __ push(ToOperand(instr->right()));
3271 }
3272 StringAddStub stub(NO_STRING_CHECK_IN_STUB); 3278 StringAddStub stub(NO_STRING_CHECK_IN_STUB);
3273 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 3279 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
3274 } 3280 }
3275 3281
3276 3282
3277 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 3283 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
3278 LOperand* input = instr->InputAt(0); 3284 LOperand* input = instr->InputAt(0);
3279 ASSERT(input->IsRegister() || input->IsStackSlot()); 3285 ASSERT(input->IsRegister() || input->IsStackSlot());
3280 LOperand* output = instr->result(); 3286 LOperand* output = instr->result();
3281 ASSERT(output->IsDoubleRegister()); 3287 ASSERT(output->IsDoubleRegister());
3282 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 3288 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
3283 } 3289 }
3284 3290
3285 3291
3286 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 3292 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
3287 class DeferredNumberTagI: public LDeferredCode { 3293 class DeferredNumberTagI: public LDeferredCode {
3288 public: 3294 public:
3289 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 3295 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
3290 : LDeferredCode(codegen), instr_(instr) { } 3296 : LDeferredCode(codegen), instr_(instr) { }
3291 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } 3297 virtual void Generate() {
3298 codegen()->DoDeferredNumberTagI(instr_);
3299 __ jmp(exit());
3300 }
3292 private: 3301 private:
3293 LNumberTagI* instr_; 3302 LNumberTagI* instr_;
3294 }; 3303 };
3295 3304
3296 LOperand* input = instr->InputAt(0); 3305 LOperand* input = instr->InputAt(0);
3297 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3306 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3298 Register reg = ToRegister(input); 3307 Register reg = ToRegister(input);
3299 3308
3300 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 3309 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
3301 __ SmiTag(reg); 3310 __ SmiTag(reg);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3341 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); 3350 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
3342 __ StoreToSafepointRegisterSlot(reg, reg); 3351 __ StoreToSafepointRegisterSlot(reg, reg);
3343 } 3352 }
3344 3353
3345 3354
3346 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 3355 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
3347 class DeferredNumberTagD: public LDeferredCode { 3356 class DeferredNumberTagD: public LDeferredCode {
3348 public: 3357 public:
3349 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 3358 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
3350 : LDeferredCode(codegen), instr_(instr) { } 3359 : LDeferredCode(codegen), instr_(instr) { }
3351 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 3360 virtual void Generate() {
3361 codegen()->DoDeferredNumberTagD(instr_);
3362 __ jmp(exit());
3363 }
3352 private: 3364 private:
3353 LNumberTagD* instr_; 3365 LNumberTagD* instr_;
3354 }; 3366 };
3355 3367
3356 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 3368 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
3357 Register reg = ToRegister(instr->result()); 3369 Register reg = ToRegister(instr->result());
3358 Register tmp = ToRegister(instr->TempAt(0)); 3370 Register tmp = ToRegister(instr->TempAt(0));
3359 3371
3360 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); 3372 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
3361 if (FLAG_inline_new) { 3373 if (FLAG_inline_new) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3438 __ cvtsi2sd(result_reg, Operand(input_reg)); 3450 __ cvtsi2sd(result_reg, Operand(input_reg));
3439 __ SmiTag(input_reg); // Retag smi. 3451 __ SmiTag(input_reg); // Retag smi.
3440 __ bind(&done); 3452 __ bind(&done);
3441 } 3453 }
3442 3454
3443 3455
3444 class DeferredTaggedToI: public LDeferredCode { 3456 class DeferredTaggedToI: public LDeferredCode {
3445 public: 3457 public:
3446 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 3458 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
3447 : LDeferredCode(codegen), instr_(instr) { } 3459 : LDeferredCode(codegen), instr_(instr) { }
3448 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 3460 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_, exit()); }
3449 private: 3461 private:
3450 LTaggedToI* instr_; 3462 LTaggedToI* instr_;
3451 }; 3463 };
3452 3464
3453 3465
3454 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 3466 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* exit) {
3455 Label done, heap_number; 3467 Label deoptimize;
3456 Register input_reg = ToRegister(instr->InputAt(0)); 3468 Register input_reg = ToRegister(instr->InputAt(0));
3457 3469
3458 // Heap number map check. 3470 // Heap number map check.
3459 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3471 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3460 factory()->heap_number_map()); 3472 factory()->heap_number_map());
3461 3473
3462 if (instr->truncating()) { 3474 if (instr->truncating()) {
3463 __ j(equal, &heap_number, Label::kNear); 3475 Label not_heap_number;
3464 // Check for undefined. Undefined is converted to zero for truncating
3465 // conversions.
3466 __ cmp(input_reg, factory()->undefined_value());
3467 DeoptimizeIf(not_equal, instr->environment());
3468 __ mov(input_reg, 0);
3469 __ jmp(&done, Label::kNear);
3470 3476
3471 __ bind(&heap_number); 3477 __ j(not_equal, &not_heap_number, Label::kNear);
3478
3472 if (CpuFeatures::IsSupported(SSE3)) { 3479 if (CpuFeatures::IsSupported(SSE3)) {
3473 CpuFeatures::Scope scope(SSE3); 3480 CpuFeatures::Scope scope(SSE3);
3474 Label convert; 3481 Label fix_fp_stack_and_deoptimize;
3475 // Use more powerful conversion when sse3 is available. 3482 // Use more powerful conversion when sse3 is available.
3476 // Load x87 register with heap number. 3483 // Load x87 register with heap number.
3477 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 3484 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
3478 // Get exponent alone and check for too-big exponent. 3485 // Get exponent alone and check for too-big exponent.
3479 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 3486 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
3480 __ and_(input_reg, HeapNumber::kExponentMask); 3487 __ and_(input_reg, HeapNumber::kExponentMask);
3481 const uint32_t kTooBigExponent = 3488 const uint32_t kTooBigExponent =
3482 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 3489 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
3483 __ cmp(Operand(input_reg), Immediate(kTooBigExponent)); 3490 __ cmp(Operand(input_reg), Immediate(kTooBigExponent));
3484 __ j(less, &convert, Label::kNear); 3491 __ j(greater_equal, &fix_fp_stack_and_deoptimize, Label::kNear);
3485 // Pop FPU stack before deoptimizing.
3486 __ ffree(0);
3487 __ fincstp();
3488 DeoptimizeIf(no_condition, instr->environment());
3489 3492
3490 // Reserve space for 64 bit answer. 3493 // Reserve space for 64 bit answer.
3491 __ bind(&convert);
3492 __ sub(Operand(esp), Immediate(kDoubleSize)); 3494 __ sub(Operand(esp), Immediate(kDoubleSize));
3493 // Do conversion, which cannot fail because we checked the exponent. 3495 // Do conversion, which cannot fail because we checked the exponent.
3494 __ fisttp_d(Operand(esp, 0)); 3496 __ fisttp_d(Operand(esp, 0));
3495 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 3497 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
3496 __ add(Operand(esp), Immediate(kDoubleSize)); 3498 __ add(Operand(esp), Immediate(kDoubleSize));
3499 __ jmp(exit);
3500
3501 __ bind(&fix_fp_stack_and_deoptimize);
3502 // Pop FPU stack before deoptimizing.
3503 __ ffree(0);
3504 __ fincstp();
3505 __ jmp(&deoptimize, Label::kNear);
3506
3497 } else { 3507 } else {
3498 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); 3508 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
3499 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3509 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3500 __ cvttsd2si(input_reg, Operand(xmm0)); 3510 __ cvttsd2si(input_reg, Operand(xmm0));
3501 __ cmp(input_reg, 0x80000000u); 3511 __ cmp(input_reg, 0x80000000u);
3502 __ j(not_equal, &done); 3512 __ j(equal, exit, Label::kNear);
3503 // Check if the input was 0x8000000 (kMinInt). 3513 // Check if the input was 0x8000000 (kMinInt).
3504 // If no, then we got an overflow and we deoptimize. 3514 // If no, then we got an overflow and we deoptimize.
3505 ExternalReference min_int = ExternalReference::address_of_min_int(); 3515 ExternalReference min_int = ExternalReference::address_of_min_int();
3506 __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 3516 __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
3507 __ ucomisd(xmm_temp, xmm0); 3517 __ ucomisd(xmm_temp, xmm0);
3508 DeoptimizeIf(not_equal, instr->environment()); 3518 __ j(not_equal, &deoptimize, Label::kNear);
3509 DeoptimizeIf(parity_even, instr->environment()); // NaN. 3519 __ j(parity_even, &deoptimize, Label::kNear); // NaN.
3520 __ jmp(exit);
3510 } 3521 }
3522
3523 __ bind(&not_heap_number);
3524 // Check for undefined. Undefined is converted to zero for truncating
3525 // conversions.
3526 __ cmp(input_reg, factory()->undefined_value());
3527 __ j(not_equal, &deoptimize, Label::kNear);
3528 __ Set(input_reg, Immediate(0));
3529 __ jmp(exit);
3530
3511 } else { 3531 } else {
3512 // Deoptimize if we don't have a heap number. 3532 // Deoptimize if we don't have a heap number.
3513 DeoptimizeIf(not_equal, instr->environment()); 3533 __ j(not_equal, &deoptimize, Label::kNear);
3514 3534
3515 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); 3535 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
3516 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3536 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3517 __ cvttsd2si(input_reg, Operand(xmm0)); 3537 __ cvttsd2si(input_reg, Operand(xmm0));
3518 __ cvtsi2sd(xmm_temp, Operand(input_reg)); 3538 __ cvtsi2sd(xmm_temp, Operand(input_reg));
3519 __ ucomisd(xmm0, xmm_temp); 3539 __ ucomisd(xmm0, xmm_temp);
3520 DeoptimizeIf(not_equal, instr->environment()); 3540 __ j(not_equal, &deoptimize, Label::kNear);
3521 DeoptimizeIf(parity_even, instr->environment()); // NaN. 3541
3522 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3542 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3543 __ j(parity_even, &deoptimize, Label::kNear); // NaN.
3523 __ test(input_reg, Operand(input_reg)); 3544 __ test(input_reg, Operand(input_reg));
3524 __ j(not_zero, &done); 3545 __ j(not_zero, exit);
3525 __ movmskpd(input_reg, xmm0); 3546 __ movmskpd(input_reg, xmm0);
3526 __ and_(input_reg, 1); 3547 __ and_(input_reg, 1);
3527 DeoptimizeIf(not_zero, instr->environment()); 3548 __ j(zero, exit);
3549 } else {
3550 __ j(parity_odd, exit); // Exit if not NaN, fall through if NaN.
3528 } 3551 }
3529 } 3552 }
3530 __ bind(&done); 3553
3554 __ bind(&deoptimize);
3555 DeoptimizeIf(no_condition, instr->environment());
3531 } 3556 }
3532 3557
3533 3558
3534 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 3559 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
3535 LOperand* input = instr->InputAt(0); 3560 LOperand* input = instr->InputAt(0);
3536 ASSERT(input->IsRegister()); 3561 ASSERT(input->IsRegister());
3537 ASSERT(input->Equals(instr->result())); 3562 ASSERT(input->Equals(instr->result()));
3538 3563
3539 Register input_reg = ToRegister(input); 3564 Register input_reg = ToRegister(input);
3540 3565
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
3684 3709
3685 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 3710 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
3686 LOperand* input = instr->InputAt(0); 3711 LOperand* input = instr->InputAt(0);
3687 __ test(ToOperand(input), Immediate(kSmiTagMask)); 3712 __ test(ToOperand(input), Immediate(kSmiTagMask));
3688 DeoptimizeIf(not_zero, instr->environment()); 3713 DeoptimizeIf(not_zero, instr->environment());
3689 } 3714 }
3690 3715
3691 3716
3692 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 3717 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
3693 LOperand* input = instr->InputAt(0); 3718 LOperand* input = instr->InputAt(0);
3694 __ test(ToOperand(input), Immediate(kSmiTagMask)); 3719 if (input->IsRegister()) {
3720 __ test(ToRegister(input), Immediate(kSmiTagMask));
3721 } else {
3722 __ test(ToOperand(input), Immediate(kSmiTagMask));
3723 }
3695 DeoptimizeIf(zero, instr->environment()); 3724 DeoptimizeIf(zero, instr->environment());
3696 } 3725 }
3697 3726
3698 3727
3699 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 3728 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
3700 Register input = ToRegister(instr->InputAt(0)); 3729 Register input = ToRegister(instr->InputAt(0));
3701 Register temp = ToRegister(instr->TempAt(0)); 3730 Register temp = ToRegister(instr->TempAt(0));
3702 3731
3703 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 3732 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
3704 3733
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3975 __ push(Immediate(pretenure 4004 __ push(Immediate(pretenure
3976 ? factory()->true_value() 4005 ? factory()->true_value()
3977 : factory()->false_value())); 4006 : factory()->false_value()));
3978 CallRuntime(Runtime::kNewClosure, 3, instr, RESTORE_CONTEXT); 4007 CallRuntime(Runtime::kNewClosure, 3, instr, RESTORE_CONTEXT);
3979 } 4008 }
3980 } 4009 }
3981 4010
3982 4011
3983 void LCodeGen::DoTypeof(LTypeof* instr) { 4012 void LCodeGen::DoTypeof(LTypeof* instr) {
3984 LOperand* input = instr->InputAt(0); 4013 LOperand* input = instr->InputAt(0);
3985 if (input->IsConstantOperand()) { 4014 EmitPush(input);
3986 __ push(ToImmediate(input));
3987 } else {
3988 __ push(ToOperand(input));
3989 }
3990 CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT); 4015 CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT);
3991 } 4016 }
3992 4017
3993 4018
3994 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 4019 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
3995 Register input = ToRegister(instr->InputAt(0)); 4020 Register input = ToRegister(instr->InputAt(0));
3996 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4021 int true_block = chunk_->LookupDestination(instr->true_block_id());
3997 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4022 int false_block = chunk_->LookupDestination(instr->false_block_id());
3998 Label* true_label = chunk_->GetAssemblyLabel(true_block); 4023 Label* true_label = chunk_->GetAssemblyLabel(true_block);
3999 Label* false_label = chunk_->GetAssemblyLabel(false_block); 4024 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
4106 4131
4107 4132
4108 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 4133 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
4109 DeoptimizeIf(no_condition, instr->environment()); 4134 DeoptimizeIf(no_condition, instr->environment());
4110 } 4135 }
4111 4136
4112 4137
4113 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { 4138 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
4114 LOperand* obj = instr->object(); 4139 LOperand* obj = instr->object();
4115 LOperand* key = instr->key(); 4140 LOperand* key = instr->key();
4116 __ push(ToOperand(obj)); 4141 EmitPush(obj);
4117 if (key->IsConstantOperand()) { 4142 EmitPush(key);
4118 __ push(ToImmediate(key));
4119 } else {
4120 __ push(ToOperand(key));
4121 }
4122 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 4143 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
4123 LPointerMap* pointers = instr->pointer_map(); 4144 LPointerMap* pointers = instr->pointer_map();
4124 LEnvironment* env = instr->deoptimization_environment(); 4145 LEnvironment* env = instr->deoptimization_environment();
4125 RecordPosition(pointers->position()); 4146 RecordPosition(pointers->position());
4126 RegisterEnvironmentForDeoptimization(env); 4147 RegisterEnvironmentForDeoptimization(env);
4127 // Create safepoint generator that will also ensure enough space in the 4148 // Create safepoint generator that will also ensure enough space in the
4128 // reloc info for patching in deoptimization (since this is invoking a 4149 // reloc info for patching in deoptimization (since this is invoking a
4129 // builtin) 4150 // builtin)
4130 SafepointGenerator safepoint_generator(this, 4151 SafepointGenerator safepoint_generator(this,
4131 pointers, 4152 pointers,
4132 env->deoptimization_index()); 4153 env->deoptimization_index());
4133 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4154 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4134 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 4155 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
4135 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); 4156 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
4136 } 4157 }
4137 4158
4138 4159
4139 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 4160 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
4140 PushSafepointRegistersScope scope(this); 4161 PushSafepointRegistersScope scope(this);
4141 CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr); 4162 CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr);
4142 } 4163 }
4143 4164
4144 4165
4145 void LCodeGen::DoStackCheck(LStackCheck* instr) { 4166 void LCodeGen::DoStackCheck(LStackCheck* instr) {
4146 class DeferredStackCheck: public LDeferredCode { 4167 class DeferredStackCheck: public LDeferredCode {
4147 public: 4168 public:
4148 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 4169 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
4149 : LDeferredCode(codegen), instr_(instr) { } 4170 : LDeferredCode(codegen), instr_(instr) { }
4150 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 4171 virtual void Generate() {
4172 codegen()->DoDeferredStackCheck(instr_);
4173 __ jmp(exit());
4174 }
4151 private: 4175 private:
4152 LStackCheck* instr_; 4176 LStackCheck* instr_;
4153 }; 4177 };
4154 4178
4155 if (instr->hydrogen()->is_function_entry()) { 4179 if (instr->hydrogen()->is_function_entry()) {
4156 // Perform stack overflow check. 4180 // Perform stack overflow check.
4157 Label done; 4181 Label done;
4158 ExternalReference stack_limit = 4182 ExternalReference stack_limit =
4159 ExternalReference::address_of_stack_limit(isolate()); 4183 ExternalReference::address_of_stack_limit(isolate());
4160 __ cmp(esp, Operand::StaticVariable(stack_limit)); 4184 __ cmp(esp, Operand::StaticVariable(stack_limit));
(...skipping 30 matching lines...) Expand all
4191 ASSERT(!environment->HasBeenRegistered()); 4215 ASSERT(!environment->HasBeenRegistered());
4192 RegisterEnvironmentForDeoptimization(environment); 4216 RegisterEnvironmentForDeoptimization(environment);
4193 ASSERT(osr_pc_offset_ == -1); 4217 ASSERT(osr_pc_offset_ == -1);
4194 osr_pc_offset_ = masm()->pc_offset(); 4218 osr_pc_offset_ = masm()->pc_offset();
4195 } 4219 }
4196 4220
4197 4221
4198 void LCodeGen::DoIn(LIn* instr) { 4222 void LCodeGen::DoIn(LIn* instr) {
4199 LOperand* obj = instr->object(); 4223 LOperand* obj = instr->object();
4200 LOperand* key = instr->key(); 4224 LOperand* key = instr->key();
4201 if (key->IsConstantOperand()) { 4225 EmitPush(key);
4202 __ push(ToImmediate(key)); 4226 EmitPush(obj);
4203 } else {
4204 __ push(ToOperand(key));
4205 }
4206 if (obj->IsConstantOperand()) {
4207 __ push(ToImmediate(obj));
4208 } else {
4209 __ push(ToOperand(obj));
4210 }
4211 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 4227 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
4212 LPointerMap* pointers = instr->pointer_map(); 4228 LPointerMap* pointers = instr->pointer_map();
4213 LEnvironment* env = instr->deoptimization_environment(); 4229 LEnvironment* env = instr->deoptimization_environment();
4214 RecordPosition(pointers->position()); 4230 RecordPosition(pointers->position());
4215 RegisterEnvironmentForDeoptimization(env); 4231 RegisterEnvironmentForDeoptimization(env);
4216 // Create safepoint generator that will also ensure enough space in the 4232 // Create safepoint generator that will also ensure enough space in the
4217 // reloc info for patching in deoptimization (since this is invoking a 4233 // reloc info for patching in deoptimization (since this is invoking a
4218 // builtin) 4234 // builtin)
4219 SafepointGenerator safepoint_generator(this, 4235 SafepointGenerator safepoint_generator(this,
4220 pointers, 4236 pointers,
4221 env->deoptimization_index()); 4237 env->deoptimization_index());
4222 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4238 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4223 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4239 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4224 } 4240 }
4225 4241
4226 4242
4227 #undef __ 4243 #undef __
4228 4244
4229 } } // namespace v8::internal 4245 } } // namespace v8::internal
4230 4246
4231 #endif // V8_TARGET_ARCH_IA32 4247 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698