diff options
Diffstat (limited to 'deps/v8/src/codegen/loong64/assembler-loong64.cc')
-rw-r--r-- | deps/v8/src/codegen/loong64/assembler-loong64.cc | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/deps/v8/src/codegen/loong64/assembler-loong64.cc b/deps/v8/src/codegen/loong64/assembler-loong64.cc index b636538f77..58cd86a563 100644 --- a/deps/v8/src/codegen/loong64/assembler-loong64.cc +++ b/deps/v8/src/codegen/loong64/assembler-loong64.cc @@ -141,7 +141,12 @@ void Assembler::AllocateAndInstallRequestedHeapNumbers(Isolate* isolate) { object = isolate->factory()->NewHeapNumber<AllocationType::kOld>( request.heap_number()); Address pc = reinterpret_cast<Address>(buffer_start_) + request.offset(); - set_target_value_at(pc, reinterpret_cast<uint64_t>(object.location())); + EmbeddedObjectIndex index = AddEmbeddedObject(object); + if (IsLu32i_d(instr_at(pc + 2 * kInstrSize))) { + set_target_value_at(pc, static_cast<uint64_t>(index)); + } else { + set_target_compressed_value_at(pc, static_cast<uint32_t>(index)); + } } } @@ -175,13 +180,13 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, SafepointTableBuilder* safepoint_table_builder, int handler_table_offset) { // As a crutch to avoid having to add manual Align calls wherever we use a - // raw workflow to create Code objects (mostly in tests), add another Align - // call here. It does no harm - the end of the Code object is aligned to the - // (larger) kCodeAlignment anyways. + // raw workflow to create InstructionStream objects (mostly in tests), add + // another Align call here. It does no harm - the end of the InstructionStream + // object is aligned to the (larger) kCodeAlignment anyways. // TODO(jgruber): Consider moving responsibility for proper alignment to // metadata table builders (safepoint, handler, constant pool, code // comments). - DataAlign(Code::kMetadataAlignment); + DataAlign(InstructionStream::kMetadataAlignment); // EmitForbiddenSlotInstruction(); TODO:LOONG64 why? @@ -507,7 +512,8 @@ void Assembler::target_at_put(int pos, int target_pos, bool is_internal) { DCHECK(target_pos == kEndOfChain || target_pos >= 0); // Emitted label constant, not part of a branch. // Make label relative to Code pointer of generated Code object. - instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); + instr_at_put( + pos, target_pos + (InstructionStream::kHeaderSize - kHeapObjectTag)); return; } @@ -937,7 +943,8 @@ void Assembler::label_at_put(Label* L, int at_offset) { int target_pos; if (L->is_bound()) { target_pos = L->pos(); - instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag)); + instr_at_put(at_offset, target_pos + (InstructionStream::kHeaderSize - + kHeapObjectTag)); } else { if (L->is_linked()) { target_pos = L->pos(); // L's link. @@ -2192,7 +2199,8 @@ void Assembler::dd(Label* label) { void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { if (!ShouldRecordRelocInfo(rmode)) return; // We do not try to reuse pool constants. - RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, Code()); + RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, Code(), + InstructionStream()); DCHECK_GE(buffer_space(), kMaxRelocSize); // Too late to grow buffer here. reloc_info_writer.Write(&rinfo); } @@ -2266,7 +2274,7 @@ Address Assembler::target_address_at(Address pc) { Instr instr1 = instr_at(pc + 1 * kInstrSize); Instr instr2 = instr_at(pc + 2 * kInstrSize); - // Interpret 4 instructions for address generated by li: See listing in + // Interpret 3 instructions for address generated by li: See listing in // Assembler::set_target_address_at() just below. DCHECK((IsLu12i_w(instr0) && (IsOri(instr1)) && (IsLu32i_d(instr2)))); @@ -2281,6 +2289,22 @@ Address Assembler::target_address_at(Address pc) { return static_cast<Address>(addr); } +uint32_t Assembler::target_compressed_address_at(Address pc) { + Instr instr0 = instr_at(pc); + Instr instr1 = instr_at(pc + 1 * kInstrSize); + + // Interpret 2 instructions for address generated by li: See listing in + // Assembler::set_target_compressed_value_at just below. + DCHECK((IsLu12i_w(instr0) && (IsOri(instr1)))); + + // Assemble the 32 bit value. + uint32_t hi20 = ((uint32_t)(instr0 >> 5) & 0xfffff) << 12; + uint32_t low12 = ((uint32_t)(instr1 >> 10) & 0xfff); + uint32_t addr = static_cast<uint32_t>(hi20 | low12); + + return addr; +} + // On loong64, a target address is stored in a 3-instruction sequence: // 0: lu12i_w(rd, (j.imm64_ >> 12) & kImm20Mask); // 1: ori(rd, rd, j.imm64_ & kImm12Mask); @@ -2301,7 +2325,7 @@ void Assembler::set_target_value_at(Address pc, uint64_t target, Instr instr0 = instr_at(pc); Instr instr1 = instr_at(pc + kInstrSize); Instr instr2 = instr_at(pc + kInstrSize * 2); - DCHECK(IsLu12i_w(instr0) && IsOri(instr1) && IsLu32i_d(instr2) || + DCHECK((IsLu12i_w(instr0) && IsOri(instr1) && IsLu32i_d(instr2)) || IsB(instr0)); #endif @@ -2334,6 +2358,31 @@ void Assembler::set_target_value_at(Address pc, uint64_t target, } } +void Assembler::set_target_compressed_value_at( + Address pc, uint32_t target, ICacheFlushMode icache_flush_mode) { +#ifdef DEBUG + // Check we have the result from a li macro-instruction. + Instr instr0 = instr_at(pc); + Instr instr1 = instr_at(pc + kInstrSize); + DCHECK(IsLu12i_w(instr0) && IsOri(instr1)); +#endif + + Instr instr = instr_at(pc); + uint32_t* p = reinterpret_cast<uint32_t*>(pc); + uint32_t rd_code = GetRd(instr); + + // Must use 2 instructions to insure patchable code. + // lu12i_w rd, high-20. + // ori rd, rd, low-12. + *p = LU12I_W | (((target >> 12) & 0xfffff) << kRjShift) | rd_code; + *(p + 1) = + ORI | (target & 0xfff) << kRkShift | (rd_code << kRjShift) | rd_code; + + if (icache_flush_mode != SKIP_ICACHE_FLUSH) { + FlushInstructionCache(pc, 2 * kInstrSize); + } +} + UseScratchRegisterScope::UseScratchRegisterScope(Assembler* assembler) : available_(assembler->GetScratchRegisterList()), availablefp_(assembler->GetScratchFPRegisterList()), |