diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td index 14e315534570d..691f10895ad93 100644 --- a/llvm/lib/Target/ARM/ARMInstrFormats.td +++ b/llvm/lib/Target/ARM/ARMInstrFormats.td @@ -1390,8 +1390,8 @@ class ThumbXI pattern, AddrMode am = AddrModeNone> - : Thumb2I; + string opc, string asm, list pattern, AddrMode am = AddrModeNone, string constraints = ""> + : Thumb2I; class T2Ii12 pattern> : Thumb2I; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 812b5730875d5..dba0bec3fd3f5 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -5440,17 +5440,17 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, } class ACI pattern, IndexMode im = IndexModeNone, + list pattern, string cstrs = "", IndexMode im = IndexModeNone, AddrMode am = AddrModeNone> : I { + opc, asm, cstrs, pattern> { let Inst{27-25} = 0b110; } class ACInoP pattern, IndexMode im = IndexModeNone, + list pattern, string constraints = "", IndexMode im = IndexModeNone, AddrMode am = AddrModeNone> : InoP { + opc, asm, constraints, pattern> { let Inst{31-28} = 0b1111; let Inst{27-25} = 0b110; } @@ -5458,7 +5458,7 @@ class ACInoP pattern> { def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), - asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone, + asm, "\t$cop, $CRd, $addr", pattern, "", IndexModeNone, AddrMode5> { bits<13> addr; bits<4> cop; @@ -5474,8 +5474,8 @@ multiclass LdStCop pattern> { let Inst{7-0} = addr{7-0}; let DecoderMethod = "DecodeCopMemInstruction"; } - def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), - asm, "\t$cop, $CRd, $addr!", [], IndexModePre> { + def _PRE : ACI<(outs GPR:$Rn_wb), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), + asm, "\t$cop, $CRd, $addr!", [], "$addr.base = $Rn_wb", IndexModePre> { bits<13> addr; bits<4> cop; bits<4> CRd; @@ -5492,7 +5492,7 @@ multiclass LdStCop pattern> { } def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, postidx_imm8s4:$offset), - asm, "\t$cop, $CRd, $addr, $offset", [], IndexModePost> { + asm, "\t$cop, $CRd, $addr, $offset", [], "", IndexModePost> { bits<9> offset; bits<4> addr; bits<4> cop; @@ -5530,7 +5530,7 @@ multiclass LdStCop pattern> { } multiclass LdSt2Cop pattern> { def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), - asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone, + asm, "\t$cop, $CRd, $addr", pattern, "", IndexModeNone, AddrMode5> { bits<13> addr; bits<4> cop; @@ -5546,8 +5546,8 @@ multiclass LdSt2Cop pattern> { let Inst{7-0} = addr{7-0}; let DecoderMethod = "DecodeCopMemInstruction"; } - def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), - asm, "\t$cop, $CRd, $addr!", [], IndexModePre> { + def _PRE : ACInoP<(outs GPR:$Rn_wb), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), + asm, "\t$cop, $CRd, $addr!", [], "$addr.base = $Rn_wb", IndexModePre> { bits<13> addr; bits<4> cop; bits<4> CRd; @@ -5564,7 +5564,7 @@ multiclass LdSt2Cop pattern> { } def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, postidx_imm8s4:$offset), - asm, "\t$cop, $CRd, $addr, $offset", [], IndexModePost> { + asm, "\t$cop, $CRd, $addr, $offset", [], "", IndexModePost> { bits<9> offset; bits<4> addr; bits<4> cop; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index acd46e8093aa7..1e9613368c151 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -4383,8 +4383,8 @@ def t2ABS : PseudoInst<(outs rGPR:$dst), (ins rGPR:$src), // Coprocessor load/store -- for disassembly only // class T2CI op31_28, dag oops, dag iops, string opc, string asm, - list pattern, AddrMode am = AddrModeNone> - : T2I { + list pattern, AddrMode am = AddrModeNone, string constraints = ""> + : T2I { let Inst{31-28} = op31_28; let Inst{27-25} = 0b110; } @@ -4408,8 +4408,8 @@ multiclass t2LdStCop op31_28, bit load, bit Dbit, string asm, list let DecoderMethod = "DecodeCopMemInstruction"; } def _PRE : T2CI { + (outs GPR:$Rn_wb), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), + asm, "\t$cop, $CRd, $addr!", [], AddrMode5, "$addr.base = $Rn_wb"> { bits<13> addr; bits<4> cop; bits<4> CRd; diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index def54f95409d6..f3e4a87931b33 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -1862,12 +1862,17 @@ static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, const MCDisassembler *Decoder) { DecodeStatus S = MCDisassembler::Success; + unsigned P = fieldFromInstruction(Insn, 24, 1); + unsigned W = fieldFromInstruction(Insn, 21, 1); unsigned pred = fieldFromInstruction(Insn, 28, 4); unsigned CRd = fieldFromInstruction(Insn, 12, 4); unsigned coproc = fieldFromInstruction(Insn, 8, 4); unsigned imm = fieldFromInstruction(Insn, 0, 8); unsigned Rn = fieldFromInstruction(Insn, 16, 4); unsigned U = fieldFromInstruction(Insn, 23, 1); + // Pre-Indexed implies writeback to Rn + bool IsPreIndexed = (P == 1) && (W == 1); + const FeatureBitset &featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits(); @@ -1943,6 +1948,10 @@ static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, if (featureBits[ARM::HasV8Ops] && (coproc != 14)) return MCDisassembler::Fail; + if (IsPreIndexed) + // Dummy operand for Rn_wb. + Inst.addOperand(MCOperand::createImm(0)); + Inst.addOperand(MCOperand::createImm(coproc)); Inst.addOperand(MCOperand::createImm(CRd)); if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))