Skip to content

Commit

Permalink
Fix Thumb2 decoding of CPS instructions to mirror ARM decoding of the…
Browse files Browse the repository at this point in the history
… same instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138339 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
resistor committed Aug 23, 2011
1 parent cefe4c9 commit 6153a03
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
1 change: 0 additions & 1 deletion lib/Target/ARM/ARMInstrFormats.td
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions lib/Target/ARM/ARMInstrThumb2.td
Expand Up @@ -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
Expand Down
52 changes: 43 additions & 9 deletions lib/Target/ARM/Disassembler/ARMDisassembler.cpp
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

0 comments on commit 6153a03

Please sign in to comment.