summaryrefslogtreecommitdiff
path: root/deps/v8/src/codegen/loong64/assembler-loong64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/codegen/loong64/assembler-loong64.cc')
-rw-r--r--deps/v8/src/codegen/loong64/assembler-loong64.cc69
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()),