v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
assembler-s390-inl.h
Go to the documentation of this file.
1// Copyright (c) 1994-2006 Sun Microsystems Inc.
2// All Rights Reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7//
8// - Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10//
11// - Redistribution in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the
14// distribution.
15//
16// - Neither the name of Sun Microsystems or the names of contributors may
17// be used to endorse or promote products derived from this software without
18// specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31// OF THE POSSIBILITY OF SUCH DAMAGE.
32
33// The original source code covered by the above license above has been modified
34// significantly by Google Inc.
35// Copyright 2014 the V8 project authors. All rights reserved.
36
37#ifndef V8_CODEGEN_S390_ASSEMBLER_S390_INL_H_
38#define V8_CODEGEN_S390_ASSEMBLER_S390_INL_H_
39
41// Include the non-inl header before the rest of the headers.
42
45#include "src/debug/debug.h"
47
48namespace v8 {
49namespace internal {
50
51bool CpuFeatures::SupportsOptimizer() { return true; }
52
53void WritableRelocInfo::apply(intptr_t delta) {
54 // Absolute code pointer inside code object moves with the code object.
56 // Jump table entry
57 Address target = Memory<Address>(pc_);
58 jit_allocation_.WriteValue(pc_, target + delta);
59 } else if (IsCodeTarget(rmode_)) {
61 Instruction::InstructionBits(reinterpret_cast<const uint8_t*>(pc_));
62 int32_t dis = static_cast<int32_t>(instr & 0xFFFFFFFF) * 2 // halfwords
63 - static_cast<int32_t>(delta);
64 instr >>= 32; // Clear the 4-byte displacement field.
65 instr <<= 32;
66 instr |= static_cast<uint32_t>(dis / 2);
68 reinterpret_cast<uint8_t*>(pc_), instr, &jit_allocation_);
69 } else {
70 // mov sequence
75 }
76}
77
80 // Jump table entry
81 return Memory<Address>(pc_);
82 } else {
83 // mov sequence
86 }
87}
88
91 return pc_;
92}
93
98}
99
102
103 // Read the address of the word containing the target_address in an
104 // instruction stream.
105 // The only architecture-independent user of this function is the serializer.
106 // The serializer uses it to find out how many raw bytes of instruction to
107 // output before the next target.
108 // For an instruction like LIS/ORI where the target bits are mixed into the
109 // instruction bits, the size of the target will be zero, indicating that the
110 // serializer should not step forward in memory after a target is resolved
111 // and written.
112 return pc_;
113}
114
116
119 WritableJitAllocation* jit_allocation, ICacheFlushMode icache_flush_mode) {
121 static_cast<Address>(target), jit_allocation,
122 icache_flush_mode);
123}
124
126 if (IsCodedSpecially()) {
128 } else {
129 return kSystemPointerSize;
130 }
131}
132
135 return static_cast<Tagged_t>(target_address_at(pc, constant_pool));
136}
137
140 Instruction::InstructionBits(reinterpret_cast<const uint8_t*>(pc));
141 int index = instr & 0xFFFFFFFF;
142 return GetCodeTarget(index);
143}
144
145Tagged<HeapObject> RelocInfo::target_object(PtrComprCageBase cage_base) {
148 return Cast<HeapObject>(
150 cage_base,
152 } else {
153 return Cast<HeapObject>(
155 }
156}
157
159 Address pc, Address const_pool) {
161}
162
163DirectHandle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
167 return Cast<HeapObject>(origin->code_target_object_handle_at(pc_));
168 } else {
170 return origin->compressed_embedded_object_handle_at(pc_, constant_pool_);
171 }
172 return DirectHandle<HeapObject>::FromSlot(reinterpret_cast<Address*>(
174 }
175}
176
178 ICacheFlushMode icache_flush_mode) {
184 icache_flush_mode);
185 } else {
188 &jit_allocation_, icache_flush_mode);
189 }
190}
191
195}
196
198 Address target, ICacheFlushMode icache_flush_mode) {
201 &jit_allocation_, icache_flush_mode);
202}
203
204WasmCodePointer RelocInfo::wasm_code_pointer_table_entry() const {
206 return WasmCodePointer{Assembler::uint32_constant_at(pc_, constant_pool_)};
207}
208
210 WasmCodePointer target, ICacheFlushMode icache_flush_mode) {
213 &jit_allocation_, icache_flush_mode);
214}
215
219}
220
221Builtin RelocInfo::target_builtin_at(Assembler* origin) { UNREACHABLE(); }
222
226}
227
228// Operand constructors
229Operand::Operand(Register rm) : rm_(rm), rmode_(RelocInfo::NO_INFO) {}
230
231// Fetch the 32bit value from the FIXED_SEQUENCE IIHF / IILF
232Address Assembler::target_address_at(Address pc, Address constant_pool) {
233 // S390 Instruction!
234 // We want to check for instructions generated by Asm::mov()
235 Opcode op1 =
236 Instruction::S390OpcodeValue(reinterpret_cast<const uint8_t*>(pc));
237 SixByteInstr instr_1 =
238 Instruction::InstructionBits(reinterpret_cast<const uint8_t*>(pc));
239
240 if (BRASL == op1 || BRCL == op1) {
241 int32_t dis = static_cast<int32_t>(instr_1 & 0xFFFFFFFF) * 2;
242 return pc + dis;
243 }
244
245 int instr1_length =
246 Instruction::InstructionLength(reinterpret_cast<const uint8_t*>(pc));
247 Opcode op2 = Instruction::S390OpcodeValue(
248 reinterpret_cast<const uint8_t*>(pc + instr1_length));
249 SixByteInstr instr_2 = Instruction::InstructionBits(
250 reinterpret_cast<const uint8_t*>(pc + instr1_length));
251 // IIHF for hi_32, IILF for lo_32
252 if (IIHF == op1 && IILF == op2) {
253 return static_cast<Address>(((instr_1 & 0xFFFFFFFF) << 32) |
254 ((instr_2 & 0xFFFFFFFF)));
255 }
256
258 return 0;
259}
260
261int Assembler::deserialization_special_target_size(
262 Address instruction_payload) {
263 return kSpecialTargetSize;
264}
265
266void Assembler::deserialization_set_target_internal_reference_at(
267 Address pc, Address target, WritableJitAllocation& jit_allocation,
268 RelocInfo::Mode mode) {
269 if (RelocInfo::IsInternalReferenceEncoded(mode)) {
270 set_target_address_at(pc, kNullAddress, target, &jit_allocation,
271 SKIP_ICACHE_FLUSH);
272 } else {
273 jit_allocation.WriteUnalignedValue<Address>(pc, target);
274 }
275}
276
277// This code assumes the FIXED_SEQUENCE of IIHF/IILF
278void Assembler::set_target_address_at(Address pc, Address constant_pool,
279 Address target,
280 WritableJitAllocation* jit_allocation,
281 ICacheFlushMode icache_flush_mode) {
282 // Check for instructions generated by Asm::mov()
283 Opcode op1 =
284 Instruction::S390OpcodeValue(reinterpret_cast<const uint8_t*>(pc));
285 SixByteInstr instr_1 =
286 Instruction::InstructionBits(reinterpret_cast<const uint8_t*>(pc));
287 bool patched = false;
288
289 if (BRASL == op1 || BRCL == op1) {
290 instr_1 >>= 32; // Zero out the lower 32-bits
291 instr_1 <<= 32;
292 int32_t halfwords = (target - pc) / 2; // number of halfwords
293 instr_1 |= static_cast<uint32_t>(halfwords);
294 Instruction::SetInstructionBits<SixByteInstr>(
295 reinterpret_cast<uint8_t*>(pc), instr_1, jit_allocation);
296 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
298 }
299 patched = true;
300 } else {
301 int instr1_length =
302 Instruction::InstructionLength(reinterpret_cast<const uint8_t*>(pc));
303 Opcode op2 = Instruction::S390OpcodeValue(
304 reinterpret_cast<const uint8_t*>(pc + instr1_length));
305 SixByteInstr instr_2 = Instruction::InstructionBits(
306 reinterpret_cast<const uint8_t*>(pc + instr1_length));
307 // IIHF for hi_32, IILF for lo_32
308 if (IIHF == op1 && IILF == op2) {
309 // IIHF
310 instr_1 >>= 32; // Zero out the lower 32-bits
311 instr_1 <<= 32;
312 instr_1 |= reinterpret_cast<uint64_t>(target) >> 32;
313
314 Instruction::SetInstructionBits<SixByteInstr>(
315 reinterpret_cast<uint8_t*>(pc), instr_1, jit_allocation);
316
317 // IILF
318 instr_2 >>= 32;
319 instr_2 <<= 32;
320 instr_2 |= reinterpret_cast<uint64_t>(target) & 0xFFFFFFFF;
321
322 Instruction::SetInstructionBits<SixByteInstr>(
323 reinterpret_cast<uint8_t*>(pc + instr1_length), instr_2,
324 jit_allocation);
325 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
327 }
328 patched = true;
329 }
330 }
331 if (!patched) UNREACHABLE();
332}
333
334uint32_t Assembler::uint32_constant_at(Address pc, Address constant_pool) {
335 return static_cast<uint32_t>(Assembler::target_address_at(pc, constant_pool));
336}
337
338void Assembler::set_uint32_constant_at(Address pc, Address constant_pool,
339 uint32_t new_constant,
340 WritableJitAllocation* jit_allocation,
341 ICacheFlushMode icache_flush_mode) {
342 Assembler::set_target_address_at(pc, constant_pool,
343 static_cast<Address>(new_constant),
344 jit_allocation, icache_flush_mode);
345}
346
347} // namespace internal
348} // namespace v8
349
350#endif // V8_CODEGEN_S390_ASSEMBLER_S390_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 constexpr int kSpecialTargetSize
static Tagged_t target_compressed_address_at(Address pc, Address constant_pool)
static void set_target_compressed_address_at(Address pc, Address constant_pool, Tagged_t target, WritableJitAllocation *jit_allocation, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
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)
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)
static V8_INLINE Address target_address_at(Address pc, Address constant_pool)
Instruction * pc() const
Handle< Code > code_target_object_handle_at(Address pc)
static uint32_t uint32_constant_at(Address pc, Address constant_pool)
static V8_INLINE DirectHandle FromSlot(Address *slot)
Definition handles.h:687
V8_EXPORT_PRIVATE void SetInstructionBits(Instr value, WritableJitAllocation *jit_allocation=nullptr)
V8_INLINE Operand(int32_t immediate, RelocInfo::Mode rmode=RelocInfo::NO_INFO)
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 IsRelativeCodeTarget(Mode mode)
Definition reloc-info.h:200
static constexpr bool IsCompressedEmbeddedObject(Mode mode)
Definition reloc-info.h:206
V8_INLINE Address target_address()
static constexpr bool IsInternalReferenceEncoded(Mode mode)
Definition reloc-info.h:241
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
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
bool HasTargetAddressAddress() const
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 WriteValue(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)
TNode< Object > target
Instruction * instr
int int32_t
Definition unicode.cc:40
uintptr_t Address
Definition memory.h:13
uint64_t SixByteInstr
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
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define UNREACHABLE()
Definition logging.h:67
#define UNIMPLEMENTED()
Definition logging.h:66
#define DCHECK(condition)
Definition logging.h:482