BOOMのBranchTagについての解析の続き。分岐命令の予測が外れて、分岐がジャンプする方向に分岐が飛んだものとする。これがこの波形。
この部分のようだ。ずっとBEQ
でループを繰り返していたが、ループの終了で予測が外れている。
121368 3 0x00000000800015ee sb a0, 0(a5) 121369 3 0x00000000800015f2 addi a4, sp, 63 x14 0x0000000080024ccf 121369 3 0x00000000800015f6 c.li a5, 10 x15 0x000000000000000a 121370 3 0x00000000800015f8 andi a4, a4, -64 x14 0x0000000080024cc0 // この命令の分岐予測が外れる 121370 3 0x00000000800015fc beq a0, a5, pc + 18 // 160eへジャンプ 121380 3 0x000000008000160e li a5, 64 x15 0x0000000000000040 121380 3 0x0000000080001612 c.sd a5, 0(a4) 121381 3 0x0000000080001614 c.li a5, 1 x15 0x0000000000000001 121381 3 0x0000000080001616 c.sd a5, 8(a4) 121382 3 0x0000000080001618 mv a2, tp x12 0x0000000080005100 121382 3 0x000000008000161c c.sd a2, 16(a4) 121383 3 0x000000008000161e c.sd a3, 24(a4) 121423 3 0x0000000080001620 fence 121437 3 0x0000000080001624 auipc a5, 0x0 x15 0x0000000080001624 121442 3 0x0000000080001628 sd a4, -1572(a5) 121443 3 0x000000008000162c auipc a3, 0x0 x13 0x000000008000162c 121445 3 0x0000000080001630 addi a3, a3, -1516 x13 0x0000000080001040
もう少し波形を追いかけてみると、命令キャッシュの格納されているフロントエンド側にリダイレクト用の信号が飛んでおり、これに基づいて命令キャッシュアドレスが変更されている。
これを作り出しているのが以下のChiselの実装部分。mispredictで動くようになっている。
src/main/scala/exu/core.scala
} .elsewhen (brupdate.b2.mispredict && !RegNext(rob.io.flush.valid)) { val block_pc = AlignPCToBoundary(io.ifu.get_pc(1).pc, icBlockBytes) val uop_maybe_pc = block_pc | brupdate.b2.uop.pc_lob val npc = uop_maybe_pc + Mux(brupdate.b2.uop.is_rvc || brupdate.b2.uop.edge_inst, 2.U, 4.U) val jal_br_target = Wire(UInt(vaddrBitsExtended.W)) jal_br_target := (uop_maybe_pc.asSInt + brupdate.b2.target_offset + (Fill(vaddrBitsExtended-1, brupdate.b2.uop.edge_inst) << 1).asSInt).asUInt val bj_addr = Mux(brupdate.b2.cfi_type === CFI_JALR, brupdate.b2.jalr_target, jal_br_target) val mispredict_target = Mux(brupdate.b2.pc_sel === PC_PLUS4, npc, bj_addr) io.ifu.redirect_val := true.B io.ifu.redirect_pc := mispredict_target io.ifu.redirect_flush := true.B io.ifu.redirect_ftq_idx := brupdate.b2.uop.ftq_idx val use_same_ghist = (brupdate.b2.cfi_type === CFI_BR &&