diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 8e5e8c1735a..842f3372d04 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3599,6 +3599,16 @@ def t2RFEIA : T2RFE<0b111010011001, (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn", [/* For disassembly only; pattern left blank */]>; +// B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction. +let Defs = [PC], Uses = [LR] in +def t2SUBS_PC_LR : T2I <(outs), (ins imm0_255:$imm), NoItinerary, + "subs", "\tpc, lr, $imm", []>, Requires<[IsThumb2]> { + let Inst{31-8} = 0b111100111101111010001111; + + bits<8> imm; + let Inst{7-0} = imm; +} + //===----------------------------------------------------------------------===// // Non-Instruction Patterns // diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 6d885a0d918..8e56a1ab942 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5138,6 +5138,26 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, } } + // FIXME: As said above, this is all a pretty gross hack. This instruction + // does not fit with other "subs" and tblgen. + // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction + // so the Mnemonic is the original name "subs" and delete the predicate + // operand so it will match the table entry. + if (isThumbTwo() && Mnemonic == "sub" && Operands.size() == 6 && + static_cast(Operands[3])->isReg() && + static_cast(Operands[3])->getReg() == ARM::PC && + static_cast(Operands[4])->isReg() && + static_cast(Operands[4])->getReg() == ARM::LR && + static_cast(Operands[5])->isImm()) { + ARMOperand *Op0 = static_cast(Operands[0]); + Operands.erase(Operands.begin()); + delete Op0; + Operands.insert(Operands.begin(), ARMOperand::CreateToken(Name, NameLoc)); + + ARMOperand *Op1 = static_cast(Operands[1]); + Operands.erase(Operands.begin() + 1); + delete Op1; + } return false; } diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index 43e03c9833a..f3a1c6a9f9f 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -3588,3 +3588,7 @@ _func: @ rdar://12596361 ldr r1, [pc, #12] @ CHECK: ldr r1, [pc, #12] @ encoding: [0x03,0x49] + +@ rdar://14214063 + subs pc, lr, #4 +@ CHECK: subs pc, lr, #4 @ encoding: [0xde,0xf3,0x04,0x8f] diff --git a/test/MC/Disassembler/ARM/thumb2.txt b/test/MC/Disassembler/ARM/thumb2.txt index 110a4c0530e..9fc166f0663 100644 --- a/test/MC/Disassembler/ARM/thumb2.txt +++ b/test/MC/Disassembler/ARM/thumb2.txt @@ -2051,6 +2051,7 @@ # CHECK: sub.w r12, r6, #256 # CHECK: subw r12, r6, #256 # CHECK: subs.w r1, r2, #496 +# CHECK: subs pc, lr, #4 0x0a 0xbf 0x11 0x1f @@ -2062,6 +2063,7 @@ 0xa6 0xf5 0x80 0x7c 0xa6 0xf2 0x00 0x1c 0xb2 0xf5 0xf8 0x71 +0xde 0xf3 0x04 0x8f #------------------------------------------------------------------------------