36 #ifndef V8_MIPS64_ASSEMBLER_MIPS64_INL_H_ 37 #define V8_MIPS64_ASSEMBLER_MIPS64_INL_H_ 39 #include "src/mips64/assembler-mips64.h" 41 #include "src/assembler.h" 42 #include "src/debug/debug.h" 43 #include "src/objects-inl.h" 48 bool CpuFeatures::SupportsOptimizer() {
return IsSupported(FPU); }
50 bool CpuFeatures::SupportsWasmSimd128() {
return IsSupported(MIPS_SIMD); }
55 bool Operand::is_reg()
const {
56 return rm_.is_valid();
59 int64_t Operand::immediate()
const {
61 DCHECK(!IsHeapObjectRequest());
62 return value_.immediate;
68 void RelocInfo::apply(intptr_t delta) {
69 if (IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_)) {
71 Assembler::RelocateInternalReference(rmode_, pc_, delta);
76 Address RelocInfo::target_address() {
77 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_));
78 return Assembler::target_address_at(pc_, constant_pool_);
81 Address RelocInfo::target_address_address() {
82 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_) ||
83 IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) ||
84 IsOffHeapTarget(rmode_));
99 return pc_ + Assembler::kInstructionsFor64BitConstant * kInstrSize;
103 Address RelocInfo::constant_pool_entry_address() {
108 int RelocInfo::target_address_size() {
109 return Assembler::kSpecialTargetSize;
112 Address Assembler::target_address_from_return_address(Address pc) {
113 return pc - kCallTargetAddressOffset;
116 void Assembler::deserialization_set_special_target_at(
117 Address instruction_payload, Code code, Address target) {
118 set_target_address_at(
119 instruction_payload - kInstructionsFor64BitConstant * kInstrSize,
120 code ? code->constant_pool() : kNullAddress, target);
123 int Assembler::deserialization_special_target_size(
124 Address instruction_payload) {
125 return kSpecialTargetSize;
128 void Assembler::set_target_internal_reference_encoded_at(Address pc,
131 Instr instr = Assembler::instr_at(pc + 0 * kInstrSize);
133 uint64_t imm28 = target &
static_cast<uint64_t
>(kImm28Mask);
135 instr &= ~kImm26Mask;
136 uint64_t imm26 = imm28 >> 2;
137 DCHECK(is_uint26(imm26));
139 instr_at_put(pc, instr | (imm26 & kImm26Mask));
144 void Assembler::deserialization_set_target_internal_reference_at(
145 Address pc, Address target, RelocInfo::Mode mode) {
146 if (mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
147 DCHECK(IsJ(instr_at(pc)));
148 set_target_internal_reference_encoded_at(pc, target);
150 DCHECK(mode == RelocInfo::INTERNAL_REFERENCE);
151 Memory<Address>(pc) = target;
155 HeapObject* RelocInfo::target_object() {
156 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
157 return HeapObject::cast(reinterpret_cast<Object*>(
158 Assembler::target_address_at(pc_, constant_pool_)));
161 Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
162 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
163 return Handle<HeapObject>(
reinterpret_cast<Address*
>(
164 Assembler::target_address_at(pc_, constant_pool_)));
167 void RelocInfo::set_target_object(Heap* heap, HeapObject* target,
168 WriteBarrierMode write_barrier_mode,
169 ICacheFlushMode icache_flush_mode) {
170 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
171 Assembler::set_target_address_at(pc_, constant_pool_,
172 reinterpret_cast<Address>(target),
174 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() !=
nullptr) {
175 WriteBarrierForCode(host(),
this, target);
180 Address RelocInfo::target_external_reference() {
181 DCHECK(rmode_ == EXTERNAL_REFERENCE);
182 return Assembler::target_address_at(pc_, constant_pool_);
185 void RelocInfo::set_target_external_reference(
186 Address target, ICacheFlushMode icache_flush_mode) {
187 DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
188 Assembler::set_target_address_at(pc_, constant_pool_, target,
192 Address RelocInfo::target_internal_reference() {
193 if (rmode_ == INTERNAL_REFERENCE) {
194 return Memory<Address>(pc_);
197 DCHECK(rmode_ == INTERNAL_REFERENCE_ENCODED);
198 Instr instr = Assembler::instr_at(pc_ + 0 * kInstrSize);
200 uint64_t imm28 = instr << 2;
201 uint64_t segment = pc_ & ~static_cast<uint64_t>(kImm28Mask);
202 return static_cast<Address
>(segment | imm28);
207 Address RelocInfo::target_internal_reference_address() {
208 DCHECK(rmode_ == INTERNAL_REFERENCE || rmode_ == INTERNAL_REFERENCE_ENCODED);
212 Address RelocInfo::target_runtime_entry(Assembler* origin) {
213 DCHECK(IsRuntimeEntry(rmode_));
214 return target_address();
217 void RelocInfo::set_target_runtime_entry(Address target,
218 WriteBarrierMode write_barrier_mode,
219 ICacheFlushMode icache_flush_mode) {
220 DCHECK(IsRuntimeEntry(rmode_));
221 if (target_address() != target)
222 set_target_address(target, write_barrier_mode, icache_flush_mode);
225 Address RelocInfo::target_off_heap_target() {
226 DCHECK(IsOffHeapTarget(rmode_));
227 return Assembler::target_address_at(pc_, constant_pool_);
230 void RelocInfo::WipeOut() {
231 DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
232 IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) ||
233 IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_) ||
234 IsOffHeapTarget(rmode_));
235 if (IsInternalReference(rmode_)) {
236 Memory<Address>(pc_) = kNullAddress;
237 }
else if (IsInternalReferenceEncoded(rmode_)) {
238 Assembler::set_target_internal_reference_encoded_at(pc_, kNullAddress);
240 Assembler::set_target_address_at(pc_, constant_pool_, kNullAddress);
244 template <
typename ObjectVisitor>
245 void RelocInfo::Visit(ObjectVisitor* visitor) {
246 RelocInfo::Mode mode = rmode();
247 if (mode == RelocInfo::EMBEDDED_OBJECT) {
248 visitor->VisitEmbeddedPointer(host(),
this);
249 }
else if (RelocInfo::IsCodeTargetMode(mode)) {
250 visitor->VisitCodeTarget(host(),
this);
251 }
else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
252 visitor->VisitExternalReference(host(),
this);
253 }
else if (mode == RelocInfo::INTERNAL_REFERENCE ||
254 mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
255 visitor->VisitInternalReference(host(),
this);
256 }
else if (RelocInfo::IsRuntimeEntry(mode)) {
257 visitor->VisitRuntimeEntry(host(),
this);
258 }
else if (RelocInfo::IsOffHeapTarget(mode)) {
259 visitor->VisitOffHeapTarget(host(),
this);
267 void Assembler::CheckBuffer() {
268 if (buffer_space() <= kGap) {
274 void Assembler::CheckForEmitInForbiddenSlot() {
275 if (!is_buffer_growth_blocked()) {
278 if (IsPrevInstrCompactBranch()) {
280 Instr nop = SPECIAL | SLL;
281 *
reinterpret_cast<Instr*
>(pc_) = nop;
284 ClearCompactBranchState();
289 void Assembler::EmitHelper(Instr x, CompactBranchType is_compact_branch) {
290 if (IsPrevInstrCompactBranch()) {
291 if (Instruction::IsForbiddenAfterBranchInstr(x)) {
293 Instr nop = SPECIAL | SLL;
294 *
reinterpret_cast<Instr*
>(pc_) = nop;
297 ClearCompactBranchState();
299 *
reinterpret_cast<Instr*
>(pc_) = x;
301 if (is_compact_branch == CompactBranchType::COMPACT_BRANCH) {
302 EmittedCompactBranchInstruction();
304 CheckTrampolinePoolQuick();
308 inline void Assembler::EmitHelper(uint8_t x);
310 template <
typename T>
311 void Assembler::EmitHelper(T x) {
312 *
reinterpret_cast<T*
>(pc_) = x;
314 CheckTrampolinePoolQuick();
318 void Assembler::EmitHelper(uint8_t x) {
319 *
reinterpret_cast<uint8_t*
>(pc_) = x;
321 if (reinterpret_cast<intptr_t>(pc_) % kInstrSize == 0) {
322 CheckTrampolinePoolQuick();
326 void Assembler::emit(Instr x, CompactBranchType is_compact_branch) {
327 if (!is_buffer_growth_blocked()) {
330 EmitHelper(x, is_compact_branch);
334 void Assembler::emit(uint64_t data) {
335 CheckForEmitInForbiddenSlot();
339 EnsureSpace::EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
344 #endif // V8_MIPS64_ASSEMBLER_MIPS64_INL_H_