Index: runtime/vm/assembler_arm64.cc |
=================================================================== |
--- runtime/vm/assembler_arm64.cc (revision 36182) |
+++ runtime/vm/assembler_arm64.cc (working copy) |
@@ -684,6 +684,12 @@ |
void Assembler::AddImmediate( |
Register dest, Register rn, int64_t imm, Register pp) { |
Operand op; |
+ if (imm == 0) { |
+ if (dest != rn) { |
+ mov(dest, rn); |
+ } |
+ return; |
+ } |
if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) { |
add(dest, rn, op); |
} else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) == |
@@ -702,9 +708,11 @@ |
Register dest, Register rn, int64_t imm, Register pp) { |
Operand op; |
if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) { |
+ // Handles imm == kMinInt64. |
adds(dest, rn, op); |
} else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) == |
Operand::Immediate) { |
+ ASSERT(imm != kMinInt64); // Would cause erroneous overflow detection. |
subs(dest, rn, op); |
} else { |
// TODO(zra): Try adding top 12 bits, then bottom 12 bits. |
@@ -715,6 +723,25 @@ |
} |
+void Assembler::SubImmediateSetFlags( |
+ Register dest, Register rn, int64_t imm, Register pp) { |
+ Operand op; |
+ if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) { |
+ // Handles imm == kMinInt64. |
+ subs(dest, rn, op); |
+ } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) == |
+ Operand::Immediate) { |
+ ASSERT(imm != kMinInt64); // Would cause erroneous overflow detection. |
+ adds(dest, rn, op); |
+ } else { |
+ // TODO(zra): Try subtracting top 12 bits, then bottom 12 bits. |
+ ASSERT(rn != TMP2); |
+ LoadImmediate(TMP2, imm, pp); |
+ subs(dest, rn, Operand(TMP2)); |
+ } |
+} |
+ |
+ |
void Assembler::AndImmediate( |
Register rd, Register rn, int64_t imm, Register pp) { |
Operand imm_op; |