summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2013-04-26 17:54:54 +0000
committerQuentin Colombet <qcolombet@apple.com>2013-04-26 17:54:54 +0000
commita83d5e9f9186a71cdd01b6d487e23aa4c97085ec (patch)
tree06bfe0a5bd3eaf9b93e8bc6ec184b0deed199d39
parent37212578ee5e7f8b014fd49d7797775b788fbd1d (diff)
downloadbcm5719-llvm-a83d5e9f9186a71cdd01b6d487e23aa4c97085ec.tar.gz
bcm5719-llvm-a83d5e9f9186a71cdd01b6d487e23aa4c97085ec.zip
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>. llvm-svn: 180617
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td6
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td17
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp5
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp10
-rw-r--r--llvm/test/MC/ARM/basic-arm-instructions.s2
-rw-r--r--llvm/test/MC/ARM/basic-thumb2-instructions.s4
-rw-r--r--llvm/test/MC/ARM/invalid-hint-arm.s7
-rw-r--r--llvm/test/MC/ARM/invalid-hint-thumb.s9
-rw-r--r--llvm/test/MC/Disassembler/ARM/invalid-hint-arm.txt13
-rw-r--r--llvm/test/MC/Disassembler/ARM/invalid-hint-thumb.txt8
10 files changed, 59 insertions, 22 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 8aa608bc97a..5d5380f34c9 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -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";
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index ad57de54c13..4dacb86df4c 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -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)>;
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 20468af9a27..114cc9e5c05 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/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/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 32b47fba514..ac937f35345 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/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/llvm/test/MC/ARM/basic-arm-instructions.s b/llvm/test/MC/ARM/basic-arm-instructions.s
index 0b7f2f9dbdb..71b5b5da09b 100644
--- a/llvm/test/MC/ARM/basic-arm-instructions.s
+++ b/llvm/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/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s
index 9278a2a94b5..8127feba6d4 100644
--- a/llvm/test/MC/ARM/basic-thumb2-instructions.s
+++ b/llvm/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/llvm/test/MC/ARM/invalid-hint-arm.s b/llvm/test/MC/ARM/invalid-hint-arm.s
new file mode 100644
index 00000000000..e0cd97a1902
--- /dev/null
+++ b/llvm/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/llvm/test/MC/ARM/invalid-hint-thumb.s b/llvm/test/MC/ARM/invalid-hint-thumb.s
new file mode 100644
index 00000000000..fd0a761da27
--- /dev/null
+++ b/llvm/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/llvm/test/MC/Disassembler/ARM/invalid-hint-arm.txt b/llvm/test/MC/Disassembler/ARM/invalid-hint-arm.txt
new file mode 100644
index 00000000000..7da96d8f15c
--- /dev/null
+++ b/llvm/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/llvm/test/MC/Disassembler/ARM/invalid-hint-thumb.txt b/llvm/test/MC/Disassembler/ARM/invalid-hint-thumb.txt
new file mode 100644
index 00000000000..1e4133668b8
--- /dev/null
+++ b/llvm/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
OpenPOWER on IntegriCloud