References:
Mips::CSetBounds new instruction support in LLVM
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]>;
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>;
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>;
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?