diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 8aa608bc97a..5d5380f34c9 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -582,7 +582,11 @@ def Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; } def imm0_3 : Operand { let ParserMatchClass = Imm0_3AsmOperand; } /// imm0_4 predicate - Immediate in the range [0,4]. -def Imm0_4AsmOperand : ImmAsmOperand { let Name = "Imm0_4"; } +def Imm0_4AsmOperand : ImmAsmOperand +{ + let Name = "Imm0_4"; + let DiagnosticType = "ImmRange0_4"; +} def imm0_4 : Operand, ImmLeaf= 0 && Imm < 5; }]> { let ParserMatchClass = Imm0_4AsmOperand; let DecoderMethod = "DecodeImm0_4"; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index ad57de54c13..4dacb86df4c 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3401,12 +3401,7 @@ class t2CPS : T2XI<(outs), iops, NoItinerary, bits<5> mode; bit M; - let Inst{31-27} = 0b11110; - let Inst{26} = 0; - let Inst{25-20} = 0b111010; - let Inst{19-16} = 0b1111; - let Inst{15-14} = 0b10; - let Inst{12} = 0; + let Inst{31-11} = 0b111100111010111110000; let Inst{10-9} = imod; let Inst{8} = M; let Inst{7-5} = iflags; @@ -3425,13 +3420,13 @@ let imod = 0, iflags = 0, M = 1 in // A6.3.4 Branches and miscellaneous control // Table A6-14 Change Processor State, and hint instructions -def t2HINT : T2I<(outs), (ins imm0_255:$imm), NoItinerary, "hint", "\t$imm",[]>{ - bits<8> imm; - let Inst{31-8} = 0b111100111010111110000000; - let Inst{7-0} = imm; +def t2HINT : T2I<(outs), (ins imm0_4:$imm), NoItinerary, "hint", "\t$imm",[]> { + bits<3> imm; + let Inst{31-3} = 0b11110011101011111000000000000; + let Inst{2-0} = imm; } -def : t2InstAlias<"hint$p.w $imm", (t2HINT imm0_255:$imm, pred:$p)>; +def : t2InstAlias<"hint$p.w $imm", (t2HINT imm0_4:$imm, pred:$p)>; def : t2InstAlias<"nop$p.w", (t2HINT 0, pred:$p)>; def : t2InstAlias<"yield$p.w", (t2HINT 1, pred:$p)>; def : t2InstAlias<"wfe$p.w", (t2HINT 2, pred:$p)>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 20468af9a27..114cc9e5c05 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7622,6 +7622,11 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(IDLoc, "instruction variant requires ARMv6 or later"); case Match_RequiresThumb2: return Error(IDLoc, "instruction variant requires Thumb2"); + case Match_ImmRange0_4: { + SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); + if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; + return Error(ErrorLoc, "immediate operand must be in the range [0,4]"); + } case Match_ImmRange0_15: { SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 32b47fba514..ac937f35345 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -1953,10 +1953,12 @@ static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, Inst.addOperand(MCOperand::CreateImm(mode)); if (iflags) S = MCDisassembler::SoftFail; } else { - // imod == '00' && M == '0' --> UNPREDICTABLE - Inst.setOpcode(ARM::t2CPS1p); - Inst.addOperand(MCOperand::CreateImm(mode)); - S = MCDisassembler::SoftFail; + // imod == '00' && M == '0' --> this is a HINT instruction + int imm = fieldFromInstruction(Insn, 0, 8); + // HINT are defined only for immediate in [0..4] + if(imm > 4) return MCDisassembler::Fail; + Inst.setOpcode(ARM::t2HINT); + Inst.addOperand(MCOperand::CreateImm(imm)); } return S; diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 0b7f2f9dbdb..71b5b5da09b 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -2870,7 +2870,6 @@ Lforward: wfilt yield yieldne - hint #5 hint #4 hint #3 hint #2 @@ -2883,7 +2882,6 @@ Lforward: @ CHECK: wfilt @ encoding: [0x03,0xf0,0x20,0xb3] @ CHECK: yield @ encoding: [0x01,0xf0,0x20,0xe3] @ CHECK: yieldne @ encoding: [0x01,0xf0,0x20,0x13] -@ CHECK-NOT: hint #5 @ CHECK: sev @ encoding: [0x04,0xf0,0x20,0xe3] @ CHECK: wfi @ encoding: [0x03,0xf0,0x20,0xe3] @ CHECK: wfe @ encoding: [0x02,0xf0,0x20,0xe3] diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index 9278a2a94b5..8127feba6d4 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -3486,8 +3486,6 @@ _func: wfelt wfige yieldlt - hint #5 - hint.w #5 hint.w #4 hint #3 hint #2 @@ -3501,8 +3499,6 @@ _func: @ CHECK: wfelt @ encoding: [0x20,0xbf] @ CHECK: wfige @ encoding: [0x30,0xbf] @ CHECK: yieldlt @ encoding: [0x10,0xbf] -@ CHECK: hint #5 @ encoding: [0xaf,0xf3,0x05,0x80] -@ CHECK: hint #5 @ encoding: [0xaf,0xf3,0x05,0x80] @ CHECK: sev.w @ encoding: [0xaf,0xf3,0x04,0x80] @ CHECK: wfi.w @ encoding: [0xaf,0xf3,0x03,0x80] @ CHECK: wfe.w @ encoding: [0xaf,0xf3,0x02,0x80] diff --git a/test/MC/ARM/invalid-hint-arm.s b/test/MC/ARM/invalid-hint-arm.s new file mode 100644 index 00000000000..e0cd97a1902 --- /dev/null +++ b/test/MC/ARM/invalid-hint-arm.s @@ -0,0 +1,7 @@ +@ RUN: llvm-mc -triple=armv7-apple-darwin -mcpu=cortex-a8 < %s 2>&1 | FileCheck %s + +hint #5 +hint #100 + +@ CHECK: error: immediate operand must be in the range [0,4] +@ CHECK: error: immediate operand must be in the range [0,4] diff --git a/test/MC/ARM/invalid-hint-thumb.s b/test/MC/ARM/invalid-hint-thumb.s new file mode 100644 index 00000000000..fd0a761da27 --- /dev/null +++ b/test/MC/ARM/invalid-hint-thumb.s @@ -0,0 +1,9 @@ +@ RUN: llvm-mc -triple=thumbv7-apple-darwin -mcpu=cortex-a8 < %s 2>&1 | FileCheck %s + +hint #5 +hint.w #5 +hint #100 + +@ CHECK: error: immediate operand must be in the range [0,4] +@ CHECK: error: immediate operand must be in the range [0,4] +@ CHECK: error: immediate operand must be in the range [0,4] diff --git a/test/MC/Disassembler/ARM/invalid-hint-arm.txt b/test/MC/Disassembler/ARM/invalid-hint-arm.txt new file mode 100644 index 00000000000..7da96d8f15c --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-hint-arm.txt @@ -0,0 +1,13 @@ +# RUN: llvm-mc -triple=armv7-apple-darwin -mcpu=cortex-a8 -disassemble < %s 2>&1 | FileCheck %s + +#------------------------------------------------------------------------------ +# Undefined encoding space for hint instructions +#------------------------------------------------------------------------------ + +0x05 0xf0 0x20 0xe3 +# CHECK: invalid instruction encoding +0x41 0xf0 0x20 0xe3 +# CHECK: invalid instruction encoding +0xfe 0xf0 0x20 0xe3 +# CHECK: invalid instruction encoding + diff --git a/test/MC/Disassembler/ARM/invalid-hint-thumb.txt b/test/MC/Disassembler/ARM/invalid-hint-thumb.txt new file mode 100644 index 00000000000..1e4133668b8 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-hint-thumb.txt @@ -0,0 +1,8 @@ +# RUN: llvm-mc -triple=thumbv7 -disassemble -show-encoding < %s 2>&1 | FileCheck %s + +#------------------------------------------------------------------------------ +# Undefined encoding space for hint instructions +#------------------------------------------------------------------------------ + +0xaf 0xf3 0x05 0x80 +# CHECK: invalid instruction encoding