|
|
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: {
1.1.1.2 ! root 26: protected:
1.1 root 27: struct BranchEntry {
28: uint32 count; // 連続通過回数
29: uint32 from; // ジャンプ元アドレス(VA)
30: uint32 to; // ジャンプ先アドレス(VA)
1.1.1.2 ! root 31: uint32 inst; // ジャンプ元命令や例外情報など (機種による↓)
1.1 root 32: } __packed;
33:
34: public:
1.1.1.2 ! root 35: // 表示系フラグ
! 36: static const uint64 ExHist = (1ULL << 63); // ヘッダを例外履歴に
! 37: static const uint64 BottomToTop = (1ULL << 62); // 新しい方を下に
1.1 root 38:
1.1.1.2 ! root 39: public:
! 40: BranchHistory();
! 41: virtual ~BranchHistory() override;
1.1 root 42:
43: // エントリを追加。
44: // エントリを返す。
1.1.1.2 ! root 45: const BranchEntry& AddEntry(uint32 from, uint32 to, uint64 inst) {
1.1 root 46: BranchEntry *e = &entry[top];
47:
48: if (e->from == from && e->to == to) {
49: // 前回と同じなら通過回数++
50: e->count++;
51: } else {
52: // そうでなければ、新規エントリ
53: top++;
54: e = &entry[top];
55: e->count = 1;
56: e->from = from;
57: e->to = to;
1.1.1.2 ! root 58: e->inst = inst;
1.1 root 59: }
60: return *e;
61: }
62:
1.1.1.2 ! root 63: void MonitorUpdate(TextScreen&) override;
! 64:
! 65: // 使用中のエントリ数を取得する
! 66: int GetUsed() const;
! 67:
1.1 root 68: // 16バイト単位のテーブルなので16バイト境界に整列がよかろう。
69: alignas(16) BranchEntry entry[256] {};
70: // 直近に使用した位置
71: uint8 top {};
1.1.1.2 ! root 72:
! 73: protected:
! 74: virtual std::string FormatEntry(const BranchEntry& e) = 0;
! 75: };
! 76:
! 77: //
! 78: // m680x0 ブランチ履歴
! 79: // (MPU に依存しないとは一体…)
! 80: //
! 81: class BranchHistory_m680x0 : public BranchHistory
! 82: {
! 83: using inherited = BranchHistory;
! 84: public:
! 85: BranchHistory_m680x0();
! 86: virtual ~BranchHistory_m680x0() override;
! 87:
! 88: std::string FormatEntry(const BranchEntry& e) override;
! 89: };
! 90:
! 91: //
! 92: // m88xx0 ブランチ履歴
! 93: // (MPU に依存しないとは一体…)
! 94: //
! 95: class BranchHistory_m88xx0 : public BranchHistory
! 96: {
! 97: using inherited = BranchHistory;
! 98: public:
! 99: BranchHistory_m88xx0();
! 100: virtual ~BranchHistory_m88xx0() override;
! 101:
! 102: std::string FormatEntry(const BranchEntry& e) override;
1.1 root 103: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.