File:  [Isaki's NoNo m68k/m88k emulator] / nono / lib / branchhistory.h
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:04:40 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v006, HEAD
nono 0.1.2

//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//

// ブランチ履歴

#pragma once

#include "object.h"

// MPU に依存しないブランチ履歴。
//
// count = 0 なら書き込み前の無効エントリを示す。
// top がカーソルで、8ビットなので勝手に循環する。
// 直近と同じジャンプが連続する場合 count だけを増加させたいため、top は
// 次回の書き込み位置ではなく、直近の書き込み位置を指すことに注意。
//
// BranchHistory クラスはモニタを持つので Object からの継承になっているが
// 他の多くの Object 派生クラスと違ってグローバル参照は用意していない。
// というのもどの MPU のブランチ履歴かなので、MPU クラスから辿ることにする。

class BranchHistory : public Object
{
 protected:
	struct BranchEntry {
		uint32 count;	// 連続通過回数
		uint32 from;	// ジャンプ元アドレス(VA)
		uint32 to;		// ジャンプ先アドレス(VA)
		uint32 inst;	// ジャンプ元命令や例外情報など (機種による↓)
	} __packed;

 public:
	// 表示系フラグ
	static const uint64 ExHist		= (1ULL << 63);	// ヘッダを例外履歴に
	static const uint64 BottomToTop	= (1ULL << 62);	// 新しい方を下に

 public:
	BranchHistory();
	virtual ~BranchHistory() override;

	// 初期化
	void Clear();

	// エントリを追加。
	// エントリを返す。
	const BranchEntry& AddEntry(uint32 from, uint32 to, uint32 inst) {
		BranchEntry *e = &entry[top];

		if (e->from == from && e->to == to) {
			// 前回と同じなら通過回数++
			e->count++;
		} else {
			// そうでなければ、新規エントリ
			top++;
			e = &entry[top];
			e->count = 1;
			e->from  = from;
			e->to    = to;
			e->inst = inst;
		}
		return *e;
	}

	void MonitorUpdate(TextScreen&) override;

	// 使用中のエントリ数を取得する
	int GetUsed() const;

	// 16バイト単位のテーブルなので16バイト境界に整列がよかろう。
	alignas(16) BranchEntry entry[256] {};
	// 直近に使用した位置
	uint8 top {};

 protected:
	virtual std::string FormatEntry(const BranchEntry& e) = 0;
};

//
// m680x0 ブランチ履歴
// (MPU に依存しないとは一体…)
//
class BranchHistory_m680x0 : public BranchHistory
{
	using inherited = BranchHistory;
 public:
	BranchHistory_m680x0();
	virtual ~BranchHistory_m680x0() override;

	std::string FormatEntry(const BranchEntry& e) override;
};

//
// m88xx0 ブランチ履歴
// (MPU に依存しないとは一体…)
//
class BranchHistory_m88xx0 : public BranchHistory
{
	using inherited = BranchHistory;
 public:
	BranchHistory_m88xx0();
	virtual ~BranchHistory_m88xx0() override;

	std::string FormatEntry(const BranchEntry& e) override;
};

unix.superglobalmegacorp.com

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