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
diff --git a/compiler/utils/arm/assembler_arm.cc b/compiler/utils/arm/assembler_arm.cc
index 807beda..68e3956 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 @@
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