FetchStage.bsv: Fix fav_parse_insts when pending_straddle has "even" PC
Despite the name, we can end up having a pending_straddle at an "even" PC (and thus an "odd" pc_start). In this case, we would erroneously treat it as if pc_start were "even", effectively shifting all the instruction parcels along by one and duplicating the first one, since the first element of the parcels vector will be a copy of the straddle's parcel itself. Instead, we should just ignore pending_straddle when determining where to start in the parcels vector, as the two are completely independent, and no longer hard-code that the straddle is merged with element 0. This can happen if we predict that the first half of an uncompressed instruction is a taken branch. We will have the instruction bytes available, but not the prediction information, so still have to do a normal Fetch3 redirect in the same manner as an unaligned uncompressed instruction. We could perhaps special-case with a fast-path (or query the predictor directly in Fetch3), but it should hit in the TLB and L1 cache, and is probably not common enough to warrant the complexity. The FreeRTOS-based netboot loader trips up on this as it overwrites itself with the payload, and thus all the branch prediction still has many taken branch entries, most of which will not be correct.
This commit is contained in:
@@ -272,8 +272,8 @@ function ActionValue #(Tuple4 #(SupCntX2,
|
||||
orig_inst: 0,
|
||||
inst: 0});
|
||||
Maybe #(Tuple3 #(Addr, Bit #(16), Bool)) next_straddle = tagged Invalid;
|
||||
// Start parse at parcel 0/1 depending on pc lsbs and pending straddle
|
||||
SupCntX2 j = ((pc_start [1:0] == 2'b00 || isValid(pending_straddle)) ? 0 : 1);
|
||||
// Start parse at parcel 0/1 depending on pc lsbs.
|
||||
SupCntX2 j = (pc_start [1:0] == 2'b00 ? 0 : 1);
|
||||
Addr pc = pc_start;
|
||||
Integer n_items = 0;
|
||||
for (Integer i = 0; i < valueOf (SupSizeX2); i = i + 1) begin
|
||||
@@ -289,9 +289,9 @@ function ActionValue #(Tuple4 #(SupCntX2,
|
||||
end
|
||||
pc = s_pc;
|
||||
inst_kind = Inst_32b;
|
||||
orig_inst = { v_x16[0], s_lsbs };
|
||||
orig_inst = { v_x16[j], s_lsbs };
|
||||
inst = orig_inst;
|
||||
j = 1;
|
||||
j = j + 1;
|
||||
next_pc = s_pc + 4;
|
||||
n_items = 1;
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user