Chromium Code Reviews| Index: runtime/vm/assembler_arm64.h |
| =================================================================== |
| --- runtime/vm/assembler_arm64.h (revision 34654) |
| +++ 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)); |
|
regis
2014/04/03 17:26:59
I missed this check before.
|
| + ASSERT((hw_idx >= 0) && (hw_idx <= 3)); |
|
regis
2014/04/03 17:26:59
You could also write
ASSERT(Utils::IsUint(2, hw_id
|
| + 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); |
| }; |