Skip to content

Commit

Permalink
Add MC support of RISCV Zcf Extension
Browse files Browse the repository at this point in the history
This patch add the instructions of Zcf extension.

Zcf is a subset of C Ext which include the single-precision floating-point instructions.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D134176
  • Loading branch information
Xinlong-Wu committed Nov 23, 2022
1 parent b264787 commit 16bf359
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 13 deletions.
5 changes: 5 additions & 0 deletions clang/test/Preprocessor/riscv-target-features.c
Expand Up @@ -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
Expand Down Expand Up @@ -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{{$}}
1 change: 1 addition & 0 deletions llvm/lib/Support/RISCVISAInfo.cpp
Expand Up @@ -111,6 +111,7 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"zihintntl", RISCVExtensionVersion{0, 2}},

{"zca", RISCVExtensionVersion{0, 70}},
{"zcf", RISCVExtensionVersion{0, 70}},
{"zvfh", RISCVExtensionVersion{0, 1}},
{"zawrs", RISCVExtensionVersion{1, 0}},
{"ztso", RISCVExtensionVersion{0, 1}},
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.td
Expand Up @@ -292,6 +292,16 @@ def HasStdExtCOrZca
"'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.">;
Expand Down
18 changes: 9 additions & 9 deletions llvm/lib/Target/RISCV/RISCVInstrInfoC.td
Expand Up @@ -328,7 +328,7 @@ def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>,
}

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;
Expand Down Expand Up @@ -362,7 +362,7 @@ def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>,
}

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;
Expand Down Expand Up @@ -515,7 +515,7 @@ def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>,
}

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};
Expand Down Expand Up @@ -575,7 +575,7 @@ def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>,
}

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};
Expand Down Expand Up @@ -733,7 +733,7 @@ def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SPMem:$rs1, 0)>;
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)>;
Expand Down Expand Up @@ -771,7 +771,7 @@ def : CompressPat<(LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
(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]
Expand All @@ -791,7 +791,7 @@ def : CompressPat<(SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
(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]
Expand Down Expand Up @@ -888,7 +888,7 @@ def : CompressPat<(LW GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
(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]
Expand Down Expand Up @@ -930,7 +930,7 @@ def : CompressPat<(SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
(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]
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/RISCVSubtarget.h
Expand Up @@ -56,6 +56,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
bool HasStdExtZbc = false;
bool HasStdExtZbs = false;
bool HasStdExtZca = false;
bool HasStdExtZcf = false;
bool HasStdExtV = false;
bool HasStdExtZve32x = false;
bool HasStdExtZve32f = false;
Expand Down Expand Up @@ -167,6 +168,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
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; }
Expand Down
10 changes: 10 additions & 0 deletions llvm/test/MC/RISCV/compress-rv32f.s
Expand Up @@ -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)
Expand Down
19 changes: 15 additions & 4 deletions llvm/test/MC/RISCV/rv32fc-valid.s
Expand Up @@ -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)

0 comments on commit 16bf359

Please sign in to comment.