ARM: Fix encoding of hint instruction for Thumb.
authorQuentin Colombet <qcolombet@apple.com>
Fri, 26 Apr 2013 17:54:54 +0000 (17:54 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Fri, 26 Apr 2013 17:54:54 +0000 (17:54 +0000)
"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

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/Disassembler/ARMDisassembler.cpp
test/MC/ARM/basic-arm-instructions.s
test/MC/ARM/basic-thumb2-instructions.s
test/MC/ARM/invalid-hint-arm.s [new file with mode: 0644]
test/MC/ARM/invalid-hint-thumb.s [new file with mode: 0644]
test/MC/Disassembler/ARM/invalid-hint-arm.txt [new file with mode: 0644]
test/MC/Disassembler/ARM/invalid-hint-thumb.txt [new file with mode: 0644]

index 8aa608bc97af647e7e3d39880aad48ff0c9d597d..5d5380f34c92bd4939341e00a2dc6f801d7f9a91 100644 (file)
@@ -582,7 +582,11 @@ def Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; }
 def imm0_3 : Operand<i32> { 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<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 5; }]> {
   let ParserMatchClass = Imm0_4AsmOperand;
   let DecoderMethod = "DecodeImm0_4";
index ad57de54c1325cf0ea4f0142a399e14e353b1b24..4dacb86df4ce3f5542311fe504454a3f60eb748c 100644 (file)
@@ -3401,12 +3401,7 @@ class t2CPS<dag iops, string asm_op> : 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)>;
index 20468af9a27f8f6ae653f3efc7e046156e641a6f..114cc9e5c05ea1d583625c2d0962a37df2eb3ff4 100644 (file)
@@ -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;
index 32b47fba514d9a18cf75ed68735908670d675a05..ac937f35345e605998ff3f4ba312ae66ba9dddd1 100644 (file)
@@ -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;
index 0b7f2f9dbdb63b446b0fc324234cc7b8c9bb768a..71b5b5da09bea2ce31ed328251db24850085de3d 100644 (file)
@@ -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]
index 9278a2a94b56a8118511014d60af3614dbd16843..8127feba6d40a6e02f238621039b60d46e65c4de 100644 (file)
@@ -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 (file)
index 0000000..e0cd97a
--- /dev/null
@@ -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 (file)
index 0000000..fd0a761
--- /dev/null
@@ -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 (file)
index 0000000..7da96d8
--- /dev/null
@@ -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 (file)
index 0000000..1e41336
--- /dev/null
@@ -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