Skip to content

Commit 5f37595

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[vm, compiler] Handle up to 32-bit offsets for pool loads on ARM64.
TEST=vm/dart/generated/many_double_literals_test, in later CL Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-arm64-try,vm-aot-linux-release-arm64-try,vm-linux-release-arm64-try,vm-linux-debug-arm64-try Change-Id: I367c6a0298aba28fb6883d8ee62815e15a0c01de Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/443900 Commit-Queue: Ryan Macnak <[email protected]> Reviewed-by: Alexander Markov <[email protected]>
1 parent e605324 commit 5f37595

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

runtime/vm/compiler/assembler/assembler_arm64.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,6 @@ void Assembler::LoadDoubleWordFromPoolIndex(Register lower,
604604
Operand op;
605605
// PP is _un_tagged on ARM64.
606606
const uint32_t offset = target::ObjectPool::element_offset(index);
607-
ASSERT(offset < (1 << 24));
608607
const uint32_t upper20 = offset & 0xfffff000;
609608
const uint32_t lower12 = offset & 0x00000fff;
610609
if (Address::CanHoldOffset(offset, Address::PairOffset)) {
@@ -618,7 +617,7 @@ void Assembler::LoadDoubleWordFromPoolIndex(Register lower,
618617
Address::CanHoldOffset(lower12, Address::PairOffset)) {
619618
add(TMP, PP, op);
620619
ldp(lower, upper, Address(TMP, lower12, Address::PairOffset));
621-
} else {
620+
} else if (Utils::IsUint(24, offset)) {
622621
const uint32_t lower12 = offset & 0xfff;
623622
const uint32_t higher12 = offset & 0xfff000;
624623

@@ -632,6 +631,15 @@ void Assembler::LoadDoubleWordFromPoolIndex(Register lower,
632631
add(TMP, PP, op_high);
633632
add(TMP, TMP, op_low);
634633
ldp(lower, upper, Address(TMP, 0, Address::PairOffset));
634+
} else if (Utils::IsUint(32, offset)) {
635+
const uint16_t offset_low = Utils::Low16Bits(offset);
636+
const uint16_t offset_high = Utils::High16Bits(offset);
637+
movz(TMP, Immediate(offset_low), 0);
638+
movk(TMP, Immediate(offset_high), 1);
639+
add(TMP, TMP, Operand(PP));
640+
ldp(lower, upper, Address(TMP, 0, Address::PairOffset));
641+
} else {
642+
UNIMPLEMENTED();
635643
}
636644
}
637645

runtime/vm/instructions_arm64.cc

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ uword InstructionPattern::DecodeLoadDoubleWordFromPool(uword end,
247247
// add tmp, tmp, #lower12
248248
// ldp reg1, reg2, [tmp, 0]
249249
//
250+
// 4. movz tmp, #lower16
251+
// movk tmp, #upper16
252+
// add tmp, tmp, pp
253+
// ldp reg1, reg2, [tmp, 0]
254+
//
250255
// Note that the pp register is untagged!
251256
//
252257
uword start = end - Instr::kInstrSize;
@@ -267,31 +272,52 @@ uword InstructionPattern::DecodeLoadDoubleWordFromPool(uword end,
267272
// Case 1.
268273
pool_offset = base_offset;
269274
} else {
270-
// Case 2 & 3.
271275
ASSERT(base_reg == TMP);
272276

273277
pool_offset = base_offset;
274278

275279
start -= Instr::kInstrSize;
276280
Instr* add_instr = Instr::At(start);
277-
ASSERT(add_instr->IsAddSubImmOp());
278-
ASSERT(add_instr->RdField() == TMP);
281+
if (add_instr->IsAddSubShiftExtOp()) {
282+
// Case 4.
283+
ASSERT(add_instr->RdField() == TMP);
279284

280-
const auto shift = add_instr->Imm12ShiftField();
281-
ASSERT(shift == 0 || shift == 1);
282-
pool_offset += (add_instr->Imm12Field() << (shift == 1 ? 12 : 0));
285+
start -= Instr::kInstrSize;
286+
Instr* movk_instr = Instr::At(start);
287+
ASSERT(movk_instr->IsMoveWideOp());
288+
ASSERT(movk_instr->Bits(29, 2) == 3);
289+
ASSERT(movk_instr->HWField() == 1); // movk tmp, imm1, 1
290+
ASSERT(movk_instr->RdField() == TMP);
291+
pool_offset += (movk_instr->Imm16Field() << 16);
283292

284-
if (add_instr->RnField() == TMP) {
285293
start -= Instr::kInstrSize;
286-
Instr* prev_add_instr = Instr::At(start);
287-
ASSERT(prev_add_instr->IsAddSubImmOp());
288-
ASSERT(prev_add_instr->RnField() == PP);
294+
Instr* movz_instr = Instr::At(start);
295+
ASSERT(movz_instr->IsMoveWideOp());
296+
ASSERT(movz_instr->Bits(29, 2) == 2);
297+
ASSERT(movz_instr->HWField() == 0); // movz tmp, imm0, 0
298+
ASSERT(movz_instr->RdField() == TMP);
299+
pool_offset += movz_instr->Imm16Field();
300+
} else {
301+
// Case 2 & 3.
302+
ASSERT(add_instr->IsAddSubImmOp());
303+
ASSERT(add_instr->RdField() == TMP);
289304

290-
const auto shift = prev_add_instr->Imm12ShiftField();
305+
const auto shift = add_instr->Imm12ShiftField();
291306
ASSERT(shift == 0 || shift == 1);
292-
pool_offset += (prev_add_instr->Imm12Field() << (shift == 1 ? 12 : 0));
293-
} else {
294-
ASSERT(add_instr->RnField() == PP);
307+
pool_offset += (add_instr->Imm12Field() << (shift == 1 ? 12 : 0));
308+
309+
if (add_instr->RnField() == TMP) {
310+
start -= Instr::kInstrSize;
311+
Instr* prev_add_instr = Instr::At(start);
312+
ASSERT(prev_add_instr->IsAddSubImmOp());
313+
ASSERT(prev_add_instr->RnField() == PP);
314+
315+
const auto shift = prev_add_instr->Imm12ShiftField();
316+
ASSERT(shift == 0 || shift == 1);
317+
pool_offset += (prev_add_instr->Imm12Field() << (shift == 1 ? 12 : 0));
318+
} else {
319+
ASSERT(add_instr->RnField() == PP);
320+
}
295321
}
296322
}
297323
*index = ObjectPool::IndexFromOffset(pool_offset - kHeapObjectTag);

0 commit comments

Comments
 (0)