OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 friend class FullCodeGenSyntaxChecker; | 469 friend class FullCodeGenSyntaxChecker; |
470 | 470 |
471 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); | 471 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); |
472 }; | 472 }; |
473 | 473 |
474 | 474 |
475 class GenericBinaryOpStub : public CodeStub { | 475 class GenericBinaryOpStub : public CodeStub { |
476 public: | 476 public: |
477 GenericBinaryOpStub(Token::Value op, | 477 GenericBinaryOpStub(Token::Value op, |
478 OverwriteMode mode, | 478 OverwriteMode mode, |
| 479 Register lhs, |
| 480 Register rhs, |
479 int constant_rhs = CodeGenerator::kUnknownIntValue) | 481 int constant_rhs = CodeGenerator::kUnknownIntValue) |
480 : op_(op), | 482 : op_(op), |
481 mode_(mode), | 483 mode_(mode), |
| 484 lhs_(lhs), |
| 485 rhs_(rhs), |
482 constant_rhs_(constant_rhs), | 486 constant_rhs_(constant_rhs), |
483 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)), | 487 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)), |
484 runtime_operands_type_(BinaryOpIC::DEFAULT), | 488 runtime_operands_type_(BinaryOpIC::DEFAULT), |
485 name_(NULL) { } | 489 name_(NULL) { } |
486 | 490 |
487 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) | 491 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) |
488 : op_(OpBits::decode(key)), | 492 : op_(OpBits::decode(key)), |
489 mode_(ModeBits::decode(key)), | 493 mode_(ModeBits::decode(key)), |
| 494 lhs_(LhsRegister(RegisterBits::decode(key))), |
| 495 rhs_(RhsRegister(RegisterBits::decode(key))), |
490 constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))), | 496 constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))), |
491 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)), | 497 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)), |
492 runtime_operands_type_(type_info), | 498 runtime_operands_type_(type_info), |
493 name_(NULL) { } | 499 name_(NULL) { } |
494 | 500 |
495 private: | 501 private: |
496 Token::Value op_; | 502 Token::Value op_; |
497 OverwriteMode mode_; | 503 OverwriteMode mode_; |
| 504 Register lhs_; |
| 505 Register rhs_; |
498 int constant_rhs_; | 506 int constant_rhs_; |
499 bool specialized_on_rhs_; | 507 bool specialized_on_rhs_; |
500 BinaryOpIC::TypeInfo runtime_operands_type_; | 508 BinaryOpIC::TypeInfo runtime_operands_type_; |
501 char* name_; | 509 char* name_; |
502 | 510 |
503 static const int kMaxKnownRhs = 0x40000000; | 511 static const int kMaxKnownRhs = 0x40000000; |
| 512 static const int kKnownRhsKeyBits = 6; |
504 | 513 |
505 // Minor key encoding in 18 bits. | 514 // Minor key encoding in 17 bits. |
506 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; | 515 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
507 class OpBits: public BitField<Token::Value, 2, 6> {}; | 516 class OpBits: public BitField<Token::Value, 2, 6> {}; |
508 class KnownIntBits: public BitField<int, 8, 8> {}; | 517 class TypeInfoBits: public BitField<int, 8, 2> {}; |
509 class TypeInfoBits: public BitField<int, 16, 2> {}; | 518 class RegisterBits: public BitField<bool, 10, 1> {}; |
| 519 class KnownIntBits: public BitField<int, 11, kKnownRhsKeyBits> {}; |
510 | 520 |
511 Major MajorKey() { return GenericBinaryOp; } | 521 Major MajorKey() { return GenericBinaryOp; } |
512 int MinorKey() { | 522 int MinorKey() { |
| 523 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || |
| 524 (lhs_.is(r1) && rhs_.is(r0))); |
513 // Encode the parameters in a unique 18 bit value. | 525 // Encode the parameters in a unique 18 bit value. |
514 return OpBits::encode(op_) | 526 return OpBits::encode(op_) |
515 | ModeBits::encode(mode_) | 527 | ModeBits::encode(mode_) |
516 | KnownIntBits::encode(MinorKeyForKnownInt()) | 528 | KnownIntBits::encode(MinorKeyForKnownInt()) |
517 | TypeInfoBits::encode(runtime_operands_type_); | 529 | TypeInfoBits::encode(runtime_operands_type_) |
| 530 | RegisterBits::encode(lhs_.is(r0)); |
518 } | 531 } |
519 | 532 |
520 void Generate(MacroAssembler* masm); | 533 void Generate(MacroAssembler* masm); |
521 void HandleNonSmiBitwiseOp(MacroAssembler* masm); | 534 void HandleNonSmiBitwiseOp(MacroAssembler* masm, Register lhs, Register rhs); |
522 void HandleBinaryOpSlowCases(MacroAssembler* masm, | 535 void HandleBinaryOpSlowCases(MacroAssembler* masm, |
523 Label* not_smi, | 536 Label* not_smi, |
| 537 Register lhs, |
| 538 Register rhs, |
524 const Builtins::JavaScript& builtin); | 539 const Builtins::JavaScript& builtin); |
525 void GenerateTypeTransition(MacroAssembler* masm); | 540 void GenerateTypeTransition(MacroAssembler* masm); |
526 | 541 |
527 static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) { | 542 static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) { |
528 if (constant_rhs == CodeGenerator::kUnknownIntValue) return false; | 543 if (constant_rhs == CodeGenerator::kUnknownIntValue) return false; |
529 if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3; | 544 if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3; |
530 if (op == Token::MOD) { | 545 if (op == Token::MOD) { |
531 if (constant_rhs <= 1) return false; | 546 if (constant_rhs <= 1) return false; |
532 if (constant_rhs <= 10) return true; | 547 if (constant_rhs <= 10) return true; |
533 if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true; | 548 if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true; |
534 return false; | 549 return false; |
535 } | 550 } |
536 return false; | 551 return false; |
537 } | 552 } |
538 | 553 |
539 int MinorKeyForKnownInt() { | 554 int MinorKeyForKnownInt() { |
540 if (!specialized_on_rhs_) return 0; | 555 if (!specialized_on_rhs_) return 0; |
541 if (constant_rhs_ <= 10) return constant_rhs_ + 1; | 556 if (constant_rhs_ <= 10) return constant_rhs_ + 1; |
542 ASSERT(IsPowerOf2(constant_rhs_)); | 557 ASSERT(IsPowerOf2(constant_rhs_)); |
543 int key = 12; | 558 int key = 12; |
544 int d = constant_rhs_; | 559 int d = constant_rhs_; |
545 while ((d & 1) == 0) { | 560 while ((d & 1) == 0) { |
546 key++; | 561 key++; |
547 d >>= 1; | 562 d >>= 1; |
548 } | 563 } |
| 564 ASSERT(key >= 0 && key < (1 << kKnownRhsKeyBits)); |
549 return key; | 565 return key; |
550 } | 566 } |
551 | 567 |
552 int KnownBitsForMinorKey(int key) { | 568 int KnownBitsForMinorKey(int key) { |
553 if (!key) return 0; | 569 if (!key) return 0; |
554 if (key <= 11) return key - 1; | 570 if (key <= 11) return key - 1; |
555 int d = 1; | 571 int d = 1; |
556 while (key != 12) { | 572 while (key != 12) { |
557 key--; | 573 key--; |
558 d <<= 1; | 574 d <<= 1; |
559 } | 575 } |
560 return d; | 576 return d; |
561 } | 577 } |
562 | 578 |
| 579 Register LhsRegister(bool lhs_is_r0) { |
| 580 return lhs_is_r0 ? r0 : r1; |
| 581 } |
| 582 |
| 583 Register RhsRegister(bool lhs_is_r0) { |
| 584 return lhs_is_r0 ? r1 : r0; |
| 585 } |
| 586 |
563 bool ShouldGenerateSmiCode() { | 587 bool ShouldGenerateSmiCode() { |
564 return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) && | 588 return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) && |
565 runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && | 589 runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && |
566 runtime_operands_type_ != BinaryOpIC::STRINGS; | 590 runtime_operands_type_ != BinaryOpIC::STRINGS; |
567 } | 591 } |
568 | 592 |
569 bool ShouldGenerateFPCode() { | 593 bool ShouldGenerateFPCode() { |
570 return runtime_operands_type_ != BinaryOpIC::STRINGS; | 594 return runtime_operands_type_ != BinaryOpIC::STRINGS; |
571 } | 595 } |
572 | 596 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 void Print() { | 805 void Print() { |
782 PrintF("NumberToStringStub\n"); | 806 PrintF("NumberToStringStub\n"); |
783 } | 807 } |
784 #endif | 808 #endif |
785 }; | 809 }; |
786 | 810 |
787 | 811 |
788 } } // namespace v8::internal | 812 } } // namespace v8::internal |
789 | 813 |
790 #endif // V8_ARM_CODEGEN_ARM_H_ | 814 #endif // V8_ARM_CODEGEN_ARM_H_ |
OLD | NEW |