Index: clang/test/Preprocessor/riscv-target-features.c =================================================================== --- clang/test/Preprocessor/riscv-target-features.c +++ clang/test/Preprocessor/riscv-target-features.c @@ -31,6 +31,8 @@ // CHECK-NOT: __riscv_zfh // CHECK-NOT: __riscv_v // CHECK-NOT: __riscv_vector +// CHECK-NOT: __riscv_zicbom +// CHECK-NOT: __riscv_zicboz // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32im -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-M-EXT %s @@ -343,3 +345,15 @@ // CHECK-ZVE32X-EXT: __riscv_v_min_vlen 32 // CHECK-ZVE32X-EXT: __riscv_vector 1 // CHECK-ZVE32X-EXT: __riscv_zve32x 1000000{{$}} + +// RUN: %clang -target riscv32 -march=rv32izicbom -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZICBOM-EXT %s +// RUN: %clang -target riscv64 -march=rv64izicbom -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZICBOM-EXT %s +// CHECK-ZICBOM-EXT: __riscv_zicbom 1000000{{$}} + +// RUN: %clang -target riscv32 -march=rv32izicboz -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZICBOZ-EXT %s +// RUN: %clang -target riscv64 -march=rv64izicboz -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZICBOZ-EXT %s +// CHECK-ZICBOZ-EXT: __riscv_zicboz 1000000{{$}} Index: llvm/lib/Support/RISCVISAInfo.cpp =================================================================== --- llvm/lib/Support/RISCVISAInfo.cpp +++ llvm/lib/Support/RISCVISAInfo.cpp @@ -90,6 +90,9 @@ {"zve64x", RISCVExtensionVersion{1, 0}}, {"zve64f", RISCVExtensionVersion{1, 0}}, {"zve64d", RISCVExtensionVersion{1, 0}}, + + {"zicbom", RISCVExtensionVersion{1, 0}}, + {"zicboz", RISCVExtensionVersion{1, 0}}, }; static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { Index: llvm/lib/Target/RISCV/RISCV.td =================================================================== --- llvm/lib/Target/RISCV/RISCV.td +++ llvm/lib/Target/RISCV/RISCV.td @@ -358,6 +358,20 @@ "'V' (Vector Extension for Application Processors), 'Zve32f', " "'Zve64f' or 'Zve64d' (Vector Extensions for Embedded Processors)">; +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()">, Index: llvm/lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1600,3 +1600,4 @@ include "RISCVInstrInfoZk.td" include "RISCVInstrInfoV.td" include "RISCVInstrInfoZfh.td" +include "RISCVInstrInfoZicbo.td" Index: llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td =================================================================== --- /dev/null +++ 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 GPRMemZeroOffset:$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] Index: llvm/lib/Target/RISCV/RISCVSubtarget.h =================================================================== --- llvm/lib/Target/RISCV/RISCVSubtarget.h +++ llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -97,6 +97,8 @@ bool HasStdExtZks = false; bool HasStdExtZkt = false; bool HasStdExtZk = false; + bool HasStdExtZicbom = false; + bool HasStdExtZicboz = false; bool HasRV64 = false; bool IsRV32E = false; bool EnableLinkerRelax = false; @@ -181,6 +183,8 @@ bool hasStdExtZksed() const { return HasStdExtZksed; } bool hasStdExtZksh() const { return HasStdExtZksh; } bool hasStdExtZkr() const { return HasStdExtZkr; } + 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; } Index: llvm/test/CodeGen/RISCV/attributes.ll =================================================================== --- llvm/test/CodeGen/RISCV/attributes.ll +++ llvm/test/CodeGen/RISCV/attributes.ll @@ -33,6 +33,8 @@ ; RUN: llc -mtriple=riscv32 -mattr=+zks %s -o - | FileCheck --check-prefix=RV32ZKS %s ; RUN: llc -mtriple=riscv32 -mattr=+zkt %s -o - | FileCheck --check-prefix=RV32ZKT %s ; RUN: llc -mtriple=riscv32 -mattr=+zk %s -o - | FileCheck --check-prefix=RV32ZK %s +; RUN: llc -mtriple=riscv32 -mattr=+zicbom %s -o - | FileCheck --check-prefix=RV32ZICBOM %s +; RUN: llc -mtriple=riscv32 -mattr=+zicboz %s -o - | FileCheck --check-prefix=RV32ZICBOZ %s ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefix=RV64M %s ; RUN: llc -mtriple=riscv64 -mattr=+a %s -o - | FileCheck --check-prefix=RV64A %s ; RUN: llc -mtriple=riscv64 -mattr=+f %s -o - | FileCheck --check-prefix=RV64F %s @@ -66,6 +68,8 @@ ; RUN: llc -mtriple=riscv64 -mattr=+zks %s -o - | FileCheck --check-prefix=RV64ZKS %s ; RUN: llc -mtriple=riscv64 -mattr=+zkt %s -o - | FileCheck --check-prefix=RV64ZKT %s ; RUN: llc -mtriple=riscv64 -mattr=+zk %s -o - | FileCheck --check-prefix=RV64ZK %s +; RUN: llc -mtriple=riscv64 -mattr=+zicbom %s -o - | FileCheck --check-prefix=RV64ZICBOM %s +; RUN: llc -mtriple=riscv64 -mattr=+zicboz %s -o - | FileCheck --check-prefix=RV64ZICBOZ %s ; RV32M: .attribute 5, "rv32i2p0_m2p0" ; RV32A: .attribute 5, "rv32i2p0_a2p0" @@ -100,6 +104,8 @@ ; RV32ZKS: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zks1p0_zksed1p0_zksh1p0" ; RV32ZKT: .attribute 5, "rv32i2p0_zkt1p0" ; RV32ZK: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0" +; RV32ZICBOM: .attribute 5, "rv32i2p0_zicbom1p0" +; RV32ZICBOZ: .attribute 5, "rv32i2p0_zicboz1p0" ; RV64M: .attribute 5, "rv64i2p0_m2p0" ; RV64A: .attribute 5, "rv64i2p0_a2p0" @@ -134,6 +140,8 @@ ; RV64ZKS: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zks1p0_zksed1p0_zksh1p0" ; RV64ZKT: .attribute 5, "rv64i2p0_zkt1p0" ; RV64ZK: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0" +; RV64ZICBOM: .attribute 5, "rv64i2p0_zicbom1p0" +; RV64ZICBOZ: .attribute 5, "rv64i2p0_zicboz1p0" define i32 @addi(i32 %a) { %1 = add i32 %a, 1 Index: llvm/test/MC/RISCV/attribute-arch.s =================================================================== --- llvm/test/MC/RISCV/attribute-arch.s +++ llvm/test/MC/RISCV/attribute-arch.s @@ -87,6 +87,12 @@ .attribute arch, "rv32ifdzve64d" # CHECK: attribute 5, "rv32i2p0_f2p0_d2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl32b1p0_zvl64b1p0" +.attribute arch, "rv32izicbom" +# CHECK: attribute 5, "rv32i2p0_zicbom1p0" + +.attribute arch, "rv32izicboz" +# CHECK: attribute 5, "rv32i2p0_zicboz1p0" + ## Experimental extensions require version string to be explicitly specified .attribute arch, "rv32izba1p0" Index: llvm/test/MC/RISCV/rv32zicbom-invalid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zicbom-invalid.s @@ -0,0 +1,24 @@ +# 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]]:13: error: expected '(' after optional integer offset +cbo.flush 2 # CHECK: :[[@LINE]]:13: error: expected '(' after optional integer offset +cbo.inval 3 # CHECK: :[[@LINE]]:13: error: expected '(' after optional integer offset + +cbo.clean t0, t1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset +cbo.flush t0, t1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset +cbo.inval t0, t1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset + +# Non-zero offsets are not supported. +cbo.clean 1(t0) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0 +cbo.flush 2(t0) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0 +cbo.inval 3(t0) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0 + +# Instructions from other zicbo* extensions aren't available without enabling +# the appropriate -mattr flag. +cbo.zero (t0) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zicboz' (Cache-Block Zero Instructions) Index: llvm/test/MC/RISCV/rv32zicbom-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zicbom-valid.s @@ -0,0 +1,31 @@ +# 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.clean (t0) +# CHECK-ASM: encoding: [0x0f,0xa0,0x12,0x00] +cbo.clean 0(t0) + +# CHECK-ASM-AND-OBJ: cbo.flush (t1) +# CHECK-ASM: encoding: [0x0f,0x20,0x23,0x00] +cbo.flush (t1) +# CHECK-ASM-AND-OBJ: cbo.flush (t1) +# CHECK-ASM: encoding: [0x0f,0x20,0x23,0x00] +cbo.flush 0(t1) + +# CHECK-ASM-AND-OBJ: cbo.inval (t2) +# CHECK-ASM: encoding: [0x0f,0xa0,0x03,0x00] +cbo.inval (t2) +# CHECK-ASM-AND-OBJ: cbo.inval (t2) +# CHECK-ASM: encoding: [0x0f,0xa0,0x03,0x00] +cbo.inval 0(t2) Index: llvm/test/MC/RISCV/rv32zicboz-invalid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zicboz-invalid.s @@ -0,0 +1,16 @@ +# 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]]:12: error: expected '(' after optional integer offset +cbo.zero t0, t1 # CHECK: :[[@LINE]]:10: error: expected '(' or optional integer offset + +# Non-zero offsets are not supported. +cbo.zero 1(t0) # CHECK: :[[@LINE]]:10: error: optional integer offset must be 0 + +# Instructions from other zicbo* extensions aren't available without 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) Index: llvm/test/MC/RISCV/rv32zicboz-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zicboz-valid.s @@ -0,0 +1,17 @@ +# 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) +# CHECK-ASM-AND-OBJ: cbo.zero (t0) +# CHECK-ASM: encoding: [0x0f,0xa0,0x42,0x00] +cbo.zero 0(t0)