OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 // CpuFeatures::Scope fscope(SSE2); | 340 // CpuFeatures::Scope fscope(SSE2); |
341 // // Generate SSE2 floating point code. | 341 // // Generate SSE2 floating point code. |
342 // } else { | 342 // } else { |
343 // // Generate standard x87 floating point code. | 343 // // Generate standard x87 floating point code. |
344 // } | 344 // } |
345 class CpuFeatures : public AllStatic { | 345 class CpuFeatures : public AllStatic { |
346 public: | 346 public: |
347 // Feature flags bit positions. They are mostly based on the CPUID spec. | 347 // Feature flags bit positions. They are mostly based on the CPUID spec. |
348 // (We assign CPUID itself to one of the currently reserved bits -- | 348 // (We assign CPUID itself to one of the currently reserved bits -- |
349 // feel free to change this if needed.) | 349 // feel free to change this if needed.) |
350 enum Feature { SSE2 = 26, CMOV = 15, RDTSC = 4, CPUID = 10 }; | 350 enum Feature { SSE3 = 32, SSE2 = 26, CMOV = 15, RDTSC = 4, CPUID = 10 }; |
351 // Detect features of the target CPU. Set safe defaults if the serializer | 351 // Detect features of the target CPU. Set safe defaults if the serializer |
352 // is enabled (snapshots must be portable). | 352 // is enabled (snapshots must be portable). |
353 static void Probe(); | 353 static void Probe(); |
354 // Check whether a feature is supported by the target CPU. | 354 // Check whether a feature is supported by the target CPU. |
355 static bool IsSupported(Feature f) { return supported_ & (1 << f); } | 355 static bool IsSupported(Feature f) { return supported_ & (1UL << f); } |
356 // Check whether a feature is currently enabled. | 356 // Check whether a feature is currently enabled. |
357 static bool IsEnabled(Feature f) { return enabled_ & (1 << f); } | 357 static bool IsEnabled(Feature f) { return enabled_ & (1UL << f); } |
358 // Enable a specified feature within a scope. | 358 // Enable a specified feature within a scope. |
359 class Scope BASE_EMBEDDED { | 359 class Scope BASE_EMBEDDED { |
360 #ifdef DEBUG | 360 #ifdef DEBUG |
361 public: | 361 public: |
362 explicit Scope(Feature f) { | 362 explicit Scope(Feature f) { |
363 ASSERT(CpuFeatures::IsSupported(f)); | 363 ASSERT(CpuFeatures::IsSupported(f)); |
364 old_enabled_ = CpuFeatures::enabled_; | 364 old_enabled_ = CpuFeatures::enabled_; |
365 CpuFeatures::enabled_ |= (1 << f); | 365 CpuFeatures::enabled_ |= (1UL << f); |
366 } | 366 } |
367 ~Scope() { CpuFeatures::enabled_ = old_enabled_; } | 367 ~Scope() { CpuFeatures::enabled_ = old_enabled_; } |
368 private: | 368 private: |
369 uint32_t old_enabled_; | 369 uint64_t old_enabled_; |
370 #else | 370 #else |
371 public: | 371 public: |
372 explicit Scope(Feature f) {} | 372 explicit Scope(Feature f) {} |
373 #endif | 373 #endif |
374 }; | 374 }; |
375 private: | 375 private: |
376 static uint32_t supported_; | 376 static uint64_t supported_; |
377 static uint32_t enabled_; | 377 static uint64_t enabled_; |
378 }; | 378 }; |
379 | 379 |
380 | 380 |
381 class Assembler : public Malloced { | 381 class Assembler : public Malloced { |
382 private: | 382 private: |
383 // The relocation writer's position is kGap bytes below the end of | 383 // The relocation writer's position is kGap bytes below the end of |
384 // the generated instructions. This leaves enough space for the | 384 // the generated instructions. This leaves enough space for the |
385 // longest possible ia32 instruction (17 bytes as of 9/26/06) and | 385 // longest possible ia32 instruction (17 bytes as of 9/26/06) and |
386 // allows for a single, fast space check per instruction. | 386 // allows for a single, fast space check per instruction. |
387 static const int kGap = 32; | 387 static const int kGap = 32; |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 void fstp_d(const Operand& adr); | 628 void fstp_d(const Operand& adr); |
629 | 629 |
630 void fild_s(const Operand& adr); | 630 void fild_s(const Operand& adr); |
631 void fild_d(const Operand& adr); | 631 void fild_d(const Operand& adr); |
632 | 632 |
633 void fist_s(const Operand& adr); | 633 void fist_s(const Operand& adr); |
634 | 634 |
635 void fistp_s(const Operand& adr); | 635 void fistp_s(const Operand& adr); |
636 void fistp_d(const Operand& adr); | 636 void fistp_d(const Operand& adr); |
637 | 637 |
| 638 void fisttp_s(const Operand& adr); |
| 639 |
638 void fabs(); | 640 void fabs(); |
639 void fchs(); | 641 void fchs(); |
640 | 642 |
641 void fadd(int i); | 643 void fadd(int i); |
642 void fsub(int i); | 644 void fsub(int i); |
643 void fmul(int i); | 645 void fmul(int i); |
644 void fdiv(int i); | 646 void fdiv(int i); |
645 | 647 |
646 void fisub_s(const Operand& adr); | 648 void fisub_s(const Operand& adr); |
647 | 649 |
648 void faddp(int i = 1); | 650 void faddp(int i = 1); |
649 void fsubp(int i = 1); | 651 void fsubp(int i = 1); |
650 void fsubrp(int i = 1); | 652 void fsubrp(int i = 1); |
651 void fmulp(int i = 1); | 653 void fmulp(int i = 1); |
652 void fdivp(int i = 1); | 654 void fdivp(int i = 1); |
653 void fprem(); | 655 void fprem(); |
654 void fprem1(); | 656 void fprem1(); |
655 | 657 |
656 void fxch(int i = 1); | 658 void fxch(int i = 1); |
657 void fincstp(); | 659 void fincstp(); |
658 void ffree(int i = 0); | 660 void ffree(int i = 0); |
659 | 661 |
660 void ftst(); | 662 void ftst(); |
661 void fucomp(int i); | 663 void fucomp(int i); |
662 void fucompp(); | 664 void fucompp(); |
663 void fcompp(); | 665 void fcompp(); |
664 void fnstsw_ax(); | 666 void fnstsw_ax(); |
665 void fwait(); | 667 void fwait(); |
| 668 void fnclex(); |
666 | 669 |
667 void frndint(); | 670 void frndint(); |
668 | 671 |
669 void sahf(); | 672 void sahf(); |
670 | 673 |
671 void cpuid(); | 674 void cpuid(); |
672 | 675 |
673 // SSE2 instructions | 676 // SSE2 instructions |
674 void cvttss2si(Register dst, const Operand& src); | 677 void cvttss2si(Register dst, const Operand& src); |
675 void cvttsd2si(Register dst, const Operand& src); | 678 void cvttsd2si(Register dst, const Operand& src); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 private: | 833 private: |
831 Assembler* assembler_; | 834 Assembler* assembler_; |
832 #ifdef DEBUG | 835 #ifdef DEBUG |
833 int space_before_; | 836 int space_before_; |
834 #endif | 837 #endif |
835 }; | 838 }; |
836 | 839 |
837 } } // namespace v8::internal | 840 } } // namespace v8::internal |
838 | 841 |
839 #endif // V8_ASSEMBLER_IA32_H_ | 842 #endif // V8_ASSEMBLER_IA32_H_ |
OLD | NEW |