[vm, compiler] Assert against unpredictable forms of load/store exclusive on ARM.

Make ARM64 disassembly closer to the standard form.

TEST=ci
Change-Id: I459093abe049835c6597b80c8020566054a12b48
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368824
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2024-05-30 20:09:29 +00:00 committed by Commit Queue
parent 31652ba921
commit 16f3ad9078
4 changed files with 84 additions and 25 deletions

View file

@ -503,6 +503,8 @@ void Assembler::stm(BlockAddressMode am,
void Assembler::ldrex(Register rt, Register rn, Condition cond) {
ASSERT(rn != kNoRegister);
ASSERT(rt != kNoRegister);
ASSERT(rn != R15);
ASSERT(rt != R15);
ASSERT(cond != kNoCondition);
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 |
B23 | L | (static_cast<int32_t>(rn) << kLdrExRnShift) |
@ -515,7 +517,14 @@ void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) {
ASSERT(rn != kNoRegister);
ASSERT(rd != kNoRegister);
ASSERT(rt != kNoRegister);
ASSERT(rn != R15);
ASSERT(rd != R15);
ASSERT(rt != R15);
ASSERT(rd != kNoRegister);
ASSERT(rt != kNoRegister);
ASSERT(cond != kNoCondition);
ASSERT(rd != rn);
ASSERT(rd != rt);
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 |
B23 | (static_cast<int32_t>(rn) << kStrExRnShift) |
(static_cast<int32_t>(rd) << kStrExRdShift) | B11 | B10 |

View file

@ -1066,6 +1066,8 @@ class Assembler : public AssemblerBase {
// rs = status (1 = failure, 0 = success)
// rt = value
// rn = address
ASSERT(rs != rt);
ASSERT((rs != rn) || (rs == ZR));
EmitLoadStoreExclusive(STXR, rs, rn, rt, size);
}
void clrex() {

View file

@ -1028,8 +1028,8 @@ ASSEMBLER_TEST_RUN(Semaphore, test) {
"movz r0, #0x28\n"
"movz r1, #0x2a\n"
"str r0, [sp, #-8]!\n"
"ldxr r0, sp\n"
"stxr tmp, r1, sp\n"
"ldxr r0, [sp]\n"
"stxr tmp, r1, [sp]\n"
"cmp tmp, #0x0\n"
"bne -12\n"
"ldr r0, [sp], #8 !\n"
@ -1061,9 +1061,9 @@ ASSEMBLER_TEST_RUN(FailedSemaphore, test) {
"movz r0, #0x28\n"
"movz r1, #0x2a\n"
"str r0, [sp, #-8]!\n"
"ldxr r0, sp\n"
"ldxr r0, [sp]\n"
"clrex\n"
"stxr tmp, r1, sp\n"
"stxr tmp, r1, [sp]\n"
"ldr r0, [sp], #8 !\n"
"add r0, r0, tmp\n"
"mov csp, sp\n"
@ -1107,8 +1107,8 @@ ASSEMBLER_TEST_RUN(Semaphore32, test) {
"str r0, [sp, #-8]!\n"
"movz r0, #0x28\n"
"movz r1, #0x2a\n"
"ldxrw r0, sp\n"
"stxrw tmp, r1, sp\n"
"ldxrw r0, [sp]\n"
"stxrw tmp, r1, [sp]\n"
"cmp tmp, #0x0\n"
"bne -12\n"
"ldr r0, [sp], #8 !\n"
@ -1149,32 +1149,80 @@ ASSEMBLER_TEST_RUN(FailedSemaphore32, test) {
"str r0, [sp, #-8]!\n"
"movz r0, #0x28\n"
"movz r1, #0x2a\n"
"ldxrw r0, sp\n"
"ldxrw r0, [sp]\n"
"clrex\n"
"stxrw tmp, r1, sp\n"
"stxrw tmp, r1, [sp]\n"
"ldr r0, [sp], #8 !\n"
"add r0, r0, tmp\n"
"mov csp, sp\n"
"ret\n");
}
ASSEMBLER_TEST_GENERATE(LoadStoreExclusiveR31, assembler) {
ASSEMBLER_TEST_GENERATE(LoadStoreExclusiveR31Address, assembler) {
__ AddImmediate(CSP, CSP, -16);
__ ldxr(ZR, CSP, kEightBytes);
__ stxr(ZR, ZR, CSP, kEightBytes);
__ stxr(R0, ZR, CSP, kEightBytes);
__ AddImmediate(CSP, CSP, 16);
__ LoadImmediate(R0, 42);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadStoreExclusiveR31, test) {
ASSEMBLER_TEST_RUN(LoadStoreExclusiveR31Address, test) {
EXPECT(test != nullptr);
typedef intptr_t (*LoadStoreExclusiveR31)() DART_UNUSED;
EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(LoadStoreExclusiveR31, test->entry()));
EXPECT_DISASSEMBLY(
"sub csp, csp, #0x10\n"
"ldxr zr, csp\n"
"stxr zr, zr, csp\n"
"ldxr zr, [csp]\n"
"stxr r0, zr, [csp]\n"
"add csp, csp, #0x10\n"
"movz r0, #0x2a\n"
"ret\n");
}
ASSEMBLER_TEST_GENERATE(LoadStoreExclusiveR31Data, assembler) {
__ AddImmediate(CSP, CSP, -16);
__ MoveRegister(R0, CSP);
__ ldxr(ZR, CSP, kEightBytes);
__ stxr(R1, ZR, R0, kEightBytes);
__ AddImmediate(CSP, CSP, 16);
__ LoadImmediate(R0, 42);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadStoreExclusiveR31Data, test) {
EXPECT(test != nullptr);
typedef intptr_t (*LoadStoreExclusiveR31)() DART_UNUSED;
EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(LoadStoreExclusiveR31, test->entry()));
EXPECT_DISASSEMBLY(
"sub csp, csp, #0x10\n"
"mov r0, csp\n"
"ldxr zr, [csp]\n"
"stxr r1, zr, [r0]\n"
"add csp, csp, #0x10\n"
"movz r0, #0x2a\n"
"ret\n");
}
ASSEMBLER_TEST_GENERATE(LoadStoreExclusiveR31Status, assembler) {
__ AddImmediate(CSP, CSP, -16);
__ MoveRegister(R0, CSP);
__ ldxr(ZR, CSP, kEightBytes);
__ stxr(ZR, R1, R0, kEightBytes);
__ AddImmediate(CSP, CSP, 16);
__ LoadImmediate(R0, 42);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadStoreExclusiveR31Status, test) {
EXPECT(test != nullptr);
typedef intptr_t (*LoadStoreExclusiveR31)() DART_UNUSED;
EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(LoadStoreExclusiveR31, test->entry()));
EXPECT_DISASSEMBLY(
"sub csp, csp, #0x10\n"
"mov r0, csp\n"
"ldxr zr, [csp]\n"
"stxr zr, r1, [r0]\n"
"add csp, csp, #0x10\n"
"movz r0, #0x2a\n"
"ret\n");
@ -1288,7 +1336,7 @@ ASSEMBLER_TEST_RUN(LoadAcquireStoreRelease, test) {
"movk tmp, #0x3344 lsl 32\n"
"movk tmp, #0x1122 lsl 48\n"
"str tmp, [sp, #-8]!\n"
"ldar r1, sp\n"
"ldar r1, [sp]\n"
"movz tmp2, #0x7788\n"
"movk tmp2, #0x5566 lsl 16\n"
"movk tmp2, #0x3344 lsl 32\n"
@ -1301,7 +1349,7 @@ ASSEMBLER_TEST_RUN(LoadAcquireStoreRelease, test) {
"movk tmp, #0x3344 lsl 32\n"
"movk tmp, #0x1122 lsl 48\n"
"str tmp, [sp, #-8]!\n"
"ldarw r1, sp\n"
"ldarw r1, [sp]\n"
"movz tmp2, #0x7788\n"
"movk tmp2, #0x5566 lsl 16\n"
"cmp r1, tmp2\n"
@ -1313,7 +1361,7 @@ ASSEMBLER_TEST_RUN(LoadAcquireStoreRelease, test) {
"movk r1, #0x5566 lsl 16\n"
"movk r1, #0x3344 lsl 32\n"
"movk r1, #0x1122 lsl 48\n"
"stlr r1, sp\n"
"stlr r1, [sp]\n"
"ldr r1, [sp], #8 !\n"
"movz tmp2, #0x7788\n"
"movk tmp2, #0x5566 lsl 16\n"
@ -1327,7 +1375,7 @@ ASSEMBLER_TEST_RUN(LoadAcquireStoreRelease, test) {
"movk r1, #0x5566 lsl 16\n"
"movk r1, #0x3344 lsl 32\n"
"movk r1, #0x1122 lsl 48\n"
"stlrw r1, sp\n"
"stlrw r1, [sp]\n"
"ldr r1, [sp], #8 !\n"
"movz tmp2, #0x7788\n"
"movk tmp2, #0x5566 lsl 16\n"
@ -7588,8 +7636,8 @@ ASSEMBLER_TEST_RUN(StoreReleaseLoadAcquire, test) {
"str r1, [sp, #-8]!\n"
"mov r1, r0\n"
"movz r0, #0x0\n"
"stlr r1, sp\n"
"ldar r0, sp\n"
"stlr r1, [sp]\n"
"ldar r0, [sp]\n"
"ldr r1, [sp], #8 !\n"
"ldr r1, [sp], #8 !\n"
"mov csp, sp\n"
@ -7627,9 +7675,9 @@ ASSEMBLER_TEST_RUN(StoreReleaseLoadAcquire1024, test) {
"movz r0, #0x0\n"
"sub sp, sp, #0x2000\n"
"add tmp2, sp, #0x400\n"
"stlr r1, tmp2\n"
"stlr r1, [tmp2]\n"
"add tmp2, sp, #0x400\n"
"ldar r0, tmp2\n"
"ldar r0, [tmp2]\n"
"add sp, sp, #0x2000\n"
"ldr r1, [sp], #8 !\n"
"ldr r1, [sp], #8 !\n"

View file

@ -806,16 +806,16 @@ void ARM64Decoder::DecodeLoadStoreExclusive(Instr* instr) {
if (is_load) {
const bool is_load_acquire = !is_exclusive && is_ordered;
if (is_load_acquire) {
Format(instr, "ldar'sz 'rt, 'rn");
Format(instr, "ldar'sz 'rt, ['rn]");
} else {
Format(instr, "ldxr'sz 'rt, 'rn");
Format(instr, "ldxr'sz 'rt, ['rn]");
}
} else {
const bool is_store_release = !is_exclusive && is_ordered;
if (is_store_release) {
Format(instr, "stlr'sz 'rt, 'rn");
Format(instr, "stlr'sz 'rt, ['rn]");
} else {
Format(instr, "stxr'sz 'rs, 'rt, 'rn");
Format(instr, "stxr'sz 'rs, 'rt, ['rn]");
}
}
}