Cheri CSetBounds Intrinsics

References:

Mips::CSetBounds new instruction support in LLVM

IR intrinsics td file

llvm/include/IR/IntrinsicsCHERICap.td

def int_cheri_cap_bounds_set :
  Intrinsic<[llvm_fatptr_ty],
            [llvm_fatptr_ty, llvm_anyint_ty],
            [IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_bounds_set_exact :
  Intrinsic<[llvm_fatptr_ty],
            [llvm_fatptr_ty, llvm_anyint_ty],
            [IntrNoMem, IntrWillReturn]>;
            

target td file

llvm/lib/Target/Mips/MipsInstrCheri.td

// Accept CIncOffsetImm as an assembler mnemonic because ancient binutils is too stupid to have an opcode
// with differing encoding depending on the parameters
def : InstAlias<"csetboundsimm $dst, $src, $imm",
                (CSetBoundsImm CheriOpnd:$dst, CheriOpnd:$src, uimm11s0:$imm), 0>;
def : InstAlias<"cincoffsetimm $dst, $src, $imm",
                (CIncOffsetImm CheriOpnd:$dst, CheriOpnd:$src, simm11s0:$imm), 0>;
def : InstAlias<"csetboundsimm $dst, $imm",
                (CSetBoundsImm CheriOpnd:$dst, CheriOpnd:$dst, uimm11s0:$imm), 0>;
def : InstAlias<"cincoffsetimm $dst, $imm",
                (CIncOffsetImm CheriOpnd:$dst, CheriOpnd:$dst, simm11s0:$imm), 0>;
// CAssertInBounds pseudo
def : InstAlias<"cassertinbounds $dst, $imm",
                (CSetBoundsImm CNULL, CheriOpnd:$dst, uimm11s0:$imm), 1>;
def : InstAlias<"cassertinbounds $dst",
                (CSetBoundsImm CNULL, CheriOpnd:$dst, 1), 0>;

// Property setters
let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
def CAndPerms  : CheriFmtCSet<0xd, "perm", "perms", "and">;
def CSetFlags  : CheriFmtCSet<0xe, "flags">;
def CSetOffset : CheriFmtCSet<0xf, "offset">;
def CSetBounds : CheriFmtCSet<0x8, "bounds">;
def CSetBoundsExact : CheriFmtCSet<0x9, "boundsexact", "bounds", "set", "set_exact">;
def CIncOffset : CheriFmt3Op<0x11, (outs CheriOpnd:$r1), (ins CheriOpnd:$r2, GPR64Opnd:$r3),
                            "cincoffset\t$r1, $r2, $r3",
                            [(set CheriOpnd:$r1, (ptradd CheriOpnd:$r2, GPR64Opnd:$r3))]>;
def CClearTag  : CheriFmt2Op<0xb, (outs CheriOpnd:$r1), (ins CheriOpnd:$r2),
                              "ccleartag\t$r1, $r2",
                              [(set CheriOpnd:$r1, (int_cheri_cap_tag_clear CheriOpnd:$r2))]>;
def CSetAddr : CheriFmtCSet<0x22, "addr", "address">;



// Add a pseudo instruction to pretend this is only one instruction to avoid register spills
def CheriBoundedStackPseudoImm : CheriBoundedStackPseudo<(ins CheriOpnd:$fi, simm11s0:$frameoffs, uimm11s0:$size)>;
// FIXME: duplicated to avoid machine verified errors
def CheriBoundedStackPseudoReg : CheriBoundedStackPseudo<(ins CheriOpnd:$fi, simm11s0:$frameoffs, GPR64Opnd:$size)>;

llvm/lib/Target/RISCV/RISCVInstrinfoXCheri.td

def CSetBounds      : Cheri_rr<0x8, "csetbounds">;
def CSetBoundsExact : Cheri_rr<0x9, "csetboundsexact">;
def CSetBoundsImm   : Cheri_ri<0x2, "csetbounds", 0>;
//...
def : InstAlias<"csetboundsimm $cd, $cs1, $imm",
                (CSetBoundsImm GPCR:$cd, GPCR:$cs1, uimm12:$imm), 0>;
}
//...

def : PatGpcrGpr<int_cheri_cap_bounds_set, CSetBounds>;
def : PatGpcrGpr<int_cheri_cap_bounds_set_exact, CSetBoundsExact>;
def : PatGpcrUimm12<int_cheri_cap_bounds_set, CSetBoundsImm>;

//...

// TODO: Make this rematerialisable like MIPS
def : PatGpcrGpr<int_cheri_bounded_stack_cap, CSetBounds>;

Mips::CJR

llvm/lib/Target/Mips/MipsInstrCheri.td

def CJR : CheriFmt1Op<0x3, (outs), (ins CheriOpnd:$r1),
                              "cjr\t${r1}",
                              []>;
}

llvm/lib/Target/RISCV/RISCVInstrinfoXCheri.td

def : InstAlias<"cjr $cs1", (CJALR C0, GPCR:$cs1), 1>;

More

Created Aug 25, 2020 // Last Updated Aug 27, 2020

If you could revise
the fundmental principles of
computer system design
to improve security...

... what would you change?