| 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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 } else { | 294 } else { |
| 295 // Need no displacement. | 295 // Need no displacement. |
| 296 buf_[0] = (modrm & 0x3f); // Mode 0. | 296 buf_[0] = (modrm & 0x3f); // Mode 0. |
| 297 len_ = disp_offset; | 297 len_ = disp_offset; |
| 298 } | 298 } |
| 299 if (has_sib) { | 299 if (has_sib) { |
| 300 buf_[1] = operand.buf_[1]; | 300 buf_[1] = operand.buf_[1]; |
| 301 } | 301 } |
| 302 } | 302 } |
| 303 | 303 |
| 304 |
| 305 bool Operand::AddressUsesRegister(Register reg) const { |
| 306 int code = reg.code(); |
| 307 ASSERT((buf_[0] & 0xC0) != 0xC0); // Always a memory operand. |
| 308 // Start with only low three bits of base register. Initial decoding doesn't |
| 309 // distinguish on the REX.B bit. |
| 310 int base_code = buf_[0] & 0x07; |
| 311 if (base_code == rsp.code()) { |
| 312 // SIB byte present in buf_[1]. |
| 313 // Check the index register from the SIB byte + REX.X prefix. |
| 314 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2); |
| 315 // Index code (including REX.X) of 0x04 (rsp) means no index register. |
| 316 if (index_code != rsp.code() && index_code == code) return true; |
| 317 // Add REX.B to get the full base register code. |
| 318 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3); |
| 319 // A base register of 0x05 (rbp) with mod = 0 means no base register. |
| 320 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false; |
| 321 return code == base_code; |
| 322 } else { |
| 323 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means |
| 324 // no base register. |
| 325 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false; |
| 326 base_code |= ((rex_ & 0x01) << 3); |
| 327 return code == base_code; |
| 328 } |
| 329 } |
| 330 |
| 331 |
| 304 // ----------------------------------------------------------------------------- | 332 // ----------------------------------------------------------------------------- |
| 305 // Implementation of Assembler. | 333 // Implementation of Assembler. |
| 306 | 334 |
| 307 #ifdef GENERATED_CODE_COVERAGE | 335 #ifdef GENERATED_CODE_COVERAGE |
| 308 static void InitCoverageLog(); | 336 static void InitCoverageLog(); |
| 309 #endif | 337 #endif |
| 310 | 338 |
| 311 Assembler::Assembler(void* buffer, int buffer_size) | 339 Assembler::Assembler(void* buffer, int buffer_size) |
| 312 : code_targets_(100), positions_recorder_(this) { | 340 : code_targets_(100), positions_recorder_(this) { |
| 313 Isolate* isolate = Isolate::Current(); | 341 Isolate* isolate = Isolate::Current(); |
| (...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1946 if (is_int8(value.value_)) { | 1974 if (is_int8(value.value_)) { |
| 1947 emit(0x6A); | 1975 emit(0x6A); |
| 1948 emit(value.value_); // Emit low byte of value. | 1976 emit(value.value_); // Emit low byte of value. |
| 1949 } else { | 1977 } else { |
| 1950 emit(0x68); | 1978 emit(0x68); |
| 1951 emitl(value.value_); | 1979 emitl(value.value_); |
| 1952 } | 1980 } |
| 1953 } | 1981 } |
| 1954 | 1982 |
| 1955 | 1983 |
| 1984 void Assembler::push_imm32(int32_t imm32) { |
| 1985 EnsureSpace ensure_space(this); |
| 1986 last_pc_ = pc_; |
| 1987 emit(0x68); |
| 1988 emitl(imm32); |
| 1989 } |
| 1990 |
| 1991 |
| 1956 void Assembler::pushfq() { | 1992 void Assembler::pushfq() { |
| 1957 EnsureSpace ensure_space(this); | 1993 EnsureSpace ensure_space(this); |
| 1958 last_pc_ = pc_; | 1994 last_pc_ = pc_; |
| 1959 emit(0x9C); | 1995 emit(0x9C); |
| 1960 } | 1996 } |
| 1961 | 1997 |
| 1962 | 1998 |
| 1963 void Assembler::rdtsc() { | 1999 void Assembler::rdtsc() { |
| 1964 EnsureSpace ensure_space(this); | 2000 EnsureSpace ensure_space(this); |
| 1965 last_pc_ = pc_; | 2001 last_pc_ = pc_; |
| (...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2638 EnsureSpace ensure_space(this); | 2674 EnsureSpace ensure_space(this); |
| 2639 last_pc_ = pc_; | 2675 last_pc_ = pc_; |
| 2640 emit(0x66); | 2676 emit(0x66); |
| 2641 emit_rex_64(src, dst); | 2677 emit_rex_64(src, dst); |
| 2642 emit(0x0F); | 2678 emit(0x0F); |
| 2643 emit(0x7E); | 2679 emit(0x7E); |
| 2644 emit_sse_operand(src, dst); | 2680 emit_sse_operand(src, dst); |
| 2645 } | 2681 } |
| 2646 | 2682 |
| 2647 | 2683 |
| 2684 void Assembler::movdqa(const Operand& dst, XMMRegister src) { |
| 2685 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); |
| 2686 EnsureSpace ensure_space(this); |
| 2687 last_pc_ = pc_; |
| 2688 emit(0x66); |
| 2689 emit_rex_64(src, dst); |
| 2690 emit(0x0F); |
| 2691 emit(0x7F); |
| 2692 emit_sse_operand(src, dst); |
| 2693 } |
| 2694 |
| 2695 |
| 2696 void Assembler::movdqa(XMMRegister dst, const Operand& src) { |
| 2697 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); |
| 2698 EnsureSpace ensure_space(this); |
| 2699 last_pc_ = pc_; |
| 2700 emit(0x66); |
| 2701 emit_rex_64(dst, src); |
| 2702 emit(0x0F); |
| 2703 emit(0x6F); |
| 2704 emit_sse_operand(dst, src); |
| 2705 } |
| 2706 |
| 2707 |
| 2648 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { | 2708 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { |
| 2649 ASSERT(is_uint2(imm8)); | 2709 ASSERT(is_uint2(imm8)); |
| 2650 EnsureSpace ensure_space(this); | 2710 EnsureSpace ensure_space(this); |
| 2651 last_pc_ = pc_; | 2711 last_pc_ = pc_; |
| 2652 emit(0x66); | 2712 emit(0x66); |
| 2653 emit_optional_rex_32(dst, src); | 2713 emit_optional_rex_32(dst, src); |
| 2654 emit(0x0F); | 2714 emit(0x0F); |
| 2655 emit(0x3A); | 2715 emit(0x3A); |
| 2656 emit(0x17); | 2716 emit(0x17); |
| 2657 emit_sse_operand(dst, src); | 2717 emit_sse_operand(dst, src); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2718 EnsureSpace ensure_space(this); | 2778 EnsureSpace ensure_space(this); |
| 2719 last_pc_ = pc_; | 2779 last_pc_ = pc_; |
| 2720 emit(0xF3); | 2780 emit(0xF3); |
| 2721 emit_optional_rex_32(dst, src); | 2781 emit_optional_rex_32(dst, src); |
| 2722 emit(0x0F); | 2782 emit(0x0F); |
| 2723 emit(0x2C); | 2783 emit(0x2C); |
| 2724 emit_operand(dst, src); | 2784 emit_operand(dst, src); |
| 2725 } | 2785 } |
| 2726 | 2786 |
| 2727 | 2787 |
| 2788 void Assembler::cvttss2si(Register dst, XMMRegister src) { |
| 2789 EnsureSpace ensure_space(this); |
| 2790 last_pc_ = pc_; |
| 2791 emit(0xF3); |
| 2792 emit_optional_rex_32(dst, src); |
| 2793 emit(0x0F); |
| 2794 emit(0x2C); |
| 2795 emit_sse_operand(dst, src); |
| 2796 } |
| 2797 |
| 2798 |
| 2728 void Assembler::cvttsd2si(Register dst, const Operand& src) { | 2799 void Assembler::cvttsd2si(Register dst, const Operand& src) { |
| 2729 EnsureSpace ensure_space(this); | 2800 EnsureSpace ensure_space(this); |
| 2730 last_pc_ = pc_; | 2801 last_pc_ = pc_; |
| 2731 emit(0xF2); | 2802 emit(0xF2); |
| 2732 emit_optional_rex_32(dst, src); | 2803 emit_optional_rex_32(dst, src); |
| 2733 emit(0x0F); | 2804 emit(0x0F); |
| 2734 emit(0x2C); | 2805 emit(0x2C); |
| 2735 emit_operand(dst, src); | 2806 emit_operand(dst, src); |
| 2736 } | 2807 } |
| 2737 | 2808 |
| 2738 | 2809 |
| 2810 void Assembler::cvttsd2si(Register dst, XMMRegister src) { |
| 2811 EnsureSpace ensure_space(this); |
| 2812 last_pc_ = pc_; |
| 2813 emit(0xF2); |
| 2814 emit_optional_rex_32(dst, src); |
| 2815 emit(0x0F); |
| 2816 emit(0x2C); |
| 2817 emit_sse_operand(dst, src); |
| 2818 } |
| 2819 |
| 2820 |
| 2739 void Assembler::cvttsd2siq(Register dst, XMMRegister src) { | 2821 void Assembler::cvttsd2siq(Register dst, XMMRegister src) { |
| 2740 EnsureSpace ensure_space(this); | 2822 EnsureSpace ensure_space(this); |
| 2741 last_pc_ = pc_; | 2823 last_pc_ = pc_; |
| 2742 emit(0xF2); | 2824 emit(0xF2); |
| 2743 emit_rex_64(dst, src); | 2825 emit_rex_64(dst, src); |
| 2744 emit(0x0F); | 2826 emit(0x0F); |
| 2745 emit(0x2C); | 2827 emit(0x2C); |
| 2746 emit_sse_operand(dst, src); | 2828 emit_sse_operand(dst, src); |
| 2747 } | 2829 } |
| 2748 | 2830 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2947 | 3029 |
| 2948 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { | 3030 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { |
| 2949 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); | 3031 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); |
| 2950 } | 3032 } |
| 2951 | 3033 |
| 2952 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { | 3034 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { |
| 2953 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); | 3035 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); |
| 2954 } | 3036 } |
| 2955 | 3037 |
| 2956 | 3038 |
| 3039 void Assembler::db(uint8_t data) { |
| 3040 EnsureSpace ensure_space(this); |
| 3041 emit(data); |
| 3042 } |
| 3043 |
| 3044 |
| 2957 void Assembler::dd(uint32_t data) { | 3045 void Assembler::dd(uint32_t data) { |
| 2958 EnsureSpace ensure_space(this); | 3046 EnsureSpace ensure_space(this); |
| 2959 emitl(data); | 3047 emitl(data); |
| 2960 } | 3048 } |
| 2961 | 3049 |
| 2962 | 3050 |
| 2963 // Relocation information implementations. | 3051 // Relocation information implementations. |
| 2964 | 3052 |
| 2965 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 3053 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
| 2966 ASSERT(rmode != RelocInfo::NONE); | 3054 ASSERT(rmode != RelocInfo::NONE); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3005 // specially coded on x64 means that it is a relative 32 bit address, as used | 3093 // specially coded on x64 means that it is a relative 32 bit address, as used |
| 3006 // by branch instructions. | 3094 // by branch instructions. |
| 3007 return (1 << rmode_) & kApplyMask; | 3095 return (1 << rmode_) & kApplyMask; |
| 3008 } | 3096 } |
| 3009 | 3097 |
| 3010 | 3098 |
| 3011 | 3099 |
| 3012 } } // namespace v8::internal | 3100 } } // namespace v8::internal |
| 3013 | 3101 |
| 3014 #endif // V8_TARGET_ARCH_X64 | 3102 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |