CSAPP-4.56 Y32的跳转指令

流水线逻辑

流水线逻辑
f_pc: 当前要取什么
f_predPC: 下条取什么
bubble: 预测错误情况下是取消错误指令
有以下几种情形

选择分支

直接跳转,预测错误再改正
下条地址 -> D_valP -> E_valA -> M_valA

int f_pc = [
    # 发现分支预测错误,本不应该跳。现在继续下条指令。
    # M_valA由D_valP传递得
    M_icode == IJXX && !M_Cnd : M_valA;
    W_icode == IRET : W_valM;
    1 : F_predPC;
];
int f_predPC = [
    # ICALL直接跳
    # JXX 先直接跳,预测错了再执行JXX下一条指令
    f_icode in { IJXX, ICALL } : f_valC;
    1 : f_valP;
];
 # !e_Cnd 表示不能跳呀, 前面猜错了,故要bubble
bool D_bubble =
    (E_icode == IJXX && !e_Cnd) ||
    #其他省略
bool E_bubble =
    (E_icode == IJXX && !e_Cnd) ||
    #其他省略

不选择分支

先不跳转,预测错误再跳转
跳转地址 -> D_valC -> E_valC -> M_valE

int f_pc = [
    # M_valE由E中A+B得到
    M_icode == IJXX && !M_Cnd : M_valE;
    W_icode == IRET : W_valM;
    1 : F_predPC;
];
int f_predPC = [
    # IJXX先不跳转
    f_icode == ICALL : f_valC;
    1 : f_valP;
];
 # E 流水线寄存器 A是E_valC,B是0。
 # 先把跳转地址准备好,万一预测错误了
int aluA = [
	E_icode == IJXX : E_valC;#跳转地址
    # 其他指令省略
];
int aluB = [
	E_icode == IJXX : 0;
	# 其他指令省略
];
    # e_Cnd 说明是要能跳呀, 前面猜错了,故要bubble
bool D_bubble =
   (E_icode == IJXX && e_Cnd) || 0  #其他指令省略
bool E_bubble =
   (E_icode == IJXX && e_Cnd) || 0  #其他指令省略

无条件跳转

属于选择分支,直接跳转,而且肯定不会预测错,废话。
f_pc,D_icode,E_icode中的IJXX要改成IJXX && f_ifun != UNCOND
f_predPC中的IJXX要改成IJXX && f_ifun == UNCOND

前(后)向分支

前向分支:下条指令在分支指令前
后向分支:下条指令在分支指令后
谁在前就先执行谁

int f_pc = [
    # 等同[不选择分支]预测错误了,应该要跳转
    M_icode == IJXX && M_ifun != UNCOND && M_valE > M_valA &&  M_Cnd : M_valE;
    # 等同[选择分支]预测错误了,不应要跳转
    M_icode == IJXX && M_ifun != UNCOND && M_valE <=M_valA && !M_Cnd : M_valA;
    # 省略
];
int f_predPC = [
    # 无条件跳转肯定是不管前支不是后支
    f_icode == IJXX && f_ifun == UNCOND : f_valC;
    # 谁在前就先执行谁
    f_icode == IJXX && f_valC <= f_valP : f_valC;
    f_icode in { ICALL } : f_valC;
    1 : f_valP;
];
bool D_bubble =
    (E_icode == IJXX && E_ifun != UNCOND && E_valC > E_valA &&  e_Cnd) ||
    (E_icode == IJXX && E_ifun != UNCOND && E_valC <=E_valA && !e_Cnd) ||
    0 ;# 省略
bool E_bubble 

总结

无非两种情况,跳与不跳
如何选择跳与不跳? f_predPC预测下条指令
预测错了,正确指令在哪? M_Cnd(e_Cnd)反馈f_pc ( ps:M_Cnd = e_Cnd )
M的正确指令哪里来? PC取了一个地址后会把另一个地址一直传到E,由E判断后给M
预测错了,错误指令在怎么取消? 逻辑控制中的bubble