*/
#include "config.h"
-
#include "A64DOpcode.h"
+
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
A64DOpcode::OpcodeGroup* A64DOpcode::opcodeTable[32];
const char* const A64DOpcode::s_conditionNames[16] = {
- "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc",
- "hi", "ls", "ge", "lt", "gt", "le", "al", "ne"
+ "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc",
+ "hi", "ls", "ge", "lt", "gt", "le", "al", "ne"
};
-const char* const A64DOpcode::s_optionName[8] =
-{ "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx" };
+const char* const A64DOpcode::s_optionName[8] = {
+ "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx"
+};
const char* const A64DOpcode::s_shiftNames[4] = {
"lsl", "lsr", "asl", "ror"
{ groupIndex, groupClass::mask, groupClass::pattern, groupClass::format }
static OpcodeGroupInitializer opcodeGroupList[] = {
+ OPCODE_GROUP_ENTRY(0x08, A64DOpcodeLoadStoreRegisterPair),
+ OPCODE_GROUP_ENTRY(0x09, A64DOpcodeLoadStoreRegisterPair),
OPCODE_GROUP_ENTRY(0x0a, A64DOpcodeLogicalShiftedRegister),
OPCODE_GROUP_ENTRY(0x0b, A64DOpcodeAddSubtractExtendedRegister),
OPCODE_GROUP_ENTRY(0x0b, A64DOpcodeAddSubtractShiftedRegister),
void A64DOpcode::appendRegisterName(unsigned registerNumber, bool is64Bit)
{
+ if (registerNumber == 29) {
+ bufferPrintf(is64Bit ? "fp" : "wfp");
+ return;
+ }
+
if (registerNumber == 30) {
bufferPrintf(is64Bit ? "lr" : "wlr");
return;
if (op2() & 0x2)
return A64DOpcode::format();
- if (rn() == rm() && (opNum() == 1 || opNum() == 2))
- {
+ if (rn() == rm() && (opNum() == 1 || opNum() == 2)) {
if (rn() == 31) {
appendInstructionName((opNum() == 1) ? "cset" : "csetm");
appendRegisterName(rd(), is64Bit());
break;
case 0x5: // DPCS1-3
switch (ll()) {
- case 0x1:
- opname = "dpcs1";
- break;
- case 0x2:
- opname = "dpcs2";
- break;
- case 0x3:
- opname = "dpcs3";
- break;
+ case 0x1:
+ opname = "dpcs1";
+ break;
+ case 0x2:
+ opname = "dpcs2";
+ break;
+ case 0x3:
+ opname = "dpcs3";
+ break;
}
break;
}
if (type() == 0x3)
return A64DOpcode::format();
- if (((rmode() & 0x1) || (rmode() & 0x2)) && (((opcode() & 0x6) == 0x2)|| ((opcode() & 0x6) == 0x4)))
+ if (((rmode() & 0x1) || (rmode() & 0x2)) && (((opcode() & 0x6) == 0x2) || ((opcode() & 0x6) == 0x4)))
return A64DOpcode::format();
if ((type() == 0x2) && (!(opcode() & 0x4) || ((opcode() & 0x6) == 0x4)))
appendCharacter('[');
appendSPOrRegisterName(rn());
- switch(type()) {
+ switch (type()) {
case 0: // Unscaled Immediate
if (immediate9()) {
appendSeparator();
return m_formatBuffer;
}
+const char* A64DOpcodeLoadStoreRegisterPair::opName()
+{
+ if (!vBit() && lBit() && size() == 0x1)
+ return "ldpsw";
+ if (lBit())
+ return "ldp";
+ return "stp";
+}
+
+const char* A64DOpcodeLoadStoreRegisterPair::format()
+{
+ const char* thisOpName = opName();
+
+ if (size() == 0x3)
+ return A64DOpcode::format();
+
+ if ((offsetMode() < 0x1) || (offsetMode() > 0x3))
+ return A64DOpcode::format();
+
+ if ((offsetMode() == 0x1) && !vBit() && !lBit())
+ return A64DOpcode::format();
+
+ appendInstructionName(thisOpName);
+ unsigned offsetShift;
+ if (vBit()) {
+ appendFPRegisterName(rt(), size());
+ appendSeparator();
+ appendFPRegisterName(rt2(), size());
+ offsetShift = size() + 2;
+ } else {
+ appendRegisterName(rt(), is64Bit());
+ appendSeparator();
+ appendRegisterName(rt2(), is64Bit());
+ offsetShift = (size() >> 1) + 2;
+ }
+
+ appendSeparator();
+ appendCharacter('[');
+ appendSPOrRegisterName(rn());
+
+ int offset = immediate7() << offsetShift;
+
+ if (offsetMode() == 1) {
+ appendCharacter(']');
+ appendSeparator();
+ appendSignedImmediate(offset);
+ } else {
+ appendSeparator();
+ appendSignedImmediate(offset);
+ appendCharacter(']');
+ if (offsetMode() == 0x3)
+ appendCharacter('!');
+ }
+
+ return m_formatBuffer;
+}
+
const char* A64DOpcodeLoadStoreUnsignedImmediate::format()
{
const char* thisOpName = opName();