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 @@ -48,6 +48,7 @@ // CHECK-NOT: __riscv_zcb // CHECK-NOT: __riscv_zcd // CHECK-NOT: __riscv_zcf +// CHECK-NOT: __riscv_zcmt // CHECK-NOT: __riscv_h // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32im -x c -E -dM %s \ @@ -488,3 +489,10 @@ // RUN: %clang -target riscv32 -march=rv32izcf1p0 -menable-experimental-extensions \ // RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCF-EXT %s // CHECK-ZCF-EXT: __riscv_zcf 1000000{{$}} + +// RUN: %clang -target riscv32 -march=rv32izcmt1p0 -menable-experimental-extensions \ +// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCMT-EXT %s +// RUN: %clang -target riscv64 -march=rv64izcmt1p0 -menable-experimental-extensions \ +// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCMT-EXT %s +// CHECK-ZCMT-EXT: __riscv_zca 1000000{{$}} +// CHECK-ZCMT-EXT: __riscv_zcmt 1000000{{$}} diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -401,7 +401,7 @@ template void copyShtGroup(uint8_t *buf); }; -static_assert(sizeof(InputSection) <= 152, "InputSection is too big"); +static_assert(sizeof(InputSection) <= 160, "InputSection is too big"); class SyntheticSection : public InputSection { public: diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -154,6 +154,9 @@ ``experimental-zcf`` LLVM implements the `1.0.1 draft specification `_. +``experimental-zcmt`` + LLVM implements the `1.0.1 draft specification `_. + ``experimental-zihintntl`` LLVM implements the `0.2 draft specification `_. 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 @@ -123,6 +123,7 @@ {"zcb", RISCVExtensionVersion{1, 0}}, {"zcd", RISCVExtensionVersion{1, 0}}, {"zcf", RISCVExtensionVersion{1, 0}}, + {"zcmt", RISCVExtensionVersion{1, 0}}, {"zvfh", RISCVExtensionVersion{0, 1}}, {"zawrs", RISCVExtensionVersion{1, 0}}, {"ztso", RISCVExtensionVersion{0, 1}}, @@ -752,6 +753,7 @@ Error RISCVISAInfo::checkDependency() { bool IsRv32 = XLen == 32; + bool HasC = Exts.count("c") != 0; bool HasE = Exts.count("e") != 0; bool HasD = Exts.count("d") != 0; bool HasF = Exts.count("f") != 0; @@ -761,6 +763,7 @@ bool HasZve32f = Exts.count("zve32f") != 0; bool HasZve64d = Exts.count("zve64d") != 0; bool HasZvl = MinVLen != 0; + bool HasZcmt = Exts.count("zcmt") != 0; if (HasE && !IsRv32) return createStringError( @@ -797,6 +800,10 @@ errc::invalid_argument, "zvl*b requires v or zve* extension to also be specified"); + if (HasZcmt && HasC) + return createStringError(errc::invalid_argument, + "zcmt is not allowed when c is specified"); + // Additional dependency checks. // TODO: The 'q' extension requires rv64. // TODO: It is illegal to specify 'e' extensions with 'f' and 'd'. @@ -833,6 +840,7 @@ static const char *ImpliedExtsZvfh[] = {"zve32f"}; static const char *ImpliedExtsXTHeadVdot[] = {"v"}; static const char *ImpliedExtsZcb[] = {"zca"}; +static const char *ImpliedExtsZcmt[] = {"zca"}; struct ImpliedExtsEntry { StringLiteral Name; @@ -850,6 +858,7 @@ {{"v"}, {ImpliedExtsV}}, {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}}, {{"zcb"}, {ImpliedExtsZcb}}, + {{"zcmt"}, {ImpliedExtsZcmt}}, {{"zdinx"}, {ImpliedExtsZdinx}}, {{"zfh"}, {ImpliedExtsZfh}}, {{"zfhmin"}, {ImpliedExtsZfhmin}}, diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -546,6 +546,7 @@ bool isUImm3() { return IsUImm<3>(); } bool isUImm5() { return IsUImm<5>(); } bool isUImm7() { return IsUImm<7>(); } + bool isUImm8() { return IsUImm<8>(); } bool isRnumArg() const { int64_t Imm; @@ -1176,6 +1177,8 @@ return generateImmOutOfRangeError( Operands, ErrorInfo, 0, (1 << 7) - 4, "immediate must be a multiple of 4 bytes in the range"); + case Match_InvalidUImm8: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); case Match_InvalidUImm8Lsb00: return generateImmOutOfRangeError( Operands, ErrorInfo, 0, (1 << 8) - 4, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -327,6 +327,14 @@ "'C' (Compressed Instructions) or " "'Zcf' (Compressed Single-Precision Floating-Point Instructions)">; +def FeatureExtZcmt + : SubtargetFeature<"experimental-zcmt", "HasStdExtZcmt", "true", + "'Zcmt' (table jump instuctions for code-size reduction)", + [FeatureExtZca]>; // TODO: add Zicsr as another dependence +def HasStdExtZcmt : Predicate<"Subtarget->hasStdExtZcmt() && !Subtarget->hasStdExtC()">, + AssemblerPredicate<(all_of FeatureExtZcmt, (not FeatureStdExtC)), + "'Zcmt' (table jump instuctions for code-size reduction)">; + def FeatureNoRVCHints : SubtargetFeature<"no-rvc-hints", "EnableRVCHintInstrs", "false", "Disable RVC Hint Instructions.">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td @@ -32,6 +32,19 @@ }]; } +def uimm8 : Operand, + ImmLeaf(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<8>; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeUImmOperand<8>"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return MCOp.isBareSymbolRef(); + }]; +} + //===----------------------------------------------------------------------===// // Instruction Class Templates //===----------------------------------------------------------------------===// @@ -116,6 +129,26 @@ } } +let Predicates = [HasStdExtZcmt], +hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +def CM_JT : RVInst16CJ<0b101, 0b10, (outs), (ins uimm5:$index), + "cm.jt", "$index">{ + bits<5> index; + + let Inst{12-7} = 0b000000; + let Inst{6-2} = index; +} + +def CM_JALT : RVInst16CJ<0b101, 0b10, (outs), (ins uimm8:$index), + "cm.jalt", "$index">{ + bits<8> index; + + let Inst{12-10} = 0b000; + let Inst{9-2} = index; +} +} // Predicates = [HasStdExtZcmt] + + let Predicates = [HasStdExtZcb, HasStdExtMOrZmmul] in{ def : CompressPat<(MUL GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), (C_MUL GPRC:$rs1, GPRC:$rs2)>; diff --git a/llvm/lib/Target/RISCV/RISCVSchedRocket.td b/llvm/lib/Target/RISCV/RISCVSchedRocket.td --- a/llvm/lib/Target/RISCV/RISCVSchedRocket.td +++ b/llvm/lib/Target/RISCV/RISCVSchedRocket.td @@ -18,9 +18,9 @@ let MispredictPenalty = 3; let CompleteModel = false; let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx, - HasStdExtZknd, HasStdExtZkne, HasStdExtZknh, - HasStdExtZksed, HasStdExtZksh, HasStdExtZkr, - HasVInstructions, HasVInstructionsI64]; + HasStdExtZcmt, HasStdExtZknd, HasStdExtZkne, + HasStdExtZknh, HasStdExtZksed, HasStdExtZksh, + HasStdExtZkr, HasVInstructions, HasVInstructionsI64]; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td --- a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td +++ b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td @@ -16,9 +16,9 @@ let MispredictPenalty = 3; let CompleteModel = 0; let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx, - HasStdExtZknd, HasStdExtZkne, HasStdExtZknh, - HasStdExtZksed, HasStdExtZksh, HasStdExtZkr, - HasVInstructions]; + HasStdExtZcmt, HasStdExtZknd, HasStdExtZkne, + HasStdExtZknh, HasStdExtZksed, HasStdExtZksh, + HasStdExtZkr, HasVInstructions]; } // The SiFive7 microarchitecture has two pipelines: A and B. diff --git a/llvm/lib/Target/RISCV/RISCVSystemOperands.td b/llvm/lib/Target/RISCV/RISCVSystemOperands.td --- a/llvm/lib/Target/RISCV/RISCVSystemOperands.td +++ b/llvm/lib/Target/RISCV/RISCVSystemOperands.td @@ -378,3 +378,9 @@ //===----------------------------------------------- def SEED : SysReg<"seed", 0x015>; + +//===----------------------------------------------- +// Jump Vector Table CSR +//===----------------------------------------------- + +def : SysReg<"jvt", 0x017>; diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -45,6 +45,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcb %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCB %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcd %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCD %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcf %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCF %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcmt %s -o - | FileCheck --check-prefix=RV32ZCMT %s ; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s @@ -97,6 +98,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zca %s -o - | FileCheck --check-prefixes=CHECK,RV64ZCA %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zcb %s -o - | FileCheck --check-prefixes=CHECK,RV64ZCB %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zcd %s -o - | FileCheck --check-prefixes=CHECK,RV64ZCD %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-zcmt %s -o - | FileCheck --check-prefix=RV64ZCMT %s ; CHECK: .attribute 4, 16 @@ -144,6 +146,7 @@ ; RV32ZCB: .attribute 5, "rv32i2p0_zca1p0_zcb1p0" ; RV32ZCD: .attribute 5, "rv32i2p0_zcd1p0" ; RV32ZCF: .attribute 5, "rv32i2p0_zcf1p0" +; RV32ZCMT: .attribute 5, "rv32i2p0_zca1p0_zcmt1p0" ; RV64M: .attribute 5, "rv64i2p0_m2p0" ; RV64ZMMUL: .attribute 5, "rv64i2p0_zmmul1p0" @@ -195,6 +198,7 @@ ; RV64ZCA: .attribute 5, "rv64i2p0_zca1p0" ; RV64ZCB: .attribute 5, "rv64i2p0_zca1p0_zcb1p0" ; RV64ZCD: .attribute 5, "rv64i2p0_zcd1p0" +; RV64ZCMT: .attribute 5, "rv64i2p0_zca1p0_zcmt1p0" define i32 @addi(i32 %a) { %1 = add i32 %a, 1 diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s --- a/llvm/test/MC/RISCV/attribute-arch.s +++ b/llvm/test/MC/RISCV/attribute-arch.s @@ -188,6 +188,9 @@ .attribute arch, "rv32izcb1p0" # CHECK: attribute 5, "rv32i2p0_zca1p0_zcb1p0" +.attribute arch, "rv32izcmt1p0" +# CHECK: attribute 5, "rv32i2p0_zca1p0_zcmt1p0" + .attribute arch, "rv32izawrs1p0" # CHECK: attribute 5, "rv32i2p0_zawrs1p0" diff --git a/llvm/test/MC/RISCV/rv32zcmt-invalid.s b/llvm/test/MC/RISCV/rv32zcmt-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zcmt-invalid.s @@ -0,0 +1,10 @@ +# RUN: not llvm-mc -triple=riscv32 -mattr=+experimental-zcmt -riscv-no-aliases -show-encoding < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s +# RUN: not llvm-mc -triple=riscv64 -mattr=+experimental-zcmt -riscv-no-aliases -show-encoding < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s + +# CHECK-ERROR: error: immediate must be an integer in the range [0, 31] +cm.jt 64 + +# CHECK-ERROR: error: immediate must be an integer in the range [0, 255] +cm.jalt 256 diff --git a/llvm/test/MC/RISCV/rv32zcmt-valid.s b/llvm/test/MC/RISCV/rv32zcmt-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zcmt-valid.s @@ -0,0 +1,39 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zcmt\ +# RUN: -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-zcmt\ +# RUN: -mattr=m < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zcmt\ +# RUN: -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zcmt\ +# RUN: -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zcmt\ +# RUN: -mattr=m < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zcmt\ +# RUN: -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s +# +# RUN: not llvm-mc -triple riscv32 \ +# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s +# RUN: not llvm-mc -triple riscv64 \ +# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s + +# CHECK-ASM-AND-OBJ: cm.jt 1 +# CHECK-ASM: encoding: [0x06,0xa0] +# CHECK-NO-EXT: error: instruction requires the following: 'Zcmt' (table jump instuctions for code-size reduction){{$}} +cm.jt 1 + +# CHECK-ASM: cm.jalt 1 +# CHECK-OBJ: cm.jt 1 +# CHECK-ASM: encoding: [0x06,0xa0] +# CHECK-NO-EXT: error: instruction requires the following: 'Zcmt' (table jump instuctions for code-size reduction){{$}} +cm.jalt 1 + +# CHECK-ASM-AND-OBJ: cm.jalt 32 +# CHECK-ASM: encoding: [0x82,0xa0] +# CHECK-NO-EXT: error: instruction requires the following: 'Zcmt' (table jump instuctions for code-size reduction){{$}} +cm.jalt 32 diff --git a/llvm/test/MC/RISCV/rvzcmt-user-csr-name.s b/llvm/test/MC/RISCV/rvzcmt-user-csr-name.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rvzcmt-user-csr-name.s @@ -0,0 +1,29 @@ +# RUN: llvm-mc %s -triple=riscv32 -riscv-no-aliases -mattr=+experimental-zcmt -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-INST,CHECK-ENC %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zcmt < %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zcmt - \ +# RUN: | FileCheck -check-prefix=CHECK-INST-ALIAS %s +# +# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases -mattr=+experimental-zcmt -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-INST,CHECK-ENC %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zcmt < %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zcmt - \ +# RUN: | FileCheck -check-prefix=CHECK-INST-ALIAS %s + +################################## +# Jump Vector Table CSR +################################## + +# jvt +# name +# CHECK-INST: csrrs t1, jvt, zero +# CHECK-ENC: encoding: [0x73,0x23,0x70,0x01] +# CHECK-INST-ALIAS: csrr t1, jvt +# uimm12 +# CHECK-INST: csrrs t2, jvt, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x70,0x01] +# CHECK-INST-ALIAS: csrr t2, jvt +# name +csrrs t1, jvt, zero +# uimm12 +csrrs t2, 0x017, zero