summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-08-23 17:45:18 +0000
committerOwen Anderson <resistor@mac.com>2011-08-23 17:45:18 +0000
commit6153a036f544beb03dfc4d58edc28cf42712743d (patch)
treeaa0f6e8d35e9c387e2d27b185a642a75bb38ed4f /lib
parentcefe4c9c483d8a50ff13f36881090ab44ec67f13 (diff)
downloadllvm-6153a036f544beb03dfc4d58edc28cf42712743d.tar.gz
llvm-6153a036f544beb03dfc4d58edc28cf42712743d.tar.bz2
llvm-6153a036f544beb03dfc4d58edc28cf42712743d.tar.xz
Fix Thumb2 decoding of CPS instructions to mirror ARM decoding of the same instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138339 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td1
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td1
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp52
3 files changed, 44 insertions, 10 deletions
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 6056eb9322..eba55944d2 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -134,7 +134,6 @@ def VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8
// ARM imod and iflag operands, used only by the CPS instruction.
def imod_op : Operand<i32> {
let PrintMethod = "printCPSIMod";
- let DecoderMethod = "DecodeCPSIMod";
}
def ProcIFlagsOperand : AsmOperandClass {
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index fe1e907176..ca5f176d72 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -3100,6 +3100,7 @@ class t2CPS<dag iops, string asm_op> : T2XI<(outs), iops, NoItinerary,
let Inst{8} = M;
let Inst{7-5} = iflags;
let Inst{4-0} = mode;
+ let DecoderMethod = "DecodeT2CPSInstruction";
}
let M = 1 in
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index cc2a583ab8..5711b69796 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -103,6 +103,8 @@ static DecodeStatus DecodeSMLAInstruction(llvm::MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCPSInstruction(llvm::MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2CPSInstruction(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrModeImm12Operand(llvm::MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAddrMode5Operand(llvm::MCInst &Inst, unsigned Val,
@@ -179,8 +181,6 @@ static DecodeStatus DecodeVMOVSRR(llvm::MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVMOVRRS(llvm::MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
-static DecodeStatus DecodeCPSIMod(llvm::MCInst &Inst, unsigned Insn,
- uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn,
uint64_t Address, const void *Decoder);
@@ -1393,6 +1393,47 @@ static DecodeStatus DecodeCPSInstruction(llvm::MCInst &Inst, unsigned Insn,
return S;
}
+static DecodeStatus DecodeT2CPSInstruction(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder) {
+ unsigned imod = fieldFromInstruction32(Insn, 9, 2);
+ unsigned M = fieldFromInstruction32(Insn, 8, 1);
+ unsigned iflags = fieldFromInstruction32(Insn, 5, 3);
+ unsigned mode = fieldFromInstruction32(Insn, 0, 5);
+
+ DecodeStatus S = Success;
+
+ // imod == '01' --> UNPREDICTABLE
+ // NOTE: Even though this is technically UNPREDICTABLE, we choose to
+ // return failure here. The '01' imod value is unprintable, so there's
+ // nothing useful we could do even if we returned UNPREDICTABLE.
+
+ if (imod == 1) CHECK(S, Fail);
+
+ if (imod && M) {
+ Inst.setOpcode(ARM::t2CPS3p);
+ Inst.addOperand(MCOperand::CreateImm(imod));
+ Inst.addOperand(MCOperand::CreateImm(iflags));
+ Inst.addOperand(MCOperand::CreateImm(mode));
+ } else if (imod && !M) {
+ Inst.setOpcode(ARM::t2CPS2p);
+ Inst.addOperand(MCOperand::CreateImm(imod));
+ Inst.addOperand(MCOperand::CreateImm(iflags));
+ if (mode) CHECK(S, Unpredictable);
+ } else if (!imod && M) {
+ Inst.setOpcode(ARM::t2CPS1p);
+ Inst.addOperand(MCOperand::CreateImm(mode));
+ if (iflags) CHECK(S, Unpredictable);
+ } else {
+ // imod == '00' && M == '0' --> UNPREDICTABLE
+ Inst.setOpcode(ARM::t2CPS1p);
+ Inst.addOperand(MCOperand::CreateImm(mode));
+ CHECK(S, Unpredictable);
+ }
+
+ return S;
+}
+
+
static DecodeStatus DecodeSMLAInstruction(llvm::MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
DecodeStatus S = Success;
@@ -3242,10 +3283,3 @@ static DecodeStatus DecodeVMOVRRS(llvm::MCInst &Inst, unsigned Insn,
return S;
}
-static DecodeStatus DecodeCPSIMod(llvm::MCInst &Inst, unsigned Val,
- uint64_t Address, const void *Decoder) {
- if (Val == 0x1) return Fail;
- Inst.addOperand(MCOperand::CreateImm(Val));
- return Success;
-}
-