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

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

Issue 151163005: A64: Synchronize with r16356. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 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/builtins-x64.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures); 56 ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures);
57 #ifdef DEBUG 57 #ifdef DEBUG
58 initialized_ = true; 58 initialized_ = true;
59 #endif 59 #endif
60 supported_ = kDefaultCpuFeatures; 60 supported_ = kDefaultCpuFeatures;
61 if (Serializer::enabled()) { 61 if (Serializer::enabled()) {
62 supported_ |= OS::CpuFeaturesImpliedByPlatform(); 62 supported_ |= OS::CpuFeaturesImpliedByPlatform();
63 return; // No features if we might serialize. 63 return; // No features if we might serialize.
64 } 64 }
65 65
66 const int kBufferSize = 4 * KB; 66 uint64_t probed_features = 0;
67 VirtualMemory* memory = new VirtualMemory(kBufferSize); 67 CPU cpu;
68 if (!memory->IsReserved()) { 68 if (cpu.has_sse41()) {
69 delete memory; 69 probed_features |= static_cast<uint64_t>(1) << SSE4_1;
70 return;
71 } 70 }
72 ASSERT(memory->size() >= static_cast<size_t>(kBufferSize)); 71 if (cpu.has_sse3()) {
73 if (!memory->Commit(memory->address(), kBufferSize, true/*executable*/)) { 72 probed_features |= static_cast<uint64_t>(1) << SSE3;
74 delete memory;
75 return;
76 } 73 }
77 74
78 Assembler assm(NULL, memory->address(), kBufferSize); 75 // SSE2 must be available on every x64 CPU.
79 Label cpuid, done; 76 ASSERT(cpu.has_sse2());
80 #define __ assm. 77 probed_features |= static_cast<uint64_t>(1) << SSE2;
81 // Save old rsp, since we are going to modify the stack.
82 __ push(rbp);
83 __ pushfq();
84 __ push(rdi);
85 __ push(rcx);
86 __ push(rbx);
87 __ movq(rbp, rsp);
88 78
89 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. 79 // CMOD must be available on every x64 CPU.
90 __ pushfq(); 80 ASSERT(cpu.has_cmov());
91 __ pop(rax); 81 probed_features |= static_cast<uint64_t>(1) << CMOV;
92 __ movq(rdx, rax);
93 __ xor_(rax, Immediate(0x200000)); // Flip bit 21.
94 __ push(rax);
95 __ popfq();
96 __ pushfq();
97 __ pop(rax);
98 __ xor_(rax, rdx); // Different if CPUID is supported.
99 __ j(not_zero, &cpuid);
100 82
101 // CPUID not supported. Clear the supported features in rax. 83 // SAHF is not generally available in long mode.
102 __ xor_(rax, rax); 84 if (cpu.has_sahf()) {
103 __ jmp(&done); 85 probed_features |= static_cast<uint64_t>(1) << SAHF;
86 }
104 87
105 // Invoke CPUID with 1 in eax to get feature information in
106 // ecx:edx. Temporarily enable CPUID support because we know it's
107 // safe here.
108 __ bind(&cpuid);
109 __ movl(rax, Immediate(1));
110 supported_ = kDefaultCpuFeatures | (1 << CPUID);
111 { CpuFeatureScope fscope(&assm, CPUID);
112 __ cpuid();
113 // Move the result from ecx:edx to rdi.
114 __ movl(rdi, rdx); // Zero-extended to 64 bits.
115 __ shl(rcx, Immediate(32));
116 __ or_(rdi, rcx);
117
118 // Get the sahf supported flag, from CPUID(0x80000001)
119 __ movq(rax, 0x80000001, RelocInfo::NONE64);
120 __ cpuid();
121 }
122 supported_ = kDefaultCpuFeatures;
123
124 // Put the CPU flags in rax.
125 // rax = (rcx & 1) | (rdi & ~1) | (1 << CPUID).
126 __ movl(rax, Immediate(1));
127 __ and_(rcx, rax); // Bit 0 is set if SAHF instruction supported.
128 __ not_(rax);
129 __ and_(rax, rdi);
130 __ or_(rax, rcx);
131 __ or_(rax, Immediate(1 << CPUID));
132
133 // Done.
134 __ bind(&done);
135 __ movq(rsp, rbp);
136 __ pop(rbx);
137 __ pop(rcx);
138 __ pop(rdi);
139 __ popfq();
140 __ pop(rbp);
141 __ ret(0);
142 #undef __
143
144 typedef uint64_t (*F0)();
145 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address()));
146
147 uint64_t probed_features = probe();
148 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform(); 88 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform();
149 supported_ = probed_features | platform_features; 89 supported_ = probed_features | platform_features;
150 found_by_runtime_probing_only_ 90 found_by_runtime_probing_only_
151 = probed_features & ~kDefaultCpuFeatures & ~platform_features; 91 = probed_features & ~kDefaultCpuFeatures & ~platform_features;
152
153 // CMOV must be available on an X64 CPU.
154 ASSERT(IsSupported(CPUID));
155 ASSERT(IsSupported(CMOV));
156
157 delete memory;
158 } 92 }
159 93
160 94
161 // ----------------------------------------------------------------------------- 95 // -----------------------------------------------------------------------------
162 // Implementation of RelocInfo 96 // Implementation of RelocInfo
163 97
164 // Patch the code at the current PC with a call to the target address. 98 // Patch the code at the current PC with a call to the target address.
165 // Additional guard int3 instructions can be added if required. 99 // Additional guard int3 instructions can be added if required.
166 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 100 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
167 int code_size = Assembler::kCallSequenceLength + guard_bytes; 101 int code_size = Assembler::kCallSequenceLength + guard_bytes;
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 914
981 void Assembler::cmpb_al(Immediate imm8) { 915 void Assembler::cmpb_al(Immediate imm8) {
982 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_)); 916 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
983 EnsureSpace ensure_space(this); 917 EnsureSpace ensure_space(this);
984 emit(0x3c); 918 emit(0x3c);
985 emit(imm8.value_); 919 emit(imm8.value_);
986 } 920 }
987 921
988 922
989 void Assembler::cpuid() { 923 void Assembler::cpuid() {
990 ASSERT(IsEnabled(CPUID));
991 EnsureSpace ensure_space(this); 924 EnsureSpace ensure_space(this);
992 emit(0x0F); 925 emit(0x0F);
993 emit(0xA2); 926 emit(0xA2);
994 } 927 }
995 928
996 929
997 void Assembler::cqo() { 930 void Assembler::cqo() {
998 EnsureSpace ensure_space(this); 931 EnsureSpace ensure_space(this);
999 emit_rex_64(); 932 emit_rex_64();
1000 emit(0x99); 933 emit(0x99);
(...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after
1912 emitl(imm32); 1845 emitl(imm32);
1913 } 1846 }
1914 1847
1915 1848
1916 void Assembler::pushfq() { 1849 void Assembler::pushfq() {
1917 EnsureSpace ensure_space(this); 1850 EnsureSpace ensure_space(this);
1918 emit(0x9C); 1851 emit(0x9C);
1919 } 1852 }
1920 1853
1921 1854
1922 void Assembler::rdtsc() {
1923 EnsureSpace ensure_space(this);
1924 emit(0x0F);
1925 emit(0x31);
1926 }
1927
1928
1929 void Assembler::ret(int imm16) { 1855 void Assembler::ret(int imm16) {
1930 EnsureSpace ensure_space(this); 1856 EnsureSpace ensure_space(this);
1931 ASSERT(is_uint16(imm16)); 1857 ASSERT(is_uint16(imm16));
1932 if (imm16 == 0) { 1858 if (imm16 == 0) {
1933 emit(0xC3); 1859 emit(0xC3);
1934 } else { 1860 } else {
1935 emit(0xC2); 1861 emit(0xC2);
1936 emit(imm16 & 0xFF); 1862 emit(imm16 & 0xFF);
1937 emit((imm16 >> 8) & 0xFF); 1863 emit((imm16 >> 8) & 0xFF);
1938 } 1864 }
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after
2985 void Assembler::ucomisd(XMMRegister dst, const Operand& src) { 2911 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
2986 EnsureSpace ensure_space(this); 2912 EnsureSpace ensure_space(this);
2987 emit(0x66); 2913 emit(0x66);
2988 emit_optional_rex_32(dst, src); 2914 emit_optional_rex_32(dst, src);
2989 emit(0x0f); 2915 emit(0x0f);
2990 emit(0x2e); 2916 emit(0x2e);
2991 emit_sse_operand(dst, src); 2917 emit_sse_operand(dst, src);
2992 } 2918 }
2993 2919
2994 2920
2921 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
2922 EnsureSpace ensure_space(this);
2923 emit(0xF2);
2924 emit_optional_rex_32(dst, src);
2925 emit(0x0F);
2926 emit(0xC2);
2927 emit_sse_operand(dst, src);
2928 emit(0x01); // LT == 1
2929 }
2930
2931
2995 void Assembler::roundsd(XMMRegister dst, XMMRegister src, 2932 void Assembler::roundsd(XMMRegister dst, XMMRegister src,
2996 Assembler::RoundingMode mode) { 2933 Assembler::RoundingMode mode) {
2997 ASSERT(IsEnabled(SSE4_1)); 2934 ASSERT(IsEnabled(SSE4_1));
2998 EnsureSpace ensure_space(this); 2935 EnsureSpace ensure_space(this);
2999 emit(0x66); 2936 emit(0x66);
3000 emit_optional_rex_32(dst, src); 2937 emit_optional_rex_32(dst, src);
3001 emit(0x0f); 2938 emit(0x0f);
3002 emit(0x3a); 2939 emit(0x3a);
3003 emit(0x0b); 2940 emit(0x0b);
3004 emit_sse_operand(dst, src); 2941 emit_sse_operand(dst, src);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 bool RelocInfo::IsCodedSpecially() { 3047 bool RelocInfo::IsCodedSpecially() {
3111 // The deserializer needs to know whether a pointer is specially coded. Being 3048 // The deserializer needs to know whether a pointer is specially coded. Being
3112 // specially coded on x64 means that it is a relative 32 bit address, as used 3049 // specially coded on x64 means that it is a relative 32 bit address, as used
3113 // by branch instructions. 3050 // by branch instructions.
3114 return (1 << rmode_) & kApplyMask; 3051 return (1 << rmode_) & kApplyMask;
3115 } 3052 }
3116 3053
3117 } } // namespace v8::internal 3054 } } // namespace v8::internal
3118 3055
3119 #endif // V8_TARGET_ARCH_X64 3056 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/builtins-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698