|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2020 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ブランチ履歴 ! 8: ! 9: #pragma once ! 10: ! 11: #include "object.h" ! 12: ! 13: // MPU に依存しないブランチ履歴。 ! 14: // ! 15: // count = 0 なら書き込み前の無効エントリを示す。 ! 16: // top がカーソルで、8ビットなので勝手に循環する。 ! 17: // 直近と同じジャンプが連続する場合 count だけを増加させたいため、top は ! 18: // 次回の書き込み位置ではなく、直近の書き込み位置を指すことに注意。 ! 19: // ! 20: // BranchHistory クラスはモニタを持つので Object からの継承になっているが ! 21: // 他の多くの Object 派生クラスと違ってグローバル参照は用意していない。 ! 22: // というのもどの MPU のブランチ履歴かなので、MPU クラスから辿ることにする。 ! 23: ! 24: class BranchHistory : public Object ! 25: { ! 26: protected: ! 27: struct BranchEntry { ! 28: uint32 count; // 連続通過回数 ! 29: uint32 from; // ジャンプ元アドレス(VA) ! 30: uint32 to; // ジャンプ先アドレス(VA) ! 31: uint32 inst; // ジャンプ元命令や例外情報など (機種による↓) ! 32: } __packed; ! 33: ! 34: public: ! 35: // 表示系フラグ ! 36: static const uint64 ExHist = (1ULL << 63); // ヘッダを例外履歴に ! 37: static const uint64 BottomToTop = (1ULL << 62); // 新しい方を下に ! 38: ! 39: public: ! 40: BranchHistory(); ! 41: virtual ~BranchHistory() override; ! 42: ! 43: // 初期化 ! 44: void Clear(); ! 45: ! 46: // エントリを追加。 ! 47: // エントリを返す。 ! 48: const BranchEntry& AddEntry(uint32 from, uint32 to, uint32 inst) { ! 49: BranchEntry *e = &entry[top]; ! 50: ! 51: if (e->from == from && e->to == to) { ! 52: // 前回と同じなら通過回数++ ! 53: e->count++; ! 54: } else { ! 55: // そうでなければ、新規エントリ ! 56: top++; ! 57: e = &entry[top]; ! 58: e->count = 1; ! 59: e->from = from; ! 60: e->to = to; ! 61: e->inst = inst; ! 62: } ! 63: return *e; ! 64: } ! 65: ! 66: void MonitorUpdate(TextScreen&) override; ! 67: ! 68: // 使用中のエントリ数を取得する ! 69: int GetUsed() const; ! 70: ! 71: // 16バイト単位のテーブルなので16バイト境界に整列がよかろう。 ! 72: alignas(16) BranchEntry entry[256] {}; ! 73: // 直近に使用した位置 ! 74: uint8 top {}; ! 75: ! 76: protected: ! 77: virtual std::string FormatEntry(const BranchEntry& e) = 0; ! 78: }; ! 79: ! 80: // ! 81: // m680x0 ブランチ履歴 ! 82: // (MPU に依存しないとは一体…) ! 83: // ! 84: class BranchHistory_m680x0 : public BranchHistory ! 85: { ! 86: using inherited = BranchHistory; ! 87: public: ! 88: BranchHistory_m680x0(); ! 89: virtual ~BranchHistory_m680x0() override; ! 90: ! 91: std::string FormatEntry(const BranchEntry& e) override; ! 92: }; ! 93: ! 94: // ! 95: // m88xx0 ブランチ履歴 ! 96: // (MPU に依存しないとは一体…) ! 97: // ! 98: class BranchHistory_m88xx0 : public BranchHistory ! 99: { ! 100: using inherited = BranchHistory; ! 101: public: ! 102: BranchHistory_m88xx0(); ! 103: virtual ~BranchHistory_m88xx0() override; ! 104: ! 105: std::string FormatEntry(const BranchEntry& e) override; ! 106: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.