diff options
author | Georgia Kouveli <georgia.kouveli@arm.com> | 2017-02-10 15:39:19 +0000 |
---|---|---|
committer | Georgia Kouveli <georgia.kouveli@arm.com> | 2017-02-13 13:20:11 +0000 |
commit | 896682f0411643afa78e8c62caf723ec5f2b4dbe (patch) | |
tree | 2fa57870af5a7e26bd5b621690dab52e28e42cf6 /test/aarch64 | |
parent | 2ab5c802e70ab95e794032878c95a7e446b23a07 (diff) | |
download | vixl-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.cc | 60 |
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(); |