summaryrefslogtreecommitdiff
path: root/compiler/utils/arm/assembler_arm.cc
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2015-10-19 21:31:53 -0700
committer Andreas Gampe <agampe@google.com> 2015-10-30 11:15:26 -0700
commit7cffc3b0004d32faffc552c0a59286f369b21504 (patch)
treee3838b8ba2a782ed91ef8faa381362b7a686a32a /compiler/utils/arm/assembler_arm.cc
parent9e1b56f0e77aa5b6c72374b86d0cef58484ddcaa (diff)
ART: Arm32 packed-switch jump tables
Add jump table support to the thumb2 assembler. Jump tables are a collection of labels for the case targets, and an anchor label denoting the position of the jump. Use the jump table support to implement packed-switch support for arm32. Add tests for BindTrackedLabel and JumpTable to the thumb2 assembler test. Bug: 24092914 Change-Id: I5c84f193dfebf9e07f48678efc8bd151bb1410dd
Diffstat (limited to 'compiler/utils/arm/assembler_arm.cc')
-rw-r--r--compiler/utils/arm/assembler_arm.cc21
1 files changed, 21 insertions, 0 deletions
diff --git a/compiler/utils/arm/assembler_arm.cc b/compiler/utils/arm/assembler_arm.cc
index 807bedaa04..68e39568bb 100644
--- a/compiler/utils/arm/assembler_arm.cc
+++ b/compiler/utils/arm/assembler_arm.cc
@@ -16,6 +16,8 @@
#include "assembler_arm.h"
+#include <algorithm>
+
#include "base/bit_utils.h"
#include "base/logging.h"
#include "entrypoints/quick/quick_entrypoints.h"
@@ -922,5 +924,24 @@ uint32_t ArmAssembler::ModifiedImmediate(uint32_t value) {
return value | i << 26 | imm3 << 12 | a << 7;
}
+void ArmAssembler::FinalizeTrackedLabels() {
+ if (!tracked_labels_.empty()) {
+ // This array should be sorted, as assembly is generated in linearized order. It isn't
+ // technically required, but GetAdjustedPosition() used in AdjustLabelPosition() can take
+ // advantage of it. So ensure that it's actually the case.
+ DCHECK(std::is_sorted(
+ tracked_labels_.begin(),
+ tracked_labels_.end(),
+ [](const Label* lhs, const Label* rhs) { return lhs->Position() < rhs->Position(); }));
+
+ Label* last_label = nullptr; // Track duplicates, we must not adjust twice.
+ for (Label* label : tracked_labels_) {
+ DCHECK_NE(label, last_label);
+ AdjustLabelPosition(label);
+ last_label = label;
+ }
+ }
+}
+
} // namespace arm
} // namespace art