Make JAL and JALR mode-dependent
This commit is contained in:
@@ -1184,6 +1184,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Auipc, Auipcc: auipcCnt = auipcCnt + 1;
|
||||
Br: brCnt = brCnt + 1;
|
||||
J : jmpCnt = jmpCnt + 1;
|
||||
CJAL: jmpCnt = jmpCnt + 1;
|
||||
Jr: jrCnt = jrCnt + 1;
|
||||
CJALR: jrCnt = jrCnt + 1;
|
||||
Ld: begin
|
||||
|
||||
@@ -717,7 +717,7 @@ module mkFetchStage(FetchStage);
|
||||
CapMem push_addr = addPc(pc, ((in.inst_kind == Inst_32b) ? 4 : 2));
|
||||
|
||||
CapMem pop_addr = ras.ras[i].first;
|
||||
if (dInst.iType == J && dst_link) begin
|
||||
if ((dInst.iType == J || dInst.iType == CJAL) && dst_link) begin
|
||||
// rs1 is invalid, i.e., not link: push
|
||||
ras.ras[i].popPush(False, Valid (push_addr));
|
||||
end
|
||||
@@ -821,7 +821,7 @@ module mkFetchStage(FetchStage);
|
||||
if(redirectInst matches tagged Valid .iType &&& doStats) begin
|
||||
case(iType)
|
||||
Br: decRedirectBrCnt.incr(1);
|
||||
J : decRedirectJmpCnt.incr(1);
|
||||
J, CJAL: decRedirectJmpCnt.incr(1);
|
||||
Jr: decRedirectJrCnt.incr(1);
|
||||
default: decRedirectOtherCnt.incr(1);
|
||||
endcase
|
||||
@@ -930,7 +930,7 @@ module mkFetchStage(FetchStage);
|
||||
CapMem pc, CapMem next_pc, IType iType, Bool taken,
|
||||
DirPredTrainInfo dpTrain, Bool mispred, Bool isCompressed
|
||||
);
|
||||
//if (iType == J || (iType == Br && next_pc < pc)) begin
|
||||
//if (iType == J || iType == CJAL || (iType == Br && next_pc < pc)) begin
|
||||
// // Only train the next address predictor for jumps and backward branches
|
||||
// // next_pc != pc + 4 is a substitute for taken
|
||||
// nextAddrPred.update(pc, next_pc, taken);
|
||||
|
||||
@@ -48,7 +48,7 @@ function Maybe#(CapMem) decodeBrPred( CapMem pc, DecodedInst dInst, Bool histTak
|
||||
Maybe#(CapMem) nextPc = tagged Invalid;
|
||||
CapPipe pcPipe = cast(pc);
|
||||
CapMem jTarget = cast(incOffset(pcPipe, imm_val).value);
|
||||
if( dInst.iType == J ) begin
|
||||
if( dInst.iType == J || dInst.iType == CJAL ) begin
|
||||
nextPc = tagged Valid jTarget;
|
||||
end else if( dInst.iType == Br ) begin
|
||||
if( histTaken ) begin
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
`CAP_CHECK_FIELD(ddc_unsealed,"ddc_unsealed")
|
||||
`CAP_CHECK_FIELD(src1_unsealed,"src1_unsealed")
|
||||
`CAP_CHECK_FIELD(src1_unsealed_or_sentry,"src1_unsealed_or_sentry")
|
||||
`CAP_CHECK_FIELD(src1_unsealed_or_imm_zero,"src1_unsealed_or_imm_zero")
|
||||
`CAP_CHECK_FIELD(src2_unsealed,"src2_unsealed")
|
||||
`CAP_CHECK_FIELD(src1_src2_types_match,"src1_src2_types_match")
|
||||
`CAP_CHECK_FIELD(src1_permit_ccall,"src1_permit_ccall")
|
||||
|
||||
@@ -491,7 +491,13 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
|
||||
end
|
||||
|
||||
opcJal: begin
|
||||
dInst.iType = J;
|
||||
if (cap_mode) begin
|
||||
dInst.iType = CJAL;
|
||||
end
|
||||
else begin
|
||||
dInst.iType = J;
|
||||
end
|
||||
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Invalid;
|
||||
regs.src2 = Invalid;
|
||||
@@ -506,18 +512,32 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
|
||||
end
|
||||
|
||||
opcJalr: begin
|
||||
dInst.iType = Jr;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Invalid;
|
||||
dInst.imm = Valid(immI);
|
||||
dInst.csr = tagged Invalid;
|
||||
dInst.execFunc = tagged Br AT;
|
||||
|
||||
dInst.capChecks.check_enable = True;
|
||||
dInst.capChecks.check_authority_src = Pcc;
|
||||
dInst.capChecks.check_low_src = Src1Addr;
|
||||
dInst.capChecks.check_high_src = Src1AddrPlus2;
|
||||
dInst.capChecks.check_inclusive = True;
|
||||
if (cap_mode) begin
|
||||
dInst.iType = CJALR;
|
||||
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src1_permit_x = True;
|
||||
dInst.capChecks.src1_unsealed_or_sentry = True;
|
||||
dInst.capChecks.src1_unsealed_or_imm_zero = True;
|
||||
|
||||
dInst.capChecks.check_authority_src = Src1;
|
||||
end
|
||||
else begin
|
||||
dInst.iType = Jr;
|
||||
|
||||
dInst.capChecks.check_authority_src = Pcc;
|
||||
end
|
||||
end
|
||||
|
||||
opcBranch: begin
|
||||
|
||||
@@ -46,54 +46,56 @@ import ISA_Decls_CHERI::*;
|
||||
import CacheUtils::*; // For CLoadTags alignment
|
||||
|
||||
(* noinline *)
|
||||
function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact);
|
||||
function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact, ImmData imm);
|
||||
function Maybe#(CSR_XCapCause) e1(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e});
|
||||
function Maybe#(CSR_XCapCause) e2(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e});
|
||||
function Maybe#(CSR_XCapCause) eDDC(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1, pack(scrAddrDDC)}, cheri_exc_code: e});
|
||||
Maybe#(CSR_XCapCause) result = Invalid;
|
||||
if (toCheck.ddc_tag && !isValidCap(ddc))
|
||||
if (toCheck.ddc_tag && !isValidCap(ddc))
|
||||
result = eDDC(cheriExcTagViolation);
|
||||
else if (toCheck.src1_tag && !isValidCap(a))
|
||||
else if (toCheck.src1_tag && !isValidCap(a))
|
||||
result = e1(cheriExcTagViolation);
|
||||
else if (toCheck.src2_tag && !isValidCap(b))
|
||||
else if (toCheck.src2_tag && !isValidCap(b))
|
||||
result = e2(cheriExcTagViolation);
|
||||
else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED))
|
||||
else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED))
|
||||
result = eDDC(cheriExcSealViolation);
|
||||
else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED))
|
||||
else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED))
|
||||
result = e1(cheriExcSealViolation);
|
||||
else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY))
|
||||
else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY))
|
||||
result = e1(cheriExcSealViolation);
|
||||
else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED))
|
||||
else if (toCheck.src1_unsealed_or_imm_zero && isValidCap(a) && (getKind(a) != UNSEALED) && (imm != 0))
|
||||
result = e1(cheriExcSealViolation);
|
||||
else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED))
|
||||
result = e2(cheriExcSealViolation);
|
||||
else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True))
|
||||
else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True))
|
||||
result = e1(cheriExcSealViolation);
|
||||
else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True))
|
||||
else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True))
|
||||
result = e2(cheriExcSealViolation);
|
||||
else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getKind(a).SEALED_WITH_TYPE)))
|
||||
else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getKind(a).SEALED_WITH_TYPE)))
|
||||
result = e1(cheriExcTypeViolation);
|
||||
else if (toCheck.src1_src2_types_match && getKind(a).SEALED_WITH_TYPE != getKind(b).SEALED_WITH_TYPE)
|
||||
else if (toCheck.src1_src2_types_match && getKind(a).SEALED_WITH_TYPE != getKind(b).SEALED_WITH_TYPE)
|
||||
result = e1(cheriExcTypeViolation);
|
||||
else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall)
|
||||
else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall)
|
||||
result = e1(cheriExcPermitCCallViolation);
|
||||
else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall)
|
||||
else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall)
|
||||
result = e2(cheriExcPermitCCallViolation);
|
||||
else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute)
|
||||
else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute)
|
||||
result = e1(cheriExcPermitXViolation);
|
||||
else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute)
|
||||
else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute)
|
||||
result = e2(cheriExcPermitXViolation);
|
||||
else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal)
|
||||
else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal)
|
||||
result = e2(cheriExcPermitUnsealViolation);
|
||||
else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal)
|
||||
else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal)
|
||||
result = e2(cheriExcPermitSealViolation);
|
||||
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE))
|
||||
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE))
|
||||
result = e2(cheriExcTypeViolation);
|
||||
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
|
||||
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
|
||||
result = e2(cheriExcLengthViolation);
|
||||
else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a))
|
||||
else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a))
|
||||
result = e2(cheriExcSoftwarePermViolation);
|
||||
else if (toCheck.src1_derivable && !isDerivable(a))
|
||||
else if (toCheck.src1_derivable && !isDerivable(a))
|
||||
result = e1(cheriExcLengthViolation);
|
||||
else if (toCheck.cap_exact && !cap_exact)
|
||||
else if (toCheck.cap_exact && !cap_exact)
|
||||
result = e1(cheriExcRepresentViolation);
|
||||
return result;
|
||||
endfunction
|
||||
@@ -358,7 +360,7 @@ function CapPipe brAddrCalc(CapPipe pc, CapPipe val, IType iType, Data imm, Bool
|
||||
jumpTarget = setAddrUnsafe(jumpTarget, {truncateLSB(getAddr(jumpTarget)), 1'b0});
|
||||
jumpTarget = setKind(jumpTarget, UNSEALED); // It is checked elsewhere that we have an unsealed cap already, or sentry if permitted
|
||||
CapPipe targetAddr = (case (iType)
|
||||
J : branchTarget;
|
||||
J, CJAL : branchTarget;
|
||||
Jr,CCall,CJALR : jumpTarget;
|
||||
Br : (taken? branchTarget : pcPlusN);
|
||||
default : pcPlusN;
|
||||
@@ -407,7 +409,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
cf.taken = aluBr(getAddr(rVal1), getAddr(rVal2), br_f);
|
||||
cf.nextPc = brAddrCalc(pcc, rVal1, dInst.iType, fromMaybe(0,getDInstImm(dInst)), cf.taken, orig_inst, newPcc);
|
||||
|
||||
Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact);
|
||||
Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact, dInst.imm.Valid);
|
||||
if (dInst.execFunc matches tagged Br .unused) begin
|
||||
rVal1 = cf.nextPc;
|
||||
if (!cf.taken) dInst.capChecks.check_enable = False;
|
||||
@@ -431,6 +433,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
Sc : rVal2;
|
||||
Amo : rVal2;
|
||||
J : nullWithAddr(getOffset(link_pcc));
|
||||
CJAL : setKind(link_pcc, SENTRY);
|
||||
CCall : cap_alu_result;
|
||||
CJALR : setKind(link_pcc, SENTRY);
|
||||
Jr : nullWithAddr(getOffset(link_pcc));
|
||||
|
||||
@@ -268,7 +268,7 @@ typedef enum {
|
||||
Alu,
|
||||
Ld, St, Lr, Sc,
|
||||
J, Jr, Br,
|
||||
CCall, CJALR, Cap,
|
||||
CCall, CJAL, CJALR, Cap,
|
||||
Auipc,
|
||||
Auipcc,
|
||||
Fpu,
|
||||
|
||||
@@ -57,7 +57,7 @@ import Cur_Cycle :: *;
|
||||
// some parts of full_result are for verification
|
||||
// but some are truly used for execution
|
||||
|
||||
// ppc is only used by iType = BR/J/JR
|
||||
// ppc is only used by iType = BR/J/CJAL/JR
|
||||
// csrData is only used by iType = Csr
|
||||
// vaddr is only used by mem inst in page fault
|
||||
typedef union tagged {
|
||||
|
||||
Reference in New Issue
Block a user