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

Now with the asm operand definition included.

llvm-svn: 336432
This commit is contained in:
Sjoerd Meijer 2018-07-06 12:32:33 +00:00
parent 4c13935522
commit 757ee882e7
6 changed files with 143 additions and 0 deletions

View File

@ -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, string asm,
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.
//---

View File

@ -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)>;

View File

@ -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!");

View File

@ -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: ^

View File

@ -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: ^

View File

@ -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