Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(689)

Unified Diff: runtime/vm/assembler_arm64.cc

Issue 262793006: Uses double load/store on arm64, enables tests. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/constants_arm64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_arm64.cc
===================================================================
--- runtime/vm/assembler_arm64.cc (revision 35689)
+++ runtime/vm/assembler_arm64.cc (working copy)
@@ -603,7 +603,6 @@
void Assembler::CompareImmediate(Register rn, int64_t imm, Register pp) {
- ASSERT(rn != TMP2);
Operand op;
if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
cmp(rn, op);
@@ -611,6 +610,7 @@
Operand::Immediate) {
cmn(rn, op);
} else {
+ ASSERT(rn != TMP2);
LoadImmediate(TMP2, imm, pp);
cmp(rn, Operand(TMP2));
}
@@ -619,10 +619,10 @@
void Assembler::LoadFromOffset(
Register dest, Register base, int32_t offset, OperandSize sz) {
- ASSERT(base != TMP2);
if (Address::CanHoldOffset(offset, Address::Offset, sz)) {
ldr(dest, Address(base, offset, Address::Offset, sz), sz);
} else {
+ ASSERT(base != TMP2);
// Since offset is 32-bits, it won't be loaded from the pool.
AddImmediate(TMP2, base, offset, kNoPP);
ldr(dest, Address(TMP2), sz);
@@ -630,13 +630,25 @@
}
+void Assembler::LoadDFromOffset(VRegister dest, Register base, int32_t offset) {
+ if (Address::CanHoldOffset(offset, Address::Offset, kDWord)) {
+ fldrd(dest, Address(base, offset, Address::Offset, kDWord));
+ } else {
+ ASSERT(base != TMP2);
+ // Since offset is 32-bits, it won't be loaded from the pool.
+ AddImmediate(TMP2, base, offset, kNoPP);
+ fldrd(dest, Address(TMP2));
+ }
+}
+
+
void Assembler::StoreToOffset(
Register src, Register base, int32_t offset, OperandSize sz) {
- ASSERT(src != TMP2);
ASSERT(base != TMP2);
if (Address::CanHoldOffset(offset, Address::Offset, sz)) {
str(src, Address(base, offset, Address::Offset, sz), sz);
} else {
+ ASSERT(src != TMP2);
// Since offset is 32-bits, it won't be loaded from the pool.
AddImmediate(TMP2, base, offset, kNoPP);
str(src, Address(TMP2), sz);
@@ -644,6 +656,18 @@
}
+void Assembler::StoreDToOffset(VRegister src, Register base, int32_t offset) {
+ if (Address::CanHoldOffset(offset, Address::Offset, kDWord)) {
+ fstrd(src, Address(base, offset, Address::Offset, kDWord));
+ } else {
+ ASSERT(base != TMP2);
+ // Since offset is 32-bits, it won't be loaded from the pool.
+ AddImmediate(TMP2, base, offset, kNoPP);
+ fstrd(src, Address(TMP2));
+ }
+}
+
+
// Store into object.
// Preserves object and value registers.
void Assembler::StoreIntoObjectFilterNoSmi(Register object,
@@ -873,11 +897,22 @@
void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
EnterFrame(0);
- // TODO(zra): also save volatile FPU registers.
+ // Store fpu registers with the lowest register number at the lowest
+ // address.
+ for (int i = kNumberOfVRegisters - 1; i >= 0; i--) {
+ if ((i >= kAbiFirstPreservedFpuReg) && (i <= kAbiLastPreservedFpuReg)) {
+ // TODO(zra): When SIMD is added, we must also preserve the top
+ // 64-bits of the callee-saved registers.
+ continue;
+ }
+ // TODO(zra): Save the whole V register.
+ VRegister reg = static_cast<VRegister>(i);
+ PushDouble(reg);
+ }
for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) {
const Register reg = static_cast<Register>(i);
- if ((reg != R16) && (reg != R17)) {
+ if ((reg != TMP) && (reg != TMP2)) {
Push(reg);
}
}
@@ -892,15 +927,27 @@
// We need to restore it before restoring registers.
// TODO(zra): Also include FPU regs in this count once they are added.
const intptr_t kPushedRegistersSize =
- kDartVolatileCpuRegCount * kWordSize;
+ kDartVolatileCpuRegCount * kWordSize +
+ kDartVolatileFpuRegCount * kWordSize;
AddImmediate(SP, FP, -kPushedRegistersSize, PP);
for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) {
const Register reg = static_cast<Register>(i);
- if ((reg != R16) && (reg != R17)) {
+ if ((reg != TMP) && (reg != TMP2)) {
Pop(reg);
}
}
+ for (int i = 0; i < kNumberOfVRegisters; i++) {
+ if ((i >= kAbiFirstPreservedFpuReg) && (i <= kAbiLastPreservedFpuReg)) {
+ // TODO(zra): When SIMD is added, we must also restore the top
+ // 64-bits of the callee-saved registers.
+ continue;
+ }
+ // TODO(zra): Restore the whole V register.
+ VRegister reg = static_cast<VRegister>(i);
+ PopDouble(reg);
+ }
+
Pop(FP);
Pop(LR);
}
@@ -1017,6 +1064,48 @@
}
}
+
+void Assembler::TryAllocate(const Class& cls,
+ Label* failure,
+ Register instance_reg,
+ Register temp_reg,
+ Register pp) {
+ ASSERT(failure != NULL);
+ if (FLAG_inline_alloc) {
+ Heap* heap = Isolate::Current()->heap();
+ const intptr_t instance_size = cls.instance_size();
+ LoadImmediate(instance_reg, heap->TopAddress(), pp);
+ ldr(instance_reg, Address(instance_reg));
+ AddImmediate(instance_reg, instance_reg, instance_size, pp);
+
+ // instance_reg: potential next object start.
+ LoadImmediate(TMP, heap->EndAddress(), pp);
+ ldr(TMP, Address(TMP));
+ CompareRegisters(TMP, instance_reg);
+ // fail if heap end unsigned less than or equal to instance_reg.
+ b(failure, LS);
+
+ // Successfully allocated the object, now update top to point to
+ // next object start and store the class in the class field of object.
+ LoadImmediate(TMP, heap->TopAddress(), pp);
+ str(instance_reg, Address(TMP));
+
+ ASSERT(instance_size >= kHeapObjectTag);
+ AddImmediate(
+ instance_reg, instance_reg, -instance_size + kHeapObjectTag, pp);
+ UpdateAllocationStats(cls.id(), temp_reg, pp);
+
+ uword tags = 0;
+ tags = RawObject::SizeTag::update(instance_size, tags);
+ ASSERT(cls.id() != kIllegalCid);
+ tags = RawObject::ClassIdTag::update(cls.id(), tags);
+ LoadImmediate(TMP, tags, pp);
+ StoreFieldToOffset(TMP, instance_reg, Object::tags_offset());
+ } else {
+ b(failure);
+ }
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_ARM64
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/constants_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698