[AArch64][SVE] Asm: Support for FADD, FMUL and FMAX immediate instructions.

Reviewers: rengolin, fhahn, SjoerdMeijer, samparker, javed.absar

Reviewed By: javed.absar

Differential Revision: https://reviews.llvm.org/D47712

llvm-svn: 334831
This commit is contained in:
Sander de Smalen 2018-06-15 13:57:51 +00:00
parent c3a419fcf3
commit dda2100a0f
9 changed files with 306 additions and 0 deletions

View File

@ -35,6 +35,10 @@ let Predicates = [HasSVE] in {
defm EOR_ZI : sve_int_log_imm<0b01, "eor", "eon">;
defm AND_ZI : sve_int_log_imm<0b10, "and", "bic">;
defm FADD_ZPmI : sve_fp_2op_i_p_zds<0b000, "fadd", sve_fpimm_half_one>;
defm FMUL_ZPmI : sve_fp_2op_i_p_zds<0b010, "fmul", sve_fpimm_half_two>;
defm FMAX_ZPmI : sve_fp_2op_i_p_zds<0b110, "fmax", sve_fpimm_zero_one>;
// Splat immediate (unpredicated)
defm DUP_ZI : sve_int_dup_imm<"dup">;
defm FDUP_ZI : sve_int_dup_fpimm<"fdup">;

View File

@ -4011,6 +4011,12 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
case Match_InvalidSVEPredicate3bSReg:
case Match_InvalidSVEPredicate3bDReg:
return Error(Loc, "restricted predicate has range [0, 7].");
case Match_InvalidSVEExactFPImmOperandHalfOne:
return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0.");
case Match_InvalidSVEExactFPImmOperandHalfTwo:
return Error(Loc, "Invalid floating point constant, expected 0.5 or 2.0.");
case Match_InvalidSVEExactFPImmOperandZeroOne:
return Error(Loc, "Invalid floating point constant, expected 0.0 or 1.0.");
default:
llvm_unreachable("unexpected error code!");
}
@ -4509,6 +4515,9 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSVEPredicate3bHReg:
case Match_InvalidSVEPredicate3bSReg:
case Match_InvalidSVEPredicate3bDReg:
case Match_InvalidSVEExactFPImmOperandHalfOne:
case Match_InvalidSVEExactFPImmOperandHalfTwo:
case Match_InvalidSVEExactFPImmOperandZeroOne:
case Match_MSR:
case Match_MRS: {
if (ErrorInfo >= Operands.size())

View File

@ -216,6 +216,16 @@ class SVEExactFPImmOperand<string Suffix, string ValA, string ValB> : Operand<i3
let ParserMatchClass = SVEExactFPImm<Suffix, ValA, ValB>;
}
def sve_fpimm_half_one
: SVEExactFPImmOperand<"HalfOne", "AArch64ExactFPImm::half",
"AArch64ExactFPImm::one">;
def sve_fpimm_half_two
: SVEExactFPImmOperand<"HalfTwo", "AArch64ExactFPImm::half",
"AArch64ExactFPImm::two">;
def sve_fpimm_zero_one
: SVEExactFPImmOperand<"ZeroOne", "AArch64ExactFPImm::zero",
"AArch64ExactFPImm::one">;
//===----------------------------------------------------------------------===//
// SVE PTrue - These are used extensively throughout the pattern matching so
// it's important we define them first.
@ -461,6 +471,40 @@ multiclass sve_int_bin_cons_arit_0<bits<3> opc, string asm> {
def _D : sve_int_bin_cons_arit_0<0b11, opc, asm, ZPR64>;
}
//===----------------------------------------------------------------------===//
// SVE Floating Point Arithmetic - Predicated Group
//===----------------------------------------------------------------------===//
class sve_fp_2op_i_p_zds<bits<2> sz, bits<3> opc, string asm,
ZPRRegOp zprty,
Operand imm_ty>
: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, imm_ty:$i1),
asm, "\t$Zdn, $Pg/m, $_Zdn, $i1",
"",
[]>, Sched<[]> {
bits<3> Pg;
bits<5> Zdn;
bit i1;
let Inst{31-24} = 0b01100101;
let Inst{23-22} = sz;
let Inst{21-19} = 0b011;
let Inst{18-16} = opc;
let Inst{15-13} = 0b100;
let Inst{12-10} = Pg;
let Inst{9-6} = 0b0000;
let Inst{5} = i1;
let Inst{4-0} = Zdn;
let Constraints = "$Zdn = $_Zdn";
}
multiclass sve_fp_2op_i_p_zds<bits<3> opc, string asm, Operand imm_ty> {
def _H : sve_fp_2op_i_p_zds<0b01, opc, asm, ZPR16, imm_ty>;
def _S : sve_fp_2op_i_p_zds<0b10, opc, asm, ZPR32, imm_ty>;
def _D : sve_fp_2op_i_p_zds<0b11, opc, asm, ZPR64, imm_ty>;
}
//===----------------------------------------------------------------------===//
// SVE Stack Allocation Group
//===----------------------------------------------------------------------===//

View File

@ -0,0 +1,29 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Invalid immediates (must be 0.5 or 1.0)
fadd z0.h, p0/m, z0.h, #0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 1.0.
// CHECK-NEXT: fadd z0.h, p0/m, z0.h, #0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fadd z0.h, p0/m, z0.h, #0.4999999999999999999999999
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 1.0.
// CHECK-NEXT: fadd z0.h, p0/m, z0.h, #0.4999999999999999999999999
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fadd z0.h, p0/m, z0.h, #0.5000000000000000000000001
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 1.0.
// CHECK-NEXT: fadd z0.h, p0/m, z0.h, #0.5000000000000000000000001
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fadd z0.h, p0/m, z0.h, #1.0000000000000000000000001
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 1.0.
// CHECK-NEXT: fadd z0.h, p0/m, z0.h, #1.0000000000000000000000001
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fadd z0.h, p0/m, z0.h, #0.9999999999999999999999999
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 1.0.
// CHECK-NEXT: fadd z0.h, p0/m, z0.h, #0.9999999999999999999999999
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -0,0 +1,56 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
fadd z0.h, p0/m, z0.h, #0.500000000000000
// CHECK-INST: fadd z0.h, p0/m, z0.h, #0.5
// CHECK-ENCODING: [0x00,0x80,0x58,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 58 65 <unknown>
fadd z0.h, p0/m, z0.h, #0.5
// CHECK-INST: fadd z0.h, p0/m, z0.h, #0.5
// CHECK-ENCODING: [0x00,0x80,0x58,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 58 65 <unknown>
fadd z0.s, p0/m, z0.s, #0.5
// CHECK-INST: fadd z0.s, p0/m, z0.s, #0.5
// CHECK-ENCODING: [0x00,0x80,0x98,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 98 65 <unknown>
fadd z0.d, p0/m, z0.d, #0.5
// CHECK-INST: fadd z0.d, p0/m, z0.d, #0.5
// CHECK-ENCODING: [0x00,0x80,0xd8,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 d8 65 <unknown>
fadd z31.h, p7/m, z31.h, #1.000000000000000
// CHECK-INST: fadd z31.h, p7/m, z31.h, #1.0
// CHECK-ENCODING: [0x3f,0x9c,0x58,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c 58 65 <unknown>
fadd z31.h, p7/m, z31.h, #1.0
// CHECK-INST: fadd z31.h, p7/m, z31.h, #1.0
// CHECK-ENCODING: [0x3f,0x9c,0x58,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c 58 65 <unknown>
fadd z31.s, p7/m, z31.s, #1.0
// CHECK-INST: fadd z31.s, p7/m, z31.s, #1.0
// CHECK-ENCODING: [0x3f,0x9c,0x98,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c 98 65 <unknown>
fadd z31.d, p7/m, z31.d, #1.0
// CHECK-INST: fadd z31.d, p7/m, z31.d, #1.0
// CHECK-ENCODING: [0x3f,0x9c,0xd8,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c d8 65 <unknown>

View File

@ -0,0 +1,30 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Invalid immediates (must be 0.0 or 1.0)
fmax z0.h, p0/m, z0.h, #0.5
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.0 or 1.0.
// CHECK-NEXT: fmax z0.h, p0/m, z0.h, #0.5
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmax z0.h, p0/m, z0.h, #-0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.0 or 1.0.
// CHECK-NEXT: fmax z0.h, p0/m, z0.h, #-0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmax z0.h, p0/m, z0.h, #0.0000000000000000000000001
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.0 or 1.0.
// CHECK-NEXT: fmax z0.h, p0/m, z0.h, #0.0000000000000000000000001
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmax z0.h, p0/m, z0.h, #1.0000000000000000000000001
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.0 or 1.0.
// CHECK-NEXT: fmax z0.h, p0/m, z0.h, #1.0000000000000000000000001
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmax z0.h, p0/m, z0.h, #0.9999999999999999999999999
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.0 or 1.0.
// CHECK-NEXT: fmax z0.h, p0/m, z0.h, #0.9999999999999999999999999
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -0,0 +1,50 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
fmax z0.h, p0/m, z0.h, #0.000000000000000
// CHECK-INST: fmax z0.h, p0/m, z0.h, #0.0
// CHECK-ENCODING: [0x00,0x80,0x5e,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 5e 65 <unknown>
fmax z0.h, p0/m, z0.h, #0.0
// CHECK-INST: fmax z0.h, p0/m, z0.h, #0.0
// CHECK-ENCODING: [0x00,0x80,0x5e,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 5e 65 <unknown>
fmax z0.s, p0/m, z0.s, #0.0
// CHECK-INST: fmax z0.s, p0/m, z0.s, #0.0
// CHECK-ENCODING: [0x00,0x80,0x9e,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 9e 65 <unknown>
fmax z31.d, p7/m, z31.d, #1.0
// CHECK-INST: fmax z31.d, p7/m, z31.d, #1.0
// CHECK-ENCODING: [0x3f,0x9c,0xde,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c de 65 <unknown>
fmax z31.h, p7/m, z31.h, #1.0
// CHECK-INST: fmax z31.h, p7/m, z31.h, #1.0
// CHECK-ENCODING: [0x3f,0x9c,0x5e,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c 5e 65 <unknown>
fmax z31.s, p7/m, z31.s, #1.0
// CHECK-INST: fmax z31.s, p7/m, z31.s, #1.0
// CHECK-ENCODING: [0x3f,0x9c,0x9e,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c 9e 65 <unknown>
fmax z0.d, p0/m, z0.d, #0.0
// CHECK-INST: fmax z0.d, p0/m, z0.d, #0.0
// CHECK-ENCODING: [0x00,0x80,0xde,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 de 65 <unknown>

View File

@ -0,0 +1,34 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Invalid immediates (must be 0.5 or 2.0)
fmul z0.h, p0/m, z0.h, #1.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 2.0.
// CHECK-NEXT: fmul z0.h, p0/m, z0.h, #1.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmul z0.h, p0/m, z0.h, #0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 2.0.
// CHECK-NEXT: fmul z0.h, p0/m, z0.h, #0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmul z0.h, p0/m, z0.h, #0.4999999999999999999999999
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 2.0.
// CHECK-NEXT: fmul z0.h, p0/m, z0.h, #0.4999999999999999999999999
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmul z0.h, p0/m, z0.h, #0.5000000000000000000000001
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 2.0.
// CHECK-NEXT: fmul z0.h, p0/m, z0.h, #0.5000000000000000000000001
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmul z0.h, p0/m, z0.h, #2.0000000000000000000000001
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 2.0.
// CHECK-NEXT: fmul z0.h, p0/m, z0.h, #2.0000000000000000000000001
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmul z0.h, p0/m, z0.h, #1.9999999999999999999999999
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 2.0.
// CHECK-NEXT: fmul z0.h, p0/m, z0.h, #1.9999999999999999999999999
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -0,0 +1,50 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
fmul z0.h, p0/m, z0.h, #0.5000000000000
// CHECK-INST: fmul z0.h, p0/m, z0.h, #0.5
// CHECK-ENCODING: [0x00,0x80,0x5a,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 5a 65 <unknown>
fmul z0.h, p0/m, z0.h, #0.5
// CHECK-INST: fmul z0.h, p0/m, z0.h, #0.5
// CHECK-ENCODING: [0x00,0x80,0x5a,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 5a 65 <unknown>
fmul z0.s, p0/m, z0.s, #0.5
// CHECK-INST: fmul z0.s, p0/m, z0.s, #0.5
// CHECK-ENCODING: [0x00,0x80,0x9a,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 9a 65 <unknown>
fmul z0.d, p0/m, z0.d, #0.5
// CHECK-INST: fmul z0.d, p0/m, z0.d, #0.5
// CHECK-ENCODING: [0x00,0x80,0xda,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 80 da 65 <unknown>
fmul z31.h, p7/m, z31.h, #2.0
// CHECK-INST: fmul z31.h, p7/m, z31.h, #2.0
// CHECK-ENCODING: [0x3f,0x9c,0x5a,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c 5a 65 <unknown>
fmul z31.s, p7/m, z31.s, #2.0
// CHECK-INST: fmul z31.s, p7/m, z31.s, #2.0
// CHECK-ENCODING: [0x3f,0x9c,0x9a,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c 9a 65 <unknown>
fmul z31.d, p7/m, z31.d, #2.0
// CHECK-INST: fmul z31.d, p7/m, z31.d, #2.0
// CHECK-ENCODING: [0x3f,0x9c,0xda,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c da 65 <unknown>