diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -42,6 +42,7 @@ // CHECK-NOT: __riscv_svnapot // CHECK-NOT: __riscv_svinval // CHECK-NOT: __riscv_xventanacondops +// CHECK-NOT: __riscv_zcf // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32im -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-M-EXT %s @@ -437,3 +438,7 @@ // RUN: %clang -target riscv64 -march=rv64ixventanacondops -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-XVENTANACONDOPS-EXT %s // CHECK-XVENTANACONDOPS-EXT: __riscv_xventanacondops 1000000{{$}} + +// RUN: %clang -target riscv32 -march=rv32izcf0p70 -menable-experimental-extensions \ +// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCF-EXT %s +// CHECK-ZCF-EXT: __riscv_zcf 70000{{$}} diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -111,6 +111,7 @@ {"zihintntl", RISCVExtensionVersion{0, 2}}, {"zca", RISCVExtensionVersion{0, 70}}, + {"zcf", RISCVExtensionVersion{0, 70}}, {"zvfh", RISCVExtensionVersion{0, 1}}, {"zawrs", RISCVExtensionVersion{1, 0}}, {"ztso", RISCVExtensionVersion{0, 1}}, diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -292,6 +292,16 @@ "'Zca' (part of the C extension, excluding " "compressed floating point loads/stores)">; +def FeatureExtZcf + : SubtargetFeature<"experimental-zcf", "HasStdExtZcf", "true", + "'Zcf' (Compressed Single-Precision Floating-Point Instructions)">; + +def HasStdExtCOrZcf + : Predicate<"Subtarget->hasStdExtC() || Subtarget->hasStdExtZcf()">, + AssemblerPredicate<(any_of FeatureStdExtC, FeatureExtZcf), + "'C' (Compressed Instructions) or " + "'Zcf' (Compressed Single-Precision Floating-Point Instructions)">; + def FeatureNoRVCHints : SubtargetFeature<"no-rvc-hints", "EnableRVCHintInstrs", "false", "Disable RVC Hint Instructions.">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -328,7 +328,7 @@ } let DecoderNamespace = "RISCV32Only_", - Predicates = [HasStdExtC, HasStdExtF, IsRV32] in + Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>, Sched<[WriteFLD32, ReadMemBase]> { bits<7> imm; @@ -362,7 +362,7 @@ } let DecoderNamespace = "RISCV32Only_", - Predicates = [HasStdExtC, HasStdExtF, IsRV32] in + Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>, Sched<[WriteFST32, ReadStoreData, ReadMemBase]> { bits<7> imm; @@ -515,7 +515,7 @@ } let DecoderNamespace = "RISCV32Only_", - Predicates = [HasStdExtC, HasStdExtF, IsRV32] in + Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>, Sched<[WriteFLD32, ReadMemBase]> { let Inst{6-4} = imm{4-2}; @@ -575,7 +575,7 @@ } let DecoderNamespace = "RISCV32Only_", - Predicates = [HasStdExtC, HasStdExtF, IsRV32] in + Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>, Sched<[WriteFST32, ReadStoreData, ReadMemBase]> { let Inst{12-9} = imm{5-2}; @@ -733,7 +733,7 @@ def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SPMem:$rs1, 0)>; } -let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { +let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in { def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRCMem:$rs1, 0)>; def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRCMem:$rs1, 0)>; def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SPMem:$rs1, 0)>; @@ -771,7 +771,7 @@ (C_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>; } // Predicates = [HasStdExtCOrZca] -let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { +let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in { def : CompressPat<(FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm), (C_FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>; } // Predicates = [HasStdExtC, HasStdExtF, IsRV32] @@ -791,7 +791,7 @@ (C_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>; } // Predicates = [HasStdExtCOrZca] -let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { +let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in { def : CompressPat<(FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm), (C_FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>; } // Predicates = [HasStdExtC, HasStdExtF, IsRV32] @@ -888,7 +888,7 @@ (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>; } // Predicates = [HasStdExtCOrZca] -let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { +let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in { def : CompressPat<(FLW FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm), (C_FLWSP FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>; } // Predicates = [HasStdExtC, HasStdExtF, IsRV32] @@ -930,7 +930,7 @@ (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>; } // Predicates = [HasStdExtCOrZca] -let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in { +let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in { def : CompressPat<(FSW FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm), (C_FSWSP FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>; } // Predicates = [HasStdExtC, HasStdExtF, IsRV32] diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -56,6 +56,7 @@ bool HasStdExtZbc = false; bool HasStdExtZbs = false; bool HasStdExtZca = false; + bool HasStdExtZcf = false; bool HasStdExtV = false; bool HasStdExtZve32x = false; bool HasStdExtZve32f = false; @@ -167,6 +168,7 @@ bool hasStdExtZbc() const { return HasStdExtZbc; } bool hasStdExtZbs() const { return HasStdExtZbs; } bool hasStdExtZca() const { return HasStdExtZca; } + bool hasStdExtZcf() const { return HasStdExtZcf; } bool hasStdExtZvl() const { return ZvlLen != 0; } bool hasStdExtZvfh() const { return HasStdExtZvfh; } bool hasStdExtZfhmin() const { return HasStdExtZfhmin; } diff --git a/llvm/test/MC/RISCV/compress-rv32f.s b/llvm/test/MC/RISCV/compress-rv32f.s --- a/llvm/test/MC/RISCV/compress-rv32f.s +++ b/llvm/test/MC/RISCV/compress-rv32f.s @@ -8,6 +8,16 @@ # RUN: llvm-mc -triple riscv32 -mattr=+c,+f -filetype=obj < %s \ # RUN: | llvm-objdump --triple=riscv32 --mattr=+c,+f -d -M no-aliases - \ # RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-INST %s +# RUN: llvm-mc -triple riscv32 -mattr=+experimental-zcf,+f -show-encoding < %s \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-ALIAS %s +# RUN: llvm-mc -triple riscv32 -mattr=+experimental-zcf,+f -show-encoding \ +# RUN: -riscv-no-aliases < %s | FileCheck -check-prefixes=CHECK,CHECK-INST %s +# RUN: llvm-mc -triple riscv32 -mattr=+experimental-zcf,+f -filetype=obj < %s \ +# RUN: | llvm-objdump --triple=riscv32 --mattr=+experimental-zcf,+f -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-ALIAS %s +# RUN: llvm-mc -triple riscv32 -mattr=+experimental-zcf,+f -filetype=obj < %s \ +# RUN: | llvm-objdump --triple=riscv32 --mattr=+experimental-zcf,+f -d -M no-aliases - \ +# RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-INST %s # Instructions that are 32 bit only. flw ft0, 124(sp) diff --git a/llvm/test/MC/RISCV/rv32fc-valid.s b/llvm/test/MC/RISCV/rv32fc-valid.s --- a/llvm/test/MC/RISCV/rv32fc-valid.s +++ b/llvm/test/MC/RISCV/rv32fc-valid.s @@ -3,41 +3,52 @@ # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+c,+f < %s \ # RUN: | llvm-objdump --mattr=+c,+f -M no-aliases -d -r - \ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zcf,+f -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zcf,+f < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zcf,+f -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s # # RUN: not llvm-mc -triple riscv32 -mattr=+c \ # RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ # RUN: | FileCheck -check-prefixes=CHECK-NO-EXT-F %s +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zcf \ +# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK-NO-EXT-F %s # RUN: not llvm-mc -triple riscv32 \ # RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ # RUN: | FileCheck -check-prefixes=CHECK-NO-EXT-FC %s # RUN: not llvm-mc -triple riscv64 -mattr=+c,+f \ # RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ # RUN: | FileCheck -check-prefixes=CHECK-NO-RV32 %s +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zcf,+f \ +# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK-NO-RV32 %s # FIXME: error messages for rv64fc are misleading # CHECK-ASM-AND-OBJ: c.flwsp fs0, 252(sp) # CHECK-ASM: encoding: [0x7e,0x74] # CHECK-NO-EXT-F: error: instruction requires the following: 'F' (Single-Precision Floating-Point){{$}} -# CHECK-NO-EXT-FC: error: instruction requires the following: 'C' (Compressed Instructions), 'F' (Single-Precision Floating-Point){{$}} +# CHECK-NO-EXT-FC: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zcf' (Compressed Single-Precision Floating-Point Instructions), 'F' (Single-Precision Floating-Point){{$}} # CHECK-NO-RV32: error: instruction requires the following: RV32I Base Instruction Set{{$}} c.flwsp fs0, 252(sp) # CHECK-ASM-AND-OBJ: c.fswsp fa7, 252(sp) # CHECK-ASM: encoding: [0xc6,0xff] # CHECK-NO-EXT-F: error: instruction requires the following: 'F' (Single-Precision Floating-Point){{$}} -# CHECK-NO-EXT-FC: error: instruction requires the following: 'C' (Compressed Instructions), 'F' (Single-Precision Floating-Point){{$}} +# CHECK-NO-EXT-FC: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zcf' (Compressed Single-Precision Floating-Point Instructions), 'F' (Single-Precision Floating-Point){{$}} # CHECK-NO-RV32: error: instruction requires the following: RV32I Base Instruction Set{{$}} c.fswsp fa7, 252(sp) # CHECK-ASM-AND-OBJ: c.flw fa3, 124(a5) # CHECK-ASM: encoding: [0xf4,0x7f] # CHECK-NO-EXT-F: error: instruction requires the following: 'F' (Single-Precision Floating-Point){{$}} -# CHECK-NO-EXT-FC: error: instruction requires the following: 'C' (Compressed Instructions), 'F' (Single-Precision Floating-Point){{$}} +# CHECK-NO-EXT-FC: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zcf' (Compressed Single-Precision Floating-Point Instructions), 'F' (Single-Precision Floating-Point){{$}} # CHECK-NO-RV32: error: instruction requires the following: RV32I Base Instruction Set{{$}} c.flw fa3, 124(a5) # CHECK-ASM-AND-OBJ: c.fsw fa2, 124(a1) # CHECK-ASM: encoding: [0xf0,0xfd] # CHECK-NO-EXT-F: error: instruction requires the following: 'F' (Single-Precision Floating-Point){{$}} -# CHECK-NO-EXT-FC: error: instruction requires the following: 'C' (Compressed Instructions), 'F' (Single-Precision Floating-Point){{$}} +# CHECK-NO-EXT-FC: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zcf' (Compressed Single-Precision Floating-Point Instructions), 'F' (Single-Precision Floating-Point){{$}} # CHECK-NO-RV32: error: instruction requires the following: RV32I Base Instruction Set{{$}} c.fsw fa2, 124(a1)