aboutsummaryrefslogtreecommitdiff
path: root/test/aarch64
diff options
context:
space:
mode:
authorGeorgia Kouveli <georgia.kouveli@arm.com>2017-02-10 15:39:19 +0000
committerGeorgia Kouveli <georgia.kouveli@arm.com>2017-02-13 13:20:11 +0000
commit896682f0411643afa78e8c62caf723ec5f2b4dbe (patch)
tree2fa57870af5a7e26bd5b621690dab52e28e42cf6 /test/aarch64
parent2ab5c802e70ab95e794032878c95a7e446b23a07 (diff)
downloadvixl-896682f0411643afa78e8c62caf723ec5f2b4dbe.tar.gz
Fix issue with TBZ and large literal pool.
Before emitting a TBZ or TBNZ instruction, check whether the literal pool exceeds the range of these branches and if it does, emit it. Change-Id: I7de1e58c7ff0670a10dc09961bdafcabc5f874d5
Diffstat (limited to 'test/aarch64')
-rw-r--r--test/aarch64/test-assembler-aarch64.cc60
1 files changed, 60 insertions, 0 deletions
diff --git a/test/aarch64/test-assembler-aarch64.cc b/test/aarch64/test-assembler-aarch64.cc
index f083b35a..63a6278f 100644
--- a/test/aarch64/test-assembler-aarch64.cc
+++ b/test/aarch64/test-assembler-aarch64.cc
@@ -1643,6 +1643,66 @@ TEST(rbit_rev) {
TEARDOWN();
}
+typedef void (MacroAssembler::*TestBranchSignature)(const Register& rt,
+ unsigned bit_pos,
+ Label* label);
+
+static void TbzRangePoolLimitHelper(TestBranchSignature test_branch) {
+ const int kTbzRange = 32768;
+ const int kNumLdrLiteral = kTbzRange / 4;
+ const int fuzzRange = 2;
+ for (int n = kNumLdrLiteral - fuzzRange; n <= kNumLdrLiteral + fuzzRange;
+ ++n) {
+ for (int margin = -32; margin < 32; margin += 4) {
+ SETUP();
+
+ START();
+
+ // Emit 32KB of literals (equal to the range of TBZ).
+ for (int i = 0; i < n; ++i) {
+ __ Ldr(w0, 0x12345678);
+ }
+
+ const int kLiteralMargin = 128 * KBytes;
+
+ // Emit enough NOPs to be just about to emit the literal pool.
+ ptrdiff_t end =
+ masm.GetCursorOffset() + (kLiteralMargin - n * 4 + margin);
+ while (masm.GetCursorOffset() < end) {
+ __ Nop();
+ }
+
+ // Add a TBZ instruction.
+ Label label;
+
+ (masm.*test_branch)(x0, 2, &label);
+
+ // Add enough NOPs to surpass its range, to make sure we can encode the
+ // veneer.
+ end = masm.GetCursorOffset() + (kTbzRange - 4);
+ {
+ ExactAssemblyScope scope(&masm,
+ kTbzRange,
+ ExactAssemblyScope::kMaximumSize);
+ while (masm.GetCursorOffset() < end) __ nop();
+ }
+
+ // Finally, bind the label.
+ __ Bind(&label);
+
+ END();
+
+ RUN();
+
+ TEARDOWN();
+ }
+ }
+}
+
+TEST(test_branch_limits_literal_pool_size) {
+ TbzRangePoolLimitHelper(&MacroAssembler::Tbz);
+ TbzRangePoolLimitHelper(&MacroAssembler::Tbnz);
+}
TEST(clz_cls) {
SETUP();