diff options
author | Silviu Baranga <silviu.baranga@arm.com> | 2012-04-18 13:12:50 +0000 |
---|---|---|
committer | Silviu Baranga <silviu.baranga@arm.com> | 2012-04-18 13:12:50 +0000 |
commit | fa1ebc6abe95b79b7f82030eea53586a8704eb7e (patch) | |
tree | 158b6ad7a4ddd16be07017fc6616a12f9bd8e53b | |
parent | e546c4c9c3004274c8e275e8303ca078b794bf28 (diff) |
Added support for unpredictable mcrr/mcrr2/mrrc/mrrc2 ARM instruction in the disassembler. Since the upredicability conditions are complex, C++ code was added to handle them.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155001 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 10 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 30 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-MRRC2-arm.txt | 4 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/unpredictable-MRRC2-arm.txt | 13 |
4 files changed, 53 insertions, 4 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 3361ad472a..7b0a3ac42a 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -4590,7 +4590,7 @@ def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, class MovRRCopro<string opc, bit direction, list<dag> pattern = []> : ABI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, - GPR:$Rt, GPR:$Rt2, c_imm:$CRm), + GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { let Inst{23-21} = 0b010; let Inst{20} = direction; @@ -4609,13 +4609,13 @@ class MovRRCopro<string opc, bit direction, list<dag> pattern = []> } def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, - [(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, + [(int_arm_mcrr imm:$cop, imm:$opc1, GPRnopc:$Rt, GPRnopc:$Rt2, imm:$CRm)]>; def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>; class MovRRCopro2<string opc, bit direction, list<dag> pattern = []> : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, - GPR:$Rt, GPR:$Rt2, c_imm:$CRm), NoItinerary, + GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> { let Inst{31-28} = 0b1111; let Inst{23-21} = 0b010; @@ -4632,10 +4632,12 @@ class MovRRCopro2<string opc, bit direction, list<dag> pattern = []> let Inst{11-8} = cop; let Inst{7-4} = opc1; let Inst{3-0} = CRm; + + let DecoderMethod = "DecodeMRRC2"; } def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */, - [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, + [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPRnopc:$Rt, GPRnopc:$Rt2, imm:$CRm)]>; def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>; diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index f352bffa44..87a5f019d4 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -326,6 +326,8 @@ static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val, static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); #include "ARMGenDisassemblerTables.inc" #include "ARMGenInstrInfo.inc" #include "ARMGenEDInfo.inc" @@ -4403,3 +4405,31 @@ static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, return S; } +static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder) { + + DecodeStatus S = MCDisassembler::Success; + + unsigned CRm = fieldFromInstruction32(Val, 0, 4); + unsigned opc1 = fieldFromInstruction32(Val, 4, 4); + unsigned cop = fieldFromInstruction32(Val, 8, 4); + unsigned Rt = fieldFromInstruction32(Val, 12, 4); + unsigned Rt2 = fieldFromInstruction32(Val, 16, 4); + + if ((cop & ~0x1) == 0xa) + return MCDisassembler::Fail; + + if (Rt == Rt2) + S = MCDisassembler::SoftFail; + + Inst.addOperand(MCOperand::CreateImm(cop)); + Inst.addOperand(MCOperand::CreateImm(opc1)); + if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::CreateImm(CRm)); + + return S; +} + diff --git a/test/MC/Disassembler/ARM/invalid-MRRC2-arm.txt b/test/MC/Disassembler/ARM/invalid-MRRC2-arm.txt new file mode 100644 index 0000000000..aaae6ce2e4 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-MRRC2-arm.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc --disassemble %s -triple=armv7-linux-gnueabi |& FileCheck %s + +# CHECK: invalid instruction encoding +0x00 0x1a 0x50 0xfc diff --git a/test/MC/Disassembler/ARM/unpredictable-MRRC2-arm.txt b/test/MC/Disassembler/ARM/unpredictable-MRRC2-arm.txt new file mode 100644 index 0000000000..26b286dbf4 --- /dev/null +++ b/test/MC/Disassembler/ARM/unpredictable-MRRC2-arm.txt @@ -0,0 +1,13 @@ +# RUN: llvm-mc --disassemble %s -triple=armv7-linux-gnueabi |& FileCheck %s + +# CHECK: potentially undefined +# CHECK: 0x00 0x10 0x51 0xfc +0x00 0x10 0x51 0xfc + +# CHECK: potentially undefined +# CHECK: 0x00 0xf0 0x41 0x0c +0x00 0xf0 0x41 0x0c + +# CHECK: potentially undefined +# CHECK: 0x00 0x00 0x4f 0x0c +0x00 0x00 0x4f 0x0c |