Skip to content

Commit

Permalink
CSetBoundsRoundDown implementation
Browse files Browse the repository at this point in the history
FIXES #72
  • Loading branch information
nwf committed Oct 3, 2024
1 parent 43dead9 commit 5faa709
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/cheri_insts.sail
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,48 @@ function clause execute (CSetBoundsExact(cd, cs1, rs2)) = {
RETIRE_SUCCESS
}

/*
* Count trailing zeros; this is in the upstream RISC-V model but our submodule
* isn't new enough for it to be there, too.
*/
val LowestSetBit : forall 'N, 0 < 'N . bits('N) -> int
function LowestSetBit x = {
foreach (i from 0 to (sizeof('N) - 1) by 1 in dec)
if [x[i]] == 0b1 then return(i) else ();
return sizeof('N);
}

union clause ast = CSetBoundsRoundDown : (regidx, regidx, regidx)
/*!
* Capability register *cd* is set to capability register *cs1* with its
* **base** field replaced with *cs1*.**address** and its **length** field
* replaced with the maximum exactly representable value no larger than
* the value in the integer register *rs2*.
*
* ## Notes
* - The same caveat regarding the order of the bounds check applies as for
* [CSetBounds].
*/
function clause execute (CSetBoundsRoundDown(cd, cs1, rs2)) = {
let cs1_val = C(cs1);
let rs2_val = X(rs2);

let newBase = cs1_val.address;
let maxLen = sail_zero_extend(sail_ones(cap_mantissa_width), sizeof(xlen))
<< LowestSetBit(newBase);
let reqLen = X(rs2);
let newLen = if unsigned(reqLen) > unsigned(maxLen) then maxLen else reqLen;
let inBounds = inCapBounds(cs1_val, newBase, unsigned(newLen));

let inCap = clearTagIfSealed(cs1_val);
let (exact, newCap) = setCapBounds(inCap, newBase, newLen);

assert(exact, "CSetBoundsRoundDown must always result in an exact cap");

C(cd) = clearTagIf(newCap, not(inBounds));
RETIRE_SUCCESS
}

union clause ast = CClearTag : (regidx, regidx)
/*!
* Capability register *cd* is replaced with the contents of *cs1*, with
Expand Down Expand Up @@ -980,6 +1022,7 @@ mapping clause encdec = CSetHigh(cd, cs1, rs2) if (haveXcheri()) <-> 0b001011
mapping clause encdec = CIncAddr(cd, cs1, rs2) if (haveXcheri()) <-> 0b0010001 @ rs2 @ cs1 @ 0b000 @ cd @ 0b1011011 if (haveXcheri())
mapping clause encdec = CSetBounds(cd, cs1, rs2) if (haveXcheri()) <-> 0b0001000 @ rs2 @ cs1 @ 0b000 @ cd @ 0b1011011 if (haveXcheri())
mapping clause encdec = CSetBoundsExact(cd, cs1, rs2) if (haveXcheri()) <-> 0b0001001 @ rs2 @ cs1 @ 0b000 @ cd @ 0b1011011 if (haveXcheri())
mapping clause encdec = CSetBoundsRoundDown(cd, cs1, rs2) if (haveXcheri()) <-> 0b0001010 @ rs2 @ cs1 @ 0b000 @ cd @ 0b1011011 if (haveXcheri())

mapping clause encdec = CSub(rd, cs1, cs2) if (haveXcheri()) <-> 0b0010100 @ cs2 @ cs1 @ 0b000 @ rd @ 0b1011011 if (haveXcheri())

Expand All @@ -999,6 +1042,7 @@ mapping clause assembly = CSetHigh(cd, cs1, rs2) <-> "csethigh" ^ spc() ^ ca
mapping clause assembly = CIncAddr(cd, cs1, rs2) <-> "cincaddr" ^ spc() ^ cap_reg_name(cd) ^ sep() ^ cap_reg_name(cs1) ^ sep() ^ reg_name(rs2)
mapping clause assembly = CSetBounds(cd, cs1, rs2) <-> "csetbounds" ^ spc() ^ cap_reg_name(cd) ^ sep() ^ cap_reg_name(cs1) ^ sep() ^ reg_name(rs2)
mapping clause assembly = CSetBoundsExact(cd, cs1, rs2) <-> "csetboundsexact" ^ spc() ^ cap_reg_name(cd) ^ sep() ^ cap_reg_name(cs1) ^ sep() ^ reg_name(rs2)
mapping clause assembly = CSetBoundsRoundDown(cd, cs1, rs2) <-> "csetboundsrounddown" ^ spc() ^ cap_reg_name(cd) ^ sep() ^ cap_reg_name(cs1) ^ sep() ^ reg_name(rs2)

mapping clause assembly = CSub(rd, cs1, cs2) <-> "csub" ^ spc() ^ reg_name(rd) ^ sep() ^ cap_reg_name(cs1) ^ sep() ^ cap_reg_name(cs2)

Expand Down

0 comments on commit 5faa709

Please sign in to comment.