Exemplo n.º 1
0
        public uint Lookup(uint baddr, uint btarget, DynamicInstruction dynamicInst, out BranchPredictorUpdate dirUpdate, out uint stackRecoverIndex)
        {
            StaticInstruction staticInst = dynamicInst.StaticInstruction;

            if (!staticInst.IsControl) {
                dirUpdate = null;
                stackRecoverIndex = 0;

                return 0;
            }

            dirUpdate = new BranchPredictorUpdate ();
            dirUpdate.Ras = false;
            dirUpdate.Pdir1 = null;
            dirUpdate.Pdir2 = null;
            dirUpdate.Pmeta = null;

            if (staticInst.IsControl && !staticInst.IsUnconditionalBranch) {
                BranchPredictorInfo bimodCtr = this.Bimod.Lookup (baddr);
                BranchPredictorInfo twoLevelCtr = this.TwoLevel.Lookup (baddr);
                BranchPredictorInfo metaCtr = this.Meta.Lookup (baddr);

                dirUpdate.Pmeta = metaCtr;
                dirUpdate.Meta = (metaCtr.Value >= 2);
                dirUpdate.Bimod = (bimodCtr.Value >= 2);
                dirUpdate.TwoLevel = (bimodCtr.Value >= 2);

                if (metaCtr.Value >= 2) {
                    dirUpdate.Pdir1 = twoLevelCtr;
                    dirUpdate.Pdir2 = bimodCtr;
                } else {
                    dirUpdate.Pdir1 = bimodCtr;
                    dirUpdate.Pdir2 = twoLevelCtr;
                }
            }

            if (this.Ras.Size > 0) {
                stackRecoverIndex = this.Ras.TopOfStack;
            } else {
                stackRecoverIndex = 0;
            }

            if (staticInst.IsFunctionReturn && this.Ras.Size > 0) {
                this.Ras.TopOfStack = (this.Ras.TopOfStack + this.Ras.Size - 1) % this.Ras.Size;
                dirUpdate.Ras = true;
            }

            if (staticInst.IsFunctionCall && this.Ras.Size > 0) {
                this.Ras.TopOfStack = (this.Ras.TopOfStack + 1) % this.Ras.Size;
                this.Ras[this.Ras.TopOfStack].Target = (uint)(baddr + Marshal.SizeOf (typeof(uint)));
            }

            uint index = (baddr >> (int)BranchPredictorConstants.BRANCH_SHIFT) & (this.Btb.NumSets - 1);

            BranchTargetBufferEntry btbEntry = null;

            if (this.Btb.Associativity > 1) {
                index *= this.Btb.Associativity;

                for (uint i = index; i < (index + this.Btb.Associativity); i++) {
                    if (this.Btb[i].Addr == baddr) {
                        btbEntry = this.Btb[i];
                        break;
                    }
                }
            } else {
                btbEntry = this.Btb[index];
                if (btbEntry.Addr != baddr) {
                    btbEntry = null;
                }
            }

            if (staticInst.IsControl && staticInst.IsUnconditionalBranch) {
                return btbEntry != null ? btbEntry.Target : 1;
            }

            if (btbEntry == null) {
                return (uint)(dirUpdate.Pdir1.Value >= 2 ? 1 : 0);
            } else {
                return (uint)(dirUpdate.Pdir1.Value >= 2 ? btbEntry.Target : 0);
            }
        }
Exemplo n.º 2
0
        public void Update(uint baddr, uint btarget, bool isTaken, bool isPredTaken, bool isCorrect, DynamicInstruction dynamicInst, BranchPredictorUpdate dirUpdate)
        {
            StaticInstruction staticInst = dynamicInst.StaticInstruction;

            BranchTargetBufferEntry btbEntry = null;

            if (!staticInst.IsControl) {
                return;
            }

            if (staticInst.IsControl && !staticInst.IsUnconditionalBranch) {
                uint l1Index = (baddr >> (int)BranchPredictorConstants.BRANCH_SHIFT) & (this.TwoLevel.L1Size - 1);
                uint shiftReg = (this.TwoLevel.ShiftRegs[l1Index] << 1) | (uint)(isTaken ? 1 : 0);
                this.TwoLevel.ShiftRegs[l1Index] = (uint)(shiftReg & ((1 << (int)this.TwoLevel.ShiftWidth) - 1));
            }

            if (isTaken) {
                uint index = (baddr >> (int)BranchPredictorConstants.BRANCH_SHIFT) & (this.Btb.NumSets - 1);

                if (this.Btb.Associativity > 1) {
                    index *= this.Btb.Associativity;

                    BranchTargetBufferEntry lruHead = null, lruItem = null;

                    for (uint i = index; i < (index + this.Btb.Associativity); i++) {
                        if (this.Btb[i].Addr == baddr) {
                            btbEntry = this.Btb[i];
                        }

                        if (this.Btb[i].Prev == null) {
                            lruHead = this.Btb[i];
                        }

                        if (this.Btb[i].Next == null) {
                            lruItem = this.Btb[i];
                        }
                    }

                    if (btbEntry == null) {
                        btbEntry = lruItem;
                    }

                    if (btbEntry != lruHead) {
                        if (btbEntry.Prev != null) {
                            btbEntry.Prev.Next = btbEntry.Next;
                        }

                        if (btbEntry.Next != null) {
                            btbEntry.Next.Prev = btbEntry.Prev;
                        }

                        btbEntry.Next = lruHead;
                        btbEntry.Prev = null;
                        lruHead.Prev = btbEntry;
                    }
                } else {
                    btbEntry = this.Btb[index];
                }
            }

            if (dirUpdate.Pdir1 != null) {
                if (isTaken) {
                    if (dirUpdate.Pdir1.Value < 3) {
                        dirUpdate.Pdir1.Value++;
                    }
                } else {
                    if (dirUpdate.Pdir1.Value > 0) {
                        dirUpdate.Pdir1.Value--;
                    }
                }
            }

            if (dirUpdate.Pdir2 != null) {
                if (isTaken) {
                    if (dirUpdate.Pdir2.Value < 3) {
                        dirUpdate.Pdir2.Value++;
                    }
                } else {
                    if (dirUpdate.Pdir2.Value > 0) {
                        dirUpdate.Pdir2.Value--;
                    }
                }
            }

            if (dirUpdate.Pmeta != null) {
                if (dirUpdate.Bimod != dirUpdate.TwoLevel) {
                    if (dirUpdate.TwoLevel == isTaken) {
                        if (dirUpdate.Pmeta.Value < 3) {
                            dirUpdate.Pmeta.Value++;
                        }
                    } else {
                        if (dirUpdate.Pmeta.Value > 0) {
                            dirUpdate.Pmeta.Value--;
                        }
                    }
                }
            }

            if (btbEntry != null) {
                if (btbEntry.Addr == baddr) {
                    if (!isCorrect) {
                        btbEntry.Target = btarget;
                    }
                } else {
                    btbEntry.Addr = baddr;
                    btbEntry.StaticInstruction = staticInst;
                    btbEntry.Target = btarget;
                }
            }
        }
Exemplo n.º 3
0
        public void Fetch()
        {
            uint cacheLineToFetch = BitHelper.Aligned (this.FetchNpc, this.Core.ICache.Cache.LineSize);
            if (cacheLineToFetch != this.LastFetchedCacheLine) {
                this.LastFetchedCacheLine = cacheLineToFetch;

                this.IFetch (this.Core.Processor.MMU.GetPhysicalAddress (this.MemoryMapId, this.FetchNpc), false, () => this.IsFetchStalled = false);

                this.IsFetchStalled = true;
            }

            bool hasDone = false;

            while (!hasDone && !this.DecodeBuffer.IsFull (this.Core.Processor.Config.DecodeBufferCapcity) && !this.IsFetchStalled) {
                if (this.SetNpc ()) {
                    this.Regs.IsSpeculative = this.IsSpeculative = true;
                }

                this.FetchPc = this.FetchNpc;
                this.FetchNpc = this.FetchNnpc;

                DynamicInstruction dynamicInst = this.DecodeAndExecute ();

                if (this.FetchNpc != this.FetchPc + Marshal.SizeOf (typeof(uint))) {
                    hasDone = true;
                }

                if ((this.FetchPc + Marshal.SizeOf (typeof(uint))) % this.Core.ICache.Cache.LineSize == 0) {
                    hasDone = true;
                }

                uint stackRecoverIndex;
                BranchPredictorUpdate dirUpdate = new BranchPredictorUpdate ();

                uint dest = this.Bpred.Lookup (this.Core.Processor.MMU.GetPhysicalAddress (this.MemoryMapId, this.FetchPc), 0, dynamicInst, out dirUpdate, out stackRecoverIndex);
                this.FetchNnpc = dest <= 1 ? (uint)(this.FetchNpc + Marshal.SizeOf (typeof(uint))) : dest;

                this.FetchNnpc = this.Regs.Nnpc;
                //TODO: remove it
                DecodeBufferEntry decodeBufferEntry = new DecodeBufferEntry (dynamicInst);
                decodeBufferEntry.Npc = this.Regs.Npc;
                decodeBufferEntry.Nnpc = this.Regs.Nnpc;
                decodeBufferEntry.PredNpc = this.FetchNpc;
                decodeBufferEntry.PredNnpc = this.FetchNnpc;
                decodeBufferEntry.StackRecoverIndex = stackRecoverIndex;
                decodeBufferEntry.DirUpdate = dirUpdate;
                decodeBufferEntry.IsSpeculative = this.IsSpeculative;

                this.DecodeBuffer.Add (decodeBufferEntry);
            }
        }