ARM: Use stm/ldm for live registers save/restore in SlowPathCode.
In case when there is more than 4 register to save/restore in the
SlowPathCode stm/ldm can save some code size.
Test: m test-art-target; m test-art-host
Change-Id: I2d5b44bab58b67207105302cd7d8ee3300b9040a
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc
index f5ccf40..2269ba2 100644
--- a/compiler/utils/arm/assembler_thumb2.cc
+++ b/compiler/utils/arm/assembler_thumb2.cc
@@ -3372,6 +3372,30 @@
ldm(IA_W, SP, regs, cond);
}
+void Thumb2Assembler::StoreList(RegList regs, size_t stack_offset) {
+ DCHECK_NE(regs, 0u);
+ DCHECK_EQ(regs & (1u << IP), 0u);
+ if (IsPowerOfTwo(regs)) {
+ Register reg = static_cast<Register>(CTZ(static_cast<uint32_t>(regs)));
+ str(reg, Address(SP, stack_offset));
+ } else {
+ add(IP, SP, ShifterOperand(stack_offset));
+ stm(IA, IP, regs);
+ }
+}
+
+void Thumb2Assembler::LoadList(RegList regs, size_t stack_offset) {
+ DCHECK_NE(regs, 0u);
+ DCHECK_EQ(regs & (1u << IP), 0u);
+ if (IsPowerOfTwo(regs)) {
+ Register reg = static_cast<Register>(CTZ(static_cast<uint32_t>(regs)));
+ ldr(reg, Address(SP, stack_offset));
+ } else {
+ Register lowest_reg = static_cast<Register>(CTZ(static_cast<uint32_t>(regs)));
+ add(lowest_reg, SP, ShifterOperand(stack_offset));
+ ldm(IA, lowest_reg, regs);
+ }
+}
void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) {
if (cond != AL || rd != rm) {