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 @@ -55,6 +55,9 @@ {"zbb", RISCVExtensionVersion{1, 0}}, {"zbc", RISCVExtensionVersion{1, 0}}, {"zbs", RISCVExtensionVersion{1, 0}}, + + {"zicbom", RISCVExtensionVersion{1, 0}}, + {"zicboz", RISCVExtensionVersion{1, 0}}, }; static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { 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 @@ -180,6 +180,20 @@ AssemblerPredicate<(all_of FeatureStdExtZvlsseg), "'Zvlsseg' (Vector segment load/store instructions)">; +def FeatureStdExtZicbom + : SubtargetFeature<"zicbom", "HasStdExtZicbom", "true", + "'Zicbom' (Cache-Block Management Instructions)">; +def HasStdExtZicbom : Predicate<"Subtarget->hasStdExtZicbom()">, + AssemblerPredicate<(all_of FeatureStdExtZicbom), + "'Zicbom' (Cache-Block Management Instructions)">; + +def FeatureStdExtZicboz + : SubtargetFeature<"zicboz", "HasStdExtZicboz", "true", + "'Zicboz' (Cache-Block Zero Instructions)">; +def HasStdExtZicboz : Predicate<"Subtarget->hasStdExtZicboz()">, + AssemblerPredicate<(all_of FeatureStdExtZicboz), + "'Zicboz' (Cache-Block Zero Instructions)">; + def Feature64Bit : SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">; def IsRV64 : Predicate<"Subtarget->is64Bit()">, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1513,3 +1513,4 @@ include "RISCVInstrInfoZb.td" include "RISCVInstrInfoV.td" include "RISCVInstrInfoZfh.td" +include "RISCVInstrInfoZicbo.td" diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td @@ -0,0 +1,37 @@ +//===-- RISCVInstrInfoZicbo.td - RISC-V CMO instructions ---*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the RISC-V instructions from the standard Base Cache +// Management Operation ISA Extensions document (Zicbop, Zicboz, and Zicbop). +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction Class Templates +//===----------------------------------------------------------------------===// +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in +class CBO_r optype, string opcodestr> + : RVInstI<0b010, OPC_MISC_MEM, (outs), (ins GPR:$rs1), + opcodestr, "$rs1"> { + let imm12 = optype; + let rd = 0b00000; +} + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +let Predicates = [HasStdExtZicbom] in { +def CBO_CLEAN : CBO_r<0b000000000001, "cbo.clean">, Sched<[]>; +def CBO_FLUSH : CBO_r<0b000000000010, "cbo.flush">, Sched<[]>; +def CBO_INVAL : CBO_r<0b000000000000, "cbo.inval">, Sched<[]>; +} // Predicates = [HasStdExtZicbom] + +let Predicates = [HasStdExtZicboz] in { +def CBO_ZERO : CBO_r<0b000000000100, "cbo.zero">, Sched<[]>; +} // Predicates = [HasStdExtZicboz] 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 @@ -79,6 +79,8 @@ bool HasStdExtZvlsseg = false; bool HasStdExtZfhmin = false; bool HasStdExtZfh = false; + bool HasStdExtZicbom = false; + bool HasStdExtZicboz = false; bool HasRV64 = false; bool IsRV32E = false; bool EnableLinkerRelax = false; @@ -154,6 +156,8 @@ bool hasStdExtZvl() const { return ZvlLen != ExtZvl::NotSet; } bool hasStdExtZfhmin() const { return HasStdExtZfhmin; } bool hasStdExtZfh() const { return HasStdExtZfh; } + bool hasStdExtZicbom() const { return HasStdExtZicbom; } + bool hasStdExtZicboz() const { return HasStdExtZicboz; } bool is64Bit() const { return HasRV64; } bool isRV32E() const { return IsRV32E; } bool enableLinkerRelax() const { return EnableLinkerRelax; } diff --git a/llvm/test/MC/RISCV/rv32zicbom-invalid.s b/llvm/test/MC/RISCV/rv32zicbom-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zicbom-invalid.s @@ -0,0 +1,19 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zicbom < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple riscv64 -mattr=+zicbom < %s 2>&1 | FileCheck %s + +# Must have a single register argument. +cbo.clean # CHECK: :[[@LINE]]:1: error: too few operands for instruction +cbo.flush # CHECK: :[[@LINE]]:1: error: too few operands for instruction +cbo.inval # CHECK: :[[@LINE]]:1: error: too few operands for instruction + +cbo.clean 1 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction +cbo.flush 2 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction +cbo.inval 3 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction + +cbo.clean t0, t1 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction +cbo.flush t0, t1 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction +cbo.inval t0, t1 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction + +# Instructions from other zicbo* extensions aren't avalable with enabling the +# appropriate -mattr flag. +cbo.zero t0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zicboz' (Cache-Block Zero Instructions) diff --git a/llvm/test/MC/RISCV/rv32zicbom-valid.s b/llvm/test/MC/RISCV/rv32zicbom-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zicbom-valid.s @@ -0,0 +1,22 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zicbom -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zicbom -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zicbom < %s \ +# RUN: | llvm-objdump --mattr=+zicbom -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zicbom < %s \ +# RUN: | llvm-objdump --mattr=+zicbom -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: cbo.clean t0 +# CHECK-ASM: encoding: [0x0f,0xa0,0x12,0x00] +cbo.clean t0 + +# CHECK-ASM-AND-OBJ: cbo.flush t1 +# CHECK-ASM: encoding: [0x0f,0x20,0x23,0x00] +cbo.flush t1 + +# CHECK-ASM-AND-OBJ: cbo.inval t2 +# CHECK-ASM: encoding: [0x0f,0xa0,0x03,0x00] +cbo.inval t2 diff --git a/llvm/test/MC/RISCV/rv32zicboz-invalid.s b/llvm/test/MC/RISCV/rv32zicboz-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zicboz-invalid.s @@ -0,0 +1,13 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zicboz < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple riscv64 -mattr=+zicboz < %s 2>&1 | FileCheck %s + +# Must have a single register argument. +cbo.zero # CHECK: :[[@LINE]]:1: error: too few operands for instruction +cbo.zero 1 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction +cbo.zero t0, t1 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction + +# Instructions from other zicbo* extensions aren't avalable with enabling the +# appropriate -mattr flag. +cbo.clean t0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zicbom' (Cache-Block Management Instructions) +cbo.flush t1 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zicbom' (Cache-Block Management Instructions) +cbo.inval t2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zicbom' (Cache-Block Management Instructions) diff --git a/llvm/test/MC/RISCV/rv32zicboz-valid.s b/llvm/test/MC/RISCV/rv32zicboz-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zicboz-valid.s @@ -0,0 +1,14 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zicboz -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zicboz -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zicboz < %s \ +# RUN: | llvm-objdump --mattr=+zicboz -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zicboz < %s \ +# RUN: | llvm-objdump --mattr=+zicboz -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: cbo.zero t0 +# CHECK-ASM: encoding: [0x0f,0xa0,0x42,0x00] +cbo.zero t0