| Index: runtime/vm/assembler_arm64.h
|
| ===================================================================
|
| --- runtime/vm/assembler_arm64.h (revision 34712)
|
| +++ runtime/vm/assembler_arm64.h (working copy)
|
| @@ -118,6 +118,7 @@
|
| ASSERT((rm != R31) && (rm != SP));
|
| const Register crm = ConcreteRegister(rm);
|
| encoding_ = (static_cast<int32_t>(crm) << kRmShift);
|
| + type_ = Shifted;
|
| }
|
|
|
| Operand(Register rm, Shift shift, int32_t imm) {
|
| @@ -259,13 +260,35 @@
|
| static bool IsSafe(const Object& object) { return true; }
|
| static bool IsSafeSmi(const Object& object) { return object.IsSmi(); }
|
|
|
| + // Addition and subtraction.
|
| void add(Register rd, Register rn, Operand o) {
|
| AddSubHelper(kDoubleWord, false, false, rd, rn, o);
|
| }
|
| void addw(Register rd, Register rn, Operand o) {
|
| AddSubHelper(kWord, false, false, rd, rn, o);
|
| }
|
| + void sub(Register rd, Register rn, Operand o) {
|
| + AddSubHelper(kDoubleWord, false, true, rd, rn, o);
|
| + }
|
|
|
| + // Move wide immediate.
|
| + void movk(Register rd, int32_t imm, int32_t hw_idx) {
|
| + ASSERT(rd != SP);
|
| + const Register crd = ConcreteRegister(rd);
|
| + EmitMoveWideOp(MOVK, crd, imm, hw_idx, kDoubleWord);
|
| + }
|
| + void movn(Register rd, int32_t imm, int32_t hw_idx) {
|
| + ASSERT(rd != SP);
|
| + const Register crd = ConcreteRegister(rd);
|
| + EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord);
|
| + }
|
| + void movz(Register rd, int32_t imm, int32_t hw_idx) {
|
| + ASSERT(rd != SP);
|
| + const Register crd = ConcreteRegister(rd);
|
| + EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord);
|
| + }
|
| +
|
| +
|
| // Function return.
|
| void ret(Register rn = R30) {
|
| EmitUnconditionalBranchRegOp(RET, rn);
|
| @@ -303,15 +326,13 @@
|
| if (o.type() == Operand::Immediate) {
|
| ASSERT((rd != ZR) && (rn != ZR));
|
| EmitAddSubImmOp(subtract ? SUBI : ADDI, crd, crn, o, os, set_flags);
|
| + } else if (o.type() == Operand::Shifted) {
|
| + ASSERT((rd != SP) && (rn != SP));
|
| + EmitAddSubShiftExtOp(subtract ? SUB : ADD, crd, crn, o, os, set_flags);
|
| } else {
|
| - if (o.type() == Operand::Shifted) {
|
| - ASSERT((rd != SP) && (rn != SP));
|
| - EmitAddSubShiftExtOp(subtract ? SUB : ADD, crd, crn, o, os, set_flags);
|
| - } else {
|
| - ASSERT(o.type() == Operand::Extended);
|
| - ASSERT((rd != SP) && (rn != ZR));
|
| - EmitAddSubShiftExtOp(subtract ? SUB : ADD, crd, crn, o, os, set_flags);
|
| - }
|
| + ASSERT(o.type() == Operand::Extended);
|
| + ASSERT((rd != SP) && (rn != ZR));
|
| + EmitAddSubShiftExtOp(subtract ? SUB : ADD, crd, crn, o, os, set_flags);
|
| }
|
| }
|
|
|
| @@ -330,9 +351,9 @@
|
|
|
| void EmitAddSubShiftExtOp(AddSubShiftExtOp op,
|
| Register rd, Register rn, Operand o,
|
| - OperandSize os, bool set_flags) {
|
| - ASSERT((os == kDoubleWord) || (os == kWord));
|
| - const int32_t size = (os == kDoubleWord) ? B31 : 0;
|
| + OperandSize sz, bool set_flags) {
|
| + ASSERT((sz == kDoubleWord) || (sz == kWord));
|
| + const int32_t size = (sz == kDoubleWord) ? B31 : 0;
|
| const int32_t s = set_flags ? B29 : 0;
|
| const int32_t encoding =
|
| op | size | s |
|
| @@ -348,6 +369,20 @@
|
| Emit(encoding);
|
| }
|
|
|
| + void EmitMoveWideOp(MoveWideOp op, Register rd, int32_t imm, int32_t hw_idx,
|
| + OperandSize sz) {
|
| + ASSERT(Utils::IsUint(16, imm));
|
| + ASSERT((hw_idx >= 0) && (hw_idx <= 3));
|
| + ASSERT((sz == kDoubleWord) || (sz == kWord));
|
| + const int32_t size = (sz == kDoubleWord) ? B31 : 0;
|
| + const int32_t encoding =
|
| + op | size |
|
| + (static_cast<int32_t>(rd) << kRdShift) |
|
| + (hw_idx << kHWShift) |
|
| + (imm << kImm16Shift);
|
| + Emit(encoding);
|
| + }
|
| +
|
| DISALLOW_ALLOCATION();
|
| DISALLOW_COPY_AND_ASSIGN(Assembler);
|
| };
|
|
|