/*
 * fwrisc_ctest_base.cpp
 *
 *  Created on: Nov 19, 2018
 *      Author: ballance
 */

#include "fwrisc_ctest_base.h"

#include <stdio.h>
#include "CmdlineProcessor.h"

fwrisc_ctest_base::fwrisc_ctest_base(uint32_t timeout) : fwrisc_instr_tests(timeout) {
	// TODO Auto-generated constructor stub

}

fwrisc_ctest_base::~fwrisc_ctest_base() {
	// TODO Auto-generated destructor stub
}

void fwrisc_ctest_base::SetUp() {
	const CmdlineProcessor &clp = GoogletestHdl::clp();
	std::string elf_file, v;
	fwrisc_instr_tests::SetUp();

	m_trace_funcs = clp.has_plusarg("+TRACE_FUNCS");
	m_trace_instr = clp.has_plusarg("+TRACE_INSTR");
	m_trace_regs  = clp.has_plusarg("+TRACE_REGS");


	clp.get_plusarg_value("+SW_IMAGE", elf_file);

	if (!m_symtab.read(elf_file)) {
		fprintf(stdout, "Error: failed to read elf file\n");
	}

//	m_ram_console = m_symtab.find_sym("ram_console").st_value;
//	// _Fault is called when the main function returns
//	m_halt_addr = m_symtab.find_sym("_Fault").st_value;
//	fprintf(stdout, "Ram Console: 0x%08x\n", m_ram_console);
}

void fwrisc_ctest_base::exec(uint32_t addr, uint32_t instr) {
//	fprintf(stdout, "exec: 0x%08x\n", addr);
	if (m_call_stack.size() == 0) {
		// Look for an entry symbol
		int32_t sym_idx;

		if ((sym_idx = m_symtab.find_sym(addr)) != -1) {
			if (sym_idx+1 >= m_symtab.n_syms()) {
				fprintf(stdout, "Error: entering the last symbol in the file\n");
				fflush(stdout);
			}
			const Elf32_Sym &next = m_symtab.get_sym(sym_idx+1);
			const std::string &func = m_symtab.get_sym_name(sym_idx);
			if (m_filter_funcs.find(func) == m_filter_funcs.end()) {
				enter_func(next.st_value, func);
			}
			m_call_stack.push(std::pair<Elf32_Addr,Elf32_Addr>(addr,next.st_value-4));
		}
	} else {
		// We should be in a function
		const std::pair<Elf32_Addr,Elf32_Addr> &func = m_call_stack.top();

		if (addr < func.first || addr > func.second) {
			// We're outside the current function
			int32_t sym_idx;

			if ((sym_idx = m_symtab.find_sym(addr)) != -1) {
				// We jumped to the beginning of a new function
				// Consider this entering a new function
				if (sym_idx+1 >= m_symtab.n_syms()) {
					fprintf(stdout, "Error: entering the last symbol in the file\n");
					fflush(stdout);
				}
				const Elf32_Sym &next = m_symtab.get_sym(sym_idx+1);
				const std::string &func = m_symtab.get_sym_name(sym_idx);
				if (m_filter_funcs.find(func) == m_filter_funcs.end()) {
					enter_func(next.st_value, func);
				}
				m_call_stack.push(std::pair<Elf32_Addr,Elf32_Addr>(addr,next.st_value-4));
			} else {
				sym_idx = m_symtab.find_sym(func.first);
				// Consider this exiting the current scope
				m_call_stack.pop();

				if (m_call_stack.size() > 0) {
					const std::pair<Elf32_Addr,Elf32_Addr> &new_func = m_call_stack.top();

					if (addr >= new_func.first && addr <= new_func.second) {
						const std::string &func = m_symtab.get_sym_name(sym_idx);
						if (m_filter_funcs.find(func) == m_filter_funcs.end()) {
							leave_func(new_func.first, func);
						}
					} else {
//						fprintf(stdout, "Error: left function for unknown scope 0x%08x..0x%08x (0x%08x)\n",
//							new_func.first, new_func.second, addr);
//					fflush(stdout);
					}
				} else {
					fprintf(stdout, "Error: stack is now empty\n");
					fflush(stdout);
				}
			}
		}
	}

//	std::string sym;
//	if (m_trace_funcs) {
//		if (m_symtab.find_sym(addr, sym)) {
//			fprintf(stdout, "EXEC: %s (0x%08x)\n", sym.c_str(), addr);
//		}
//	}
	if (m_trace_instr) {
		fprintf(stdout, "EXEC: 0x%08x 0x%08x\n", addr, instr);
	}

	if (addr == m_halt_addr) {
		fprintf(stdout, "hit halt address 0x%08x\n", m_halt_addr);
		m_end_of_test = true;
		GoogletestHdl::dropObjection();
	}
}

void fwrisc_ctest_base::regwrite(uint32_t raddr, uint32_t rdata) {
	if (m_trace_regs) {
		fprintf(stdout, "regwrite 0x%02x <= 0x%08x\n", raddr, rdata);
	}
}

void fwrisc_ctest_base::enter_func(uint32_t addr, const std::string &name) {
	if (m_trace_funcs) {
		fprintf(stdout, "%s==> %s\n", m_indent.c_str(), name.c_str());
		fflush(stdout);
		m_indent.append("  ");
	}
}

void fwrisc_ctest_base::leave_func(uint32_t addr, const std::string &name) {
	if (m_trace_funcs) {
		m_indent = m_indent.substr(0, m_indent.size()-2);
		fprintf(stdout, "%s<== %s\n", m_indent.c_str(), name.c_str());
		fflush(stdout);
	}
}

