A.
consider load/use hazard
E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB };
situation | 1 | 2 | 3 | 4 |
---|---|---|---|---|
E_dstM == d_srcA | 1 | 1 | 0 | 0 |
E_dstM == d_srcB | 1 | 0 | 1 | 0 |
situation 4:
normal, no hazard happens
situation 1,2,3:
load/use hazard happens
if E_icode in { IMRMOVQ, IPOPQ }, then E_dstM must not be RNONE
consider situation 1 and 3, E_dstM == d_srcB, then d_srcB is not RNONE and must be used in phase E, so load-forward can’t work. load-forward only work in situation 2!
consider all the instructions that d_srcA is not RNONE
instructions | d_srcA | valA used in phase E? | load-forward works? |
---|---|---|---|
rrmovq | rA | Y | N |
rmmovq | rA | N | Y |
opq | rA | Y | N |
pushq | rA | N | Y |
ret | rsp | N | N |
popq | rsp | N | N |
ret and popq can’t work because d_srcA == d_srcB == %rsp, that’s not in situation 2!!
finally, load/use only work in condition:
E_icode in { IMRMOVQ, IPOPQ } &&
(
E_dstM == d_srcB ||
(
E_dstM == d_srcA && !(D_icode in { IRMMOVQ, IPUSHQ })
)
);
B.
check file ./site/content/chapter4/code/sim/pipe/pipe-lf.hcl
only watch changes with origin pipe-lf.hcl
(cd ./site/content/chapter4/code/sim/pipe; diff -u origin-pipe-lf.hcl pipe-lf.hcl)
--- origin-pipe-lf.hcl 2021-02-25 07:26:33.309259378 +0000
+++ pipe-lf.hcl 2021-02-25 07:26:33.309259378 +0000
@@ -271,6 +271,7 @@
## from memory stage when appropriate
## Here it is set to the default used in the normal pipeline
word e_valA = [
+ E_icode in { IRMMOVQ, IPUSHQ } && E_srcA == M_dstM : m_valM;
1 : E_valA; # Use valA from stage pipe register
];
@@ -329,7 +330,13 @@
bool F_stall =
# Conditions for a load/use hazard
## Set this to the new load/use condition
- 0 ||
+ E_icode in { IMRMOVQ, IPOPQ } &&
+ (
+ E_dstM == d_srcB ||
+ (
+ E_dstM == d_srcA && !(D_icode in { IRMMOVQ, IPUSHQ })
+ )
+ ) ||
# Stalling at fetch while ret passes through pipeline
IRET in { D_icode, E_icode, M_icode };
@@ -338,15 +345,29 @@
bool D_stall =
# Conditions for a load/use hazard
## Set this to the new load/use condition
- 0;
+ E_icode in { IMRMOVQ, IPOPQ } &&
+ (
+ E_dstM == d_srcB ||
+ (
+ E_dstM == d_srcA && !(D_icode in { IRMMOVQ, IPUSHQ })
+ )
+ );
bool D_bubble =
# Mispredicted branch
(E_icode == IJXX && !e_Cnd) ||
# Stalling at fetch while ret passes through pipeline
# but not condition for a load/use hazard
- !(E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB }) &&
- IRET in { D_icode, E_icode, M_icode };
+ !(
+ E_icode in { IMRMOVQ, IPOPQ } &&
+ (
+ E_dstM == d_srcB ||
+ (
+ E_dstM == d_srcA && !(D_icode in { IRMMOVQ, IPUSHQ })
+ )
+ )
+ ) &&
+ IRET in { D_icode, E_icode, M_icode };
# Should I stall or inject a bubble into Pipeline Register E?
# At most one of these can be true.
@@ -356,7 +377,13 @@
(E_icode == IJXX && !e_Cnd) ||
# Conditions for a load/use hazard
## Set this to the new load/use condition
- 0;
+ E_icode in { IMRMOVQ, IPOPQ } &&
+ (
+ E_dstM == d_srcB ||
+ (
+ E_dstM == d_srcA && !(D_icode in { IRMMOVQ, IPUSHQ })
+ )
+ );
# Should I stall or inject a bubble into Pipeline Register M?
# At most one of these can be true.