37 #ifndef V8_IA32_ASSEMBLER_IA32_INL_H_ 38 #define V8_IA32_ASSEMBLER_IA32_INL_H_ 40 #include "src/ia32/assembler-ia32.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 IsSupported(SSE4_1); }
55 void RelocInfo::apply(intptr_t delta) {
56 DCHECK_EQ(kApplyMask, (RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
57 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
58 RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
59 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY)));
60 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_) ||
61 IsOffHeapTarget(rmode_)) {
62 int32_t* p =
reinterpret_cast<int32_t*
>(pc_);
64 }
else if (IsInternalReference(rmode_)) {
66 int32_t* p =
reinterpret_cast<int32_t*
>(pc_);
72 Address RelocInfo::target_address() {
73 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_));
74 return Assembler::target_address_at(pc_, constant_pool_);
77 Address RelocInfo::target_address_address() {
78 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_) ||
79 IsWasmStubCall(rmode_) || IsEmbeddedObject(rmode_) ||
80 IsExternalReference(rmode_) || IsOffHeapTarget(rmode_));
85 Address RelocInfo::constant_pool_entry_address() {
90 int RelocInfo::target_address_size() {
91 return Assembler::kSpecialTargetSize;
94 HeapObject* RelocInfo::target_object() {
95 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
96 return HeapObject::cast(Memory<Object*>(pc_));
99 Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
100 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
101 return Handle<HeapObject>::cast(Memory<Handle<Object>>(pc_));
104 void RelocInfo::set_target_object(Heap* heap, HeapObject* target,
105 WriteBarrierMode write_barrier_mode,
106 ICacheFlushMode icache_flush_mode) {
107 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
108 Memory<Object*>(pc_) = target;
109 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
110 Assembler::FlushICache(pc_,
sizeof(Address));
112 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() !=
nullptr) {
113 WriteBarrierForCode(host(),
this, target);
118 Address RelocInfo::target_external_reference() {
119 DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
120 return Memory<Address>(pc_);
123 void RelocInfo::set_target_external_reference(
124 Address target, ICacheFlushMode icache_flush_mode) {
125 DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
126 Memory<Address>(pc_) = target;
127 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
128 Assembler::FlushICache(pc_,
sizeof(Address));
132 Address RelocInfo::target_internal_reference() {
133 DCHECK(rmode_ == INTERNAL_REFERENCE);
134 return Memory<Address>(pc_);
138 Address RelocInfo::target_internal_reference_address() {
139 DCHECK(rmode_ == INTERNAL_REFERENCE);
143 Address RelocInfo::target_runtime_entry(Assembler* origin) {
144 DCHECK(IsRuntimeEntry(rmode_));
145 return static_cast<Address
>(*
reinterpret_cast<int32_t*
>(pc_));
148 void RelocInfo::set_target_runtime_entry(Address target,
149 WriteBarrierMode write_barrier_mode,
150 ICacheFlushMode icache_flush_mode) {
151 DCHECK(IsRuntimeEntry(rmode_));
152 if (target_address() != target) {
153 set_target_address(target, write_barrier_mode, icache_flush_mode);
157 Address RelocInfo::target_off_heap_target() {
158 DCHECK(IsOffHeapTarget(rmode_));
159 return Assembler::target_address_at(pc_, constant_pool_);
162 void RelocInfo::WipeOut() {
163 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) ||
164 IsInternalReference(rmode_)) {
165 Memory<Address>(pc_) = kNullAddress;
166 }
else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) ||
167 IsOffHeapTarget(rmode_)) {
169 Assembler::set_target_address_at(pc_, constant_pool_,
170 pc_ +
sizeof(int32_t));
176 template <
typename ObjectVisitor>
177 void RelocInfo::Visit(ObjectVisitor* visitor) {
178 RelocInfo::Mode mode = rmode();
179 if (mode == RelocInfo::EMBEDDED_OBJECT) {
180 visitor->VisitEmbeddedPointer(host(),
this);
181 Assembler::FlushICache(pc_,
sizeof(Address));
182 }
else if (RelocInfo::IsCodeTargetMode(mode)) {
183 visitor->VisitCodeTarget(host(),
this);
184 }
else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
185 visitor->VisitExternalReference(host(),
this);
186 }
else if (mode == RelocInfo::INTERNAL_REFERENCE) {
187 visitor->VisitInternalReference(host(),
this);
188 }
else if (IsRuntimeEntry(mode)) {
189 visitor->VisitRuntimeEntry(host(),
this);
190 }
else if (RelocInfo::IsOffHeapTarget(mode)) {
191 visitor->VisitOffHeapTarget(host(),
this);
196 *
reinterpret_cast<uint32_t*
>(pc_) = x;
201 void Assembler::emit_q(uint64_t x) {
202 *
reinterpret_cast<uint64_t*
>(pc_) = x;
203 pc_ +=
sizeof(uint64_t);
206 void Assembler::emit(Handle<HeapObject> handle) {
207 emit(handle.address(), RelocInfo::EMBEDDED_OBJECT);
210 void Assembler::emit(
uint32_t x, RelocInfo::Mode rmode) {
211 if (!RelocInfo::IsNone(rmode)) {
212 RecordRelocInfo(rmode);
217 void Assembler::emit(Handle<Code> code, RelocInfo::Mode rmode) {
218 emit(code.address(), rmode);
222 void Assembler::emit(
const Immediate& x) {
223 if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) {
224 Label* label =
reinterpret_cast<Label*
>(x.immediate());
225 emit_code_relative_offset(label);
228 if (!RelocInfo::IsNone(x.rmode_)) RecordRelocInfo(x.rmode_);
229 if (x.is_heap_object_request()) {
230 RequestHeapObject(x.heap_object_request());
238 void Assembler::emit_code_relative_offset(Label* label) {
239 if (label->is_bound()) {
241 pos = label->pos() + Code::kHeaderSize - kHeapObjectTag;
244 emit_disp(label, Displacement::CODE_RELATIVE);
248 void Assembler::emit_b(Immediate x) {
249 DCHECK(x.is_int8() || x.is_uint8());
250 uint8_t value =
static_cast<uint8_t
>(x.immediate());
254 void Assembler::emit_w(
const Immediate& x) {
255 DCHECK(RelocInfo::IsNone(x.rmode_));
256 uint16_t value =
static_cast<uint16_t
>(x.immediate());
257 reinterpret_cast<uint16_t*
>(pc_)[0] = value;
258 pc_ +=
sizeof(uint16_t);
262 Address Assembler::target_address_at(Address pc, Address constant_pool) {
263 return pc +
sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
266 void Assembler::set_target_address_at(Address pc, Address constant_pool,
268 ICacheFlushMode icache_flush_mode) {
269 *
reinterpret_cast<int32_t*
>(pc) = target - (pc +
sizeof(int32_t));
270 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
271 Assembler::FlushICache(pc,
sizeof(int32_t));
275 Address Assembler::target_address_from_return_address(Address pc) {
276 return pc - kCallTargetAddressOffset;
279 void Assembler::deserialization_set_special_target_at(
280 Address instruction_payload, Code code, Address target) {
281 set_target_address_at(instruction_payload,
282 code ? code->constant_pool() : kNullAddress, target);
285 int Assembler::deserialization_special_target_size(
286 Address instruction_payload) {
287 return kSpecialTargetSize;
290 Displacement Assembler::disp_at(Label* L) {
291 return Displacement(long_at(L->pos()));
295 void Assembler::disp_at_put(Label* L, Displacement disp) {
296 long_at_put(L->pos(), disp.data());
300 void Assembler::emit_disp(Label* L, Displacement::Type type) {
301 Displacement disp(L, type);
302 L->link_to(pc_offset());
303 emit(static_cast<int>(disp.data()));
307 void Assembler::emit_near_disp(Label* L) {
309 if (L->is_near_linked()) {
310 int offset = L->near_link_pos() - pc_offset();
311 DCHECK(is_int8(offset));
312 disp =
static_cast<byte
>(offset & 0xFF);
314 L->link_to(pc_offset(), Label::kNear);
318 void Assembler::deserialization_set_target_internal_reference_at(
319 Address pc, Address target, RelocInfo::Mode mode) {
320 Memory<Address>(pc) = target;
324 void Operand::set_sib(ScaleFactor scale, Register index, Register base) {
326 DCHECK_EQ(scale & -4, 0);
328 DCHECK(index != esp || base == esp);
329 buf_[1] = scale << 6 | index.code() << 3 | base.code();
334 void Operand::set_disp8(int8_t disp) {
335 DCHECK(len_ == 1 || len_ == 2);
336 *
reinterpret_cast<int8_t*
>(&buf_[len_++]) = disp;
342 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_