[ARM] Introduce the 'sevl' instruction in ARMv8.
authorJoey Gouly <joey.gouly@arm.com>
Tue, 1 Oct 2013 12:39:11 +0000 (12:39 +0000)
committerJoey Gouly <joey.gouly@arm.com>
Tue, 1 Oct 2013 12:39:11 +0000 (12:39 +0000)
This also removes the restriction on the immediate field of the 'hint'
instruction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191744 91177308-0d34-0410-b5e6-96231b3b80d8

16 files changed:
include/llvm/IR/IntrinsicsARM.td
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
test/CodeGen/ARM/intrinsics-v8.ll
test/MC/ARM/basic-arm-instructions-v8.s
test/MC/ARM/basic-arm-instructions.s
test/MC/ARM/basic-thumb2-instructions-v8.s
test/MC/ARM/invalid-hint-arm.s [deleted file]
test/MC/ARM/invalid-hint-thumb.s [deleted file]
test/MC/Disassembler/ARM/basic-arm-instructions-v8.txt
test/MC/Disassembler/ARM/basic-arm-instructions.txt
test/MC/Disassembler/ARM/invalid-armv7.txt
test/MC/Disassembler/ARM/invalid-thumbv7.txt

index 8d8c4af850f1029bf4f08bfd92e9d05136f5bfac..2d82735f83a39fe7bf5f76943ba24359d6718c0f 100644 (file)
@@ -112,6 +112,10 @@ def int_arm_crc32w  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
 def int_arm_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
     [IntrNoMem]>;
 
+//===----------------------------------------------------------------------===//
+// HINT
+def int_arm_sevl : Intrinsic<[], []>;
+
 //===----------------------------------------------------------------------===//
 // Advanced SIMD (NEON)
 
index 59d2f7a00a1afed40e9927f8bae379d559865dc4..740b71cb2adad0f1448e3de880a3abd2e1d571a8 100644 (file)
@@ -594,17 +594,6 @@ def imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; }
 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"; 
-  let DiagnosticType = "ImmRange0_4";  
-}
-def imm0_4 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 5; }]> {
-  let ParserMatchClass = Imm0_4AsmOperand;
-  let DecoderMethod = "DecodeImm0_4";
-}
-
 /// imm0_7 predicate - Immediate in the range [0,7].
 def Imm0_7AsmOperand: ImmAsmOperand { let Name = "Imm0_7"; }
 def imm0_7 : Operand<i32>, ImmLeaf<i32, [{
@@ -1677,11 +1666,11 @@ PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
            [(ARMcallseq_start timm:$amt)]>;
 }
 
-def HINT : AI<(outs), (ins imm0_4:$imm), MiscFrm, NoItinerary,
+def HINT : AI<(outs), (ins imm0_255:$imm), MiscFrm, NoItinerary,
               "hint", "\t$imm", []>, Requires<[IsARM, HasV6]> {
-  bits<3> imm;
-  let Inst{27-3} = 0b0011001000001111000000000;
-  let Inst{2-0} = imm;
+  bits<8> imm;
+  let Inst{27-8} = 0b00110010000011110000;
+  let Inst{7-0} = imm;
 }
 
 def : InstAlias<"nop$p", (HINT 0, pred:$p)>, Requires<[IsARM, HasV6T2]>;
@@ -1689,6 +1678,9 @@ def : InstAlias<"yield$p", (HINT 1, pred:$p)>, Requires<[IsARM, HasV6T2]>;
 def : InstAlias<"wfe$p", (HINT 2, pred:$p)>, Requires<[IsARM, HasV6T2]>;
 def : InstAlias<"wfi$p", (HINT 3, pred:$p)>, Requires<[IsARM, HasV6T2]>;
 def : InstAlias<"sev$p", (HINT 4, pred:$p)>, Requires<[IsARM, HasV6T2]>;
+def : InstAlias<"sevl$p", (HINT 5, pred:$p)>, Requires<[IsARM, HasV8]>;
+
+def : Pat<(int_arm_sevl), (HINT 5)>;
 
 def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
              "\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> {
index dd5f2cf8fbbdc7a4876294eef4299d2dc04de3b0..2c547910be773ca8426106cdf6b120dfac09ae7a 100644 (file)
@@ -289,6 +289,11 @@ def tSEV : T1pI<(outs), (ins), NoItinerary, "sev", "", []>,
            T1SystemEncoding<0x40>, // A8.6.157
            Requires<[IsThumb2]>;
 
+def tSEVL : T1pI<(outs), (ins), NoItinerary, "sevl", "", [(int_arm_sevl)]>,
+            T1SystemEncoding<0x50>,
+            Requires<[IsThumb2, HasV8]>;
+
+
 // The imm operand $val can be used by a debugger to store more information
 // about the breakpoint.
 def tBKPT : T1I<(outs), (ins imm0_255:$val), NoItinerary, "bkpt\t$val",
index 07baf2d8ae61242dcb2c34cb5ad8caca259b1482..754970093f05dd8040088615b3274c5b42023feb 100644 (file)
@@ -3652,18 +3652,21 @@ def : t2InstAlias<"cps.w $mode", (t2CPS1p imm0_31:$mode), 0>;
 
 // A6.3.4 Branches and miscellaneous control
 // Table A6-14 Change Processor State, and hint instructions
-def t2HINT : T2I<(outs), (ins imm0_4:$imm), NoItinerary, "hint", "\t$imm",[]> {
+def t2HINT : T2I<(outs), (ins imm0_255:$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_4:$imm, pred:$p)>;
+def : t2InstAlias<"hint$p.w $imm", (t2HINT imm0_255:$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)>;
 def : t2InstAlias<"wfi$p.w", (t2HINT 3, pred:$p)>;
 def : t2InstAlias<"sev$p.w", (t2HINT 4, pred:$p)>;
+def : t2InstAlias<"sevl$p.w", (t2HINT 5, pred:$p)> {
+  let Predicates = [IsThumb2, HasV8];
+}
 
 def t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt", []> {
   bits<4> opt;
index 4faf3b32c291aac0f2fc472ece2b22d7b181b3f2..ebc382cef443b0a738d9a8b9a6ff8550d6785243 100644 (file)
@@ -679,13 +679,6 @@ public:
     int64_t Value = CE->getValue();
     return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
   }
-  bool isImm0_4() const {
-    if (!isImm()) return false;
-    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
-    if (!CE) return false;
-    int64_t Value = CE->getValue();
-    return Value >= 0 && Value < 5;
-  }
   bool isImm0_1020s4() const {
     if (!isImm()) return false;
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
@@ -7687,11 +7680,6 @@ 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 82c12944f3c6ab0486270dde2f9ad9d99d57f7f1..efa8306b8b4855ec29465f7d18031952f83478b4 100644 (file)
@@ -84,6 +84,11 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
     case 2: O << "\twfe"; break;
     case 3: O << "\twfi"; break;
     case 4: O << "\tsev"; break;
+    case 5:
+      if ((getAvailableFeatures() & ARM::HasV8Ops)) {
+        O << "\tsevl";
+        break;
+      } // Fallthrough for non-v8
     default:
       // Anything else should just print normally.
       printInstruction(MI, O);
index a6a45459e8843bc68cd3408f4c3520b0d32a6d3f..247bfc1e58849e380968ebc9a7b89a67f9c2ff26 100644 (file)
@@ -9,8 +9,11 @@ define void @test() {
   call void @llvm.arm.dsb(i32 15)
   ; CHECK: dsb ishld
   call void @llvm.arm.dsb(i32 9)
+  ; CHECK: sevl
+  tail call void @llvm.arm.sevl() nounwind
   ret void
 }
 
 declare void @llvm.arm.dmb(i32)
 declare void @llvm.arm.dsb(i32)
+declare void @llvm.arm.sevl() nounwind
index a447e0f22cf5a1731a8762ae91893ca3f092230f..70b1496156b5945fb1fe2a19cf0f8797089c8a5c 100644 (file)
 @ CHECK-V7: error: invalid operand for instruction
 @ CHECK-V7: error: invalid operand for instruction
 @ CHECK-V7: error: invalid operand for instruction
+
+@------------------------------------------------------------------------------
+@ SEVL
+@------------------------------------------------------------------------------
+        sevl
+
+@ CHECK: sevl @ encoding: [0x05,0xf0,0x20,0xe3]
index 5d40a397660d82e0b6607832b17c6fb170441c3a..636682f3a9358ec6cdf4d1a47eaa42a089c2bac2 100644 (file)
@@ -2928,6 +2928,7 @@ Lforward:
         hint #2
         hint #1
         hint #0
+        hint #255
 
 @ CHECK: wfe                            @ encoding: [0x02,0xf0,0x20,0xe3]
 @ CHECK: wfehi                          @ encoding: [0x02,0xf0,0x20,0x83]
@@ -2940,3 +2941,4 @@ Lforward:
 @ CHECK: wfe                            @ encoding: [0x02,0xf0,0x20,0xe3]
 @ CHECK: yield                          @ encoding: [0x01,0xf0,0x20,0xe3]
 @ CHECK: nop                            @ encoding: [0x00,0xf0,0x20,0xe3]
+@ CHECK: hint #255                      @ encoding: [0xff,0xf0,0x20,0xe3]
index 69a7cff6abd007a435948ba760e0f982fd0814d8..ba6f0da2ee43889449319c26a7a87d40081dccc0 100644 (file)
 @ CHECK-V7: error: invalid operand for instruction
 @ CHECK-V7: error: invalid operand for instruction
 @ CHECK-V7: error: invalid operand for instruction
+
+@------------------------------------------------------------------------------
+@ SEVL
+@------------------------------------------------------------------------------
+        sevl
+        sevl.w
+        it ge
+        sevlge
+
+@ CHECK-V8: sevl @ encoding: [0x50,0xbf]
+@ CHECK-V8: sevl.w @ encoding: [0xaf,0xf3,0x05,0x80]
+@ CHECK-V8: it ge @ encoding: [0xa8,0xbf]
+@ CHECK-V8: sevlge @ encoding: [0x50,0xbf]
diff --git a/test/MC/ARM/invalid-hint-arm.s b/test/MC/ARM/invalid-hint-arm.s
deleted file mode 100644 (file)
index 3608e95..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-@ RUN: not 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
deleted file mode 100644 (file)
index bde987c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-@ RUN: not 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]
index c14748a6102816817743b0589b9abc1205fbaa18..454b39479464c8f3b793042cef02a8ec811287c1 100644 (file)
@@ -18,3 +18,6 @@
 # CHECK: dmb oshld
 # CHECK: dmb nshld
 # CHECK: dmb ld
+
+0x05 0xf0 0x20 0xe3
+# CHECK: sevl
index fd36268a380a84ad194421472eed581719dbdd0b..8bcf4e6e3faa9c2749bf407bd42a68afde9f5754 100644 (file)
 # CHECK: wfilt
 # CHECK: yield
 # CHECK: yieldne
+# CHECK: hint #5
 
 0x02 0xf0 0x20 0xe3
 0x02 0xf0 0x20 0x83
 0x03 0xf0 0x20 0xb3
 0x01 0xf0 0x20 0xe3
 0x01 0xf0 0x20 0x13
+0x05 0xf0 0x20 0xe3
index 11d9790d7da3db73acc473f8aa9033a232877b2d..550173f7823d01dfe8ac2ba09bfdc49e13688169 100644 (file)
 # Undefined encoding space for hint instructions
 #------------------------------------------------------------------------------
 
-[0x05 0xf0 0x20 0xe3]
-# CHECK: invalid instruction encoding
-# CHECK-NEXT: [0x05 0xf0 0x20 0xe3]
-
-[0x41 0xf0 0x20 0xe3]
-# CHECK: invalid instruction encoding
-# CHECK-NEXT: [0x41 0xf0 0x20 0xe3]
-
 # FIXME: is it "dbg #14" or not????
 [0xfe 0xf0 0x20 0xe3]
 # CHCK: invalid instruction encoding
index f465b3c1f4a28233355ed11d366516ec8c60c068..f8adbcfbdc59ee3f8b37612718c81ca48488539e 100644 (file)
 # Undefined encoding space for hint instructions
 #------------------------------------------------------------------------------
 
-[0xaf 0xf3 0x05 0x80]
+[0x60 0xbf]
 # CHECK: invalid instruction encoding
-# CHECK-NEXT: [0xaf 0xf3 0x05 0x80]
-
+# CHECK-NEXT: [0x60 0xbf]
 
 #------------------------------------------------------------------------------
 # Undefined encoding for it