Skip to content

Commit

Permalink
Added support for unpredictable mcrr/mcrr2/mrrc/mrrc2 ARM instruction…
Browse files Browse the repository at this point in the history
… 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
  • Loading branch information
sbaranga-arm committed Apr 18, 2012
1 parent e546c4c commit fa1ebc6
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
10 changes: 6 additions & 4 deletions lib/Target/ARM/ARMInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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 */>;

Expand Down
30 changes: 30 additions & 0 deletions lib/Target/ARM/Disassembler/ARMDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}

4 changes: 4 additions & 0 deletions test/MC/Disassembler/ARM/invalid-MRRC2-arm.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# RUN: llvm-mc --disassemble %s -triple=armv7-linux-gnueabi |& FileCheck %s

# CHECK: invalid instruction encoding
0x00 0x1a 0x50 0xfc
13 changes: 13 additions & 0 deletions test/MC/Disassembler/ARM/unpredictable-MRRC2-arm.txt
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit fa1ebc6

Please sign in to comment.