Index: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td @@ -1612,6 +1612,30 @@ let Inst{4-0} = Rd; } +// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions +class BaseFlagManipulation + : 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 + : 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. //--- Index: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td @@ -557,6 +557,17 @@ } // 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)>; Index: llvm/trunk/test/MC/AArch64/armv8.4a-flag-error.s =================================================================== --- llvm/trunk/test/MC/AArch64/armv8.4a-flag-error.s +++ llvm/trunk/test/MC/AArch64/armv8.4a-flag-error.s @@ -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: ^ Index: llvm/trunk/test/MC/AArch64/armv8.4a-flag.s =================================================================== --- llvm/trunk/test/MC/AArch64/armv8.4a-flag.s +++ llvm/trunk/test/MC/AArch64/armv8.4a-flag.s @@ -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: ^ Index: llvm/trunk/test/MC/Disassembler/AArch64/armv8.4a-flag.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/AArch64/armv8.4a-flag.txt +++ llvm/trunk/test/MC/Disassembler/AArch64/armv8.4a-flag.txt @@ -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