summaryrefslogtreecommitdiff
path: root/compiler/utils
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils')
-rw-r--r--compiler/utils/arm/assembler_arm_vixl.cc45
-rw-r--r--compiler/utils/arm/assembler_arm_vixl.h3
-rw-r--r--compiler/utils/assembler_thumb_test.cc2
-rw-r--r--compiler/utils/assembler_thumb_test_expected.cc.inc2
4 files changed, 50 insertions, 2 deletions
diff --git a/compiler/utils/arm/assembler_arm_vixl.cc b/compiler/utils/arm/assembler_arm_vixl.cc
index 3c5973ebe6..8045bd2c6a 100644
--- a/compiler/utils/arm/assembler_arm_vixl.cc
+++ b/compiler/utils/arm/assembler_arm_vixl.cc
@@ -346,6 +346,51 @@ void ArmVIXLAssembler::LoadDFromOffset(vixl32::DRegister reg,
___ Vldr(reg, MemOperand(base, offset));
}
+// Prefer Str to Add/Stm in ArmVIXLAssembler::StoreRegisterList and
+// ArmVIXLAssembler::LoadRegisterList where this generates less code (size).
+static constexpr int kRegListThreshold = 4;
+
+void ArmVIXLAssembler::StoreRegisterList(RegList regs, size_t stack_offset) {
+ int number_of_regs = POPCOUNT(static_cast<uint32_t>(regs));
+ if (number_of_regs != 0) {
+ if (number_of_regs > kRegListThreshold) {
+ UseScratchRegisterScope temps(GetVIXLAssembler());
+ vixl32::Register base = sp;
+ if (stack_offset != 0) {
+ base = temps.Acquire();
+ DCHECK_EQ(regs & (1u << base.GetCode()), 0u);
+ ___ Add(base, sp, stack_offset);
+ }
+ ___ Stm(base, NO_WRITE_BACK, RegisterList(regs));
+ } else {
+ for (uint32_t i : LowToHighBits(static_cast<uint32_t>(regs))) {
+ ___ Str(vixl32::Register(i), MemOperand(sp, stack_offset));
+ stack_offset += kRegSizeInBytes;
+ }
+ }
+ }
+}
+
+void ArmVIXLAssembler::LoadRegisterList(RegList regs, size_t stack_offset) {
+ int number_of_regs = POPCOUNT(static_cast<uint32_t>(regs));
+ if (number_of_regs != 0) {
+ if (number_of_regs > kRegListThreshold) {
+ UseScratchRegisterScope temps(GetVIXLAssembler());
+ vixl32::Register base = sp;
+ if (stack_offset != 0) {
+ base = temps.Acquire();
+ ___ Add(base, sp, stack_offset);
+ }
+ ___ Ldm(base, NO_WRITE_BACK, RegisterList(regs));
+ } else {
+ for (uint32_t i : LowToHighBits(static_cast<uint32_t>(regs))) {
+ ___ Ldr(vixl32::Register(i), MemOperand(sp, stack_offset));
+ stack_offset += kRegSizeInBytes;
+ }
+ }
+ }
+}
+
void ArmVIXLAssembler::AddConstant(vixl32::Register rd, int32_t value) {
AddConstant(rd, rd, value);
}
diff --git a/compiler/utils/arm/assembler_arm_vixl.h b/compiler/utils/arm/assembler_arm_vixl.h
index c8f3a9b863..c5575faaa1 100644
--- a/compiler/utils/arm/assembler_arm_vixl.h
+++ b/compiler/utils/arm/assembler_arm_vixl.h
@@ -90,6 +90,9 @@ class ArmVIXLAssembler FINAL : public Assembler {
void LoadSFromOffset(vixl32::SRegister reg, vixl32::Register base, int32_t offset);
void LoadDFromOffset(vixl32::DRegister reg, vixl32::Register base, int32_t offset);
+ void LoadRegisterList(RegList regs, size_t stack_offset);
+ void StoreRegisterList(RegList regs, size_t stack_offset);
+
bool ShifterOperandCanAlwaysHold(uint32_t immediate);
bool ShifterOperandCanHold(Opcode opcode, uint32_t immediate, SetCc set_cc);
bool CanSplitLoadStoreOffset(int32_t allowed_offset_bits,
diff --git a/compiler/utils/assembler_thumb_test.cc b/compiler/utils/assembler_thumb_test.cc
index 86a4aa2245..10bed13dad 100644
--- a/compiler/utils/assembler_thumb_test.cc
+++ b/compiler/utils/assembler_thumb_test.cc
@@ -158,7 +158,7 @@ void DumpAndCheck(std::vector<uint8_t>& code, const char* testname, const char*
}
if (CompareIgnoringSpace(results[lineindex], testline) != 0) {
LOG(FATAL) << "Output is not as expected at line: " << lineindex
- << results[lineindex] << "/" << testline;
+ << results[lineindex] << "/" << testline << ", test name: " << testname;
}
++lineindex;
}
diff --git a/compiler/utils/assembler_thumb_test_expected.cc.inc b/compiler/utils/assembler_thumb_test_expected.cc.inc
index 91f397087c..69e1d8f6fa 100644
--- a/compiler/utils/assembler_thumb_test_expected.cc.inc
+++ b/compiler/utils/assembler_thumb_test_expected.cc.inc
@@ -5544,7 +5544,7 @@ const char* const VixlJniHelpersResults[] = {
" 10c: ecbd 8a10 vpop {s16-s31}\n",
" 110: e8bd 8de0 ldmia.w sp!, {r5, r6, r7, r8, sl, fp, pc}\n",
" 114: 4660 mov r0, ip\n",
- " 116: f8d9 c2ac ldr.w ip, [r9, #684] ; 0x2ac\n",
+ " 116: f8d9 c2b0 ldr.w ip, [r9, #688] ; 0x2b0\n",
" 11a: 47e0 blx ip\n",
nullptr
};