Annotation of nono/debugger/branchhistory.h, revision 1.1.1.6

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.