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

Unified Diff: runtime/vm/assembler_arm64.h

Issue 241573002: Code patching for ARM64. (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 | « no previous file | runtime/vm/assembler_arm64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_arm64.h
===================================================================
--- runtime/vm/assembler_arm64.h (revision 35127)
+++ runtime/vm/assembler_arm64.h (working copy)
@@ -140,7 +140,7 @@
static Address PC(int32_t pc_off) {
ASSERT(CanHoldOffset(pc_off, PCOffset));
Address addr;
- addr.encoding_ = (((pc_off >> 2) & kImm19Mask) << kImm19Shift);
+ addr.encoding_ = (((pc_off >> 2) << kImm19Shift) & kImm19Mask);
addr.base_ = kNoRegister;
addr.type_ = PCOffset;
return addr;
@@ -578,11 +578,22 @@
madd(rd, rn, rm, ZR);
}
void Push(Register reg) {
+ ASSERT(reg != PP); // Only push PP with PushPP().
str(reg, Address(SP, -1 * kWordSize, Address::PreIndex));
}
void Pop(Register reg) {
+ ASSERT(reg != PP); // Only pop PP with PopPP().
ldr(reg, Address(SP, 1 * kWordSize, Address::PostIndex));
}
+ void PushPP() {
+ // Add the heap object tag back to PP before putting it on the stack.
+ add(PP, PP, Operand(kHeapObjectTag));
+ str(PP, Address(SP, -1 * kWordSize, Address::PreIndex));
+ }
+ void PopPP() {
+ ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex));
+ sub(PP, PP, Operand(kHeapObjectTag));
+ }
void tst(Register rn, Operand o) {
ands(ZR, rn, o);
}
@@ -590,6 +601,32 @@
andis(ZR, rn, imm);
}
+ // Branching to ExternalLabels.
+ void Branch(const ExternalLabel* label) {
+ LoadExternalLabel(TMP, label, kPatchable, PP);
+ br(TMP);
+ }
+
+ void BranchPatchable(const ExternalLabel* label) {
+ LoadPatchableImmediate(TMP, label->address());
+ br(TMP);
+ }
+
+ void BranchLink(const ExternalLabel* label, Register pp) {
+ if (Isolate::Current() == Dart::vm_isolate()) {
+ LoadImmediate(TMP, label->address(), kNoRegister);
+ blr(TMP);
+ } else {
+ LoadExternalLabel(TMP, label, kNotPatchable, pp);
+ blr(TMP);
+ }
+ }
+
+ void BranchLinkPatchable(const ExternalLabel* label) {
+ LoadExternalLabel(TMP, label, kPatchable, PP);
+ blr(TMP);
+ }
+
// Object pool, loading from pool, etc.
void LoadPoolPointer(Register pp) {
const intptr_t object_pool_pc_dist =
@@ -597,6 +634,14 @@
CodeSize();
// PP <- Read(PC - object_pool_pc_dist).
ldr(pp, Address::PC(-object_pool_pc_dist));
+
+ // When in the PP register, the pool pointer is untagged. When we
+ // push it on the stack with PushPP it is tagged again. PopPP then untags
+ // when restoring from the stack. This will make loading from the object
+ // pool only one instruction for the first 4096 entries. Otherwise, because
+ // the offset wouldn't be aligned, it would always be at least two
+ // instructions.
+ sub(pp, pp, Operand(kHeapObjectTag));
}
enum Patchability {
@@ -605,11 +650,17 @@
};
void LoadWordFromPoolOffset(Register dst, Register pp, uint32_t offset);
+ intptr_t FindExternalLabel(const ExternalLabel* label,
+ Patchability patchable);
intptr_t FindObject(const Object& obj, Patchability patchable);
intptr_t FindImmediate(int64_t imm);
bool CanLoadObjectFromPool(const Object& object);
bool CanLoadImmediateFromPool(int64_t imm, Register pp);
+ void LoadExternalLabel(Register dst, const ExternalLabel* label,
+ Patchability patchable, Register pp);
void LoadObject(Register dst, const Object& obj, Register pp);
+ void LoadDecodableImmediate(Register reg, int64_t imm, Register pp);
+ void LoadPatchableImmediate(Register reg, int64_t imm);
void LoadImmediate(Register reg, int64_t imm, Register pp);
private:
@@ -766,8 +817,8 @@
int32_t EncodeImm19BranchOffset(int64_t imm, int32_t instr) {
const int32_t imm32 = static_cast<int32_t>(imm);
- const int32_t off = (((imm32 >> 2) & kImm19Mask) << kImm19Shift);
- return (instr & ~(kImm19Mask << kImm19Shift)) | off;
+ const int32_t off = (((imm32 >> 2) << kImm19Shift) & kImm19Mask);
+ return (instr & ~kImm19Mask) | off;
}
int64_t DecodeImm19BranchOffset(int32_t instr) {
@@ -794,7 +845,7 @@
const int32_t encoding =
op |
(static_cast<int32_t>(cond) << kCondShift) |
- (((imm >> 2) & kImm19Mask) << kImm19Shift);
+ (((imm >> 2) << kImm19Shift) & kImm19Mask);
Emit(encoding);
}
@@ -868,7 +919,7 @@
ASSERT((rd != R31) && (rd != SP));
const Register crd = ConcreteRegister(rd);
const int32_t loimm = (imm & 0x3) << 29;
- const int32_t hiimm = ((imm >> 2) & kImm19Mask) << kImm19Shift;
+ const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask;
const int32_t encoding =
op | loimm | hiimm |
(static_cast<int32_t>(crd) << kRdShift);
« no previous file with comments | « no previous file | runtime/vm/assembler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698