diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index f472e915b068..6eba3479612b 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -1687,6 +1687,7 @@ BUILTIN(__builtin_cheri_address_set, "v*mvC*mz", "nct") BUILTIN(__builtin_cheri_base_get, "zvC*m", "nct") BUILTIN(__builtin_cheri_bounds_set, "v*mvC*mz", "nct") BUILTIN(__builtin_cheri_bounds_set_exact, "v*mvC*mz", "nct") +BUILTIN(__builtin_cheri_bounds_set_round_down, "v*mvC*mz", "nct") BUILTIN(__builtin_cheri_equal_exact, "bvC*mvC*m", "nct") BUILTIN(__builtin_cheri_flags_set, "v*mvC*mz", "nct") BUILTIN(__builtin_cheri_flags_get, "zvC*m", "nct") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index d130c4bca415..78f433c1bf68 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5032,6 +5032,15 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, {SizeTy}, {Cap, Length}), Cap->getType())); } + case Builtin::BI__builtin_cheri_bounds_set_round_down: { + Value *Cap = EmitScalarExpr(E->getArg(0)); + Value *Length = EmitScalarExpr(E->getArg(1)); + return RValue::get(Builder.CreateBitCast( + Builder.CreateIntrinsic( + llvm::Intrinsic::cheri_cap_bounds_set_round_down, {SizeTy}, + {Cap, Length}), + Cap->getType())); + } case Builtin::BI__builtin_cheri_flags_get: return RValue::get( Builder.CreateIntrinsic(llvm::Intrinsic::cheri_cap_flags_get, {SizeTy}, diff --git a/llvm/include/llvm/IR/IntrinsicsCHERICap.td b/llvm/include/llvm/IR/IntrinsicsCHERICap.td index 00d5a201de1d..305d0d281873 100644 --- a/llvm/include/llvm/IR/IntrinsicsCHERICap.td +++ b/llvm/include/llvm/IR/IntrinsicsCHERICap.td @@ -57,6 +57,10 @@ def int_cheri_cap_bounds_set_exact : Intrinsic<[llvm_cap_ty], [llvm_cap_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>; +def int_cheri_cap_bounds_set_round_down : + Intrinsic<[llvm_cap_ty], + [llvm_cap_ty, llvm_anyint_ty], + [IntrNoMem, IntrWillReturn]>; def int_cheri_cap_type_get : Intrinsic<[llvm_anyint_ty], [llvm_cap_ty], diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index d734c6181856..4ad702a786e7 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1494,6 +1494,7 @@ bool RISCVInstrInfo::isSetBoundsInstr(const MachineInstr &I, case RISCV::CSetBounds: case RISCV::CSetBoundsExact: case RISCV::CSetBoundsImm: + case RISCV::CSetBoundsRoundDown: Base = &I.getOperand(1); Size = &I.getOperand(2); return true; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td index 2290355d8882..229be959e128 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -408,6 +408,7 @@ let mayTrap = 1 in { def CSetBounds : Cheri_rr<0x8, "csetbounds">; def CSetBoundsExact : Cheri_rr<0x9, "csetboundsexact">; def CSetBoundsImm : Cheri_ri<0x2, "csetbounds", 0>; +def CSetBoundsRoundDown : Cheri_rr<0xA, "csetboundsrounddown">; } // mayTrap = 1 } // let Constraints = "@traps_if_sealed $rs1" def CClearTag : Cheri_r<0xb, "ccleartag", GPCR>; @@ -1301,6 +1302,7 @@ def : PatGpcrGpr; def : PatGpcrSimm12; def : PatGpcrGpr; def : PatGpcrGpr; +def : PatGpcrGpr; def : PatGpcrGpr; def : PatGpcrUimm12; def : PatGpcrUimm12;