llvm.org GIT mirror llvm / 1ad3a41
ARM: Fix encoding of hint instruction for Thumb. "hint" space for Thumb actually overlaps the encoding space of the CPS instruction. In actuality, hints can be defined as CPS instructions where imod and M bits are all nil. Handle decoding of permitted nop-compatible hints (i.e. nop, yield, wfi, wfe, sev) in DecodeT2CPSInstruction. This commit adds a proper diagnostic message for Imm0_4 and updates all tests. Patch by Mihail Popa <Mihail.Popa@arm.com>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180617 91177308-0d34-0410-b5e6-96231b3b80d8 Quentin Colombet 7 years ago
10 changed file(s) with 61 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
581581 def imm0_3 : Operand { let ParserMatchClass = Imm0_3AsmOperand; }
582582
583583 /// imm0_4 predicate - Immediate in the range [0,4].
584 def Imm0_4AsmOperand : ImmAsmOperand { let Name = "Imm0_4"; }
584 def Imm0_4AsmOperand : ImmAsmOperand
585 {
586 let Name = "Imm0_4";
587 let DiagnosticType = "ImmRange0_4";
588 }
585589 def imm0_4 : Operand, ImmLeaf= 0 && Imm < 5; }]> {
586590 let ParserMatchClass = Imm0_4AsmOperand;
587591 let DecoderMethod = "DecodeImm0_4";
34003400 bits<5> mode;
34013401 bit M;
34023402
3403 let Inst{31-27} = 0b11110;
3404 let Inst{26} = 0;
3405 let Inst{25-20} = 0b111010;
3406 let Inst{19-16} = 0b1111;
3407 let Inst{15-14} = 0b10;
3408 let Inst{12} = 0;
3403 let Inst{31-11} = 0b111100111010111110000;
34093404 let Inst{10-9} = imod;
34103405 let Inst{8} = M;
34113406 let Inst{7-5} = iflags;
34243419
34253420 // A6.3.4 Branches and miscellaneous control
34263421 // Table A6-14 Change Processor State, and hint instructions
3427 def t2HINT : T2I<(outs), (ins imm0_255:$imm), NoItinerary, "hint", "\t$imm",[]>{
3428 bits<8> imm;
3429 let Inst{31-8} = 0b111100111010111110000000;
3430 let Inst{7-0} = imm;
3431 }
3432
3433 def : t2InstAlias<"hint$p.w $imm", (t2HINT imm0_255:$imm, pred:$p)>;
3422 def t2HINT : T2I<(outs), (ins imm0_4:$imm), NoItinerary, "hint", "\t$imm",[]> {
3423 bits<3> imm;
3424 let Inst{31-3} = 0b11110011101011111000000000000;
3425 let Inst{2-0} = imm;
3426 }
3427
3428 def : t2InstAlias<"hint$p.w $imm", (t2HINT imm0_4:$imm, pred:$p)>;
34343429 def : t2InstAlias<"nop$p.w", (t2HINT 0, pred:$p)>;
34353430 def : t2InstAlias<"yield$p.w", (t2HINT 1, pred:$p)>;
34363431 def : t2InstAlias<"wfe$p.w", (t2HINT 2, pred:$p)>;
76217621 return Error(IDLoc, "instruction variant requires ARMv6 or later");
76227622 case Match_RequiresThumb2:
76237623 return Error(IDLoc, "instruction variant requires Thumb2");
7624 case Match_ImmRange0_4: {
7625 SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
7626 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
7627 return Error(ErrorLoc, "immediate operand must be in the range [0,4]");
7628 }
76247629 case Match_ImmRange0_15: {
76257630 SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
76267631 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
19521952 Inst.addOperand(MCOperand::CreateImm(mode));
19531953 if (iflags) S = MCDisassembler::SoftFail;
19541954 } else {
1955 // imod == '00' && M == '0' --> UNPREDICTABLE
1956 Inst.setOpcode(ARM::t2CPS1p);
1957 Inst.addOperand(MCOperand::CreateImm(mode));
1958 S = MCDisassembler::SoftFail;
1955 // imod == '00' && M == '0' --> this is a HINT instruction
1956 int imm = fieldFromInstruction(Insn, 0, 8);
1957 // HINT are defined only for immediate in [0..4]
1958 if(imm > 4) return MCDisassembler::Fail;
1959 Inst.setOpcode(ARM::t2HINT);
1960 Inst.addOperand(MCOperand::CreateImm(imm));
19591961 }
19601962
19611963 return S;
28692869 wfilt
28702870 yield
28712871 yieldne
2872 hint #5
28732872 hint #4
28742873 hint #3
28752874 hint #2
28822881 @ CHECK: wfilt @ encoding: [0x03,0xf0,0x20,0xb3]
28832882 @ CHECK: yield @ encoding: [0x01,0xf0,0x20,0xe3]
28842883 @ CHECK: yieldne @ encoding: [0x01,0xf0,0x20,0x13]
2885 @ CHECK-NOT: hint #5
28862884 @ CHECK: sev @ encoding: [0x04,0xf0,0x20,0xe3]
28872885 @ CHECK: wfi @ encoding: [0x03,0xf0,0x20,0xe3]
28882886 @ CHECK: wfe @ encoding: [0x02,0xf0,0x20,0xe3]
34853485 wfelt
34863486 wfige
34873487 yieldlt
3488 hint #5
3489 hint.w #5
34903488 hint.w #4
34913489 hint #3
34923490 hint #2
35003498 @ CHECK: wfelt @ encoding: [0x20,0xbf]
35013499 @ CHECK: wfige @ encoding: [0x30,0xbf]
35023500 @ CHECK: yieldlt @ encoding: [0x10,0xbf]
3503 @ CHECK: hint #5 @ encoding: [0xaf,0xf3,0x05,0x80]
3504 @ CHECK: hint #5 @ encoding: [0xaf,0xf3,0x05,0x80]
35053501 @ CHECK: sev.w @ encoding: [0xaf,0xf3,0x04,0x80]
35063502 @ CHECK: wfi.w @ encoding: [0xaf,0xf3,0x03,0x80]
35073503 @ CHECK: wfe.w @ encoding: [0xaf,0xf3,0x02,0x80]
0 @ RUN: llvm-mc -triple=armv7-apple-darwin -mcpu=cortex-a8 < %s 2>&1 | FileCheck %s
1
2 hint #5
3 hint #100
4
5 @ CHECK: error: immediate operand must be in the range [0,4]
6 @ CHECK: error: immediate operand must be in the range [0,4]
0 @ RUN: llvm-mc -triple=thumbv7-apple-darwin -mcpu=cortex-a8 < %s 2>&1 | FileCheck %s
1
2 hint #5
3 hint.w #5
4 hint #100
5
6 @ CHECK: error: immediate operand must be in the range [0,4]
7 @ CHECK: error: immediate operand must be in the range [0,4]
8 @ CHECK: error: immediate operand must be in the range [0,4]
0 # RUN: llvm-mc -triple=armv7-apple-darwin -mcpu=cortex-a8 -disassemble < %s 2>&1 | FileCheck %s
1
2 #------------------------------------------------------------------------------
3 # Undefined encoding space for hint instructions
4 #------------------------------------------------------------------------------
5
6 0x05 0xf0 0x20 0xe3
7 # CHECK: invalid instruction encoding
8 0x41 0xf0 0x20 0xe3
9 # CHECK: invalid instruction encoding
10 0xfe 0xf0 0x20 0xe3
11 # CHECK: invalid instruction encoding
12
0 # RUN: llvm-mc -triple=thumbv7 -disassemble -show-encoding < %s 2>&1 | FileCheck %s
1
2 #------------------------------------------------------------------------------
3 # Undefined encoding space for hint instructions
4 #------------------------------------------------------------------------------
5
6 0xaf 0xf3 0x05 0x80
7 # CHECK: invalid instruction encoding