Modified: trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.cpp (214415 => 214416)
--- trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.cpp 2017-03-27 16:18:33 UTC (rev 214415)
+++ trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.cpp 2017-03-27 16:39:47 UTC (rev 214416)
@@ -84,7 +84,9 @@
OPCODE_GROUP_ENTRY(0x15, A64DOpcodeConditionalBranchImmediate),
OPCODE_GROUP_ENTRY(0x15, A64DOpcodeCompareAndBranchImmediate),
OPCODE_GROUP_ENTRY(0x15, A64DOpcodeHint),
- OPCODE_GROUP_ENTRY(0x15, A64DOpcodeDmb),
+ OPCODE_GROUP_ENTRY(0x15, A64DOpcodeSystemSync),
+ OPCODE_GROUP_ENTRY(0x15, A64DOpcodeMSRImmediate),
+ OPCODE_GROUP_ENTRY(0x15, A64DOpcodeMSROrMRSRegister),
OPCODE_GROUP_ENTRY(0x16, A64DOpcodeUnconditionalBranchImmediate),
OPCODE_GROUP_ENTRY(0x16, A64DOpcodeUnconditionalBranchRegister),
OPCODE_GROUP_ENTRY(0x16, A64DOpcodeTestAndBranchImmediate),
@@ -880,6 +882,82 @@
return m_formatBuffer;
}
+const char* A64DOpcodeMSRImmediate::format()
+{
+ const char* pstateField = nullptr;
+
+ if (!op1() && (op2() == 0x5))
+ pstateField = "spsel";
+
+ if ((op1() == 0x3) && (op2() == 0x6))
+ pstateField = "daifset";
+
+ if ((op1() == 0x3) && (op2() == 0x7))
+ pstateField = "daifclr";
+
+ if (!!op1() && !(op2() & 0x4))
+ return A64DOpcode::format();
+
+ if (!pstateField)
+ return A64DOpcode::format();
+
+ appendInstructionName("msr");
+ appendString(pstateField);
+ appendSeparator();
+ appendUnsignedImmediate(crM());
+
+ return m_formatBuffer;
+}
+
+const char* A64DOpcodeMSROrMRSRegister::format()
+{
+ appendInstructionName(opName());
+
+ if (lBit()) {
+ appendZROrRegisterName(rt());
+ appendSeparator();
+ }
+
+ bufferPrintf("S%u_%u_C%u_C%u_%u", op0(), op1(), crN(), crM(), op2());
+
+ if (!lBit()) {
+ appendSeparator();
+ appendZROrRegisterName(rt());
+ }
+
+ const char* systemRegisterName = nullptr;
+
+ switch (systemRegister()) {
+ case 0b1101100000000001:
+ systemRegisterName = "ctr_el0";
+ break;
+ case 0b1101101000010000:
+ systemRegisterName = "nzcv";
+ break;
+ case 0b1101101000010001:
+ systemRegisterName = "daif";
+ break;
+ case 0b1101101000100000:
+ systemRegisterName = "fpcr";
+ break;
+ case 0b1101101000100001:
+ systemRegisterName = "fpsr";
+ break;
+ case 0b1101111010000010:
+ systemRegisterName = "tpidr_el0";
+ break;
+ case 0b1101111010000011:
+ systemRegisterName = "tpidrr0_el0";
+ break;
+ }
+
+ if (systemRegisterName) {
+ appendString(" ; ");
+ appendString(systemRegisterName);
+ }
+ return m_formatBuffer;
+}
+
const char* const A64DOpcodeHint::s_opNames[6] = {
"nop", "yield", "wfe", "wfi", "sev", "sevl"
};
@@ -894,20 +972,37 @@
return m_formatBuffer;
}
-const char* const A64DOpcodeDmb::s_optionNames[16] = {
+const char* const A64DOpcodeSystemSync::s_opNames[8] = {
+ 0, 0, "clrex", 0, "dsb", "dmb", "isb", 0
+};
+
+const char* const A64DOpcodeSystemSync::s_optionNames[16] = {
0, "oshld", "oshst", "osh", 0, "nshld", "nshst", "nsh",
0, "ishld", "ishst", "ish", 0, "ld", "st", "sy"
};
-const char* A64DOpcodeDmb::format()
+const char* A64DOpcodeSystemSync::format()
{
- appendInstructionName(opName());
- const char* thisOption = option();
- if (thisOption)
- appendString(thisOption);
- else
- appendUnsignedImmediate(crM());
+ const char* thisOpName = opName();
+ if (!thisOpName)
+ return A64DOpcode::format();
+
+ appendInstructionName(thisOpName);
+
+ if (op2() & 0x2) {
+ if (crM() != 0xf) {
+ appendCharacter('#');
+ appendUnsignedImmediate(crM());
+ }
+ } else {
+ const char* thisOption = option();
+ if (thisOption)
+ appendString(thisOption);
+ else
+ appendUnsignedImmediate(crM());
+ }
+
return m_formatBuffer;
}
Modified: trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.h (214415 => 214416)
--- trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.h 2017-03-27 16:18:33 UTC (rev 214415)
+++ trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.h 2017-03-27 16:39:47 UTC (rev 214416)
@@ -536,7 +536,40 @@
unsigned opNum() { return (m_opcode >> 16) & 0x1f; }
};
-class A64DOpcodeHint : public A64DOpcode {
+class A64DOpcodeSystem : public A64DOpcode {
+public:
+ unsigned lBit() { return (m_opcode >> 21) & 0x1; }
+ unsigned op0() { return (m_opcode >> 19) & 0x3; }
+ unsigned op1() { return (m_opcode >> 16) & 0x7; }
+ unsigned crN() { return (m_opcode >> 12) & 0xf; }
+ unsigned crM() { return (m_opcode >> 8) & 0xf; }
+ unsigned op2() { return (m_opcode >> 5) & 0x7; }
+};
+
+class A64DOpcodeMSRImmediate : public A64DOpcodeSystem {
+public:
+ static const uint32_t mask = 0xfff8f01f;
+ static const uint32_t pattern = 0xd500401f;
+
+ DEFINE_STATIC_FORMAT(A64DOpcodeMSRImmediate, thisObj);
+
+ const char* format();
+};
+
+class A64DOpcodeMSROrMRSRegister : public A64DOpcodeSystem {
+public:
+ static const uint32_t mask = 0xffd00000;
+ static const uint32_t pattern = 0xd5100000;
+
+ DEFINE_STATIC_FORMAT(A64DOpcodeMSROrMRSRegister, thisObj);
+
+ const char* format();
+
+ const char* opName() { return lBit() ? "mrs" : "msr"; }
+ unsigned systemRegister() { return ((op0() << 14) | (op1() << 11) | (crN() << 7) | (crM() << 3) | op2()); }
+};
+
+class A64DOpcodeHint : public A64DOpcodeSystem {
private:
static const char* const s_opNames[6];
@@ -552,20 +585,20 @@
unsigned immediate7() { return (m_opcode >> 5) & 0x7f; }
};
-class A64DOpcodeDmb : public A64DOpcode {
+class A64DOpcodeSystemSync : public A64DOpcodeSystem {
+ static const char* const s_opNames[8];
static const char* const s_optionNames[16];
public:
- static const uint32_t mask = 0xfffff0ff;
- static const uint32_t pattern = 0xd50330bf;
+ static const uint32_t mask = 0xfffff01f;
+ static const uint32_t pattern = 0xd503301f;
- DEFINE_STATIC_FORMAT(A64DOpcodeDmb, thisObj);
+ DEFINE_STATIC_FORMAT(A64DOpcodeSystemSync, thisObj);
const char* format();
- const char* opName() { return "dmb"; }
+ const char* opName() { return s_opNames[op2()]; }
const char* option() { return s_optionNames[crM()]; }
- unsigned crM() { return (m_opcode >> 8) & 0xf; }
};
class A64DOpcodeLoadStore : public A64DOpcode {