Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -343,6 +343,7 @@ Match_RequiresNotITBlock, Match_RequiresV6, Match_RequiresThumb2, + Match_RequiresV8, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "ARMGenAsmMatcher.inc" @@ -8530,17 +8531,29 @@ inITBlock()) return Match_RequiresNotITBlock; } - // Some high-register supporting Thumb1 encodings only allow both registers - // to be from r0-r7 when in Thumb2. - else if (Opc == ARM::tADDhirr && isThumbOne() && !hasV6MOps() && - isARMLowRegister(Inst.getOperand(1).getReg()) && - isARMLowRegister(Inst.getOperand(2).getReg())) - return Match_RequiresThumb2; - // Others only require ARMv6 or later. - else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && - isARMLowRegister(Inst.getOperand(0).getReg()) && - isARMLowRegister(Inst.getOperand(1).getReg())) - return Match_RequiresV6; + else if (isThumbOne()) { + // Some high-register supporting Thumb1 encodings only allow both registers + // to be from r0-r7 when in Thumb2. + if (Opc == ARM::tADDhirr && !hasV6MOps() && + isARMLowRegister(Inst.getOperand(1).getReg()) && + isARMLowRegister(Inst.getOperand(2).getReg())) + return Match_RequiresThumb2; + // Others only require ARMv6 or later. + else if (Opc == ARM::tMOVr && !hasV6Ops() && + isARMLowRegister(Inst.getOperand(0).getReg()) && + isARMLowRegister(Inst.getOperand(1).getReg())) + return Match_RequiresV6; + } + + for (unsigned I = 0; I < MCID.NumOperands; ++I) + if (MCID.OpInfo[I].RegClass == ARM::rGPRRegClassID) { + // rGPRRegClass excludes PC, and also excluded SP before ARMv8 + if ((Inst.getOperand(I).getReg() == ARM::SP) && !hasV8Ops()) + return Match_RequiresV8; + else if (Inst.getOperand(I).getReg() == ARM::PC) + return Match_InvalidOperand; + } + return Match_Success; } @@ -8639,6 +8652,8 @@ return Error(IDLoc, "instruction variant requires ARMv6 or later"); case Match_RequiresThumb2: return Error(IDLoc, "instruction variant requires Thumb2"); + case Match_RequiresV8: + return Error(IDLoc, "using SP in this instruction requires ARMv8 or later"); case Match_ImmRange0_15: { SMLoc ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getStartLoc(); if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; Index: test/MC/ARM/thumb-shift-encoding.s =================================================================== --- test/MC/ARM/thumb-shift-encoding.s +++ test/MC/ARM/thumb-shift-encoding.s @@ -6,40 +6,40 @@ sbc.w r12, lr, r0 sbc.w r1, r8, r9, lsr #32 - sbc.w r2, r7, pc, lsr #16 + sbc.w r2, r7, r10, lsr #16 sbc.w r3, r6, r10, lsl #0 sbc.w r4, r5, lr, lsl #16 sbc.w r5, r4, r11, asr #32 - sbc.w r6, r3, sp, asr #16 + sbc.w r6, r3, r12, asr #16 sbc.w r7, r2, r12, rrx sbc.w r8, r1, r0, ror #16 @ CHECK: sbc.w r12, lr, r0 @ encoding: [0x6e,0xeb,0x00,0x0c] @ CHECK: sbc.w r1, r8, r9, lsr #32 @ encoding: [0x68,0xeb,0x19,0x01] -@ CHECK: sbc.w r2, r7, pc, lsr #16 @ encoding: [0x67,0xeb,0x1f,0x42] +@ CHECK: sbc.w r2, r7, r10, lsr #16 @ encoding: [0x67,0xeb,0x1a,0x42] @ CHECK: sbc.w r3, r6, r10 @ encoding: [0x66,0xeb,0x0a,0x03] @ CHECK: sbc.w r4, r5, lr, lsl #16 @ encoding: [0x65,0xeb,0x0e,0x44] @ CHECK: sbc.w r5, r4, r11, asr #32 @ encoding: [0x64,0xeb,0x2b,0x05] -@ CHECK: sbc.w r6, r3, sp, asr #16 @ encoding: [0x63,0xeb,0x2d,0x46] +@ CHECK: sbc.w r6, r3, r12, asr #16 @ encoding: [0x63,0xeb,0x2c,0x46] @ CHECK: sbc.w r7, r2, r12, rrx @ encoding: [0x62,0xeb,0x3c,0x07] @ CHECK: sbc.w r8, r1, r0, ror #16 @ encoding: [0x61,0xeb,0x30,0x48] and.w r12, lr, r0 and.w r1, r8, r9, lsr #32 - and.w r2, r7, pc, lsr #16 + and.w r2, r7, r10, lsr #16 and.w r3, r6, r10, lsl #0 and.w r4, r5, lr, lsl #16 and.w r5, r4, r11, asr #32 - and.w r6, r3, sp, asr #16 + and.w r6, r3, r12, asr #16 and.w r7, r2, r12, rrx and.w r8, r1, r0, ror #16 @ CHECK: and.w r12, lr, r0 @ encoding: [0x0e,0xea,0x00,0x0c] @ CHECK: and.w r1, r8, r9, lsr #32 @ encoding: [0x08,0xea,0x19,0x01] -@ CHECK: and.w r2, r7, pc, lsr #16 @ encoding: [0x07,0xea,0x1f,0x42] +@ CHECK: and.w r2, r7, r10, lsr #16 @ encoding: [0x07,0xea,0x1a,0x42] @ CHECK: and.w r3, r6, r10 @ encoding: [0x06,0xea,0x0a,0x03] @ CHECK: and.w r4, r5, lr, lsl #16 @ encoding: [0x05,0xea,0x0e,0x44] @ CHECK: and.w r5, r4, r11, asr #32 @ encoding: [0x04,0xea,0x2b,0x05] -@ CHECK: and.w r6, r3, sp, asr #16 @ encoding: [0x03,0xea,0x2d,0x46] +@ CHECK: and.w r6, r3, r12, asr #16 @ encoding: [0x03,0xea,0x2c,0x46] @ CHECK: and.w r7, r2, r12, rrx @ encoding: [0x02,0xea,0x3c,0x07] @ CHECK: and.w r8, r1, r0, ror #16 @ encoding: [0x01,0xea,0x30,0x48] Index: test/MC/ARM/thumb2-diagnostics.s =================================================================== --- test/MC/ARM/thumb2-diagnostics.s +++ test/MC/ARM/thumb2-diagnostics.s @@ -87,7 +87,14 @@ @ CHECK-ERRORS: error: invalid operand for instruction @ CHECK-ERRORS: error: invalid operand for instruction -ssat r0, #1, r0, asr #32 -usat r0, #1, r0, asr #32 + ssat r0, #1, r0, asr #32 + usat r0, #1, r0, asr #32 @ CHECK-ERRORS: error: 'asr #32' shift amount not allowed in Thumb mode @ CHECK-ERRORS: error: 'asr #32' shift amount not allowed in Thumb mode + + @ PC is not valid as shifted-rGPR + sbc.w r2, r7, pc, lsr #16 + and.w r2, r7, pc, lsr #16 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +