|
|
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.