Implement CCall, hopefully as well as CJALR.
This passes the unmodified TestRIG routine for CHERI Control Flow, which is very promising indeed! There are some cases that are not covered there, but a lot is covered.
This commit is contained in:
@@ -823,21 +823,22 @@ function DecodeResult decode(Instruction inst);
|
||||
f7_cap_TwoSrc: begin
|
||||
case (rd)
|
||||
rd_cap_CCall: begin
|
||||
// TODO
|
||||
// dInst.capChecks.src1_tag = True;
|
||||
// dInst.capChecks.src2_tag = True;
|
||||
// dInst.capChecks.src1_sealed = True;
|
||||
// dInst.capChecks.src2_sealed = True;
|
||||
// dInst.capChecks.src1_src2_types_match = True;
|
||||
// dInst.capChecks.src1_permit_x = True;
|
||||
// dInst.capChecks.src2_no_permit_x = True;
|
||||
// dInst.capChecks.src1_permit_ccall = True;
|
||||
// dInst.capChecks.src2_permit_ccall = True;
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src2_tag = True;
|
||||
dInst.capChecks.src1_sealed = True;
|
||||
dInst.capChecks.src2_sealed = True;
|
||||
dInst.capChecks.src1_src2_types_match = True;
|
||||
dInst.capChecks.src1_permit_x = True;
|
||||
dInst.capChecks.src2_no_permit_x = True;
|
||||
dInst.capChecks.src1_permit_ccall = True;
|
||||
dInst.capChecks.src2_permit_ccall = True;
|
||||
|
||||
// regs.rd = Invalid;
|
||||
// regs.src1 = Valid(tagged Gpr rs1);
|
||||
// regs.src2 = Valid(tagged Gpr rs2);
|
||||
// dInst.imm = Invalid;
|
||||
dInst.iType = Jr;
|
||||
dInst.execFunc = tagged Br AT;
|
||||
regs.dst = Valid(tagged Gpr 31);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Valid(tagged Gpr rs2);
|
||||
dInst.imm = Invalid;
|
||||
end
|
||||
default: begin
|
||||
illegalInst = True;
|
||||
@@ -857,7 +858,7 @@ function DecodeResult decode(Instruction inst);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Valid(tagged Gpr rs2);
|
||||
dInst.imm = Invalid;
|
||||
dInst.execFunc = CapModify (Unseal);
|
||||
dInst.execFunc = CapModify (Unseal (Src1));
|
||||
end
|
||||
f7_cap_CTestSubset: begin
|
||||
dInst.iType = Alu;
|
||||
@@ -1036,16 +1037,16 @@ function DecodeResult decode(Instruction inst);
|
||||
dInst.execFunc = CapInspect (GetPerm);
|
||||
end
|
||||
f5rs2_cap_CJALR: begin
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src1_permit_x = True;
|
||||
dInst.capChecks.src1_unsealed = True;
|
||||
|
||||
dInst.iType = Jr;
|
||||
dInst.execFunc = tagged Br AT;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Invalid;
|
||||
dInst.imm = Invalid;
|
||||
//dInst.scr = tagged Valid SCR_PCC;
|
||||
dInst.execFunc = tagged Br AT;
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src1_permit_x = True;
|
||||
dInst.capChecks.src1_unsealed = True;
|
||||
end
|
||||
f5rs2_cap_CGetType: begin
|
||||
dInst.iType = Alu;
|
||||
|
||||
@@ -110,8 +110,8 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func);
|
||||
setAddr(a, addrSource == Src2Type ? (isSealed(b) ? zeroExtend(getType(b)) : -1) : getAddr(b)).value;
|
||||
tagged Seal :
|
||||
setType(a, truncate(getAddr(b)));
|
||||
tagged Unseal :
|
||||
setType(a, -1);
|
||||
tagged Unseal .src :
|
||||
setType(((src == Src1) ? a:b), -1);
|
||||
tagged AndPerm :
|
||||
setPerms(a, pack(getPerms(a)) & truncate(getAddr(b)));
|
||||
tagged SetFlags :
|
||||
@@ -213,7 +213,13 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
CapPipe data = nullCap;
|
||||
Data csr_data = 0;
|
||||
CapPipe addr = nullCap;
|
||||
Bool cjalr = (dInst.iType == Jr) && dInst.capChecks.src1_tag;
|
||||
Bool cjalr = False;
|
||||
Bool ccall = False;
|
||||
if (dInst.iType == Jr) begin
|
||||
if (dInst.capChecks.src1_src2_types_match) ccall = True;
|
||||
else if (dInst.capChecks.src1_tag) cjalr = True;
|
||||
end
|
||||
|
||||
ControlFlow cf = ControlFlow{pc: pc, nextPc: 0, taken: False, newPcc: cjalr, mispredict: False};
|
||||
|
||||
CapPipe aluVal2 = rVal2;
|
||||
@@ -223,11 +229,13 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
Data alu_result = alu(getAddr(rVal1), getAddr(aluVal2), alu_f);
|
||||
|
||||
Data inspect_result = capInspect(rVal1, aluVal2, dInst.execFunc.CapInspect);
|
||||
CapPipe modify_result = capModify(rVal1, aluVal2, dInst.execFunc.CapModify);
|
||||
CapModifyFunc modFunc = ccall ? (Unseal (Src1)):dInst.execFunc.CapModify;
|
||||
CapPipe modify_result = capModify(rVal1, aluVal2, modFunc);
|
||||
Maybe#(CapException) capException = capChecks(rVal1, aluVal2, dInst.capChecks); // TODO use this to throw exceptions
|
||||
|
||||
CapPipe cap_alu_result = case (dInst.execFunc) matches tagged CapInspect .x: nullWithAddr(inspect_result);
|
||||
tagged CapModify .x: modify_result;
|
||||
tagged Br .x: modify_result;
|
||||
default: nullWithAddr(alu_result);
|
||||
endcase;
|
||||
|
||||
@@ -240,9 +248,14 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
Addr fallthrough_incr = ((orig_inst [1:0] == 2'b11) ? 4 : 2);
|
||||
CapPipe link_pcc = setAddrUnsafe(pcc, getAddr(pcc) + fallthrough_incr);
|
||||
|
||||
data = (case (dInst.iType)
|
||||
St, Sc, Amo : rVal2;
|
||||
J, Jr : (cjalr ? link_pcc : nullWithAddr(getAddr(link_pcc))); // could be computed with alu
|
||||
data = (case (dInst.iType) matches
|
||||
St : rVal2;
|
||||
Sc : rVal2;
|
||||
Amo : rVal2;
|
||||
J : nullWithAddr(getAddr(link_pcc));
|
||||
Jr &&& (ccall): cap_alu_result; // Depending on defaults falling through!
|
||||
Jr &&& (cjalr): link_pcc;
|
||||
Jr : nullWithAddr(getAddr(link_pcc));
|
||||
Auipc : nullWithAddr(pc + fromMaybe(?, getDInstImm(dInst))); // could be computed with alu
|
||||
Csr : rVal1;
|
||||
default : cap_alu_result;
|
||||
|
||||
@@ -224,6 +224,13 @@ function Opcode unpackOpcode(Bit#(7) x);
|
||||
endcase);
|
||||
endfunction
|
||||
|
||||
/* If Bluespec never allows illegal values of sparse enumerated types, this function should replace the one above:
|
||||
function Opcode unpackOpcode(Bit#(7) x);
|
||||
Opcode test = unpack(x);
|
||||
if (pack(test) != x) return Invalid;
|
||||
else return test;
|
||||
endfunction
|
||||
*/
|
||||
typedef enum {
|
||||
// user standard CSRs
|
||||
CSRfflags = 12'h001,
|
||||
@@ -420,13 +427,17 @@ typedef enum {
|
||||
Src2Type, Src2Addr
|
||||
} AddrSource deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef enum {
|
||||
Src1, Src2
|
||||
} SrcSelector deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef union tagged {
|
||||
ModifyOffsetFunc ModifyOffset;
|
||||
Bool SetBounds;
|
||||
void SpecialRW;
|
||||
AddrSource SetAddr;
|
||||
void Seal;
|
||||
void Unseal;
|
||||
SrcSelector Unseal;
|
||||
void AndPerm;
|
||||
void SetFlags;
|
||||
void BuildCap;
|
||||
|
||||
Reference in New Issue
Block a user