執行一道分支(branch)
一道分支指令決定要直線繼續走,還是跳到程式的另一部分——它就是迴圈與 if 敘述如何化為機器動作。以「beq x1, x2, L」為例,意思是「若 x1 等於 x2,就到標籤 L 繼續執行;否則就走到下一道指令」。追蹤一道分支,能看出資料路徑如何同時測試條件並選擇下一道指令的位址。
有兩件運算同時進行。其一是比較:暫存器檔讀出 x1 與 x2,ALU 把它們相減,結果為「零」就表示兩者相等(這就是條件測試)。其二是目標位址:分支偏移從指令取出、符號擴展,再與目前的 PC 相加,算出分支目標(PC + 偏移)。然後資料路徑最前端的一個多工器選擇下一個 PC:若分支成立(ALU 的零旗標被設定,且 Branch 控制訊號為 1),下一個 PC 就是分支目標;否則下一個 PC 就是普通的 PC + 4。
誠實的微妙之處:分支不寫任何暫存器,也不碰資料記憶體(RegWrite、MemRead、MemWrite 全為 0)。它唯一的作用在程式計數器上——它引導接下來執行什麼。正因如此,在接下來的管線章節裡,分支會造成控制危障:機器往往在還不知道分支是否成立之前,就已經開始提取直線落下的那道指令。在單週期模型裡沒有這個問題,因為下一個 PC 在同一個週期內就確定了。
對「beq x1, x2, L」且 x1 = 5、x2 = 5:ALU 算出 5 − 5 = 0,於是零旗標被設定;Branch 為 1,所以下一個 PC 的多工器選擇 PC + 偏移(L 的位址)。若 x1 是 7,差值便非零,下一個 PC 就只是 PC + 4。
分支用 ALU 測試條件,再由多工器選下一個 PC:成立則選目標位址,否則選 PC + 4。
分支的全部工作就是設定下一個 PC,它不寫任何暫存器。「成立(taken)」只是表示條件為真、PC 跳到目標——並不是某種另類的寫回。