[llvm-commits] [llvm] r101974 - in /llvm/trunk: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.h lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h test/MC/Disassembler/thumb-tests.txt
Johnny Chen
johnny.chen at apple.com
Tue Apr 20 18:01:19 PDT 2010
Author: johnny
Date: Tue Apr 20 20:01:19 2010
New Revision: 101974
URL: http://llvm.org/viewvc/llvm-project?rev=101974&view=rev
Log:
Thumb instructions which have reglist operands at the end and predicate operands
before reglist were not properly handled with respect to IT Block. Fix that by
creating a new method ARMBasicMCBuilder::DoPredicateOperands() used by those
instructions for disassembly. Add a test case.
Modified:
llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
llvm/trunk/test/MC/Disassembler/thumb-tests.txt
Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=101974&r1=101973&r2=101974&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Tue Apr 20 20:01:19 2010
@@ -3218,6 +3218,40 @@
return CondField;
}
+/// DoPredicateOperands - DoPredicateOperands process the predicate operands
+/// of some Thumb instructions which come before the reglist operands. It
+/// returns true if the two predicate operands have been processed.
+bool ARMBasicMCBuilder::DoPredicateOperands(MCInst& MI, unsigned Opcode,
+ uint32_t /* insn */, unsigned short NumOpsRemaining) {
+
+ assert(NumOpsRemaining > 0 && "Invalid argument");
+
+ const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
+ unsigned Idx = MI.getNumOperands();
+
+ // First, we check whether this instr specifies the PredicateOperand through
+ // a pair of TargetOperandInfos with isPredicate() property.
+ if (NumOpsRemaining >= 2 &&
+ OpInfo[Idx].isPredicate() && OpInfo[Idx+1].isPredicate() &&
+ OpInfo[Idx].RegClass == 0 && OpInfo[Idx+1].RegClass == ARM::CCRRegClassID)
+ {
+ // If we are inside an IT block, get the IT condition bits maintained via
+ // ARMBasicMCBuilder::ITState[7:0], through ARMBasicMCBuilder::GetITCond().
+ // See also A2.5.2.
+ if (InITBlock())
+ MI.addOperand(MCOperand::CreateImm(GetITCond()));
+ else
+ MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
+ MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
+ return true;
+ }
+
+ return false;
+}
+
+/// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
+/// the possible Predicate and SBitModifier, to build the remaining MCOperand
+/// constituents.
bool ARMBasicMCBuilder::TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
uint32_t insn, unsigned short NumOpsRemaining) {
@@ -3258,10 +3292,11 @@
MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
Idx += 2;
NumOpsRemaining -= 2;
- if (NumOpsRemaining == 0)
- return true;
}
+ if (NumOpsRemaining == 0)
+ return true;
+
// Next, if OptionalDefOperand exists, we check whether the 'S' bit is set.
if (OpInfo[Idx].isOptionalDef() && OpInfo[Idx].RegClass==ARM::CCRRegClassID) {
MI.addOperand(MCOperand::CreateReg(getSBit(insn) == 1 ? ARM::CPSR : 0));
Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h?rev=101974&r1=101973&r2=101974&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h Tue Apr 20 20:01:19 2010
@@ -210,6 +210,12 @@
Err = ErrCode;
}
+ /// DoPredicateOperands - DoPredicateOperands process the predicate operands
+ /// of some Thumb instructions which come before the reglist operands. It
+ /// returns true if the two predicate operands have been processed.
+ bool DoPredicateOperands(MCInst& MI, unsigned Opcode,
+ uint32_t insn, unsigned short NumOpsRemaning);
+
/// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
/// the possible Predicate and SBitModifier, to build the remaining MCOperand
/// constituents.
Modified: llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h?rev=101974&r1=101973&r2=101974&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h Tue Apr 20 20:01:19 2010
@@ -713,13 +713,17 @@
unsigned &OpIdx = NumOpsAdded;
// Handling the two predicate operands before the reglist.
- MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
- MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
- OpIdx = 2;
+ if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
+ OpIdx += 2;
+ else {
+ DEBUG(errs() << "Expected predicate operands not found.\n");
+ return false;
+ }
- // Fill the variadic part of reglist.
unsigned RegListBits = slice(insn, 8, 8) << (Opcode == ARM::tPUSH ? 14 : 15)
| slice(insn, 7, 0);
+
+ // Fill the variadic part of reglist.
for (unsigned i = 0; i < 16; ++i) {
if ((RegListBits >> i) & 1) {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
@@ -840,7 +844,6 @@
unsigned &OpIdx = NumOpsAdded;
unsigned tRt = getT1tRt(insn);
- unsigned RegListBits = slice(insn, 7, 0);
OpIdx = 0;
@@ -856,13 +859,19 @@
++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;
// Handling the two predicate operands before the reglist.
- MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
- MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
- OpIdx += 2;
+ if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
+ OpIdx += 2;
+ else {
+ DEBUG(errs() << "Expected predicate operands not found.\n");
+ return false;
+ }
+
+ unsigned RegListBits = slice(insn, 7, 0);
// Fill the variadic part of reglist.
for (unsigned i = 0; i < 8; ++i) {
@@ -1137,12 +1146,16 @@
++OpIdx;
// Handling the two predicate operands before the reglist.
- MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
- MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
- OpIdx += 2;
+ if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
+ OpIdx += 2;
+ else {
+ DEBUG(errs() << "Expected predicate operands not found.\n");
+ return false;
+ }
- // Fill the variadic part of reglist.
unsigned RegListBits = insn & ((1 << 16) - 1);
+
+ // Fill the variadic part of reglist.
for (unsigned i = 0; i < 16; ++i) {
if ((RegListBits >> i) & 1) {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
Modified: llvm/trunk/test/MC/Disassembler/thumb-tests.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/thumb-tests.txt?rev=101974&r1=101973&r2=101974&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/thumb-tests.txt (original)
+++ llvm/trunk/test/MC/Disassembler/thumb-tests.txt Tue Apr 20 20:01:19 2010
@@ -85,6 +85,9 @@
# CHECK: lsleq r1, r0, #28
0x01 0x07
-# CHECK: rsbne r1, r2, #0
-0x51 0x42
+# CHECK: stmiane r0!, {r1, r2, r3}
+0x0e 0xc0
+
# IT block end
+# CHECK: rsbs r1, r2, #0
+0x51 0x42
More information about the llvm-commits
mailing list