Author: Jonathan Thackray Date: 2026-10-09T14:48:55+01:00 New Revision: a8f1f81a4da6651ab6816100cd67a49d4230abca
URL: https://github.com/llvm/llvm-project/commit/a8f1f81a4da6651ab6816100cd67a49d4230abca DIFF: https://github.com/llvm/llvm-project/commit/a8f1f81a4da6651ab6816100cd67a49d4230abca.diff LOG: [AArch64][llvm] Armv9.8-A: Add support for FEAT_CFLT (Conditional Fault instructions) (#229362) Add support for FEAT_CFLT (Conditional Fault instructions), which are optional from Armv9.7 onwards: ``` CFLTEQ, CFLTNE, CFLTGT, CFLTLT, CFLTGE, CFLTLE, CFLTHI, CFLTLO, CFLTHS, CFLTLS, CFLTZ, CFLTNZ, TFLTZ, TFLTNZ, FLT.NE, FLT.EQ, FLT.MI, FLT.PL, FLT.VS, FLT.VC, FLT.HI, FLT.LS, FLT.GE, FLT.LT, FLT.GT, FLT.LE, FLT.AL, FLT.NV, FLT.CS, FLT.CC, FLT.HS, FLT.LO ``` --- <sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub> Added: llvm/test/MC/AArch64/armv9.8a-cflt-diagnostics.s llvm/test/MC/AArch64/armv9.8a-cflt.s Modified: clang/test/Driver/aarch64-v98a.c clang/test/Driver/print-supported-extensions-aarch64.c llvm/lib/Target/AArch64/AArch64Features.td llvm/lib/Target/AArch64/AArch64InstrFormats.td llvm/lib/Target/AArch64/AArch64InstrInfo.td llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp llvm/test/MC/AArch64/directive-arch-negative.s llvm/test/MC/AArch64/directive-arch.s llvm/test/MC/AArch64/directive-arch_extension-negative.s llvm/test/MC/AArch64/directive-arch_extension.s llvm/unittests/TargetParser/TargetParserTest.cpp Removed: ################################################################################ diff --git a/clang/test/Driver/aarch64-v98a.c b/clang/test/Driver/aarch64-v98a.c index b578c577d00a17..8427b2b4aa2539 100644 --- a/clang/test/Driver/aarch64-v98a.c +++ b/clang/test/Driver/aarch64-v98a.c @@ -17,3 +17,7 @@ // GENERICV98A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.8a"{{.*}} "-target-feature" "+fprcvt"{{.*}} "-target-feature" "+sve2p3"{{.*}} // ===== Features supported on aarch64 ===== +// +// RUN: %clang -target aarch64 -march=armv9.8a+cflt -### -c %s 2>&1 | FileCheck -check-prefix=V98A-CFLT %s +// RUN: %clang -target aarch64 -march=armv9.8-a+cflt -### -c %s 2>&1 | FileCheck -check-prefix=V98A-CFLT %s +// V98A-CFLT: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.8a"{{.*}} "-target-feature" "+cflt" diff --git a/clang/test/Driver/print-supported-extensions-aarch64.c b/clang/test/Driver/print-supported-extensions-aarch64.c index 1e2882550c81fa..a57fff693eec45 100644 --- a/clang/test/Driver/print-supported-extensions-aarch64.c +++ b/clang/test/Driver/print-supported-extensions-aarch64.c @@ -9,6 +9,7 @@ // CHECK-NEXT: brbe FEAT_BRBE Enable Branch Record Buffer Extension // CHECK-NEXT: bti FEAT_BTI Enable Branch Target Identification // CHECK-NEXT: btie FEAT_BTIE Enable Enhanced Branch Target Identification extension +// CHECK-NEXT: cflt FEAT_CFLT Enable Armv9.8-A Conditional Fault instructions // CHECK-NEXT: cmpbr FEAT_CMPBR Enable Armv9.6-A base compare and branch instructions // CHECK-NEXT: fcma FEAT_FCMA Enable Armv8.3-A Floating-point complex number support // CHECK-NEXT: cpa FEAT_CPA Enable Armv9.5-A Checked Pointer Arithmetic diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td index cda947c1bbea0b..fd1db78da1773c 100644 --- a/llvm/lib/Target/AArch64/AArch64Features.td +++ b/llvm/lib/Target/AArch64/AArch64Features.td @@ -621,6 +621,9 @@ def FeatureF16F32MM : ExtensionWithMArch<"f16f32mm", "F16F32MM", "FEAT_F16F32MM" // Armv9.8 Architecture Extensions //===----------------------------------------------------------------------===// +def FeatureCFLT : ExtensionWithMArch<"cflt", "CFLT", "FEAT_CFLT", + "Enable Armv9.8-A Conditional Fault instructions">; + //===----------------------------------------------------------------------===// // Future Architecture Technologies //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index fc603c2d59240f..ce6c98c29b7424 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -522,6 +522,45 @@ def uimm6m1_64b : Operand<i64> { let OperandType = "OPERAND_IMMEDIATE"; } +def uimm9 : Operand<i64> { + let ParserMatchClass = AsmImmRange<0, 511>; + let OperandType = "OPERAND_IMMEDIATE"; +} + +// TODO: Use AdjImmAsmOperand for the uimm6m1 and uimm6p1 operands too. +class AdjImmAsmOperand<string name, string diagnostic, int adjustment, + int low, int high> : AsmOperandClass { + let Name = name; + let DiagnosticType = diagnostic; + let RenderMethod = "addAdjImmOperands<" # adjustment # ">"; + let PredicateMethod = "isImmInRange<" # !sub(low, adjustment) # "," # + !sub(high, adjustment) # ">"; +} + +def uimm9p1 : Operand<i64> { + let ParserMatchClass = + AdjImmAsmOperand<"UImm9P1", "InvalidImm1_512", -1, 0, 511>; + let OperandType = "OPERAND_IMMEDIATE"; +} + +def uimm9m1 : Operand<i64> { + let ParserMatchClass = + AdjImmAsmOperand<"UImm9M1", "InvalidImmM1_510", 1, 0, 511>; + let OperandType = "OPERAND_IMMEDIATE"; +} + +def simm9p1 : Operand<i64> { + let ParserMatchClass = + AdjImmAsmOperand<"SImm9P1", "InvalidImmM255_256", -1, -256, 255>; + let OperandType = "OPERAND_IMMEDIATE"; +} + +def simm9m1 : Operand<i64> { + let ParserMatchClass = + AdjImmAsmOperand<"SImm9M1", "InvalidImmM257_254", 1, -256, 255>; + let OperandType = "OPERAND_IMMEDIATE"; +} + def SImm9Operand : SImmOperand<9>; def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { let ParserMatchClass = SImm9Operand; @@ -1124,6 +1163,7 @@ def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ return ((uint64_t)Imm) < 32; }]> { let ParserMatchClass = Imm0_31Operand; + let MCOperandPredicate = [{ return MCOp.isImm() && isUInt<5>(MCOp.getImm()); }]; } // timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) @@ -13658,3 +13698,99 @@ multiclass TEXIT<string asm> { def NAME : TEXITInst<asm>; def : InstAlias<asm, (!cast<Instruction>(NAME) 0), 1>; } + +//---------------------------------------------------------------------------- +// Conditional Fault instructions (FEAT_CFLT) +//---------------------------------------------------------------------------- + +class BaseCondFLT + : I<(outs), (ins ccode:$cond, uimm16:$imm), + "flt", ".$cond\t$imm", "", []>, Sched<[]> { + bits<4> cond; + bits<16> imm; + let Inst{31-21} = 0b11010100001; + let Inst{20-5} = imm; + let Inst{4} = 1; + let Inst{3-0} = cond; + + let Uses = [NZCV]; +} + +class BaseFLT<bit sf, dag iops, string asm, string operands> + : I<(outs), iops, asm, operands, "", []>, Sched<[]> { + bits<2> reason; + bits<5> Rt; + let Inst{31} = sf; + let Inst{30-24} = 0b1110110; + let Inst{15-12} = 0b0000; + let Inst{11-10} = reason; + let Inst{4-0} = Rt; +} + +class BaseCFLTImm<RegisterClass regtype, bit sf, Operand immtype, + bits<3> cc, string asm> + : BaseFLT<sf, (ins imm0_3:$reason, regtype:$Rt, immtype:$imm), + asm, "\t$reason, $Rt, $imm"> { + bits<9> imm; + let Inst{23-21} = cc; + let Inst{20-16} = imm{8-4}; + let Inst{9} = 0; + let Inst{8-5} = imm{3-0}; +} + +class BaseCFLTReg<RegisterClass regtype, bit sf, bits<3> cc, string asm> + : BaseFLT<sf, (ins imm0_3:$reason, regtype:$Rt, regtype:$Rm), + asm, "\t$reason, $Rt, $Rm"> { + bits<5> Rm; + let Inst{23-21} = cc; + let Inst{20-16} = Rm; + let Inst{9-5} = 0b10000; +} + +multiclass CFLTImm<bits<3> cc, string asm, Operand immtype> { + def Wi : BaseCFLTImm<GPR32, 0, immtype, cc, asm>; + def Xi : BaseCFLTImm<GPR64, 1, immtype, cc, asm>; +} + +multiclass CFLTReg<bits<3> cc, string asm> { + def Wr : BaseCFLTReg<GPR32sp, 0, cc, asm>; + def Xr : BaseCFLTReg<GPR64sp, 1, cc, asm>; +} + +multiclass CFLTRegAlias<string mnemonic, string inst> { + def : InstAlias<mnemonic # "\t$reason, $Rm, $Rt", + (!cast<Instruction>(inst # "Wr") imm0_3:$reason, + GPR32sp:$Rt, GPR32sp:$Rm), 0>; + def : InstAlias<mnemonic # "\t$reason, $Rm, $Rt", + (!cast<Instruction>(inst # "Xr") imm0_3:$reason, + GPR64sp:$Rt, GPR64sp:$Rm), 0>; +} + +multiclass CFLTImmAlias<string mnemonic, string inst, Operand immtype> { + def : InstAlias<mnemonic # "\t$reason, $Rt, $imm", + (!cast<Instruction>(inst # "Wi") imm0_3:$reason, + GPR32:$Rt, immtype:$imm), 0>; + def : InstAlias<mnemonic # "\t$reason, $Rt, $imm", + (!cast<Instruction>(inst # "Xi") imm0_3:$reason, + GPR64:$Rt, immtype:$imm), 0>; +} + +class BaseTFLT<RegisterClass regtype, Operand immtype, bit op, + string asm> + : BaseFLT<0, (ins imm0_3:$reason, regtype:$Rt, immtype:$bit_off), + asm, "\t$reason, $Rt, $bit_off"> { + bits<6> bit_off; + let Inst{31} = bit_off{5}; + let Inst{23-19} = bit_off{4-0}; + let Inst{18-16} = 0b000; + let Inst{9-6} = 0b1001; + let Inst{5} = op; +} + +multiclass TFLT<bit op, string asm> { + def NAME : BaseTFLT<GPR64, imm0_63, op, asm>; + + def : InstAlias<asm # "\t$reason, $Rt, $imm", + (!cast<Instruction>(NAME) imm0_3:$reason, + GPR64as32:$Rt, imm0_31:$imm), 1>; +} diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index a23250d4e1d4e6..16131190410e86 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -237,6 +237,8 @@ def HasF16F32DOT : Predicate<"Subtarget->hasF16F32DOT()">, AssemblerPredicateWithAll<(all_of FeatureF16F32DOT), "f16f32dot">; def HasF16F32MM : Predicate<"Subtarget->hasF16F32MM()">, AssemblerPredicateWithAll<(all_of FeatureF16F32MM), "f16f32mm">; +def HasCFLT : Predicate<"Subtarget->hasCFLT()">, + AssemblerPredicateWithAll<(all_of FeatureCFLT), "cflt">; // A subset of SVE(2) instructions are legal in Streaming SVE execution mode, // they should be enabled if either has been specified. @@ -12756,6 +12758,53 @@ let Predicates = [HasTEV] in { defm TEXIT : TEXIT<"texit">; } +//===-----------------------------------------------------===// +// Conditional Fault instructions (FEAT_CFLT) +//===-----------------------------------------------------===// +let Predicates = [HasCFLT] in { + def FLTcc : BaseCondFLT; + + defm CFLTEQ : CFLTReg<0b110, "cflteq">; + defm CFLTEQ : CFLTImm<0b100, "cflteq", simm9>; + + defm CFLTNE : CFLTReg<0b111, "cfltne">; + defm CFLTNE : CFLTImm<0b101, "cfltne", simm9>; + + defm CFLTGT : CFLTReg<0b000, "cfltgt">; + defm CFLTGT : CFLTImm<0b000, "cfltgt", simm9>; + + defm CFLTGE : CFLTReg<0b001, "cfltge">; + defm CFLTLT : CFLTImm<0b001, "cfltlt", simm9>; + + defm CFLTHI : CFLTReg<0b010, "cflthi">; + defm CFLTHI : CFLTImm<0b010, "cflthi", uimm9>; + + defm CFLTHS : CFLTReg<0b011, "cflths">; + defm CFLTLO : CFLTImm<0b011, "cfltlo", uimm9>; + + defm : CFLTImmAlias<"cfltge", "CFLTGT", simm9p1>; + defm : CFLTImmAlias<"cflths", "CFLTHI", uimm9p1>; + defm : CFLTImmAlias<"cfltle", "CFLTLT", simm9m1>; + defm : CFLTImmAlias<"cfltls", "CFLTLO", uimm9m1>; + + defm : CFLTRegAlias<"cfltle", "CFLTGE">; + defm : CFLTRegAlias<"cfltlo", "CFLTHI">; + defm : CFLTRegAlias<"cfltls", "CFLTHS">; + defm : CFLTRegAlias<"cfltlt", "CFLTGT">; + + def : InstAlias<"cfltnz\t$reason, $Rt", + (CFLTNEWi imm0_3:$reason, GPR32:$Rt, 0), 0>; + def : InstAlias<"cfltnz\t$reason, $Rt", + (CFLTNEXi imm0_3:$reason, GPR64:$Rt, 0), 0>; + def : InstAlias<"cfltz\t$reason, $Rt", + (CFLTEQWi imm0_3:$reason, GPR32:$Rt, 0), 0>; + def : InstAlias<"cfltz\t$reason, $Rt", + (CFLTEQXi imm0_3:$reason, GPR64:$Rt, 0), 0>; + + defm TFLTZ : TFLT<0, "tfltz">; + defm TFLTNZ : TFLT<1, "tfltnz">; +} + include "AArch64InstrAtomics.td" include "AArch64SVEInstrInfo.td" include "AArch64SMEInstrInfo.td" diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index b2928485d46add..4497f97e6f63e9 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1932,6 +1932,12 @@ class AArch64Operand : public MCParsedAsmOperand { addExpr(Inst, getImm()); } + template <int Adj> void addAdjImmOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + int64_t Imm = cast<MCConstantExpr>(getImm())->getValue(); + Inst.addOperand(MCOperand::createImm(Imm + Adj)); + } + template <int Shift> void addImmWithOptionalShiftOperands(MCInst &Inst, unsigned N) const { assert(N == 2 && "Invalid number of operands!"); @@ -3757,6 +3763,7 @@ constexpr EnumStringDef<FeatureBitset> ExtensionDefs[] = { {{"pauth-lr"}, {AArch64::FeaturePAuthLR}}, {{"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}}, {{"wfxt"}, {AArch64::FeatureWFxT}}, + {{"cflt"}, {AArch64::FeatureCFLT}}, }; constexpr auto ExtensionMap = BUILD_ENUM_STRINGS(ExtensionDefs); @@ -5309,8 +5316,9 @@ bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info, Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext())); Mnemonic = Head; - // Handle condition codes for a branch mnemonic - if ((Head == "b" || Head == "bc") && Next != StringRef::npos) { + // Handle condition codes for a branch or fault mnemonic. + if ((Head == "b" || Head == "bc" || Head == "flt") && + Next != StringRef::npos) { Start = Next; Next = Name.find('.', Start + 1); Head = Name.slice(Start + 1, Next); @@ -6091,6 +6099,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, return Error(Loc, "immediate must be an integer in range [0, 127]."); case Match_InvalidImm0_255: return Error(Loc, "immediate must be an integer in range [0, 255]."); + case Match_InvalidImm0_511: + return Error(Loc, "immediate must be an integer in range [0, 511]."); case Match_InvalidImm0_65535: return Error(Loc, "immediate must be an integer in range [0, 65535]."); case Match_InvalidHinteUImm16: @@ -6106,8 +6116,16 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, return Error(Loc, "immediate must be an integer in range [1, 32]."); case Match_InvalidImm1_64: return Error(Loc, "immediate must be an integer in range [1, 64]."); + case Match_InvalidImm1_512: + return Error(Loc, "immediate must be an integer in range [1, 512]."); case Match_InvalidImmM1_62: return Error(Loc, "immediate must be an integer in range [-1, 62]."); + case Match_InvalidImmM1_510: + return Error(Loc, "immediate must be an integer in range [-1, 510]."); + case Match_InvalidImmM255_256: + return Error(Loc, "immediate must be an integer in range [-255, 256]."); + case Match_InvalidImmM257_254: + return Error(Loc, "immediate must be an integer in range [-257, 254]."); case Match_InvalidMemoryIndexedRange2UImm0: return Error(Loc, "vector select offset must be the immediate range 0:1."); case Match_InvalidMemoryIndexedRange2UImm1: @@ -6879,13 +6897,18 @@ bool AArch64AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidImm0_63: case Match_InvalidImm0_127: case Match_InvalidImm0_255: + case Match_InvalidImm0_511: case Match_InvalidImm0_65535: case Match_InvalidHinteUImm16: case Match_InvalidImm1_8: case Match_InvalidImm1_16: case Match_InvalidImm1_32: case Match_InvalidImm1_64: + case Match_InvalidImm1_512: case Match_InvalidImmM1_62: + case Match_InvalidImmM1_510: + case Match_InvalidImmM255_256: + case Match_InvalidImmM257_254: case Match_InvalidMemoryIndexedRange2UImm0: case Match_InvalidMemoryIndexedRange2UImm1: case Match_InvalidMemoryIndexedRange2UImm2: @@ -7050,6 +7073,11 @@ bool AArch64AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_MRS: { if (ErrorInfo >= Operands.size()) return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc())); + // CFLT has both register and immediate forms. The matcher may select an + // immediate-form failure for an invalid register operand. + if (Tok.starts_with("cflt") && + static_cast<AArch64Operand &>(*Operands[ErrorInfo]).isScalarReg()) + MatchResult = Match_InvalidOperand; // Any time we get here, there's nothing fancy to do. Just get the // operand SMLoc and display the diagnostic. SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); diff --git a/llvm/test/MC/AArch64/armv9.8a-cflt-diagnostics.s b/llvm/test/MC/AArch64/armv9.8a-cflt-diagnostics.s new file mode 100644 index 00000000000000..b9c6683a99d226 --- /dev/null +++ b/llvm/test/MC/AArch64/armv9.8a-cflt-diagnostics.s @@ -0,0 +1,95 @@ +// RUN: not llvm-mc -triple=aarch64 -mattr=+cflt -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s + +flt.me #0 +// CHECK: [[@LINE-1]]:5: error: invalid condition code + +flt.eq #65536 +// CHECK: [[@LINE-1]]:8: error: immediate must be an integer in range [0, 65535]. + +cflteq #0, wsp, #0 +// CHECK: [[@LINE-1]]:17: error: invalid operand for instruction + +cflteq #0, sp, #0 +// CHECK: [[@LINE-1]]:16: error: invalid operand for instruction + +cflteq #4, w0, #1 +// CHECK: [[@LINE-1]]:8: error: immediate must be an integer in range [0, 3]. + +cfltgt #0, w0, #-257 +// CHECK: [[@LINE-1]]:16: error: index must be an integer in range [-256, 255]. + +cfltgt #0, w0, #256 +// CHECK: [[@LINE-1]]:16: error: index must be an integer in range [-256, 255]. + +cflthi #0, w0, #-1 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [0, 511]. + +cflthi #0, w0, #512 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [0, 511]. + +cfltge #0, w0, #-256 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [-255, 256]. + +cfltge #0, w0, #257 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [-255, 256]. + +cflths #0, w0, #0 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [1, 512]. + +cflths #0, w0, #513 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [1, 512]. + +cfltle #0, w0, #-258 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [-257, 254]. + +cfltle #0, w0, #255 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [-257, 254]. + +cfltls #0, w0, #-2 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [-1, 510]. + +cfltls #0, w0, #511 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [-1, 510]. + +cfltlo #0, w0, #-1 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [0, 511]. + +cfltlo #0, w0, #512 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [0, 511]. + +cflteq #0, wzr, w0 +// CHECK: [[@LINE-1]]:17: error: invalid operand for instruction + +cflteq #0, xzr, x0 +// CHECK: [[@LINE-1]]:17: error: invalid operand for instruction + +cflteq #0, w0, wzr +// CHECK: [[@LINE-1]]:16: error: invalid operand for instruction + +cflteq #0, x0, xzr +// CHECK: [[@LINE-1]]:16: error: invalid operand for instruction + +cfltz #0, wsp +// CHECK: [[@LINE-1]]:11: error: invalid operand for instruction + +cfltnz #0, sp +// CHECK: [[@LINE-1]]:12: error: invalid operand for instruction + +tfltz #4, w0, #0 +// CHECK: [[@LINE-1]]:7: error: immediate must be an integer in range [0, 3]. + +tfltz #0, w0, #32 +// CHECK: [[@LINE-1]]:15: error: immediate must be an integer in range [0, 31]. + +tfltz #0, w0, #-1 +// CHECK: [[@LINE-1]]:15: error: immediate must be an integer in range [0, 31]. + +tfltnz #4, x0, #32 +// CHECK: [[@LINE-1]]:8: error: immediate must be an integer in range [0, 3]. + +tfltnz #0, x0, #64 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [0, 63]. + +tfltnz #0, x0, #-1 +// CHECK: [[@LINE-1]]:16: error: immediate must be an integer in range [0, 63]. diff --git a/llvm/test/MC/AArch64/armv9.8a-cflt.s b/llvm/test/MC/AArch64/armv9.8a-cflt.s new file mode 100644 index 00000000000000..2a7ea280576f7e --- /dev/null +++ b/llvm/test/MC/AArch64/armv9.8a-cflt.s @@ -0,0 +1,341 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+cflt < %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=+cflt < %s \ +// RUN: | llvm-objdump -d --mattr=+cflt --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+cflt < %s \ +// RUN: | llvm-objdump -d --mattr=-cflt --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+cflt < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+cflt -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +//------------------------------------------------------------------------------ +// Conditional Fault instructions (FEAT_CFLT) +//------------------------------------------------------------------------------ + +flt.eq #0 +// CHECK-INST: flt.eq #0 +// CHECK-ENCODING: [0x10,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d4200010 +// CHECK-ERROR: error: instruction requires: cflt + +flt.ne #1 +// CHECK-INST: flt.ne #1 +// CHECK-ENCODING: [0x31,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d4200031 +// CHECK-ERROR: error: instruction requires: cflt + +flt.cs #2 +// CHECK-INST: flt.hs #2 +// CHECK-ENCODING: [0x52,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d4200052 +// CHECK-ERROR: error: instruction requires: cflt + +flt.hs #2 +// CHECK-INST: flt.hs #2 +// CHECK-ENCODING: [0x52,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d4200052 +// CHECK-ERROR: error: instruction requires: cflt + +flt.cc #3 +// CHECK-INST: flt.lo #3 +// CHECK-ENCODING: [0x73,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d4200073 +// CHECK-ERROR: error: instruction requires: cflt + +flt.lo #3 +// CHECK-INST: flt.lo #3 +// CHECK-ENCODING: [0x73,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d4200073 +// CHECK-ERROR: error: instruction requires: cflt + +flt.mi #4 +// CHECK-INST: flt.mi #4 +// CHECK-ENCODING: [0x94,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d4200094 +// CHECK-ERROR: error: instruction requires: cflt + +flt.pl #5 +// CHECK-INST: flt.pl #5 +// CHECK-ENCODING: [0xb5,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d42000b5 +// CHECK-ERROR: error: instruction requires: cflt + +flt.vs #6 +// CHECK-INST: flt.vs #6 +// CHECK-ENCODING: [0xd6,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d42000d6 +// CHECK-ERROR: error: instruction requires: cflt + +flt.vc #7 +// CHECK-INST: flt.vc #7 +// CHECK-ENCODING: [0xf7,0x00,0x20,0xd4] +// CHECK-UNKNOWN: d42000f7 +// CHECK-ERROR: error: instruction requires: cflt + +flt.hi #8 +// CHECK-INST: flt.hi #8 +// CHECK-ENCODING: [0x18,0x01,0x20,0xd4] +// CHECK-UNKNOWN: d4200118 +// CHECK-ERROR: error: instruction requires: cflt + +flt.ls #9 +// CHECK-INST: flt.ls #9 +// CHECK-ENCODING: [0x39,0x01,0x20,0xd4] +// CHECK-UNKNOWN: d4200139 +// CHECK-ERROR: error: instruction requires: cflt + +flt.ge #10 +// CHECK-INST: flt.ge #10 +// CHECK-ENCODING: [0x5a,0x01,0x20,0xd4] +// CHECK-UNKNOWN: d420015a +// CHECK-ERROR: error: instruction requires: cflt + +flt.lt #11 +// CHECK-INST: flt.lt #11 +// CHECK-ENCODING: [0x7b,0x01,0x20,0xd4] +// CHECK-UNKNOWN: d420017b +// CHECK-ERROR: error: instruction requires: cflt + +flt.gt #12 +// CHECK-INST: flt.gt #12 +// CHECK-ENCODING: [0x9c,0x01,0x20,0xd4] +// CHECK-UNKNOWN: d420019c +// CHECK-ERROR: error: instruction requires: cflt + +flt.le #13 +// CHECK-INST: flt.le #13 +// CHECK-ENCODING: [0xbd,0x01,0x20,0xd4] +// CHECK-UNKNOWN: d42001bd +// CHECK-ERROR: error: instruction requires: cflt + +flt.al #65535 +// CHECK-INST: flt.al #65535 +// CHECK-ENCODING: [0xfe,0xff,0x3f,0xd4] +// CHECK-UNKNOWN: d43ffffe +// CHECK-ERROR: error: instruction requires: cflt + +flt.nv #15 +// CHECK-INST: flt.nv #15 +// CHECK-ENCODING: [0xff,0x01,0x20,0xd4] +// CHECK-UNKNOWN: d42001ff +// CHECK-ERROR: error: instruction requires: cflt + +// CFLT<cc> (immediate). + +cflteq #0, w0, #1 +// CHECK-INST: cflteq #0, w0, #1 +// CHECK-ENCODING: [0x20,0x00,0x80,0x76] +// CHECK-UNKNOWN: 76800020 +// CHECK-ERROR: error: instruction requires: cflt + +cfltne #3, x3, #-1 +// CHECK-INST: cfltne #3, x3, #-1 +// CHECK-ENCODING: [0xe3,0x0d,0xbf,0xf6] +// CHECK-UNKNOWN: f6bf0de3 +// CHECK-ERROR: error: instruction requires: cflt + +cfltgt #0, w4, #-256 +// CHECK-INST: cfltgt #0, w4, #-256 +// CHECK-ENCODING: [0x04,0x00,0x10,0x76] +// CHECK-UNKNOWN: 76100004 +// CHECK-ERROR: error: instruction requires: cflt + +cfltlt #3, x7, #0 +// CHECK-INST: cfltlt #3, x7, #0 +// CHECK-ENCODING: [0x07,0x0c,0x20,0xf6] +// CHECK-UNKNOWN: f6200c07 +// CHECK-ERROR: error: instruction requires: cflt + +cflthi #1, x9, #511 +// CHECK-INST: cflthi #1, x9, #511 +// CHECK-ENCODING: [0xe9,0x05,0x5f,0xf6] +// CHECK-UNKNOWN: f65f05e9 +// CHECK-ERROR: error: instruction requires: cflt + +cfltlo #2, w10, #1 +// CHECK-INST: cfltlo #2, w10, #1 +// CHECK-ENCODING: [0x2a,0x08,0x60,0x76] +// CHECK-UNKNOWN: 7660082a +// CHECK-ERROR: error: instruction requires: cflt + +// CFLT<cc> (immediate) aliases. + +cfltge #0, x0, #(2 - 1) +// CHECK-INST: cfltgt #0, x0, #0 +// CHECK-ENCODING: [0x00,0x00,0x00,0xf6] +// CHECK-UNKNOWN: f6000000 +// CHECK-ERROR: error: instruction requires: cflt + +cfltge #1, x13, #256 +// CHECK-INST: cfltgt #1, x13, #255 +// CHECK-ENCODING: [0xed,0x05,0x0f,0xf6] +// CHECK-UNKNOWN: f60f05ed +// CHECK-ERROR: error: instruction requires: cflt + +cflths #2, w14, #1 +// CHECK-INST: cflthi #2, w14, #0 +// CHECK-ENCODING: [0x0e,0x08,0x40,0x76] +// CHECK-UNKNOWN: 7640080e +// CHECK-ERROR: error: instruction requires: cflt + +cflths #2, w14, #+1 +// CHECK-INST: cflthi #2, w14, #0 +// CHECK-ENCODING: [0x0e,0x08,0x40,0x76] +// CHECK-UNKNOWN: 7640080e +// CHECK-ERROR: error: instruction requires: cflt + +cfltle #0, w16, #-257 +// CHECK-INST: cfltlt #0, w16, #-256 +// CHECK-ENCODING: [0x10,0x00,0x30,0x76] +// CHECK-UNKNOWN: 76300010 +// CHECK-ERROR: error: instruction requires: cflt + +cfltle #0, w16, #(-257) +// CHECK-INST: cfltlt #0, w16, #-256 +// CHECK-ENCODING: [0x10,0x00,0x30,0x76] +// CHECK-UNKNOWN: 76300010 +// CHECK-ERROR: error: instruction requires: cflt + +cfltls #3, x19, #510 +// CHECK-INST: cfltlo #3, x19, #511 +// CHECK-ENCODING: [0xf3,0x0d,0x7f,0xf6] +// CHECK-UNKNOWN: f67f0df3 +// CHECK-ERROR: error: instruction requires: cflt + +// CFLT<cc> (register). + +cflteq #0, w0, wsp +// CHECK-INST: cflteq #0, w0, wsp +// CHECK-ENCODING: [0x00,0x02,0xdf,0x76] +// CHECK-UNKNOWN: 76df0200 +// CHECK-ERROR: error: instruction requires: cflt + +cfltne #3, x3, x4 +// CHECK-INST: cfltne #3, x3, x4 +// CHECK-ENCODING: [0x03,0x0e,0xe4,0xf6] +// CHECK-UNKNOWN: f6e40e03 +// CHECK-ERROR: error: instruction requires: cflt + +cfltgt #0, w4, w5 +// CHECK-INST: cfltgt #0, w4, w5 +// CHECK-ENCODING: [0x04,0x02,0x05,0x76] +// CHECK-UNKNOWN: 76050204 +// CHECK-ERROR: error: instruction requires: cflt + +cfltge #3, x7, x8 +// CHECK-INST: cfltge #3, x7, x8 +// CHECK-ENCODING: [0x07,0x0e,0x28,0xf6] +// CHECK-UNKNOWN: f6280e07 +// CHECK-ERROR: error: instruction requires: cflt + +cflthi #0, w8, w9 +// CHECK-INST: cflthi #0, w8, w9 +// CHECK-ENCODING: [0x08,0x02,0x49,0x76] +// CHECK-UNKNOWN: 76490208 +// CHECK-ERROR: error: instruction requires: cflt + +cflths #3, x11, x12 +// CHECK-INST: cflths #3, x11, x12 +// CHECK-ENCODING: [0x0b,0x0e,0x6c,0xf6] +// CHECK-UNKNOWN: f66c0e0b +// CHECK-ERROR: error: instruction requires: cflt + +// CFLT<cc> (register) aliases. + +cfltle #0, w13, w14 +// CHECK-INST: cfltge #0, w14, w13 +// CHECK-ENCODING: [0x0e,0x02,0x2d,0x76] +// CHECK-UNKNOWN: 762d020e +// CHECK-ERROR: error: instruction requires: cflt + +cfltlo #3, x16, x17 +// CHECK-INST: cflthi #3, x17, x16 +// CHECK-ENCODING: [0x11,0x0e,0x50,0xf6] +// CHECK-UNKNOWN: f6500e11 +// CHECK-ERROR: error: instruction requires: cflt + +cfltls #0, w17, w18 +// CHECK-INST: cflths #0, w18, w17 +// CHECK-ENCODING: [0x12,0x02,0x71,0x76] +// CHECK-UNKNOWN: 76710212 +// CHECK-ERROR: error: instruction requires: cflt + +cfltlt #3, x20, x21 +// CHECK-INST: cfltgt #3, x21, x20 +// CHECK-ENCODING: [0x15,0x0e,0x14,0xf6] +// CHECK-UNKNOWN: f6140e15 +// CHECK-ERROR: error: instruction requires: cflt + +// CFLTZ and CFLTNZ. + +cfltz #0, w21 +// CHECK-INST: cflteq #0, w21, #0 +// CHECK-ENCODING: [0x15,0x00,0x80,0x76] +// CHECK-UNKNOWN: 76800015 +// CHECK-ERROR: error: instruction requires: cflt + +cfltnz #3, x24 +// CHECK-INST: cfltne #3, x24, #0 +// CHECK-ENCODING: [0x18,0x0c,0xa0,0xf6] +// CHECK-UNKNOWN: f6a00c18 +// CHECK-ERROR: error: instruction requires: cflt + +cfltnz #3, xzr +// CHECK-INST: cfltne #3, xzr, #0 +// CHECK-ENCODING: [0x1f,0x0c,0xa0,0xf6] +// CHECK-UNKNOWN: f6a00c1f +// CHECK-ERROR: error: instruction requires: cflt + +// TFLTZ and TFLTNZ. + +tfltz #0, w0, #0 +// CHECK-INST: tfltz #0, w0, #0 +// CHECK-ENCODING: [0x40,0x02,0x00,0x76] +// CHECK-UNKNOWN: 76000240 +// CHECK-ERROR: error: instruction requires: cflt + +tfltz #0, x0, #0 +// CHECK-INST: tfltz #0, w0, #0 +// CHECK-ENCODING: [0x40,0x02,0x00,0x76] +// CHECK-UNKNOWN: 76000240 +// CHECK-ERROR: error: instruction requires: cflt + +tfltz #1, x1, #32 +// CHECK-INST: tfltz #1, x1, #32 +// CHECK-ENCODING: [0x41,0x06,0x00,0xf6] +// CHECK-UNKNOWN: f6000641 +// CHECK-ERROR: error: instruction requires: cflt + +tfltz #3, wzr, #31 +// CHECK-INST: tfltz #3, wzr, #31 +// CHECK-ENCODING: [0x5f,0x0e,0xf8,0x76] +// CHECK-UNKNOWN: 76f80e5f +// CHECK-ERROR: error: instruction requires: cflt + +tfltnz #2, w3, #31 +// CHECK-INST: tfltnz #2, w3, #31 +// CHECK-ENCODING: [0x63,0x0a,0xf8,0x76] +// CHECK-UNKNOWN: 76f80a63 +// CHECK-ERROR: error: instruction requires: cflt + +tfltnz #3, xzr, #31 +// CHECK-INST: tfltnz #3, wzr, #31 +// CHECK-ENCODING: [0x7f,0x0e,0xf8,0x76] +// CHECK-UNKNOWN: 76f80e7f +// CHECK-ERROR: error: instruction requires: cflt + +tfltnz #3, xzr, #32 +// CHECK-INST: tfltnz #3, xzr, #32 +// CHECK-ENCODING: [0x7f,0x0e,0x00,0xf6] +// CHECK-UNKNOWN: f6000e7f +// CHECK-ERROR: error: instruction requires: cflt + +tfltnz #3, x4, #63 +// CHECK-INST: tfltnz #3, x4, #63 +// CHECK-ENCODING: [0x64,0x0e,0xf8,0xf6] +// CHECK-UNKNOWN: f6f80e64 +// CHECK-ERROR: error: instruction requires: cflt diff --git a/llvm/test/MC/AArch64/directive-arch-negative.s b/llvm/test/MC/AArch64/directive-arch-negative.s index 4c17c560971203..2e7bed1ef2692e 100644 --- a/llvm/test/MC/AArch64/directive-arch-negative.s +++ b/llvm/test/MC/AArch64/directive-arch-negative.s @@ -79,3 +79,9 @@ # CHECK: error: instruction requires: f8f32mm # CHECK-NEXT: fmmla v0.4s, v1.16b, v2.16b + + .arch armv9-a+cflt+nocflt + cfltz #1, w0 + +# CHECK: error: instruction requires: cflt +# CHECK-NEXT: cfltz #1, w0 diff --git a/llvm/test/MC/AArch64/directive-arch.s b/llvm/test/MC/AArch64/directive-arch.s index ba605cc5d1a698..cd68b6651448f0 100644 --- a/llvm/test/MC/AArch64/directive-arch.s +++ b/llvm/test/MC/AArch64/directive-arch.s @@ -38,3 +38,7 @@ .arch armv9-a+f8f32mm fmmla v0.4s, v1.16b, v2.16b # CHECK: fmmla v0.4s, v1.16b, v2.16b + + .arch armv9-a+cflt + cfltz #1, w0 +# CHECK: cflteq #1, w0, #0 diff --git a/llvm/test/MC/AArch64/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/directive-arch_extension-negative.s index 0f01d899151534..7d6f608ea47cda 100644 --- a/llvm/test/MC/AArch64/directive-arch_extension-negative.s +++ b/llvm/test/MC/AArch64/directive-arch_extension-negative.s @@ -250,3 +250,9 @@ fmmla v2.8h, v1.16b, v0.16b fmmla v2.4s, v1.16b, v0.16b // CHECK: [[@LINE-1]]:1: error: instruction requires: f8f32mm // CHECK-NEXT: fmmla v2.4s, v1.16b, v0.16b + +.arch_extension cflt +.arch_extension nocflt +cfltz #1, w0 +// CHECK: [[@LINE-1]]:1: error: instruction requires: cflt +// CHECK-NEXT: cfltz #1, w0 diff --git a/llvm/test/MC/AArch64/directive-arch_extension.s b/llvm/test/MC/AArch64/directive-arch_extension.s index f3377fd80c276e..6f4274f0e0edfd 100644 --- a/llvm/test/MC/AArch64/directive-arch_extension.s +++ b/llvm/test/MC/AArch64/directive-arch_extension.s @@ -228,3 +228,7 @@ fcmla v0.4s, v1.4s, v2.4s, #0 .arch_extension bti bti c // CHECK: bti c + +.arch_extension cflt +cfltz #1, w0 +// CHECK: cflteq #1, w0, #0 diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 95661bf4a007ea..fa6bf6cb9d0966 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -1508,6 +1508,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { AArch64::AEK_BTIE, AArch64::AEK_F64MM, AArch64::AEK_POPS, AArch64::AEK_SVESM4, AArch64::AEK_MTETC, AArch64::AEK_HINTE, + AArch64::AEK_CFLT, }; std::vector<StringRef> Features; @@ -1632,6 +1633,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { EXPECT_TRUE(llvm::is_contained(Features, "+tev")); EXPECT_TRUE(llvm::is_contained(Features, "+btie")); EXPECT_TRUE(llvm::is_contained(Features, "+hinte")); + EXPECT_TRUE(llvm::is_contained(Features, "+cflt")); // Assuming we listed every extension above, this should produce the same // result. @@ -1813,6 +1815,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { {"tev", "notev", "+tev", "-tev"}, {"btie", "nobtie", "+btie", "-btie"}, {"hinte", "nohinte", "+hinte", "-hinte"}, + {"cflt", "nocflt", "+cflt", "-cflt"}, }; for (unsigned i = 0; i < std::size(ArchExt); i++) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
