| 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);
|
|
|