diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 135 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 6 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 74 |
3 files changed, 116 insertions, 99 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 7f24f81c57..471ec29674 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3444,106 +3444,95 @@ def t2ABS : PseudoInst<(outs rGPR:$dst), (ins rGPR:$src), //===----------------------------------------------------------------------===// // Coprocessor load/store -- for disassembly only // -class T2CI<dag oops, dag iops, string opc, string asm> +class T2CI<bits<4> op31_28, dag oops, dag iops, string opc, string asm> : T2I<oops, iops, NoItinerary, opc, asm, []> { + let Inst{31-28} = op31_28; let Inst{27-25} = 0b110; } -multiclass T2LdStCop<bits<4> op31_28, bit load, string opc> { - def _OFFSET : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr"> { - let Inst{31-28} = op31_28; - let Inst{24} = 1; // P = 1 - let Inst{21} = 0; // W = 0 - let Inst{22} = 0; // D = 0 - let Inst{20} = load; - let DecoderMethod = "DecodeCopMemInstruction"; - } - - def _PRE : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr!"> { - let Inst{31-28} = op31_28; - let Inst{24} = 1; // P = 1 - let Inst{21} = 1; // W = 1 - let Inst{22} = 0; // D = 0 - let Inst{20} = load; - let DecoderMethod = "DecodeCopMemInstruction"; - } - - def _POST : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr"> { - let Inst{31-28} = op31_28; - let Inst{24} = 0; // P = 0 - let Inst{21} = 1; // W = 1 - let Inst{22} = 0; // D = 0 - let Inst{20} = load; - let DecoderMethod = "DecodeCopMemInstruction"; - } - - def _OPTION : T2CI<(outs), - (ins nohash_imm:$cop,nohash_imm:$CRd,GPR:$base, nohash_imm:$option), - opc, "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { - let Inst{31-28} = op31_28; - let Inst{24} = 0; // P = 0 - let Inst{23} = 1; // U = 1 - let Inst{21} = 0; // W = 0 - let Inst{22} = 0; // D = 0 - let Inst{20} = load; - let DecoderMethod = "DecodeCopMemInstruction"; - } - - def L_OFFSET : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> { - let Inst{31-28} = op31_28; +multiclass t2LdStCop<bits<4> op31_28, bit load, bit Dbit, string asm> { + def _OFFSET : T2CI<op31_28, + (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), + asm, "\t$cop, $CRd, $addr"> { + bits<13> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 1; // P = 1 + let Inst{23} = addr{8}; + let Inst{22} = Dbit; let Inst{21} = 0; // W = 0 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = addr{7-0}; let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_PRE : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { - let Inst{31-28} = op31_28; + def _PRE : T2CI<op31_28, + (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), + asm, "\t$cop, $CRd, $addr!"> { + bits<13> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 1; // P = 1 + let Inst{23} = addr{8}; + let Inst{22} = Dbit; let Inst{21} = 1; // W = 1 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = addr{7-0}; let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_POST : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addr_offset_none:$addr, - postidx_imm8s4:$offset), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr, $offset"> { - let Inst{31-28} = op31_28; + def _POST: T2CI<op31_28, + (outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, + postidx_imm8s4:$offset), + asm, "\t$cop, $CRd, $addr, $offset"> { + bits<9> offset; + bits<4> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 0; // P = 0 + let Inst{23} = offset{8}; + let Inst{22} = Dbit; let Inst{21} = 1; // W = 1 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = offset{7-0}; let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_OPTION : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd,GPR:$base,nohash_imm:$option), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { - let Inst{31-28} = op31_28; + def _OPTION : T2CI<op31_28, (outs), + (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, + coproc_option_imm:$option), + asm, "\t$cop, $CRd, $addr, $option"> { + bits<8> option; + bits<4> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 0; // P = 0 let Inst{23} = 1; // U = 1 + let Inst{22} = Dbit; let Inst{21} = 0; // W = 0 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = option; let DecoderMethod = "DecodeCopMemInstruction"; } } -defm t2LDC : T2LdStCop<0b1111, 1, "ldc">; -defm t2STC : T2LdStCop<0b1111, 0, "stc">; +defm t2LDC : t2LdStCop<0b1110, 1, 0, "ldc">; +defm t2LDCL : t2LdStCop<0b1110, 1, 1, "ldcl">; +defm t2STC : t2LdStCop<0b1110, 0, 0, "stc">; +defm t2STCL : t2LdStCop<0b1110, 0, 1, "stcl">; +defm t2LDC2 : t2LdStCop<0b1111, 1, 0, "ldc2">; +defm t2LDC2L : t2LdStCop<0b1111, 1, 1, "ldc2l">; +defm t2STC2 : t2LdStCop<0b1111, 0, 0, "stc2">; +defm t2STC2L : t2LdStCop<0b1111, 0, 1, "stc2l">; //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3ce086a049..24f15b4694 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2086,7 +2086,8 @@ ARMAsmParser::OperandMatchResultTy ARMAsmParser:: parseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); + if (Tok.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); if (Num == -1) @@ -2104,7 +2105,8 @@ ARMAsmParser::OperandMatchResultTy ARMAsmParser:: parseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); + if (Tok.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); if (Reg == -1) diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 7576801f71..7cead8c13b 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -1244,34 +1244,60 @@ static DecodeStatus DecodeCopMemInstruction(llvm::MCInst &Inst, unsigned Insn, idx_mode = ARMII::IndexModePost; switch (Inst.getOpcode()) { - case ARM::LDCL_POST: - case ARM::STCL_POST: - case ARM::t2LDCL_POST: - case ARM::t2STCL_POST: + case ARM::t2LDC2_OFFSET: + case ARM::t2LDC2L_OFFSET: + case ARM::t2LDC2_PRE: + case ARM::t2LDC2L_PRE: + case ARM::t2LDC2_POST: + case ARM::t2LDC2L_POST: + case ARM::t2STC2_OFFSET: + case ARM::t2STC2L_OFFSET: + case ARM::t2STC2_PRE: + case ARM::t2STC2L_PRE: + case ARM::t2STC2_POST: + case ARM::t2STC2L_POST: + case ARM::LDC2_OFFSET: + case ARM::LDC2L_OFFSET: + case ARM::LDC2_PRE: + case ARM::LDC2L_PRE: + case ARM::LDC2_POST: case ARM::LDC2L_POST: + case ARM::STC2_OFFSET: + case ARM::STC2L_OFFSET: + case ARM::STC2_PRE: + case ARM::STC2L_PRE: + case ARM::STC2_POST: case ARM::STC2L_POST: + case ARM::t2LDC_OFFSET: + case ARM::t2LDCL_OFFSET: + case ARM::t2LDC_PRE: + case ARM::t2LDCL_PRE: + case ARM::t2LDC_POST: + case ARM::t2LDCL_POST: + case ARM::t2STC_OFFSET: + case ARM::t2STCL_OFFSET: + case ARM::t2STC_PRE: + case ARM::t2STCL_PRE: + case ARM::t2STC_POST: + case ARM::t2STCL_POST: + case ARM::LDC_OFFSET: + case ARM::LDCL_OFFSET: + case ARM::LDC_PRE: + case ARM::LDCL_PRE: + case ARM::LDC_POST: + case ARM::LDCL_POST: + case ARM::STC_OFFSET: + case ARM::STCL_OFFSET: + case ARM::STC_PRE: + case ARM::STCL_PRE: + case ARM::STC_POST: + case ARM::STCL_POST: imm |= U << 8; - case ARM::LDC_OPTION: - case ARM::LDCL_OPTION: - case ARM::LDC2_OPTION: - case ARM::LDC2L_OPTION: - case ARM::STC_OPTION: - case ARM::STCL_OPTION: - case ARM::STC2_OPTION: - case ARM::STC2L_OPTION: - case ARM::t2LDC_OPTION: - case ARM::t2LDCL_OPTION: - case ARM::t2STC_OPTION: - case ARM::t2STCL_OPTION: - Inst.addOperand(MCOperand::CreateImm(imm)); - break; + // fall through. default: - if (U) - Inst.addOperand(MCOperand::CreateImm( - ARM_AM::getAM2Opc(ARM_AM::add, imm, ARM_AM::lsl, idx_mode))); - else - Inst.addOperand(MCOperand::CreateImm( - ARM_AM::getAM2Opc(ARM_AM::sub, imm, ARM_AM::lsl, idx_mode))); + // The 'option' variant doesn't encode 'U' in the immediate since + // the immediate is unsigned [0,255]. + Inst.addOperand(MCOperand::CreateImm(imm)); break; } |