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

Side by Side Diff: src/x64/assembler-x64.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 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/x64/assembler-x64.h ('k') | src/x64/assembler-x64-inl.h » ('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 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { 179 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
180 // Patch the code at the current address with the supplied instructions. 180 // Patch the code at the current address with the supplied instructions.
181 for (int i = 0; i < instruction_count; i++) { 181 for (int i = 0; i < instruction_count; i++) {
182 *(pc_ + i) = *(instructions + i); 182 *(pc_ + i) = *(instructions + i);
183 } 183 }
184 184
185 // Indicate that code has changed. 185 // Indicate that code has changed.
186 CPU::FlushICache(pc_, instruction_count); 186 CPU::FlushICache(pc_, instruction_count);
187 } 187 }
188 188
189
190 // -----------------------------------------------------------------------------
191 // Register constants.
192
193 const int Register::registerCodeByAllocationIndex[kNumAllocatableRegisters] = {
194 // rax, rbx, rdx, rcx, rdi, r8, r9, r11, r14, r12
195 0, 3, 2, 1, 7, 8, 9, 11, 14, 12
196 };
197
198 const int Register::allocationIndexByRegisterCode[kNumRegisters] = {
199 0, 3, 2, 1, -1, -1, -1, 4, 5, 6, -1, 7, 9, -1, 8, -1
200 };
201
202
189 // ----------------------------------------------------------------------------- 203 // -----------------------------------------------------------------------------
190 // Implementation of Operand 204 // Implementation of Operand
191 205
192 Operand::Operand(Register base, int32_t disp) : rex_(0) { 206 Operand::Operand(Register base, int32_t disp) : rex_(0) {
193 len_ = 1; 207 len_ = 1;
194 if (base.is(rsp) || base.is(r12)) { 208 if (base.is(rsp) || base.is(r12)) {
195 // SIB byte is needed to encode (rsp + offset) or (r12 + offset). 209 // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
196 set_sib(times_1, rsp, base); 210 set_sib(times_1, rsp, base);
197 } 211 }
198 212
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } else { 293 } else {
280 // Need no displacement. 294 // Need no displacement.
281 buf_[0] = (modrm & 0x3f); // Mode 0. 295 buf_[0] = (modrm & 0x3f); // Mode 0.
282 len_ = disp_offset; 296 len_ = disp_offset;
283 } 297 }
284 if (has_sib) { 298 if (has_sib) {
285 buf_[1] = operand.buf_[1]; 299 buf_[1] = operand.buf_[1];
286 } 300 }
287 } 301 }
288 302
303
304 bool Operand::AddressUsesRegister(Register reg) const {
305 int code = reg.code();
306 ASSERT((buf_[0] & 0xC0) != 0xC0); // Always a memory operand.
307 // Start with only low three bits of base register. Initial decoding doesn't
308 // distinguish on the REX.B bit.
309 int base_code = buf_[0] & 0x07;
310 if (base_code == rsp.code()) {
311 // SIB byte present in buf_[1].
312 // Check the index register from the SIB byte + REX.X prefix.
313 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
314 // Index code (including REX.X) of 0x04 (rsp) means no index register.
315 if (index_code != rsp.code() && index_code == code) return true;
316 // Add REX.B to get the full base register code.
317 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
318 // A base register of 0x05 (rbp) with mod = 0 means no base register.
319 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
320 return code == base_code;
321 } else {
322 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
323 // no base register.
324 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
325 base_code |= ((rex_ & 0x01) << 3);
326 return code == base_code;
327 }
328 }
329
330
289 // ----------------------------------------------------------------------------- 331 // -----------------------------------------------------------------------------
290 // Implementation of Assembler. 332 // Implementation of Assembler.
291 333
292 #ifdef GENERATED_CODE_COVERAGE 334 #ifdef GENERATED_CODE_COVERAGE
293 static void InitCoverageLog(); 335 static void InitCoverageLog();
294 #endif 336 #endif
295 337
296 byte* Assembler::spare_buffer_ = NULL; 338 byte* Assembler::spare_buffer_ = NULL;
297 339
298 Assembler::Assembler(void* buffer, int buffer_size) 340 Assembler::Assembler(void* buffer, int buffer_size)
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 positions_recorder()->WriteRecordedPositions(); 909 positions_recorder()->WriteRecordedPositions();
868 EnsureSpace ensure_space(this); 910 EnsureSpace ensure_space(this);
869 last_pc_ = pc_; 911 last_pc_ = pc_;
870 // Opcode: FF /2 m64. 912 // Opcode: FF /2 m64.
871 emit_optional_rex_32(op); 913 emit_optional_rex_32(op);
872 emit(0xFF); 914 emit(0xFF);
873 emit_operand(0x2, op); 915 emit_operand(0x2, op);
874 } 916 }
875 917
876 918
919 // Calls directly to the given address using a relative offset.
920 // Should only ever be used in Code objects for calls within the
921 // same Code object. Should not be used when generating new code (use labels),
922 // but only when patching existing code.
923 void Assembler::call(Address target) {
924 positions_recorder()->WriteRecordedPositions();
925 EnsureSpace ensure_space(this);
926 last_pc_ = pc_;
927 // 1110 1000 #32-bit disp.
928 emit(0xE8);
929 Address source = pc_ + 4;
930 intptr_t displacement = target - source;
931 ASSERT(is_int32(displacement));
932 emitl(static_cast<int32_t>(displacement));
933 }
934
935
877 void Assembler::clc() { 936 void Assembler::clc() {
878 EnsureSpace ensure_space(this); 937 EnsureSpace ensure_space(this);
879 last_pc_ = pc_; 938 last_pc_ = pc_;
880 emit(0xF8); 939 emit(0xF8);
881 } 940 }
882 941
883 void Assembler::cdq() { 942 void Assembler::cdq() {
884 EnsureSpace ensure_space(this); 943 EnsureSpace ensure_space(this);
885 last_pc_ = pc_; 944 last_pc_ = pc_;
886 emit(0x99); 945 emit(0x99);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 void Assembler::imull(Register dst, Register src) { 1181 void Assembler::imull(Register dst, Register src) {
1123 EnsureSpace ensure_space(this); 1182 EnsureSpace ensure_space(this);
1124 last_pc_ = pc_; 1183 last_pc_ = pc_;
1125 emit_optional_rex_32(dst, src); 1184 emit_optional_rex_32(dst, src);
1126 emit(0x0F); 1185 emit(0x0F);
1127 emit(0xAF); 1186 emit(0xAF);
1128 emit_modrm(dst, src); 1187 emit_modrm(dst, src);
1129 } 1188 }
1130 1189
1131 1190
1191 void Assembler::imull(Register dst, const Operand& src) {
1192 EnsureSpace ensure_space(this);
1193 last_pc_ = pc_;
1194 emit_optional_rex_32(dst, src);
1195 emit(0x0F);
1196 emit(0xAF);
1197 emit_operand(dst, src);
1198 }
1199
1200
1132 void Assembler::imull(Register dst, Register src, Immediate imm) { 1201 void Assembler::imull(Register dst, Register src, Immediate imm) {
1133 EnsureSpace ensure_space(this); 1202 EnsureSpace ensure_space(this);
1134 last_pc_ = pc_; 1203 last_pc_ = pc_;
1135 emit_optional_rex_32(dst, src); 1204 emit_optional_rex_32(dst, src);
1136 if (is_int8(imm.value_)) { 1205 if (is_int8(imm.value_)) {
1137 emit(0x6B); 1206 emit(0x6B);
1138 emit_modrm(dst, src); 1207 emit_modrm(dst, src);
1139 emit(imm.value_); 1208 emit(imm.value_);
1140 } else { 1209 } else {
1141 emit(0x69); 1210 emit(0x69);
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 if (is_int8(value.value_)) { 1997 if (is_int8(value.value_)) {
1929 emit(0x6A); 1998 emit(0x6A);
1930 emit(value.value_); // Emit low byte of value. 1999 emit(value.value_); // Emit low byte of value.
1931 } else { 2000 } else {
1932 emit(0x68); 2001 emit(0x68);
1933 emitl(value.value_); 2002 emitl(value.value_);
1934 } 2003 }
1935 } 2004 }
1936 2005
1937 2006
2007 void Assembler::push_imm32(int32_t imm32) {
2008 EnsureSpace ensure_space(this);
2009 last_pc_ = pc_;
2010 emit(0x68);
2011 emitl(imm32);
2012 }
2013
2014
1938 void Assembler::pushfq() { 2015 void Assembler::pushfq() {
1939 EnsureSpace ensure_space(this); 2016 EnsureSpace ensure_space(this);
1940 last_pc_ = pc_; 2017 last_pc_ = pc_;
1941 emit(0x9C); 2018 emit(0x9C);
1942 } 2019 }
1943 2020
1944 2021
1945 void Assembler::rdtsc() { 2022 void Assembler::rdtsc() {
1946 EnsureSpace ensure_space(this); 2023 EnsureSpace ensure_space(this);
1947 last_pc_ = pc_; 2024 last_pc_ = pc_;
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
2620 EnsureSpace ensure_space(this); 2697 EnsureSpace ensure_space(this);
2621 last_pc_ = pc_; 2698 last_pc_ = pc_;
2622 emit(0x66); 2699 emit(0x66);
2623 emit_rex_64(src, dst); 2700 emit_rex_64(src, dst);
2624 emit(0x0F); 2701 emit(0x0F);
2625 emit(0x7E); 2702 emit(0x7E);
2626 emit_sse_operand(src, dst); 2703 emit_sse_operand(src, dst);
2627 } 2704 }
2628 2705
2629 2706
2707 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2708 ASSERT(CpuFeatures::IsEnabled(SSE2));
2709 EnsureSpace ensure_space(this);
2710 last_pc_ = pc_;
2711 emit(0x66);
2712 emit_rex_64(src, dst);
2713 emit(0x0F);
2714 emit(0x7F);
2715 emit_sse_operand(src, dst);
2716 }
2717
2718
2719 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2720 ASSERT(CpuFeatures::IsEnabled(SSE2));
2721 EnsureSpace ensure_space(this);
2722 last_pc_ = pc_;
2723 emit(0x66);
2724 emit_rex_64(dst, src);
2725 emit(0x0F);
2726 emit(0x6F);
2727 emit_sse_operand(dst, src);
2728 }
2729
2730
2630 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { 2731 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2631 ASSERT(is_uint2(imm8)); 2732 ASSERT(is_uint2(imm8));
2632 EnsureSpace ensure_space(this); 2733 EnsureSpace ensure_space(this);
2633 last_pc_ = pc_; 2734 last_pc_ = pc_;
2634 emit(0x66); 2735 emit(0x66);
2635 emit_optional_rex_32(dst, src); 2736 emit_optional_rex_32(dst, src);
2636 emit(0x0F); 2737 emit(0x0F);
2637 emit(0x3A); 2738 emit(0x3A);
2638 emit(0x17); 2739 emit(0x17);
2639 emit_sse_operand(dst, src); 2740 emit_sse_operand(dst, src);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2700 EnsureSpace ensure_space(this); 2801 EnsureSpace ensure_space(this);
2701 last_pc_ = pc_; 2802 last_pc_ = pc_;
2702 emit(0xF3); 2803 emit(0xF3);
2703 emit_optional_rex_32(dst, src); 2804 emit_optional_rex_32(dst, src);
2704 emit(0x0F); 2805 emit(0x0F);
2705 emit(0x2C); 2806 emit(0x2C);
2706 emit_operand(dst, src); 2807 emit_operand(dst, src);
2707 } 2808 }
2708 2809
2709 2810
2811 void Assembler::cvttss2si(Register dst, XMMRegister src) {
2812 EnsureSpace ensure_space(this);
2813 last_pc_ = pc_;
2814 emit(0xF3);
2815 emit_optional_rex_32(dst, src);
2816 emit(0x0F);
2817 emit(0x2C);
2818 emit_sse_operand(dst, src);
2819 }
2820
2821
2710 void Assembler::cvttsd2si(Register dst, const Operand& src) { 2822 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2711 EnsureSpace ensure_space(this); 2823 EnsureSpace ensure_space(this);
2712 last_pc_ = pc_; 2824 last_pc_ = pc_;
2713 emit(0xF2); 2825 emit(0xF2);
2714 emit_optional_rex_32(dst, src); 2826 emit_optional_rex_32(dst, src);
2715 emit(0x0F); 2827 emit(0x0F);
2716 emit(0x2C); 2828 emit(0x2C);
2717 emit_operand(dst, src); 2829 emit_operand(dst, src);
2718 } 2830 }
2719 2831
2720 2832
2833 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
2834 EnsureSpace ensure_space(this);
2835 last_pc_ = pc_;
2836 emit(0xF2);
2837 emit_optional_rex_32(dst, src);
2838 emit(0x0F);
2839 emit(0x2C);
2840 emit_sse_operand(dst, src);
2841 }
2842
2843
2721 void Assembler::cvttsd2siq(Register dst, XMMRegister src) { 2844 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
2722 EnsureSpace ensure_space(this); 2845 EnsureSpace ensure_space(this);
2723 last_pc_ = pc_; 2846 last_pc_ = pc_;
2724 emit(0xF2); 2847 emit(0xF2);
2725 emit_rex_64(dst, src); 2848 emit_rex_64(dst, src);
2726 emit(0x0F); 2849 emit(0x0F);
2727 emit(0x2C); 2850 emit(0x2C);
2728 emit_sse_operand(dst, src); 2851 emit_sse_operand(dst, src);
2729 } 2852 }
2730 2853
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2909 EnsureSpace ensure_space(this); 3032 EnsureSpace ensure_space(this);
2910 last_pc_ = pc_; 3033 last_pc_ = pc_;
2911 emit(0x66); 3034 emit(0x66);
2912 emit_optional_rex_32(dst, src); 3035 emit_optional_rex_32(dst, src);
2913 emit(0x0f); 3036 emit(0x0f);
2914 emit(0x2e); 3037 emit(0x2e);
2915 emit_sse_operand(dst, src); 3038 emit_sse_operand(dst, src);
2916 } 3039 }
2917 3040
2918 3041
3042 void Assembler::movmskpd(Register dst, XMMRegister src) {
3043 EnsureSpace ensure_space(this);
3044 last_pc_ = pc_;
3045 emit(0x66);
3046 emit_optional_rex_32(dst, src);
3047 emit(0x0f);
3048 emit(0x50);
3049 emit_sse_operand(dst, src);
3050 }
3051
2919 3052
2920 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 3053 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2921 Register ireg = { reg.code() }; 3054 Register ireg = { reg.code() };
2922 emit_operand(ireg, adr); 3055 emit_operand(ireg, adr);
2923 } 3056 }
2924 3057
2925 3058
2926 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 3059 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2927 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 3060 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2928 } 3061 }
2929 3062
2930 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { 3063 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2931 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 3064 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2932 } 3065 }
2933 3066
2934 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { 3067 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2935 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 3068 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2936 } 3069 }
2937 3070
2938 3071
3072 void Assembler::db(uint8_t data) {
3073 EnsureSpace ensure_space(this);
3074 emit(data);
3075 }
3076
3077
2939 void Assembler::dd(uint32_t data) { 3078 void Assembler::dd(uint32_t data) {
2940 EnsureSpace ensure_space(this); 3079 EnsureSpace ensure_space(this);
2941 emitl(data); 3080 emitl(data);
2942 } 3081 }
2943 3082
2944 3083
2945 // Relocation information implementations. 3084 // Relocation information implementations.
2946 3085
2947 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 3086 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2948 ASSERT(rmode != RelocInfo::NONE); 3087 ASSERT(rmode != RelocInfo::NONE);
2949 // Don't record external references unless the heap will be serialized. 3088 // Don't record external references unless the heap will be serialized.
2950 if (rmode == RelocInfo::EXTERNAL_REFERENCE && 3089 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2951 !Serializer::enabled() && 3090 #ifdef DEBUG
2952 !FLAG_debug_code) { 3091 if (!Serializer::enabled()) {
2953 return; 3092 Serializer::TooLateToEnableNow();
3093 }
3094 #endif
3095 if (!Serializer::enabled() && !FLAG_debug_code) {
3096 return;
3097 }
2954 } 3098 }
2955 RelocInfo rinfo(pc_, rmode, data); 3099 RelocInfo rinfo(pc_, rmode, data);
2956 reloc_info_writer.Write(&rinfo); 3100 reloc_info_writer.Write(&rinfo);
2957 } 3101 }
2958 3102
2959 void Assembler::RecordJSReturn() { 3103 void Assembler::RecordJSReturn() {
2960 positions_recorder()->WriteRecordedPositions(); 3104 positions_recorder()->WriteRecordedPositions();
2961 EnsureSpace ensure_space(this); 3105 EnsureSpace ensure_space(this);
2962 RecordRelocInfo(RelocInfo::JS_RETURN); 3106 RecordRelocInfo(RelocInfo::JS_RETURN);
2963 } 3107 }
(...skipping 23 matching lines...) Expand all
2987 // specially coded on x64 means that it is a relative 32 bit address, as used 3131 // specially coded on x64 means that it is a relative 32 bit address, as used
2988 // by branch instructions. 3132 // by branch instructions.
2989 return (1 << rmode_) & kApplyMask; 3133 return (1 << rmode_) & kApplyMask;
2990 } 3134 }
2991 3135
2992 3136
2993 3137
2994 } } // namespace v8::internal 3138 } } // namespace v8::internal
2995 3139
2996 #endif // V8_TARGET_ARCH_X64 3140 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/assembler-x64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698