37 #ifndef V8_S390_ASSEMBLER_S390_INL_H_ 38 #define V8_S390_ASSEMBLER_S390_INL_H_ 40 #include "src/s390/assembler-s390.h" 42 #include "src/assembler.h" 43 #include "src/debug/debug.h" 44 #include "src/objects-inl.h" 49 bool CpuFeatures::SupportsOptimizer() {
return true; }
51 bool CpuFeatures::SupportsWasmSimd128() {
return false; }
53 void RelocInfo::apply(intptr_t delta) {
55 if (IsInternalReference(rmode_)) {
57 Address target = Memory<Address>(pc_);
58 Memory<Address>(pc_) = target + delta;
59 }
else if (IsCodeTarget(rmode_)) {
61 Instruction::InstructionBits(reinterpret_cast<const byte*>(pc_));
62 int32_t dis =
static_cast<int32_t
>(instr & 0xFFFFFFFF) * 2
63 - static_cast<int32_t>(delta);
66 instr |=
static_cast<uint32_t>(dis / 2);
67 Instruction::SetInstructionBits<SixByteInstr>(
reinterpret_cast<byte*
>(pc_),
71 DCHECK(IsInternalReferenceEncoded(rmode_));
72 Address target = Assembler::target_address_at(pc_, constant_pool_);
73 Assembler::set_target_address_at(pc_, constant_pool_, target + delta,
78 Address RelocInfo::target_internal_reference() {
79 if (IsInternalReference(rmode_)) {
81 return Memory<Address>(pc_);
84 DCHECK(IsInternalReferenceEncoded(rmode_));
85 return Assembler::target_address_at(pc_, constant_pool_);
89 Address RelocInfo::target_internal_reference_address() {
90 DCHECK(IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_));
94 Address RelocInfo::target_address() {
95 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_));
96 return Assembler::target_address_at(pc_, constant_pool_);
99 Address RelocInfo::target_address_address() {
100 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_) ||
101 IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) ||
102 IsOffHeapTarget(rmode_));
116 Address RelocInfo::constant_pool_entry_address() {
120 int RelocInfo::target_address_size() {
return Assembler::kSpecialTargetSize; }
122 Address Assembler::target_address_from_return_address(Address pc) {
127 return pc - kCallTargetAddressOffset;
130 Address Assembler::return_address_from_call_start(Address pc) {
133 return pc + kCallTargetAddressOffset;
136 Handle<Object> Assembler::code_target_object_handle_at(Address pc) {
138 Instruction::InstructionBits(reinterpret_cast<const byte*>(pc));
139 int index = instr & 0xFFFFFFFF;
140 return GetCodeTarget(index);
143 HeapObject* RelocInfo::target_object() {
144 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
145 return HeapObject::cast(reinterpret_cast<Object*>(
146 Assembler::target_address_at(pc_, constant_pool_)));
149 Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
150 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
151 if (rmode_ == EMBEDDED_OBJECT) {
152 return Handle<HeapObject>(
reinterpret_cast<Address*
>(
153 Assembler::target_address_at(pc_, constant_pool_)));
155 return Handle<HeapObject>::cast(origin->code_target_object_handle_at(pc_));
159 void RelocInfo::set_target_object(Heap* heap, HeapObject* target,
160 WriteBarrierMode write_barrier_mode,
161 ICacheFlushMode icache_flush_mode) {
162 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
163 Assembler::set_target_address_at(pc_, constant_pool_,
164 reinterpret_cast<Address>(target),
166 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() !=
nullptr) {
167 WriteBarrierForCode(host(),
this, target);
171 Address RelocInfo::target_external_reference() {
172 DCHECK(rmode_ == EXTERNAL_REFERENCE);
173 return Assembler::target_address_at(pc_, constant_pool_);
176 void RelocInfo::set_target_external_reference(
177 Address target, ICacheFlushMode icache_flush_mode) {
178 DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
179 Assembler::set_target_address_at(pc_, constant_pool_, target,
183 Address RelocInfo::target_runtime_entry(Assembler* origin) {
184 DCHECK(IsRuntimeEntry(rmode_));
185 return target_address();
188 Address RelocInfo::target_off_heap_target() {
189 DCHECK(IsOffHeapTarget(rmode_));
190 return Assembler::target_address_at(pc_, constant_pool_);
193 void RelocInfo::set_target_runtime_entry(Address target,
194 WriteBarrierMode write_barrier_mode,
195 ICacheFlushMode icache_flush_mode) {
196 DCHECK(IsRuntimeEntry(rmode_));
197 if (target_address() != target)
198 set_target_address(target, write_barrier_mode, icache_flush_mode);
201 void RelocInfo::WipeOut() {
202 DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
203 IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) ||
204 IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_) ||
205 IsOffHeapTarget(rmode_));
206 if (IsInternalReference(rmode_)) {
208 Memory<Address>(pc_) = kNullAddress;
209 }
else if (IsInternalReferenceEncoded(rmode_) || IsOffHeapTarget(rmode_)) {
212 Assembler::set_target_address_at(pc_, constant_pool_, kNullAddress,
215 Assembler::set_target_address_at(pc_, constant_pool_, kNullAddress);
219 template <
typename ObjectVisitor>
220 void RelocInfo::Visit(ObjectVisitor* visitor) {
221 RelocInfo::Mode mode = rmode();
222 if (mode == RelocInfo::EMBEDDED_OBJECT) {
223 visitor->VisitEmbeddedPointer(host(),
this);
224 }
else if (RelocInfo::IsCodeTargetMode(mode)) {
225 visitor->VisitCodeTarget(host(),
this);
226 }
else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
227 visitor->VisitExternalReference(host(),
this);
228 }
else if (mode == RelocInfo::INTERNAL_REFERENCE) {
229 visitor->VisitInternalReference(host(),
this);
230 }
else if (IsRuntimeEntry(mode)) {
231 visitor->VisitRuntimeEntry(host(),
this);
232 }
else if (RelocInfo::IsOffHeapTarget(mode)) {
233 visitor->VisitOffHeapTarget(host(),
this);
238 Operand::Operand(Register rm) : rm_(rm), rmode_(RelocInfo::NONE) {}
241 Address Assembler::target_address_at(Address pc, Address constant_pool) {
244 Opcode op1 = Instruction::S390OpcodeValue(reinterpret_cast<const byte*>(pc));
245 SixByteInstr instr_1 =
246 Instruction::InstructionBits(reinterpret_cast<const byte*>(pc));
248 if (BRASL == op1 || BRCL == op1) {
249 int32_t dis =
static_cast<int32_t
>(instr_1 & 0xFFFFFFFF) * 2;
253 #if V8_TARGET_ARCH_S390X 255 Instruction::InstructionLength(reinterpret_cast<const byte*>(pc));
256 Opcode op2 = Instruction::S390OpcodeValue(
257 reinterpret_cast<const byte*>(pc + instr1_length));
258 SixByteInstr instr_2 = Instruction::InstructionBits(
259 reinterpret_cast<const byte*>(pc + instr1_length));
261 if (IIHF == op1 && IILF == op2) {
262 return static_cast<Address
>(((instr_1 & 0xFFFFFFFF) << 32) |
263 ((instr_2 & 0xFFFFFFFF)));
267 if (IILF == op1 || CFI == op1) {
268 return static_cast<Address
>((instr_1 & 0xFFFFFFFF));
280 void Assembler::deserialization_set_special_target_at(
281 Address instruction_payload, Code code, Address target) {
282 set_target_address_at(instruction_payload,
283 code ? code->constant_pool() : kNullAddress, target);
286 int Assembler::deserialization_special_target_size(
287 Address instruction_payload) {
288 return kSpecialTargetSize;
291 void Assembler::deserialization_set_target_internal_reference_at(
292 Address pc, Address target, RelocInfo::Mode mode) {
293 if (RelocInfo::IsInternalReferenceEncoded(mode)) {
294 set_target_address_at(pc, kNullAddress, target, SKIP_ICACHE_FLUSH);
296 Memory<Address>(pc) = target;
301 void Assembler::set_target_address_at(Address pc, Address constant_pool,
303 ICacheFlushMode icache_flush_mode) {
305 Opcode op1 = Instruction::S390OpcodeValue(reinterpret_cast<const byte*>(pc));
306 SixByteInstr instr_1 =
307 Instruction::InstructionBits(reinterpret_cast<const byte*>(pc));
308 bool patched =
false;
310 if (BRASL == op1 || BRCL == op1) {
313 int32_t halfwords = (target - pc) / 2;
314 instr_1 |=
static_cast<uint32_t>(halfwords);
315 Instruction::SetInstructionBits<SixByteInstr>(
reinterpret_cast<byte*
>(pc),
317 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
318 Assembler::FlushICache(pc, 6);
322 #if V8_TARGET_ARCH_S390X 324 Instruction::InstructionLength(reinterpret_cast<const byte*>(pc));
325 Opcode op2 = Instruction::S390OpcodeValue(
326 reinterpret_cast<const byte*>(pc + instr1_length));
327 SixByteInstr instr_2 = Instruction::InstructionBits(
328 reinterpret_cast<const byte*>(pc + instr1_length));
330 if (IIHF == op1 && IILF == op2) {
334 instr_1 |=
reinterpret_cast<uint64_t
>(target) >> 32;
336 Instruction::SetInstructionBits<SixByteInstr>(
reinterpret_cast<byte*
>(pc),
342 instr_2 |=
reinterpret_cast<uint64_t
>(target) & 0xFFFFFFFF;
344 Instruction::SetInstructionBits<SixByteInstr>(
345 reinterpret_cast<byte*
>(pc + instr1_length), instr_2);
346 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
347 Assembler::FlushICache(pc, 12);
353 if (IILF == op1 || CFI == op1) {
356 instr_1 |=
reinterpret_cast<uint32_t>(target);
358 Instruction::SetInstructionBits<SixByteInstr>(
reinterpret_cast<byte*
>(pc),
360 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
361 Assembler::FlushICache(pc, 6);
367 if (!patched) UNREACHABLE();
373 #endif // V8_S390_ASSEMBLER_S390_INL_H_