v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
assembler-x64-inl.h
Go to the documentation of this file.
1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_CODEGEN_X64_ASSEMBLER_X64_INL_H_
6#define V8_CODEGEN_X64_ASSEMBLER_X64_INL_H_
7
9// Include the non-inl header before the rest of the headers.
10
11#include "src/base/cpu.h"
12#include "src/base/memory.h"
14#include "src/debug/debug.h"
17
18namespace v8 {
19namespace internal {
20
21bool CpuFeatures::SupportsOptimizer() { return true; }
22
23// -----------------------------------------------------------------------------
24// Implementation of Assembler
25
27 emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit());
28}
29
31 emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
32}
33
35 emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
36}
37
39 emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
40}
41
43 emit(0x48 | reg.high_bit() << 2 | op.rex());
44}
45
47 emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex());
48}
49
51 DCHECK_EQ(rm_reg.code() & 0xf, rm_reg.code());
52 emit(0x48 | rm_reg.high_bit());
53}
54
55void Assembler::emit_rex_64(Operand op) { emit(0x48 | op.rex()); }
56
58 emit(0x40 | reg.high_bit() << 2 | rm_reg.high_bit());
59}
60
62 emit(0x40 | reg.high_bit() << 2 | op.rex());
63}
64
65void Assembler::emit_rex_32(Register rm_reg) { emit(0x40 | rm_reg.high_bit()); }
66
67void Assembler::emit_rex_32(Operand op) { emit(0x40 | op.rex()); }
68
70 uint8_t rex_bits = reg.high_bit() << 2 | rm_reg.high_bit();
71 if (rex_bits != 0) emit(0x40 | rex_bits);
72}
73
75 uint8_t rex_bits = reg.high_bit() << 2 | op.rex();
76 if (rex_bits != 0) emit(0x40 | rex_bits);
77}
78
80 uint8_t rex_bits = (reg.code() & 0x8) >> 1 | op.rex();
81 if (rex_bits != 0) emit(0x40 | rex_bits);
82}
83
85 uint8_t rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
86 if (rex_bits != 0) emit(0x40 | rex_bits);
87}
88
90 uint8_t rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
91 if (rex_bits != 0) emit(0x40 | rex_bits);
92}
93
95 uint8_t rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
96 if (rex_bits != 0) emit(0x40 | rex_bits);
97}
98
100 if (rm_reg.high_bit()) emit(0x41);
101}
102
104 if (rm_reg.high_bit()) emit(0x41);
105}
106
108 if (op.rex() != 0) emit(0x40 | op.rex());
109}
110
112 if (!reg.is_byte_register()) {
113 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
115 }
116}
117
119 if (!reg.is_byte_register()) {
120 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
121 emit_rex_32(reg, op);
122 } else {
124 }
125}
126
127// byte 1 of 3-byte VEX
130 uint8_t rxb = static_cast<uint8_t>(~((reg.high_bit() << 2) | rm.high_bit()))
131 << 5;
132 emit(rxb | m);
133}
134
135// byte 1 of 3-byte VEX
137 uint8_t rxb = static_cast<uint8_t>(~((reg.high_bit() << 2) | rm.rex())) << 5;
138 emit(rxb | m);
139}
140
141// byte 1 of 2-byte VEX
143 SIMDPrefix pp) {
144 uint8_t rv = static_cast<uint8_t>(~((reg.high_bit() << 4) | v.code())) << 3;
145 emit(rv | l | pp);
146}
147
148// byte 2 of 3-byte VEX
150 SIMDPrefix pp) {
151 emit(w | ((~v.code() & 0xf) << 3) | l | pp);
152}
153
156 LeadingOpcode mm, VexW w) {
157 if (rm.high_bit() || mm != k0F || w != kW0) {
159 emit_vex3_byte1(reg, rm, mm);
160 emit_vex3_byte2(w, vreg, l, pp);
161 } else {
163 emit_vex2_byte1(reg, vreg, l, pp);
164 }
165}
166
169 VexW w) {
173 emit_vex_prefix(ireg, ivreg, irm, l, pp, mm, w);
174}
175
178 VexW w) {
179 if (rm.rex() || mm != k0F || w != kW0) {
181 emit_vex3_byte1(reg, rm, mm);
182 emit_vex3_byte2(w, vreg, l, pp);
183 } else {
185 emit_vex2_byte1(reg, vreg, l, pp);
186 }
187}
188
191 VexW w) {
194 emit_vex_prefix(ireg, ivreg, rm, l, pp, mm, w);
195}
196
198 return ReadUnalignedValue<int32_t>(pc) + pc + 4;
199}
200
202 Address target,
203 WritableJitAllocation* jit_allocation,
204 ICacheFlushMode icache_flush_mode) {
205 if (jit_allocation) {
206 jit_allocation->WriteUnalignedValue(pc, relative_target_offset(target, pc));
207 } else {
208 WriteUnalignedValue(pc, relative_target_offset(target, pc));
209 }
210 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
211 FlushInstructionCache(pc, sizeof(int32_t));
212 }
213}
214
216 Address offset = target - pc - 4;
217 DCHECK(is_int32(offset));
218 return static_cast<int32_t>(offset);
219}
220
222 Address pc, Address target, WritableJitAllocation& jit_allocation,
223 RelocInfo::Mode mode) {
224 jit_allocation.WriteUnalignedValue(pc, target);
225}
226
228 Address instruction_payload) {
229 return kSpecialTargetSize;
230}
231
233 return GetCodeTarget(ReadUnalignedValue<int32_t>(pc));
234}
235
240
242 int32_t builtin_id = ReadUnalignedValue<int32_t>(pc);
243 DCHECK(Builtins::IsBuiltinId(builtin_id));
244 return static_cast<Builtin>(builtin_id);
245}
246
248 return ReadUnalignedValue<uint32_t>(pc);
249}
250
252 uint32_t new_constant,
253 WritableJitAllocation* jit_allocation,
254 ICacheFlushMode icache_flush_mode) {
255 if (jit_allocation) {
256 jit_allocation->WriteUnalignedValue<uint32_t>(pc, new_constant);
257 } else {
258 WriteUnalignedValue<uint32_t>(pc, new_constant);
259 }
260 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
261 FlushInstructionCache(pc, sizeof(uint32_t));
262 }
263}
264
265// -----------------------------------------------------------------------------
266// Implementation of RelocInfo
267
268// The modes possibly affected by apply must be in kApplyMask.
269void WritableRelocInfo::apply(intptr_t delta) {
273 pc_, ReadUnalignedValue<int32_t>(pc_) - static_cast<int32_t>(delta));
274 } else if (IsInternalReference(rmode_)) {
275 // Absolute code pointer inside code object moves with the code object.
277 pc_, ReadUnalignedValue<Address>(pc_) + delta);
278 }
279}
280
285}
286
291 return pc_;
292}
293
295
297 if (IsCodedSpecially()) {
299 } else {
302 }
303}
304
305Tagged<HeapObject> RelocInfo::target_object(PtrComprCageBase cage_base) {
308 Tagged_t compressed = ReadUnalignedValue<Tagged_t>(pc_);
309 DCHECK(!HAS_SMI_TAG(compressed));
310 Tagged<Object> obj(
311 V8HeapCompressionScheme::DecompressTagged(cage_base, compressed));
312 return Cast<HeapObject>(obj);
313 }
315 return Cast<HeapObject>(Tagged<Object>(ReadUnalignedValue<Address>(pc_)));
316}
317
318DirectHandle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
320 if (IsCodeTarget(rmode_)) {
321 return origin->code_target_object_handle_at(pc_);
322 } else {
324 return origin->compressed_embedded_object_handle_at(pc_);
325 }
327 return Cast<HeapObject>(ReadUnalignedValue<IndirectHandle<Object>>(pc_));
328 }
329}
330
333 return ReadUnalignedValue<Address>(pc_);
334}
335
337 Address target, ICacheFlushMode icache_flush_mode) {
340 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
342 }
343}
344
345WasmCodePointer RelocInfo::wasm_code_pointer_table_entry() const {
347 return WasmCodePointer{ReadUnalignedValue<uint32_t>(pc_)};
348}
349
351 WasmCodePointer target, ICacheFlushMode icache_flush_mode) {
353 jit_allocation_.WriteUnalignedValue(pc_, target.value());
354 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
356 }
357}
358
361 return ReadUnalignedValue<Address>(pc_);
362}
363
366 return pc_;
367}
368
371 return ReadUnalignedValue<JSDispatchHandle>(pc_);
372}
373
375 ICacheFlushMode icache_flush_mode) {
379 // We must not compress pointers to objects outside of the main pointer
380 // compression cage as we wouldn't be able to decompress them with the
381 // correct cage base.
384 !HeapLayout::InCodeSpace(target));
387 } else {
390 }
391 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
393 }
394}
395
396Builtin RelocInfo::target_builtin_at(Assembler* origin) {
399}
400
403 return ReadUnalignedValue<Address>(pc_);
404}
405
406} // namespace internal
407} // namespace v8
408
409#endif // V8_CODEGEN_X64_ASSEMBLER_X64_INL_H_
IndirectHandle< Code > GetCodeTarget(intptr_t code_target_index) const
Definition assembler.cc:279
IndirectHandle< HeapObject > GetEmbeddedObject(EmbeddedObjectIndex index) const
Definition assembler.cc:300
static int32_t relative_target_offset(Address target, Address pc)
static constexpr int kSpecialTargetSize
static void deserialization_set_target_internal_reference_at(Address pc, Address target, WritableJitAllocation &jit_allocation, RelocInfo::Mode mode=RelocInfo::INTERNAL_REFERENCE)
void emit_optional_rex_8(Register reg)
static void set_uint32_constant_at(Address pc, Address constant_pool, uint32_t new_constant, WritableJitAllocation *jit_allocation, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void emit_optional_rex_32(Register reg, Register rm_reg)
void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m)
void emit_rex_32(Register reg, Register rm_reg)
static V8_INLINE void set_target_address_at(Address pc, Address constant_pool, Address target, WritableJitAllocation *jit_allocation, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
Handle< HeapObject > compressed_embedded_object_handle_at(Address pc, Address constant_pool)
void emit_vex_prefix(XMMRegister v, VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w)
static Builtin target_builtin_at(Address pc)
static int deserialization_special_target_size(Address location)
void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l, SIMDPrefix pp)
static V8_INLINE Address target_address_at(Address pc, Address constant_pool)
void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l, SIMDPrefix pp)
Instruction * pc() const
Handle< Code > code_target_object_handle_at(Address pc)
static uint32_t uint32_constant_at(Address pc, Address constant_pool)
static constexpr bool IsBuiltinId(Builtin builtin)
Definition builtins.h:128
static V8_INLINE bool InTrustedSpace(Tagged< HeapObject > object)
static V8_INLINE bool InCodeSpace(Tagged< HeapObject > object)
V8_INLINE constexpr uint8_t rex() const
static constexpr XMMRegister from_code(int8_t code)
constexpr int8_t code() const
constexpr int high_bit() const
V8_INLINE Address target_internal_reference()
static constexpr bool IsInternalReference(Mode mode)
Definition reloc-info.h:238
static constexpr bool IsOffHeapTarget(Mode mode)
Definition reloc-info.h:244
static constexpr bool IsCompressedEmbeddedObject(Mode mode)
Definition reloc-info.h:206
V8_INLINE Address target_address()
static constexpr bool IsNearBuiltinEntry(Mode mode)
Definition reloc-info.h:247
V8_INLINE Address target_internal_reference_address()
static constexpr bool IsCodeTarget(Mode mode)
Definition reloc-info.h:196
static constexpr bool IsWasmCall(Mode mode)
Definition reloc-info.h:213
V8_INLINE int target_address_size()
V8_INLINE Builtin target_builtin_at(Assembler *origin)
V8_INLINE WasmCodePointer wasm_code_pointer_table_entry() const
V8_INLINE Address target_off_heap_target()
static constexpr bool IsWasmStubCall(Mode mode)
Definition reloc-info.h:214
static constexpr bool IsEmbeddedObjectMode(Mode mode)
Definition reloc-info.h:209
static constexpr bool IsExternalReference(Mode mode)
Definition reloc-info.h:235
V8_INLINE Address target_external_reference()
V8_INLINE Tagged< HeapObject > target_object(PtrComprCageBase cage_base)
V8_INLINE Address constant_pool_entry_address()
V8_INLINE JSDispatchHandle js_dispatch_handle()
V8_INLINE DirectHandle< HeapObject > target_object_handle(Assembler *origin)
static constexpr bool IsFullEmbeddedObject(Mode mode)
Definition reloc-info.h:203
V8_INLINE Address target_address_address()
static V8_INLINE Tagged_t CompressObject(Address tagged)
static V8_INLINE Address DecompressTagged(TOnHeapAddress on_heap_addr, Tagged_t raw_value)
V8_INLINE void WriteUnalignedValue(Address address, T value)
V8_INLINE void set_target_object(Tagged< InstructionStream > host, Tagged< HeapObject > target, WriteBarrierMode write_barrier_mode=UPDATE_WRITE_BARRIER, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
WritableJitAllocation & jit_allocation_
Definition reloc-info.h:462
V8_INLINE void set_wasm_code_pointer_table_entry(WasmCodePointer, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
V8_INLINE void apply(intptr_t delta)
V8_INLINE void set_target_external_reference(Address, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
#define V8_EXTERNAL_CODE_SPACE_BOOL
Definition globals.h:255
#define COMPRESS_POINTERS_BOOL
Definition globals.h:99
#define HAS_SMI_TAG(value)
Definition globals.h:1771
#define V8_ENABLE_SANDBOX_BOOL
Definition globals.h:160
int32_t offset
LiftoffRegister reg
int m
Definition mul-fft.cc:294
int int32_t
Definition unicode.cc:40
constexpr int kTaggedSize
Definition globals.h:542
void FlushInstructionCache(void *start, size_t size)
kInterpreterTrampolineOffset Tagged< HeapObject >
Address Tagged_t
Definition globals.h:547
base::StrongAlias< JSDispatchHandleAliasTag, uint32_t > JSDispatchHandle
Definition globals.h:557
constexpr int kSystemPointerSize
Definition globals.h:410
Handle< T > IndirectHandle
Definition globals.h:1086
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485