forked from OSchip/llvm-project
Fix Thumb2 decoding of CPS instructions to mirror ARM decoding of the same instructions.
llvm-svn: 138339
This commit is contained in:
parent
e364ad540a
commit
9b7bd15d0b
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue