[llvm] r336432 - Recommit: [AArch64] Armv8.4-A: Flag manipulation instructions

Sjoerd Meijer via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 6 05:32:33 PDT 2018


Author: sjoerdmeijer
Date: Fri Jul  6 05:32:33 2018
New Revision: 336432

URL: http://llvm.org/viewvc/llvm-project?rev=336432&view=rev
Log:
Recommit: [AArch64] Armv8.4-A: Flag manipulation instructions

Now with the asm operand definition included.

Added:
    llvm/trunk/test/MC/AArch64/armv8.4a-flag-error.s
    llvm/trunk/test/MC/AArch64/armv8.4a-flag.s
    llvm/trunk/test/MC/Disassembler/AArch64/armv8.4a-flag.txt
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
    llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td?rev=336432&r1=336431&r2=336432&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td Fri Jul  6 05:32:33 2018
@@ -256,6 +256,16 @@ def simm10Scaled : Operand<i64> {
   let PrintMethod = "printImmScale<8>";
 }
 
+// uimm6 predicate - True if the immediate is in the range [0, 63].
+def UImm6Operand : AsmOperandClass {
+  let Name = "UImm6";
+  let DiagnosticType = "InvalidImm0_63";
+}
+
+def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
+  let ParserMatchClass = UImm6Operand;
+}
+
 def SImm9Operand : SImmOperand<9>;
 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
   let ParserMatchClass = SImm9Operand;
@@ -1612,6 +1622,30 @@ class SignAuthTwoOperand<bits<4> opc, st
   let Inst{4-0}   = Rd;
 }
 
+// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
+class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
+    : I<(outs), iops, asm, ops, "", []>,
+      Sched<[WriteI, ReadI, ReadI]> {
+  let Uses = [NZCV];
+  bits<5> Rn;
+  let Inst{31}    = sf;
+  let Inst{30-15} = 0b0111010000000000;
+  let Inst{14}    = sz;
+  let Inst{13-10} = 0b0010;
+  let Inst{9-5}   = Rn;
+  let Inst{4-0}   = 0b01101;
+}
+
+class FlagRotate<dag iops, string asm, string ops>
+    : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
+  bits<6> imm;
+  bits<4> mask;
+  let Inst{20-15} = imm;
+  let Inst{13-10} = 0b0001;
+  let Inst{4}     = 0b0;
+  let Inst{3-0}   = mask;
+}
+
 //---
 // Basic two-operand data processing instructions.
 //---

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td?rev=336432&r1=336431&r2=336432&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td Fri Jul  6 05:32:33 2018
@@ -557,6 +557,17 @@ let Predicates = [HasV8_3a] in {
 
 } // HasV8_3A
 
+// v8.4 Flag manipulation instructions
+let Predicates = [HasV8_4a] in {
+def CFINV : SimpleSystemI<0, (ins), "cfinv", "">, Sched<[WriteSys]> {
+  let Inst{20-5} = 0b0000001000000000;
+}
+def SETF8  : BaseFlagManipulation<0, 0, (ins GPR32:$Rn), "setf8", "{\t$Rn}">;
+def SETF16 : BaseFlagManipulation<0, 1, (ins GPR32:$Rn), "setf16", "{\t$Rn}">;
+def RMIF   : FlagRotate<(ins GPR64:$Rn, uimm6:$imm, imm0_15:$mask), "rmif",
+                        "{\t$Rn, $imm, $mask}">;
+} // HasV8_4a
+
 def : InstAlias<"clrex", (CLREX 0xf)>;
 def : InstAlias<"isb", (ISB 0xf)>;
 

Modified: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp?rev=336432&r1=336431&r2=336432&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp Fri Jul  6 05:32:33 2018
@@ -537,6 +537,16 @@ public:
   bool isImm() const override { return Kind == k_Immediate; }
   bool isMem() const override { return false; }
 
+  bool isUImm6() const {
+    if (!isImm())
+      return false;
+    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
+    if (!MCE)
+      return false;
+    int64_t Val = MCE->getValue();
+    return (Val >= 0 && Val < 64);
+  }
+
   template <int Width> bool isSImm() const { return isSImmScaled<Width, 1>(); }
 
   template <int Bits, int Scale> DiagnosticPredicate isSImmScaled() const {
@@ -1499,6 +1509,12 @@ public:
     Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
   }
 
+  void addUImm6Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
+    Inst.addOperand(MCOperand::createImm(MCE->getValue()));
+  }
+
   template <int Scale>
   void addImmScaledOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");

Added: llvm/trunk/test/MC/AArch64/armv8.4a-flag-error.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/armv8.4a-flag-error.s?rev=336432&view=auto
==============================================================================
--- llvm/trunk/test/MC/AArch64/armv8.4a-flag-error.s (added)
+++ llvm/trunk/test/MC/AArch64/armv8.4a-flag-error.s Fri Jul  6 05:32:33 2018
@@ -0,0 +1,27 @@
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.4a < %s 2>&1 | FileCheck %s --check-prefix=CHECK
+
+//------------------------------------------------------------------------------
+// Armv8.4-A flag manipulation instructions
+//------------------------------------------------------------------------------
+
+  rmif  x1, #64, #15
+  rmif  x1, #-1, #15
+  rmif  x1, #63, #16
+  rmif  x1, #63, #-1
+  rmif  sp, #63, #1
+
+//CHECK:      error: immediate must be an integer in range [0, 63].
+//CHECK-NEXT: rmif  x1, #64, #15
+//CHECK-NEXT:           ^
+//CHECK-NEXT: error: immediate must be an integer in range [0, 63].
+//CHECK-NEXT: rmif  x1, #-1, #15
+//CHECK-NEXT:           ^
+//CHECK-NEXT: error: immediate must be an integer in range [0, 15].
+//CHECK-NEXT: rmif  x1, #63, #16
+//CHECK-NEXT:                ^
+//CHECK-NEXT: error: immediate must be an integer in range [0, 15].
+//CHECK-NEXT: rmif  x1, #63, #-1
+//CHECK-NEXT:                ^
+//CHECK-NEXT: error: invalid operand for instruction
+//CHECK-NEXT: rmif  sp, #63, #1
+//CHECK-NEXT:       ^

Added: llvm/trunk/test/MC/AArch64/armv8.4a-flag.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/armv8.4a-flag.s?rev=336432&view=auto
==============================================================================
--- llvm/trunk/test/MC/AArch64/armv8.4a-flag.s (added)
+++ llvm/trunk/test/MC/AArch64/armv8.4a-flag.s Fri Jul  6 05:32:33 2018
@@ -0,0 +1,44 @@
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.4a < %s | FileCheck %s --check-prefix=CHECK
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=-v8.4a < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
+//------------------------------------------------------------------------------
+// Armv8.4-A flag manipulation instructions
+//------------------------------------------------------------------------------
+
+  cfinv
+  setf8 w1
+  setf8 wzr
+  setf16 w1
+  setf16 wzr
+  rmif x1, #63, #15
+  rmif xzr, #63, #15
+
+//CHECK:      cfinv                        // encoding: [0x1f,0x40,0x00,0xd5]
+//CHECK-NEXT: setf8 w1                     // encoding: [0x2d,0x08,0x00,0x3a]
+//CHECK-NEXT: setf8 wzr                    // encoding: [0xed,0x0b,0x00,0x3a]
+//CHECK-NEXT: setf16 w1                    // encoding: [0x2d,0x48,0x00,0x3a]
+//CHECK-NEXT: setf16 wzr                   // encoding: [0xed,0x4b,0x00,0x3a]
+//CHECK-NEXT: rmif x1, #63, #15            // encoding: [0x2f,0x84,0x1f,0xba]
+//CHECK-NEXT: rmif xzr, #63, #15           // encoding: [0xef,0x87,0x1f,0xba]
+
+//CHECK-ERROR:      error: instruction requires: armv8.4a
+//CHECK-ERROR-NEXT: cfinv
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: error: instruction requires: armv8.4a
+//CHECK-ERROR-NEXT: setf8 w1
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: error: instruction requires: armv8.4a
+//CHECK-ERROR-NEXT: setf8 wzr
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: error: instruction requires: armv8.4a
+//CHECK-ERROR-NEXT: setf16 w1
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: error: instruction requires: armv8.4a
+//CHECK-ERROR-NEXT: setf16 wzr
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: error: instruction requires: armv8.4a
+//CHECK-ERROR-NEXT: rmif x1, #63, #15
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: error: instruction requires: armv8.4a
+//CHECK-ERROR-NEXT: rmif xzr, #63, #15
+//CHECK-ERROR-NEXT: ^

Added: llvm/trunk/test/MC/Disassembler/AArch64/armv8.4a-flag.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/AArch64/armv8.4a-flag.txt?rev=336432&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/AArch64/armv8.4a-flag.txt (added)
+++ llvm/trunk/test/MC/Disassembler/AArch64/armv8.4a-flag.txt Fri Jul  6 05:32:33 2018
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.4a --disassemble < %s | FileCheck %s
+
+[0x1f,0x40,0x00,0xd5]
+[0x2d,0x08,0x00,0x3a]
+[0x2d,0x48,0x00,0x3a]
+[0x2f,0x84,0x1f,0xba]
+
+#CHECK:  cfinv
+#CHECK:  setf8  w1
+#CHECK:  setf16  w1
+#CHECK:  rmif  x1, #63, #15




More information about the llvm-commits mailing list