Skip to content

Commit 0a9ee1c

Browse files
[VM] ARM64: Fix tbz instruction for bit positions >= 32
[email protected] Change-Id: I03f42ee44a37da7e064f79db18a7f45fa25ee010 Reviewed-on: https://dart-review.googlesource.com/46063 Reviewed-by: Martin Kustermann <[email protected]>
1 parent e2cd67c commit 0a9ee1c

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

assembler_arm64.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,9 +1841,11 @@ class Assembler : public ValueObject {
18411841
ASSERT(Utils::IsInt(16, imm) && ((imm & 0x3) == 0));
18421842
ASSERT((rt != CSP) && (rt != R31));
18431843
const Register crt = ConcreteRegister(rt);
1844-
const int32_t encoding = op | (static_cast<int32_t>(bit_number) << 19) |
1845-
(static_cast<int32_t>(crt) << kRtShift) |
1846-
encoded_offset;
1844+
int32_t bit_number_low = bit_number & 0x1f;
1845+
int32_t bit_number_hi = (bit_number & 0x20) >> 5;
1846+
const int32_t encoding =
1847+
op | (bit_number_low << 19) | (bit_number_hi << 31) |
1848+
(static_cast<int32_t>(crt) << kRtShift) | encoded_offset;
18471849
Emit(encoding);
18481850
}
18491851

assembler_arm64_test.cc

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,15 +1008,22 @@ ASSEMBLER_TEST_RUN(CmpBranchIfNotZeroNotTaken, test) {
10081008
EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
10091009
}
10101010

1011+
static const int64_t kBits5And35 = (1 << 5) | (1ll << 35);
1012+
10111013
ASSEMBLER_TEST_GENERATE(TstBranchIfZero, assembler) {
1012-
Label l;
1014+
Label l, l2;
10131015

10141016
__ movz(R0, Immediate(42), 0);
1015-
__ movz(R1, Immediate((0 << 5) | 1), 0);
1017+
__ LoadImmediate(R1, ~kBits5And35);
10161018

10171019
__ tbz(&l, R1, 5);
10181020
__ movz(R0, Immediate(0), 0);
10191021
__ Bind(&l);
1022+
1023+
__ tbz(&l2, R1, 35);
1024+
__ movz(R0, Immediate(0), 0);
1025+
__ Bind(&l2);
1026+
10201027
__ ret();
10211028
}
10221029

@@ -1029,7 +1036,7 @@ ASSEMBLER_TEST_GENERATE(TstBranchIfZeroNotTaken, assembler) {
10291036
Label l;
10301037

10311038
__ movz(R0, Immediate(0), 0);
1032-
__ movz(R1, Immediate((1 << 5) | 1), 0);
1039+
__ LoadImmediate(R1, kBits5And35);
10331040

10341041
__ tbz(&l, R1, 5);
10351042
__ movz(R0, Immediate(42), 0);
@@ -1043,14 +1050,19 @@ ASSEMBLER_TEST_RUN(TstBranchIfZeroNotTaken, test) {
10431050
}
10441051

10451052
ASSEMBLER_TEST_GENERATE(TstBranchIfNotZero, assembler) {
1046-
Label l;
1053+
Label l, l2;
10471054

10481055
__ movz(R0, Immediate(42), 0);
1049-
__ movz(R1, Immediate((1 << 5) | 1), 0);
1056+
__ LoadImmediate(R1, kBits5And35);
10501057

10511058
__ tbnz(&l, R1, 5);
10521059
__ movz(R0, Immediate(0), 0);
10531060
__ Bind(&l);
1061+
1062+
__ tbnz(&l2, R1, 35);
1063+
__ movz(R0, Immediate(0), 0);
1064+
__ Bind(&l2);
1065+
10541066
__ ret();
10551067
}
10561068

@@ -1063,7 +1075,7 @@ ASSEMBLER_TEST_GENERATE(TstBranchIfNotZeroNotTaken, assembler) {
10631075
Label l;
10641076

10651077
__ movz(R0, Immediate(0), 0);
1066-
__ movz(R1, Immediate((0 << 5) | 1), 0);
1078+
__ LoadImmediate(R1, ~kBits5And35);
10671079

10681080
__ tbnz(&l, R1, 5);
10691081
__ movz(R0, Immediate(42), 0);
@@ -1080,7 +1092,7 @@ ASSEMBLER_TEST_GENERATE(TstBranchIfZeroFar, assembler) {
10801092
Label l;
10811093

10821094
__ movz(R0, Immediate(42), 0);
1083-
__ movz(R1, Immediate((0 << 5) | 1), 0);
1095+
__ LoadImmediate(R1, ~kBits5And35);
10841096

10851097
__ tbz(&l, R1, 5);
10861098

@@ -1103,7 +1115,7 @@ ASSEMBLER_TEST_GENERATE(TstBranchIfNotZeroFar, assembler) {
11031115
Label l;
11041116

11051117
__ movz(R0, Immediate(42), 0);
1106-
__ movz(R1, Immediate((1 << 5) | 1), 0);
1118+
__ LoadImmediate(R1, kBits5And35);
11071119

11081120
__ tbnz(&l, R1, 5);
11091121

disassembler_arm64.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ int ARM64Decoder::FormatOption(Instr* instr, const char* format) {
358358
return 6;
359359
} else {
360360
ASSERT(STRING_STARTS_WITH(format, "bitpos"));
361-
int bitpos = instr->Bits(19, 4) | (instr->Bit(31) << 5);
361+
int bitpos = instr->Bits(19, 5) | (instr->Bit(31) << 5);
362362
buffer_pos_ +=
363363
Utils::SNPrint(current_position_in_buffer(),
364364
remaining_size_in_buffer(), "#%d", bitpos);

0 commit comments

Comments
 (0)