|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
1.1.1.3 root 7: //
1.1 root 8: // ブランチ履歴
1.1.1.3 root 9: //
1.1 root 10:
11: #pragma once
12:
13: #include "object.h"
14:
1.1.1.4 root 15: class VectorTable;
16:
1.1 root 17: // MPU に依存しないブランチ履歴。
18: //
19: // count = 0 なら書き込み前の無効エントリを示す。
20: // top がカーソルで、8ビットなので勝手に循環する。
21: // 直近と同じジャンプが連続する場合 count だけを増加させたいため、top は
22: // 次回の書き込み位置ではなく、直近の書き込み位置を指すことに注意。
23: //
24: // BranchHistory クラスはモニタを持つので Object からの継承になっているが
25: // 他の多くの Object 派生クラスと違ってグローバル参照は用意していない。
26: // というのもどの MPU のブランチ履歴かなので、MPU クラスから辿ることにする。
27:
28: class BranchHistory : public Object
29: {
1.1.1.2 root 30: using inherited = Object;
31:
1.1 root 32: protected:
33: struct BranchEntry {
34: uint32 count; // 連続通過回数
35: uint32 from; // ジャンプ元アドレス(VA)
36: uint32 to; // ジャンプ先アドレス(VA)
1.1.1.9 ! root 37: uint32 info; // ジャンプ元命令や例外情報など (機種による)
1.1 root 38: } __packed;
39:
40: public:
41: // 表示系フラグ
1.1.1.2 root 42: static const uint64 BottomToTop = (1ULL << 63); // 新しい方を下に
1.1 root 43:
44: public:
1.1.1.7 root 45: explicit BranchHistory(uint objid_);
1.1.1.6 root 46: ~BranchHistory() override;
1.1 root 47:
48: // 初期化
49: void Clear();
50:
51: // エントリを追加。
52: // エントリを返す。
1.1.1.9 ! root 53: const BranchEntry& AddEntry(uint32 from, uint32 to, uint32 info) {
1.1 root 54: BranchEntry *e = &entry[top];
55:
56: if (e->from == from && e->to == to) {
57: // 前回と同じなら通過回数++
58: e->count++;
59: } else {
60: // そうでなければ、新規エントリ
61: top++;
62: e = &entry[top];
63: e->count = 1;
64: e->from = from;
65: e->to = to;
1.1.1.9 ! root 66: e->info = info;
1.1 root 67: }
68: return *e;
69: }
70:
71: // 使用中のエントリ数を取得する
72: int GetUsed() const;
73:
74: // 16バイト単位のテーブルなので16バイト境界に整列がよかろう。
75: alignas(16) BranchEntry entry[256] {};
76: // 直近に使用した位置
77: uint8 top {};
78:
1.1.1.4 root 79: // モニタ (デバッガから直接参照する)
1.1.1.8 root 80: Monitor *monitor {};
1.1.1.2 root 81:
1.1 root 82: protected:
1.1.1.4 root 83: virtual std::string FormatHeader() const;
1.1 root 84: virtual std::string FormatEntry(const BranchEntry& e) = 0;
1.1.1.2 root 85:
86: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
87:
88: // 例外履歴かどうか。ヘッダ行が違う。
89: bool is_exhist {};
1.1.1.4 root 90:
91: // カウンタの表示開始座標 (HD64180 だけ違うため)
92: int x_count {};
93:
94: VectorTable *vectortable {};
1.1 root 95: };
96:
97: //
98: // m680x0 ブランチ履歴
99: // (MPU に依存しないとは一体…)
100: //
101: class BranchHistory_m680x0 : public BranchHistory
102: {
103: using inherited = BranchHistory;
1.1.1.9 ! root 104:
! 105: // info の分岐種別
! 106: static constexpr uint32 NORMAL = 0x00000000; // 通常分岐
! 107: static constexpr uint32 VECTORJUMP = 0x40000000; // ベクタによる分岐
! 108: static constexpr uint32 SERVICECALL = 0x80000000; // IOCS/DOS コール
! 109: static constexpr uint32 EXCEPTION = 0xc0000000; // 例外発生
! 110:
1.1.1.5 root 111: public:
1.1.1.7 root 112: explicit BranchHistory_m680x0(uint objid_);
1.1.1.6 root 113: ~BranchHistory_m680x0() override;
1.1 root 114:
1.1.1.9 ! root 115: static constexpr uint32 InfoNormal(uint16 inst) {
! 116: return NORMAL | inst;
! 117: }
! 118: static constexpr uint32 InfoVectorJump() {
! 119: return VECTORJUMP;
! 120: }
! 121: static constexpr uint32 InfoException(uint8 vector) {
! 122: return EXCEPTION | vector;
! 123: }
! 124: static constexpr uint32 InfoIOCSCall(uint8 num) {
! 125: return SERVICECALL | num;
! 126: }
! 127: static constexpr uint32 InfoDOSCall(uint16 ir) {
! 128: return SERVICECALL | ir;
! 129: }
! 130:
1.1 root 131: std::string FormatEntry(const BranchEntry& e) override;
132: };
133:
134: //
135: // m88xx0 ブランチ履歴
136: // (MPU に依存しないとは一体…)
137: //
138: class BranchHistory_m88xx0 : public BranchHistory
139: {
140: using inherited = BranchHistory;
141: public:
1.1.1.7 root 142: explicit BranchHistory_m88xx0(uint objid_);
1.1.1.6 root 143: ~BranchHistory_m88xx0() override;
1.1 root 144:
145: std::string FormatEntry(const BranchEntry& e) override;
146: };
1.1.1.4 root 147:
148: //
149: // HD64180 ブランチ履歴
150: //
151: class BranchHistory_hd64180 : public BranchHistory
152: {
153: using inherited = BranchHistory;
154: public:
1.1.1.7 root 155: explicit BranchHistory_hd64180(uint objid_);
1.1.1.6 root 156: ~BranchHistory_hd64180() override;
1.1.1.4 root 157:
158: std::string FormatHeader() const override;
159: std::string FormatEntry(const BranchEntry& e) override;
160:
161: private:
162: static std::string fstr(int);
163: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.