Intrinsic Unsafe.CompareAndSwapLong() for ARM.
(cherry picked from cb53fcd79b1a5ce608208ec454b5c19f64aaba37)
Change-Id: Iadd3cc8b4ed390670463b80f8efd579ce6ece226
diff --git a/disassembler/disassembler_arm.cc b/disassembler/disassembler_arm.cc
index 936fb07..90d84d5 100644
--- a/disassembler/disassembler_arm.cc
+++ b/disassembler/disassembler_arm.cc
@@ -440,18 +440,34 @@
if (op3 == 0) { // op3 is 00, op4 is 00
opcode << "strex";
args << Rd << ", " << Rt << ", [" << Rn << ", #" << (imm8 << 2) << "]";
+ if (Rd.r == 13 || Rd.r == 15 || Rt.r == 13 || Rt.r == 15 || Rn.r == 15 ||
+ Rd.r == Rn.r || Rd.r == Rt.r) {
+ args << " (UNPREDICTABLE)";
+ }
} else { // op3 is 01, op4 is 00
// this is one of strexb, strexh or strexd
int op5 = (instr >> 4) & 0xf;
switch (op5) {
case 4:
- opcode << "strexb";
- break;
case 5:
- opcode << "strexh";
+ opcode << ((op5 == 4) ? "strexb" : "strexh");
+ Rd = ArmRegister(instr, 0);
+ args << Rd << ", " << Rt << ", [" << Rn << "]";
+ if (Rd.r == 13 || Rd.r == 15 || Rt.r == 13 || Rt.r == 15 || Rn.r == 15 ||
+ Rd.r == Rn.r || Rd.r == Rt.r || (instr & 0xf00) != 0xf00) {
+ args << " (UNPREDICTABLE)";
+ }
break;
case 7:
opcode << "strexd";
+ ArmRegister Rt2 = Rd;
+ Rd = ArmRegister(instr, 0);
+ args << Rd << ", " << Rt << ", " << Rt2 << ", [" << Rn << "]";
+ if (Rd.r == 13 || Rd.r == 15 || Rt.r == 13 || Rt.r == 15 ||
+ Rt2.r == 13 || Rt2.r == 15 || Rn.r == 15 ||
+ Rd.r == Rn.r || Rd.r == Rt.r || Rd.r == Rt2.r) {
+ args << " (UNPREDICTABLE)";
+ }
break;
}
}
@@ -460,6 +476,9 @@
if (op3 == 0) { // op3 is 00, op4 is 01
opcode << "ldrex";
args << Rt << ", [" << Rn << ", #" << (imm8 << 2) << "]";
+ if (Rt.r == 13 || Rt.r == 15 || Rn.r == 15 || (instr & 0xf00) != 0xf00) {
+ args << " (UNPREDICTABLE)";
+ }
} else { // op3 is 01, op4 is 01
// this is one of strexb, strexh or strexd
int op5 = (instr >> 4) & 0xf;
@@ -471,13 +490,20 @@
opcode << "tbh";
break;
case 4:
- opcode << "ldrexb";
- break;
case 5:
- opcode << "ldrexh";
+ opcode << ((op5 == 4) ? "ldrexb" : "ldrexh");
+ args << Rt << ", [" << Rn << "]";
+ if (Rt.r == 13 || Rt.r == 15 || Rn.r == 15 || (instr & 0xf0f) != 0xf0f) {
+ args << " (UNPREDICTABLE)";
+ }
break;
case 7:
opcode << "ldrexd";
+ args << Rt << ", " << Rd /* Rt2 */ << ", [" << Rn << "]";
+ if (Rt.r == 13 || Rt.r == 15 || Rd.r == 13 /* Rt2 */ || Rd.r == 15 /* Rt2 */ ||
+ Rn.r == 15 || (instr & 0x00f) != 0x00f) {
+ args << " (UNPREDICTABLE)";
+ }
break;
}
}
@@ -507,15 +533,6 @@
}
}
-
- if (op3 == 0 && op4 == 0) { // STREX
- ArmRegister Rd(instr, 8);
- opcode << "strex";
- args << Rd << ", " << Rt << ", [" << Rn << ", #" << (imm8 << 2) << "]";
- } else if (op3 == 0 && op4 == 1) { // LDREX
- opcode << "ldrex";
- args << Rt << ", [" << Rn << ", #" << (imm8 << 2) << "]";
- }
} else if ((op2 & 0x60) == 0x20) { // 01x xxxx
// Data-processing (shifted register)
// |111|1110|0000|0|0000|1111|1100|00|00|0000|