Index: llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -35,6 +35,10 @@ 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">; Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -4011,6 +4011,12 @@ 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 @@ 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()) Index: llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td +++ llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td @@ -216,6 +216,16 @@ let ParserMatchClass = SVEExactFPImm; } +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. @@ -462,6 +472,40 @@ } //===----------------------------------------------------------------------===// +// SVE Floating Point Arithmetic - Predicated Group +//===----------------------------------------------------------------------===// + +class sve_fp_2op_i_p_zds 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 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 //===----------------------------------------------------------------------===// Index: llvm/trunk/test/MC/AArch64/SVE/fadd-diagnostics.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/fadd-diagnostics.s +++ llvm/trunk/test/MC/AArch64/SVE/fadd-diagnostics.s @@ -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]+}}: Index: llvm/trunk/test/MC/AArch64/SVE/fadd.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/fadd.s +++ llvm/trunk/test/MC/AArch64/SVE/fadd.s @@ -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 + +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 + +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 + +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 + +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 + +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 + +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 + +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 Index: llvm/trunk/test/MC/AArch64/SVE/fmax-diagnostics.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/fmax-diagnostics.s +++ llvm/trunk/test/MC/AArch64/SVE/fmax-diagnostics.s @@ -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]+}}: + Index: llvm/trunk/test/MC/AArch64/SVE/fmax.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/fmax.s +++ llvm/trunk/test/MC/AArch64/SVE/fmax.s @@ -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 + +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 + +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 + +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 + +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 + +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 + +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 Index: llvm/trunk/test/MC/AArch64/SVE/fmul-diagnostics.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/fmul-diagnostics.s +++ llvm/trunk/test/MC/AArch64/SVE/fmul-diagnostics.s @@ -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]+}}: Index: llvm/trunk/test/MC/AArch64/SVE/fmul.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/fmul.s +++ llvm/trunk/test/MC/AArch64/SVE/fmul.s @@ -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 + +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 + +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 + +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 + +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 + +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 + +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