summaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/Disassembler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/Disassembler')
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp49
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp259
-rw-r--r--lib/Target/ARM/Disassembler/CMakeLists.txt14
-rw-r--r--lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h298
4 files changed, 260 insertions, 360 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index e220289..78d73d3 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -39,9 +39,9 @@
/// o static uint16_t decodeThumbInstruction(field_t insn) - the decoding
/// function for a Thumb instruction.
///
-#include "../ARMGenDecoderTables.inc"
+#include "ARMGenDecoderTables.inc"
-#include "../ARMGenEDInfo.inc"
+#include "ARMGenEDInfo.inc"
using namespace llvm;
@@ -89,7 +89,8 @@ static unsigned decodeARMInstruction(uint32_t &insn) {
return ARM::BFI;
}
- // Ditto for STRBT, which is a super-instruction for A8.6.199 Encoding A1 & A2.
+ // Ditto for STRBT, which is a super-instruction for A8.6.199 Encodings
+ // A1 & A2.
// As a result, the decoder fails to deocode USAT properly.
if (slice(insn, 27, 21) == 0x37 && slice(insn, 5, 4) == 1)
return ARM::USAT;
@@ -252,9 +253,6 @@ static unsigned T2Morph2LoadLiteral(unsigned Opcode) {
default:
return Opcode; // Return unmorphed opcode.
- case ARM::t2LDRDi8:
- return ARM::t2LDRDpci;
-
case ARM::t2LDR_POST: case ARM::t2LDR_PRE:
case ARM::t2LDRi12: case ARM::t2LDRi8:
case ARM::t2LDRs: case ARM::t2LDRT:
@@ -349,36 +347,6 @@ static unsigned decodeThumbSideEffect(bool IsThumb2, unsigned &insn) {
return decodeThumbInstruction(insn);
}
-static inline bool Thumb2PreloadOpcodeNoPCI(unsigned Opcode) {
- switch (Opcode) {
- default:
- return false;
- case ARM::t2PLDi12: case ARM::t2PLDi8:
- case ARM::t2PLDr: case ARM::t2PLDs:
- case ARM::t2PLDWi12: case ARM::t2PLDWi8:
- case ARM::t2PLDWr: case ARM::t2PLDWs:
- case ARM::t2PLIi12: case ARM::t2PLIi8:
- case ARM::t2PLIr: case ARM::t2PLIs:
- return true;
- }
-}
-
-static inline unsigned T2Morph2Preload2PCI(unsigned Opcode) {
- switch (Opcode) {
- default:
- return 0;
- case ARM::t2PLDi12: case ARM::t2PLDi8:
- case ARM::t2PLDr: case ARM::t2PLDs:
- return ARM::t2PLDpci;
- case ARM::t2PLDWi12: case ARM::t2PLDWi8:
- case ARM::t2PLDWr: case ARM::t2PLDWs:
- return ARM::t2PLDWpci;
- case ARM::t2PLIi12: case ARM::t2PLIi8:
- case ARM::t2PLIr: case ARM::t2PLIs:
- return ARM::t2PLIpci;
- }
-}
-
//
// Public interface for the disassembler
//
@@ -485,11 +453,6 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
// instructions as well.
unsigned Opcode = decodeThumbSideEffect(IsThumb2, insn);
- // A8.6.117/119/120/121.
- // PLD/PLDW/PLI instructions with Rn==15 is transformed to the pci variant.
- if (Thumb2PreloadOpcodeNoPCI(Opcode) && slice(insn, 19, 16) == 15)
- Opcode = T2Morph2Preload2PCI(Opcode);
-
ARMFormat Format = ARMFormats[Opcode];
Size = IsThumb2 ? 4 : 2;
@@ -568,9 +531,9 @@ static MCDisassembler *createThumbDisassembler(const Target &T) {
return new ThumbDisassembler;
}
-extern "C" void LLVMInitializeARMDisassembler() {
+extern "C" void LLVMInitializeARMDisassembler() {
// Register the disassembler.
- TargetRegistry::RegisterMCDisassembler(TheARMTarget,
+ TargetRegistry::RegisterMCDisassembler(TheARMTarget,
createARMDisassembler);
TargetRegistry::RegisterMCDisassembler(TheThumbTarget,
createThumbDisassembler);
diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
index 9f493b9..bac68dd 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -79,22 +79,9 @@ const char *ARMUtils::OpcodeName(unsigned Opcode) {
}
// Return the register enum Based on RegClass and the raw register number.
-// For DRegPair, see comments below.
// FIXME: Auto-gened?
-static unsigned getRegisterEnum(BO B, unsigned RegClassID, unsigned RawRegister,
- bool DRegPair = false) {
-
- if (DRegPair && RegClassID == ARM::QPRRegClassID) {
- // LLVM expects { Dd, Dd+1 } to form a super register; this is not specified
- // in the ARM Architecture Manual as far as I understand it (A8.6.307).
- // Therefore, we morph the RegClassID to be the sub register class and don't
- // subsequently transform the RawRegister encoding when calculating RegNum.
- //
- // See also ARMinstPrinter::printOperand() wrt "dregpair" modifier part
- // where this workaround is meant for.
- RegClassID = ARM::DPRRegClassID;
- }
-
+static unsigned
+getRegisterEnum(BO B, unsigned RegClassID, unsigned RawRegister) {
// For this purpose, we can treat rGPR as if it were GPR.
if (RegClassID == ARM::rGPRRegClassID) RegClassID = ARM::GPRRegClassID;
@@ -704,8 +691,8 @@ static bool DisassembleCoprocessor(MCInst &MI, unsigned Opcode, uint32_t insn,
// MSR/MSRsys: Rm mask=Inst{19-16}
// BXJ: Rm
// MSRi/MSRsysi: so_imm
-// SRSW/SRS: addrmode4:$addr mode_imm
-// RFEW/RFE: addrmode4:$addr Rn
+// SRSW/SRS: ldstm_mode:$amode mode_imm
+// RFEW/RFE: ldstm_mode:$amode Rn
static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
@@ -733,35 +720,34 @@ static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
NumOpsAdded = 1;
return true;
}
- // MSR and MSRsys take one GPR reg Rm, followed by the mask.
- if (Opcode == ARM::MSR || Opcode == ARM::MSRsys) {
- assert(NumOps >= 1 && OpInfo[0].RegClass == ARM::GPRRegClassID &&
+ // MSR take a mask, followed by one GPR reg Rm. The mask contains the R Bit in
+ // bit 4, and the special register fields in bits 3-0.
+ if (Opcode == ARM::MSR) {
+ assert(NumOps >= 1 && OpInfo[1].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 22, 22) << 4 /* R Bit */ |
+ slice(insn, 19, 16) /* Special Reg */ ));
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
- MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
NumOpsAdded = 2;
return true;
}
- // MSRi and MSRsysi take one so_imm operand, followed by the mask.
- if (Opcode == ARM::MSRi || Opcode == ARM::MSRsysi) {
+ // MSRi take a mask, followed by one so_imm operand. The mask contains the
+ // R Bit in bit 4, and the special register fields in bits 3-0.
+ if (Opcode == ARM::MSRi) {
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 22, 22) << 4 /* R Bit */ |
+ slice(insn, 19, 16) /* Special Reg */ ));
// SOImm is 4-bit rotate amount in bits 11-8 with 8-bit imm in bits 7-0.
// A5.2.4 Rotate amount is twice the numeric value of Inst{11-8}.
// See also ARMAddressingModes.h: getSOImmValImm() and getSOImmValRot().
unsigned Rot = (insn >> ARMII::SoRotImmShift) & 0xF;
unsigned Imm = insn & 0xFF;
MI.addOperand(MCOperand::CreateImm(ARM_AM::rotr32(Imm, 2*Rot)));
- MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
NumOpsAdded = 2;
return true;
}
- // SRSW and SRS requires addrmode4:$addr for ${addr:submode}, followed by the
- // mode immediate (Inst{4-0}).
if (Opcode == ARM::SRSW || Opcode == ARM::SRS ||
Opcode == ARM::RFEW || Opcode == ARM::RFE) {
- // ARMInstPrinter::printAddrMode4Operand() prints special mode string
- // if the base register is SP; so don't set ARM::SP.
- MI.addOperand(MCOperand::CreateReg(0));
ARM_AM::AMSubMode SubMode = getAMSubModeForBits(getPUBits(insn));
MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(SubMode)));
@@ -807,9 +793,8 @@ static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
}
// Misc. Branch Instructions.
-// BR_JTadd, BR_JTr, BR_JTm
// BLXr9, BXr9
-// BRIND, BX_RET
+// BX, BX_RET
static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
@@ -820,12 +805,12 @@ static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
OpIdx = 0;
- // BX_RET has only two predicate operands, do an early return.
- if (Opcode == ARM::BX_RET)
+ // BX_RET and MOVPCLR have only two predicate operands; do an early return.
+ if (Opcode == ARM::BX_RET || Opcode == ARM::MOVPCLR)
return true;
- // BLXr9 and BRIND take one GPR reg.
- if (Opcode == ARM::BLXr9 || Opcode == ARM::BRIND) {
+ // BLXr9 and BX take one GPR reg.
+ if (Opcode == ARM::BLXr9 || Opcode == ARM::BX) {
assert(NumOps >= 1 && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
@@ -834,72 +819,6 @@ static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
return true;
}
- // BR_JTadd is an ADD with Rd = PC, (Rn, Rm) as the target and index regs.
- if (Opcode == ARM::BR_JTadd) {
- // InOperandList with GPR:$target and GPR:$idx regs.
-
- assert(NumOps == 4 && "Expect 4 operands");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
- decodeRn(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
- decodeRm(insn))));
-
- // Fill in the two remaining imm operands to signify build completion.
- MI.addOperand(MCOperand::CreateImm(0));
- MI.addOperand(MCOperand::CreateImm(0));
-
- OpIdx = 4;
- return true;
- }
-
- // BR_JTr is a MOV with Rd = PC, and Rm as the source register.
- if (Opcode == ARM::BR_JTr) {
- // InOperandList with GPR::$target reg.
-
- assert(NumOps == 3 && "Expect 3 operands");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
- decodeRm(insn))));
-
- // Fill in the two remaining imm operands to signify build completion.
- MI.addOperand(MCOperand::CreateImm(0));
- MI.addOperand(MCOperand::CreateImm(0));
-
- OpIdx = 3;
- return true;
- }
-
- // BR_JTm is an LDR with Rt = PC.
- if (Opcode == ARM::BR_JTm) {
- // This is the reg/reg form, with base reg followed by +/- reg shop imm.
- // See also ARMAddressingModes.h (Addressing Mode #2).
-
- assert(NumOps == 5 && getIBit(insn) == 1 && "Expect 5 operands && I-bit=1");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
- decodeRn(insn))));
-
- ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
-
- // Disassemble the offset reg (Rm), shift type, and immediate shift length.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
- decodeRm(insn))));
- // Inst{6-5} encodes the shift opcode.
- ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
- // Inst{11-7} encodes the imm5 shift amount.
- unsigned ShImm = slice(insn, 11, 7);
-
- // A8.4.1. Possible rrx or shift amount of 32...
- getImmShiftSE(ShOp, ShImm);
- MI.addOperand(MCOperand::CreateImm(
- ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
-
- // Fill in the two remaining imm operands to signify build completion.
- MI.addOperand(MCOperand::CreateImm(0));
- MI.addOperand(MCOperand::CreateImm(0));
-
- OpIdx = 5;
- return true;
- }
-
return false;
}
@@ -1324,30 +1243,28 @@ static bool DisassembleLdStMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 5 && "LdStMulFrm expects NumOps >= 5");
-
- unsigned &OpIdx = NumOpsAdded;
-
- OpIdx = 0;
+ NumOpsAdded = 0;
unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
// Writeback to base, if necessary.
- if (Opcode == ARM::LDM_UPD || Opcode == ARM::STM_UPD) {
+ if (Opcode == ARM::LDMIA_UPD || Opcode == ARM::STMIA_UPD ||
+ Opcode == ARM::LDMDA_UPD || Opcode == ARM::STMDA_UPD ||
+ Opcode == ARM::LDMDB_UPD || Opcode == ARM::STMDB_UPD ||
+ Opcode == ARM::LDMIB_UPD || Opcode == ARM::STMIB_UPD) {
MI.addOperand(MCOperand::CreateReg(Base));
- ++OpIdx;
+ ++NumOpsAdded;
}
+ // Add the base register operand.
MI.addOperand(MCOperand::CreateReg(Base));
- ARM_AM::AMSubMode SubMode = getAMSubModeForBits(getPUBits(insn));
- MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(SubMode)));
-
// Handling the two predicate operands before the reglist.
int64_t CondVal = insn >> ARMII::CondShift;
MI.addOperand(MCOperand::CreateImm(CondVal == 0xF ? 0xE : CondVal));
MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
- OpIdx += 4;
+ NumOpsAdded += 3;
// Fill the variadic part of reglist.
unsigned RegListBits = insn & ((1 << 16) - 1);
@@ -1355,7 +1272,7 @@ static bool DisassembleLdStMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
if ((RegListBits >> i) & 1) {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
i)));
- ++OpIdx;
+ ++NumOpsAdded;
}
}
@@ -1586,8 +1503,7 @@ static unsigned decodeVFPRm(uint32_t insn, bool isSPVFP) {
}
// A7.5.1
-#if 0
-static uint64_t VFPExpandImm(unsigned char byte, unsigned N) {
+static APInt VFPExpandImm(unsigned char byte, unsigned N) {
assert(N == 32 || N == 64);
uint64_t Result;
@@ -1602,13 +1518,12 @@ static uint64_t VFPExpandImm(unsigned char byte, unsigned N) {
Result = (uint64_t)slice(byte, 7, 7) << 63 |
(uint64_t)slice(byte, 5, 0) << 48;
if (bit6)
- Result |= 0xffL << 54;
+ Result |= 0xffULL << 54;
else
- Result |= 0x1L << 62;
+ Result |= 0x1ULL << 62;
}
- return Result;
+ return APInt(N, Result);
}
-#endif
// VFP Unary Format Instructions:
//
@@ -1902,8 +1817,10 @@ static bool DisassembleVFPLdStMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
// Writeback to base, if necessary.
- if (Opcode == ARM::VLDMD_UPD || Opcode == ARM::VLDMS_UPD ||
- Opcode == ARM::VSTMD_UPD || Opcode == ARM::VSTMS_UPD) {
+ if (Opcode == ARM::VLDMDIA_UPD || Opcode == ARM::VLDMSIA_UPD ||
+ Opcode == ARM::VLDMDDB_UPD || Opcode == ARM::VLDMSDB_UPD ||
+ Opcode == ARM::VSTMDIA_UPD || Opcode == ARM::VSTMSIA_UPD ||
+ Opcode == ARM::VSTMDDB_UPD || Opcode == ARM::VSTMSDB_UPD) {
MI.addOperand(MCOperand::CreateReg(Base));
++OpIdx;
}
@@ -1926,8 +1843,10 @@ static bool DisassembleVFPLdStMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
OpIdx += 4;
- bool isSPVFP = (Opcode == ARM::VLDMS || Opcode == ARM::VLDMS_UPD ||
- Opcode == ARM::VSTMS || Opcode == ARM::VSTMS_UPD);
+ bool isSPVFP = (Opcode == ARM::VLDMSIA || Opcode == ARM::VLDMSDB ||
+ Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMSDB_UPD ||
+ Opcode == ARM::VSTMSIA || Opcode == ARM::VSTMSDB ||
+ Opcode == ARM::VSTMSIA_UPD || Opcode == ARM::VSTMSDB_UPD);
unsigned RegClassID = isSPVFP ? ARM::SPRRegClassID : ARM::DPRRegClassID;
// Extract Dd/Sd.
@@ -1985,10 +1904,14 @@ static bool DisassembleVFPMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
// Extract/decode the f64/f32 immediate.
if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
&& !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
- // The asm syntax specifies the before-expanded <imm>.
- // Not VFPExpandImm(slice(insn,19,16) << 4 | slice(insn, 3, 0),
- // Opcode == ARM::FCONSTD ? 64 : 32)
- MI.addOperand(MCOperand::CreateImm(slice(insn,19,16)<<4 | slice(insn,3,0)));
+ // The asm syntax specifies the floating point value, not the 8-bit literal.
+ APInt immRaw = VFPExpandImm(slice(insn,19,16) << 4 | slice(insn, 3, 0),
+ Opcode == ARM::FCONSTD ? 64 : 32);
+ APFloat immFP = APFloat(immRaw, true);
+ double imm = Opcode == ARM::FCONSTD ? immFP.convertToDouble() :
+ immFP.convertToFloat();
+ MI.addOperand(MCOperand::CreateFPImm(imm));
+
++OpIdx;
}
@@ -2201,22 +2124,6 @@ static unsigned decodeN3VImm(uint32_t insn) {
return (insn >> 8) & 0xF;
}
-static bool UseDRegPair(unsigned Opcode) {
- switch (Opcode) {
- default:
- return false;
- case ARM::VLD1q8_UPD:
- case ARM::VLD1q16_UPD:
- case ARM::VLD1q32_UPD:
- case ARM::VLD1q64_UPD:
- case ARM::VST1q8_UPD:
- case ARM::VST1q16_UPD:
- case ARM::VST1q32_UPD:
- case ARM::VST1q64_UPD:
- return true;
- }
-}
-
// VLD*
// D[d] D[d2] ... Rn [TIED_TO Rn] align [Rm]
// VLD*LN*
@@ -2243,10 +2150,9 @@ static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn,
// We have homogeneous NEON registers for Load/Store.
unsigned RegClass = 0;
- bool DRegPair = UseDRegPair(Opcode);
// Double-spaced registers have increments of 2.
- unsigned Inc = (DblSpaced || DRegPair) ? 2 : 1;
+ unsigned Inc = DblSpaced ? 2 : 1;
unsigned Rn = decodeRn(insn);
unsigned Rm = decodeRm(insn);
@@ -2292,7 +2198,7 @@ static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn,
RegClass = OpInfo[OpIdx].RegClass;
while (OpIdx < NumOps && (unsigned)OpInfo[OpIdx].RegClass == RegClass) {
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(B, RegClass, Rd, DRegPair)));
+ getRegisterEnum(B, RegClass, Rd)));
Rd += Inc;
++OpIdx;
}
@@ -2311,7 +2217,7 @@ static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn,
while (OpIdx < NumOps && (unsigned)OpInfo[OpIdx].RegClass == RegClass) {
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(B, RegClass, Rd, DRegPair)));
+ getRegisterEnum(B, RegClass, Rd)));
Rd += Inc;
++OpIdx;
}
@@ -2771,8 +2677,8 @@ static bool DisassembleN3RegVecShFrm(MCInst &MI, unsigned Opcode,
return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
N3V_VectorShift, B);
}
-static bool DisassembleNVecExtractFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+static bool DisassembleNVecExtractFrm(MCInst &MI, unsigned Opcode,
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
N3V_VectorExtract, B);
@@ -2959,9 +2865,9 @@ static inline bool MemBarrierInstr(uint32_t insn) {
static inline bool PreLoadOpcode(unsigned Opcode) {
switch(Opcode) {
- case ARM::PLDi: case ARM::PLDr:
- case ARM::PLDWi: case ARM::PLDWr:
- case ARM::PLIi: case ARM::PLIr:
+ case ARM::PLDi12: case ARM::PLDrs:
+ case ARM::PLDWi12: case ARM::PLDWrs:
+ case ARM::PLIi12: case ARM::PLIrs:
return true;
default:
return false;
@@ -2971,18 +2877,21 @@ static inline bool PreLoadOpcode(unsigned Opcode) {
static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
- // Preload Data/Instruction requires either 2 or 4 operands.
- // PLDi, PLDWi, PLIi: Rn [+/-]imm12 add = (U == '1')
- // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: Rn Rm addrmode2_opc
+ // Preload Data/Instruction requires either 2 or 3 operands.
+ // PLDi, PLDWi, PLIi: addrmode_imm12
+ // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: ldst_so_reg
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
- if (Opcode == ARM::PLDi || Opcode == ARM::PLDWi || Opcode == ARM::PLIi) {
+ if (Opcode == ARM::PLDi12 || Opcode == ARM::PLDWi12
+ || Opcode == ARM::PLIi12) {
unsigned Imm12 = slice(insn, 11, 0);
bool Negative = getUBit(insn) == 0;
- int Offset = Negative ? -1 - Imm12 : 1 * Imm12;
- MI.addOperand(MCOperand::CreateImm(Offset));
+ // -0 is represented specially. All other values are as normal.
+ if (Imm12 == 0 && Negative)
+ Imm12 = INT32_MIN;
+ MI.addOperand(MCOperand::CreateImm(Imm12));
NumOpsAdded = 2;
} else {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
@@ -3026,22 +2935,36 @@ static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
case ARM::WFE:
case ARM::WFI:
case ARM::SEV:
- case ARM::SETENDBE:
- case ARM::SETENDLE:
return true;
default:
break;
}
- // CPS has a singleton $opt operand that contains the following information:
- // opt{4-0} = mode from Inst{4-0}
- // opt{5} = changemode from Inst{17}
- // opt{8-6} = AIF from Inst{8-6}
- // opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
- if (Opcode == ARM::CPS) {
- unsigned Option = slice(insn, 4, 0) | slice(insn, 17, 17) << 5 |
- slice(insn, 8, 6) << 6 | slice(insn, 19, 18) << 9;
- MI.addOperand(MCOperand::CreateImm(Option));
+ if (Opcode == ARM::SETEND) {
+ NumOpsAdded = 1;
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 9, 9)));
+ return true;
+ }
+
+ // FIXME: To enable correct asm parsing and disasm of CPS we need 3 different
+ // opcodes which match the same real instruction. This is needed since there's
+ // no current handling of optional arguments. Fix here when a better handling
+ // of optional arguments is implemented.
+ if (Opcode == ARM::CPS3p) {
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 18))); // imod
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 8, 6))); // iflags
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
+ NumOpsAdded = 3;
+ return true;
+ }
+ if (Opcode == ARM::CPS2p) {
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 18))); // imod
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 8, 6))); // iflags
+ NumOpsAdded = 2;
+ return true;
+ }
+ if (Opcode == ARM::CPS1p) {
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
NumOpsAdded = 1;
return true;
}
diff --git a/lib/Target/ARM/Disassembler/CMakeLists.txt b/lib/Target/ARM/Disassembler/CMakeLists.txt
new file mode 100644
index 0000000..b23dd6b
--- /dev/null
+++ b/lib/Target/ARM/Disassembler/CMakeLists.txt
@@ -0,0 +1,14 @@
+include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+
+add_llvm_library(LLVMARMDisassembler
+ ARMDisassembler.cpp
+ ARMDisassemblerCore.cpp
+ )
+# workaround for hanging compilation on MSVC8, 9 and 10
+if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 )
+set_property(
+ SOURCE ARMDisassembler.cpp
+ PROPERTY COMPILE_FLAGS "/Od"
+ )
+endif()
+add_dependencies(LLVMARMDisassembler ARMCodeGenTable_gen)
diff --git a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
index 112817b..23372e0 100644
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -564,6 +564,38 @@ static bool DisassembleThumb1LdPC(MCInst &MI, unsigned Opcode, uint32_t insn,
// t_addrmode_sp := sp + imm8 * 4
//
+// A8.6.63 LDRB (literal)
+// A8.6.79 LDRSB (literal)
+// A8.6.75 LDRH (literal)
+// A8.6.83 LDRSH (literal)
+// A8.6.59 LDR (literal)
+//
+// These instrs calculate an address from the PC value and an immediate offset.
+// Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
+static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+
+ const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
+ if (!OpInfo) return false;
+
+ assert(NumOps >= 2 &&
+ OpInfo[0].RegClass == ARM::GPRRegClassID &&
+ OpInfo[1].RegClass < 0 &&
+ "Expect >= 2 operands, first as reg, and second as imm operand");
+
+ // Build the register operand, followed by the (+/-)imm12 immediate.
+
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+ decodeRd(insn))));
+
+ MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
+
+ NumOpsAdded = 2;
+
+ return true;
+}
+
+
// A6.2.4 Load/store single data item
//
// Load/Store Register (reg|imm): tRd tRn imm5 tRm
@@ -796,14 +828,13 @@ static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
}
// CPS has a singleton $opt operand that contains the following information:
- // opt{4-0} = don't care
- // opt{5} = 0 (false)
- // opt{8-6} = AIF from Inst{2-0}
- // opt{10-9} = 1:imod from Inst{4} with 0b10 as enable and 0b11 as disable
+ // The first op would be 0b10 as enable and 0b11 as disable in regular ARM,
+ // but in Thumb it's is 0 as enable and 1 as disable. So map it to ARM's
+ // default one. The second get the AIF flags from Inst{2-0}.
if (Opcode == ARM::tCPS) {
- unsigned Option = slice(insn, 2, 0) << 6 | slice(insn, 4, 4) << 9 | 1 << 10;
- MI.addOperand(MCOperand::CreateImm(Option));
- NumOpsAdded = 1;
+ MI.addOperand(MCOperand::CreateImm(2 + slice(insn, 4, 4)));
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 2, 0)));
+ NumOpsAdded = 2;
return true;
}
@@ -833,40 +864,32 @@ static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
// A8.6.53 LDM / LDMIA
// A8.6.189 STM / STMIA
//
-// tLDM_UPD/tSTM_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
-// tLDM: tRt AM4ModeImm Pred-Imm Pred-CCR register_list
+// tLDMIA_UPD/tSTMIA_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
+// tLDMIA: tRt AM4ModeImm Pred-Imm Pred-CCR register_list
static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
-
- assert((Opcode == ARM::tLDM || Opcode == ARM::tLDM_UPD ||
- Opcode == ARM::tSTM_UPD) && "Unexpected opcode");
-
- unsigned &OpIdx = NumOpsAdded;
+ uint32_t insn, unsigned short NumOps,
+ unsigned &NumOpsAdded, BO B) {
+ assert((Opcode == ARM::tLDMIA || Opcode == ARM::tLDMIA_UPD ||
+ Opcode == ARM::tSTMIA_UPD) && "Unexpected opcode");
unsigned tRt = getT1tRt(insn);
-
- OpIdx = 0;
+ NumOpsAdded = 0;
// WB register, if necessary.
- if (Opcode == ARM::tLDM_UPD || Opcode == ARM::tSTM_UPD) {
+ if (Opcode == ARM::tLDMIA_UPD || Opcode == ARM::tSTMIA_UPD) {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
tRt)));
- ++OpIdx;
+ ++NumOpsAdded;
}
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
tRt)));
- ++OpIdx;
-
- // A8.6.53 LDM / LDMIA / LDMFD - Encoding T1
- // A8.6.53 STM / STMIA / STMEA - Encoding T1
- MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)));
- ++OpIdx;
+ ++NumOpsAdded;
// Handling the two predicate operands before the reglist.
- if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
- OpIdx += 2;
- else {
+ if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
+ NumOpsAdded += 2;
+ } else {
DEBUG(errs() << "Expected predicate operands not found.\n");
return false;
}
@@ -874,13 +897,12 @@ static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
unsigned RegListBits = slice(insn, 7, 0);
// Fill the variadic part of reglist.
- for (unsigned i = 0; i < 8; ++i) {
+ for (unsigned i = 0; i < 8; ++i)
if ((RegListBits >> i) & 1) {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
i)));
- ++OpIdx;
+ ++NumOpsAdded;
}
- }
return true;
}
@@ -959,22 +981,23 @@ static bool DisassembleThumb1Br(MCInst &MI, unsigned Opcode, uint32_t insn,
// corresponding to op.
//
// Table A6-1 16-bit Thumb instruction encoding (abridged)
-// op Instruction or instruction class
-// ------ --------------------------------------------------------------------
-// 00xxxx Shift (immediate), add, subtract, move, and compare on page A6-7
-// 010000 Data-processing on page A6-8
-// 010001 Special data instructions and branch and exchange on page A6-9
-// 01001x Load from Literal Pool, see LDR (literal) on page A8-122
-// 0101xx Load/store single data item on page A6-10
+// op Instruction or instruction class
+// ------ --------------------------------------------------------------------
+// 00xxxx Shift (immediate), add, subtract, move, and compare on page A6-7
+// 010000 Data-processing on page A6-8
+// 010001 Special data instructions and branch and exchange on page A6-9
+// 01001x Load from Literal Pool, see LDR (literal) on page A8-122
+// 0101xx Load/store single data item on page A6-10
// 011xxx
// 100xxx
-// 10100x Generate PC-relative address, see ADR on page A8-32
-// 10101x Generate SP-relative address, see ADD (SP plus immediate) on page A8-28
-// 1011xx Miscellaneous 16-bit instructions on page A6-11
-// 11000x Store multiple registers, see STM / STMIA / STMEA on page A8-374
-// 11001x Load multiple registers, see LDM / LDMIA / LDMFD on page A8-110 a
-// 1101xx Conditional branch, and Supervisor Call on page A6-13
-// 11100x Unconditional Branch, see B on page A8-44
+// 10100x Generate PC-relative address, see ADR on page A8-32
+// 10101x Generate SP-relative address, see ADD (SP plus immediate) on
+// page A8-28
+// 1011xx Miscellaneous 16-bit instructions on page A6-11
+// 11000x Store multiple registers, see STM / STMIA / STMEA on page A8-374
+// 11001x Load multiple registers, see LDM / LDMIA / LDMFD on page A8-110 a
+// 1101xx Conditional branch, and Supervisor Call on page A6-13
+// 11100x Unconditional Branch, see B on page A8-44
//
static bool DisassembleThumb1(uint16_t op, MCInst &MI, unsigned Opcode,
uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
@@ -1121,34 +1144,31 @@ static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
if (Thumb2RFEOpcode(Opcode))
return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded, B);
- assert((Opcode == ARM::t2LDM || Opcode == ARM::t2LDM_UPD ||
- Opcode == ARM::t2STM || Opcode == ARM::t2STM_UPD)
+ assert((Opcode == ARM::t2LDMIA || Opcode == ARM::t2LDMIA_UPD ||
+ Opcode == ARM::t2LDMDB || Opcode == ARM::t2LDMDB_UPD ||
+ Opcode == ARM::t2STMIA || Opcode == ARM::t2STMIA_UPD ||
+ Opcode == ARM::t2STMDB || Opcode == ARM::t2STMDB_UPD)
&& "Unexpected opcode");
assert(NumOps >= 5 && "Thumb2 LdStMul expects NumOps >= 5");
- unsigned &OpIdx = NumOpsAdded;
-
- OpIdx = 0;
+ NumOpsAdded = 0;
unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
// Writeback to base.
- if (Opcode == ARM::t2LDM_UPD || Opcode == ARM::t2STM_UPD) {
+ if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD ||
+ Opcode == ARM::t2STMIA_UPD || Opcode == ARM::t2STMDB_UPD) {
MI.addOperand(MCOperand::CreateReg(Base));
- ++OpIdx;
+ ++NumOpsAdded;
}
MI.addOperand(MCOperand::CreateReg(Base));
- ++OpIdx;
-
- ARM_AM::AMSubMode SubMode = getAMSubModeForBits(getPUBits(insn));
- MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(SubMode)));
- ++OpIdx;
+ ++NumOpsAdded;
// Handling the two predicate operands before the reglist.
- if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
- OpIdx += 2;
- else {
+ if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
+ NumOpsAdded += 2;
+ } else {
DEBUG(errs() << "Expected predicate operands not found.\n");
return false;
}
@@ -1156,13 +1176,12 @@ static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned RegListBits = insn & ((1 << 16) - 1);
// Fill the variadic part of reglist.
- for (unsigned i = 0; i < 16; ++i) {
+ for (unsigned i = 0; i < 16; ++i)
if ((RegListBits >> i) & 1) {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
i)));
- ++OpIdx;
+ ++NumOpsAdded;
}
- }
return true;
}
@@ -1260,13 +1279,7 @@ static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
return true;
}
-// PC-based defined for Codegen, which do not get decoded by design:
-//
-// t2TBB, t2TBH: Rm immDontCare immDontCare
-//
-// Generic version defined for disassembly:
-//
-// t2TBBgen, t2TBHgen: Rn Rm Pred-Imm Pred-CCR
+// t2TBB, t2TBH: Rn Rm Pred-Imm Pred-CCR
static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
@@ -1401,7 +1414,8 @@ static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
//
// Two register operands: Rs Rn ModImm
// One register operands (Rs=0b1111 no explicit dest reg): Rn ModImm
-// One register operands (Rn=0b1111 no explicit src reg): Rs ModImm - {t2MOVi, t2MVNi}
+// One register operands (Rn=0b1111 no explicit src reg): Rs ModImm -
+// {t2MOVi, t2MVNi}
//
// ModImm = ThumbExpandImm(i:imm3:imm8)
static bool DisassembleThumb2DPModImm(MCInst &MI, unsigned Opcode,
@@ -1644,15 +1658,25 @@ static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
break;
}
- // CPS has a singleton $opt operand that contains the following information:
- // opt{4-0} = mode from Inst{4-0}
- // opt{5} = changemode from Inst{8}
- // opt{8-6} = AIF from Inst{7-5}
- // opt{10-9} = imod from Inst{10-9} with 0b10 as enable and 0b11 as disable
- if (Opcode == ARM::t2CPS) {
- unsigned Option = slice(insn, 4, 0) | slice(insn, 8, 8) << 5 |
- slice(insn, 7, 5) << 6 | slice(insn, 10, 9) << 9;
- MI.addOperand(MCOperand::CreateImm(Option));
+ // FIXME: To enable correct asm parsing and disasm of CPS we need 3 different
+ // opcodes which match the same real instruction. This is needed since there's
+ // no current handling of optional arguments. Fix here when a better handling
+ // of optional arguments is implemented.
+ if (Opcode == ARM::t2CPS3p) {
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
+ NumOpsAdded = 3;
+ return true;
+ }
+ if (Opcode == ARM::t2CPS2p) {
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
+ NumOpsAdded = 2;
+ return true;
+ }
+ if (Opcode == ARM::t2CPS1p) {
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
NumOpsAdded = 1;
return true;
}
@@ -1678,11 +1702,13 @@ static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
NumOpsAdded = 1;
return true;
}
- // MSR and MSRsys take one GPR reg Rn, followed by the mask.
- if (Opcode == ARM::t2MSR || Opcode == ARM::t2MSRsys || Opcode == ARM::t2BXJ) {
+ // MSR take a mask, followed by one GPR reg Rn. The mask contains the R Bit in
+ // bit 4, and the special register fields in bits 3-0.
+ if (Opcode == ARM::t2MSR) {
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 20) << 4 /* R Bit */ |
+ slice(insn, 11, 8) /* Special Reg */));
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
- MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 8)));
NumOpsAdded = 2;
return true;
}
@@ -1728,12 +1754,12 @@ static inline bool Thumb2PreloadOpcode(unsigned Opcode) {
switch (Opcode) {
default:
return false;
- case ARM::t2PLDi12: case ARM::t2PLDi8: case ARM::t2PLDpci:
- case ARM::t2PLDr: case ARM::t2PLDs:
- case ARM::t2PLDWi12: case ARM::t2PLDWi8: case ARM::t2PLDWpci:
- case ARM::t2PLDWr: case ARM::t2PLDWs:
- case ARM::t2PLIi12: case ARM::t2PLIi8: case ARM::t2PLIpci:
- case ARM::t2PLIr: case ARM::t2PLIs:
+ case ARM::t2PLDi12: case ARM::t2PLDi8:
+ case ARM::t2PLDs:
+ case ARM::t2PLDWi12: case ARM::t2PLDWi8:
+ case ARM::t2PLDWs:
+ case ARM::t2PLIi12: case ARM::t2PLIi8:
+ case ARM::t2PLIs:
return true;
}
}
@@ -1769,11 +1795,10 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
&& !OpInfo[OpIdx].isOptionalDef()
&& "Pure imm operand expected");
int Offset = 0;
- if (Opcode == ARM::t2PLDpci || Opcode == ARM::t2PLDWpci ||
- Opcode == ARM::t2PLIpci) {
+ if (slice(insn, 19, 16) == 0xFF) {
bool Negative = slice(insn, 23, 23) == 0;
unsigned Imm12 = getImm12(insn);
- Offset = Negative ? -1 - Imm12 : 1 * Imm12;
+ Offset = Negative ? -1 - Imm12 : 1 * Imm12;
} else if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
Opcode == ARM::t2PLIi8) {
// A8.6.117 Encoding T2: add = FALSE
@@ -1795,37 +1820,6 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
return true;
}
-// A8.6.63 LDRB (literal)
-// A8.6.79 LDRSB (literal)
-// A8.6.75 LDRH (literal)
-// A8.6.83 LDRSH (literal)
-// A8.6.59 LDR (literal)
-//
-// These instrs calculate an address from the PC value and an immediate offset.
-// Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
-static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
-
- const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
- if (!OpInfo) return false;
-
- assert(NumOps >= 2 &&
- OpInfo[0].RegClass == ARM::GPRRegClassID &&
- OpInfo[1].RegClass < 0 &&
- "Expect >= 2 operands, first as reg, and second as imm operand");
-
- // Build the register operand, followed by the (+/-)imm12 immediate.
-
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
- decodeRd(insn))));
-
- MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
-
- NumOpsAdded = 2;
-
- return true;
-}
-
// A6.3.10 Store single data item
// A6.3.9 Load byte, memory hints
// A6.3.8 Load halfword, memory hints
@@ -1835,13 +1829,15 @@ static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
//
// t2LDRi12: Rd Rn (+)imm12
// t2LDRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
-// t2LDRs: Rd Rn Rm ConstantShiftSpecifier (see also DisassembleThumb2DPSoReg)
+// t2LDRs: Rd Rn Rm ConstantShiftSpecifier (see also
+// DisassembleThumb2DPSoReg)
// t2LDR_POST: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
// t2LDR_PRE: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
//
// t2STRi12: Rd Rn (+)imm12
// t2STRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
-// t2STRs: Rd Rn Rm ConstantShiftSpecifier (see also DisassembleThumb2DPSoReg)
+// t2STRs: Rd Rn Rm ConstantShiftSpecifier (see also
+// DisassembleThumb2DPSoReg)
// t2STR_POST: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
// t2STR_PRE: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
//
@@ -1862,7 +1858,6 @@ static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
// See, for example, A6.3.7 Load word: Table A6-18 Load word.
if (Load && Rn == 15)
return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
-
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
unsigned &OpIdx = NumOpsAdded;
@@ -1909,7 +1904,7 @@ static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
else
Imm = decodeImm8(insn);
}
-
+
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
R0)));
++OpIdx;
@@ -2081,25 +2076,29 @@ static bool DisassembleThumb2LongMul(MCInst &MI, unsigned Opcode, uint32_t insn,
// corresponding to (op1, op2, op).
//
// Table A6-9 32-bit Thumb instruction encoding
-// op1 op2 op Instruction class, see
-// --- ------- -- ------------------------------------------------------------
-// 01 00xx0xx - Load/store multiple on page A6-23
-// 00xx1xx - Load/store dual, load/store exclusive, table branch on page A6-24
-// 01xxxxx - Data-processing (shifted register) on page A6-31
-// 1xxxxxx - Coprocessor instructions on page A6-40
-// 10 x0xxxxx 0 Data-processing (modified immediate) on page A6-15
-// x1xxxxx 0 Data-processing (plain binary immediate) on page A6-19
-// - 1 Branches and miscellaneous control on page A6-20
-// 11 000xxx0 - Store single data item on page A6-30
-// 001xxx0 - Advanced SIMD element or structure load/store instructions on page A7-27
-// 00xx001 - Load byte, memory hints on page A6-28
-// 00xx011 - Load halfword, memory hints on page A6-26
-// 00xx101 - Load word on page A6-25
-// 00xx111 - UNDEFINED
-// 010xxxx - Data-processing (register) on page A6-33
-// 0110xxx - Multiply, multiply accumulate, and absolute difference on page A6-38
-// 0111xxx - Long multiply, long multiply accumulate, and divide on page A6-39
-// 1xxxxxx - Coprocessor instructions on page A6-40
+// op1 op2 op Instruction class, see
+// --- ------- -- -----------------------------------------------------------
+// 01 00xx0xx - Load/store multiple on page A6-23
+// 00xx1xx - Load/store dual, load/store exclusive, table branch on
+// page A6-24
+// 01xxxxx - Data-processing (shifted register) on page A6-31
+// 1xxxxxx - Coprocessor instructions on page A6-40
+// 10 x0xxxxx 0 Data-processing (modified immediate) on page A6-15
+// x1xxxxx 0 Data-processing (plain binary immediate) on page A6-19
+// - 1 Branches and miscellaneous control on page A6-20
+// 11 000xxx0 - Store single data item on page A6-30
+// 001xxx0 - Advanced SIMD element or structure load/store instructions
+// on page A7-27
+// 00xx001 - Load byte, memory hints on page A6-28
+// 00xx011 - Load halfword, memory hints on page A6-26
+// 00xx101 - Load word on page A6-25
+// 00xx111 - UNDEFINED
+// 010xxxx - Data-processing (register) on page A6-33
+// 0110xxx - Multiply, multiply accumulate, and absolute difference on
+// page A6-38
+// 0111xxx - Long multiply, long multiply accumulate, and divide on
+// page A6-39
+// 1xxxxxx - Coprocessor instructions on page A6-40
//
static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps,
@@ -2130,7 +2129,7 @@ static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
B);
}
- if (Opcode == ARM::t2TBBgen || Opcode == ARM::t2TBHgen) {
+ if (Opcode == ARM::t2TBB || Opcode == ARM::t2TBH) {
// Table branch.
return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
}
@@ -2175,7 +2174,8 @@ static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
}
} else {
// Table A6-9 32-bit Thumb instruction encoding: Load byte|halfword|word
- return DisassembleThumb2LdSt(true, MI,Opcode,insn,NumOps,NumOpsAdded, B);
+ return DisassembleThumb2LdSt(true, MI, Opcode, insn, NumOps,
+ NumOpsAdded, B);
}
break;
case 1:
@@ -2229,7 +2229,7 @@ static bool DisassembleThumbFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
}
// A6.3 32-bit Thumb instruction encoding
-
+
uint16_t op1 = slice(HalfWord, 12, 11);
uint16_t op2 = slice(HalfWord, 10, 4);
uint16_t op = slice(insn, 15, 15);
OpenPOWER on IntegriCloud