From 606b817f0a54815b30e669b1f89617ba0ce5a5e6 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Tue, 19 Nov 2024 15:46:06 +0000 Subject: [PATCH] [cheriot] CSetBoundsRoundDown instruction and intrinsic --- clang/include/clang/Basic/Builtins.def | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 9 +++++++++ .../cheri/cheriot-csetboundsrounddown.c | 12 ++++++++++++ llvm/include/llvm/IR/IntrinsicsCHERICap.td | 4 ++++ llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 1 + llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td | 2 ++ .../cheri/cheriot-csetboundsrounddown.ll | 16 ++++++++++++++++ llvm/test/MC/RISCV/cheri/cheriot.s | 19 +++++++++++++++++++ 8 files changed, 64 insertions(+) create mode 100644 clang/test/CodeGen/cheri/cheriot-csetboundsrounddown.c create mode 100644 llvm/test/CodeGen/RISCV/cheri/cheriot-csetboundsrounddown.ll create mode 100644 llvm/test/MC/RISCV/cheri/cheriot.s diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index f25a467efab7e..3ff3f35035980 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -1688,6 +1688,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 d130c4bca4158..78f433c1bf687 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/clang/test/CodeGen/cheri/cheriot-csetboundsrounddown.c b/clang/test/CodeGen/cheri/cheriot-csetboundsrounddown.c new file mode 100644 index 0000000000000..4e7646a98be47 --- /dev/null +++ b/clang/test/CodeGen/cheri/cheriot-csetboundsrounddown.c @@ -0,0 +1,12 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// RUN: %clang_cc1 %s -o - "-triple" "riscv32cheriot-unknown-cheriotrtos" "-emit-llvm" "-mframe-pointer=none" "-mcmodel=small" "-target-abi" "cheriot" "-Oz" "-Werror" -std=c2x | FileCheck %s + +// CHECK-LABEL: define dso_local ptr addrspace(200) @foo +// CHECK-SAME: (ptr addrspace(200) noundef readnone [[CAP:%.*]], i32 noundef [[B:%.*]]) local_unnamed_addr addrspace(200) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.bounds.set.round.down.i32(ptr addrspace(200) [[CAP]], i32 [[B]]) +// CHECK-NEXT: ret ptr addrspace(200) [[TMP0]] +// +void *foo(void* cap, int b) { + return __builtin_cheri_bounds_set_round_down(cap, b); +} diff --git a/llvm/include/llvm/IR/IntrinsicsCHERICap.td b/llvm/include/llvm/IR/IntrinsicsCHERICap.td index e9fd46e1ca706..c0066b653e1ad 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 35e1c4198c9b0..133c8e6c518e0 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 f2dde476f93c7..f970a31259566 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -414,6 +414,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>; @@ -1306,6 +1307,7 @@ def : PatGpcrGpr; def : PatGpcrSimm12; def : PatGpcrGpr; def : PatGpcrGpr; +def : PatGpcrGpr; def : PatGpcrGpr; def : PatGpcrUimm12; def : PatGpcrUimm12; diff --git a/llvm/test/CodeGen/RISCV/cheri/cheriot-csetboundsrounddown.ll b/llvm/test/CodeGen/RISCV/cheri/cheriot-csetboundsrounddown.ll new file mode 100644 index 0000000000000..95702fe9fba86 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/cheri/cheriot-csetboundsrounddown.ll @@ -0,0 +1,16 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc --filetype=asm --mcpu=cheriot --mtriple=riscv32cheriot-unknown-cheriotrtos -target-abi cheriot %s -mattr=+xcheri,+cap-mode -o - | FileCheck %s +target datalayout = "e-m:e-pf200:64:64:64:32-p:32:32-i64:64-n32-S128-A200-P200-G200" +target triple = "riscv32cheriot-unknown-cheriotrtos" + +define ptr addrspace(200) @foo(ptr addrspace(200) %cap, i32 noundef %b) addrspace(200) { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: csetboundsrounddown ca0, ca0, a1 +; CHECK-NEXT: cret +entry: + %0 = tail call ptr addrspace(200) @llvm.cheri.cap.bounds.set.round.down.i32(ptr addrspace(200) %cap, i32 %b) + ret ptr addrspace(200) %0 +} + +declare ptr addrspace(200) @llvm.cheri.cap.bounds.set.round.down.i32(ptr addrspace(200), i32) addrspace(200) diff --git a/llvm/test/MC/RISCV/cheri/cheriot.s b/llvm/test/MC/RISCV/cheri/cheriot.s new file mode 100644 index 0000000000000..56a4a381ea561 --- /dev/null +++ b/llvm/test/MC/RISCV/cheri/cheriot.s @@ -0,0 +1,19 @@ +# RUN: llvm-mc %s -triple=riscv32cheriot -mcpu=cheriot -mattr=+xcheri -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck %s + +csetboundsrounddown cra, cra, zero +# CHECK: encoding: [0xdb,0x80,0x00,0x14] +csetboundsrounddown cra, ca5, zero +# CHECK: encoding: [0xdb,0x80,0x07,0x14] +csetboundsrounddown cra, cra, a5 +# CHECK: encoding: [0xdb,0x80,0xf0,0x14] +csetboundsrounddown cra, ca5, a5 +# CHECK: encoding: [0xdb,0x80,0xf7,0x14] +csetboundsrounddown ca5, cra, zero +# CHECK: [0xdb,0x87,0x00,0x14] +csetboundsrounddown ca5, ca5, zero +# CHECK: [0xdb,0x87,0x07,0x14] +csetboundsrounddown ca5, cra, a5 +# CHECK: [0xdb,0x87,0xf0,0x14] +csetboundsrounddown ca5, ca5, a5 +# CHECK: [0xdb,0x87,0xf7,0x14]