diff options
author | Kartik Agaram <vc@akkartik.com> | 2019-02-25 00:17:46 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2019-02-25 01:50:53 -0800 |
commit | c442a5ad806b6cccbb3ec4c5744b14b0c1f31a01 (patch) | |
tree | 318fb1d56e7ee3c750635d3326ad0739dfdacefe /subx/010---vm.cc | |
parent | e5998f74ac29bb4bf2aedfdd6fbea801ffdb08f6 (diff) | |
download | mu-c442a5ad806b6cccbb3ec4c5744b14b0c1f31a01.tar.gz |
4987 - support `browse_trace` tool in SubX
I've extracted it into a separate binary, independent of my Mu prototype. I also cleaned up my tracing layer to be a little nicer. Major improvements: - Realized that incremental tracing really ought to be the default. And to minimize printing traces to screen. - Finally figured out how to combine layers and call stack frames in a single dimension of depth. The answer: optimize for the experience of `browse_trace`. Instructions occupy a range of depths based on their call stack frame, and minor details of an instruction lie one level deeper in each case. Other than that, I spent some time adjusting levels everywhere to make `browse_trace` useful.
Diffstat (limited to 'subx/010---vm.cc')
-rw-r--r-- | subx/010---vm.cc | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/subx/010---vm.cc b/subx/010---vm.cc index 0d30f3cd..4c346a3d 100644 --- a/subx/010---vm.cc +++ b/subx/010---vm.cc @@ -92,7 +92,7 @@ SF = ZF = OF = false; /* arg1 and arg2 must be signed */ \ int64_t tmp = arg1 op arg2; \ arg1 = arg1 op arg2; \ - trace(90, "run") << "storing 0x" << HEXWORD << arg1 << end(); \ + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << arg1 << end(); \ SF = (arg1 < 0); \ ZF = (arg1 == 0); \ OF = (arg1 != tmp); \ @@ -103,7 +103,7 @@ SF = ZF = OF = false; #define BINARY_BITWISE_OP(op, arg1, arg2) { \ /* arg1 and arg2 must be unsigned */ \ arg1 = arg1 op arg2; \ - trace(90, "run") << "storing 0x" << HEXWORD << arg1 << end(); \ + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << arg1 << end(); \ SF = (arg1 >> 31); \ ZF = (arg1 == 0); \ OF = false; \ @@ -296,13 +296,13 @@ inline bool already_allocated(uint32_t addr) { void run_one_instruction() { uint8_t op=0, op2=0, op3=0; // Run One Instruction - if (Dump_trace) { + if (Trace_file) { dump_registers(); // End Dump Info for Instruction } - trace(90, "run") << "inst: 0x" << HEXWORD << EIP << end(); + uint32_t inst_start_address = EIP; op = next(); - trace(90, "run") << "opcode: " << HEXBYTE << NUM(op) << end(); + trace(Callstack_depth, "run") << "0x" << HEXWORD << inst_start_address << " opcode: " << HEXBYTE << NUM(op) << (op == 0xe8 ? "/call" : "") << end(); switch (op) { case 0xf4: // hlt EIP = End_of_program; @@ -372,7 +372,7 @@ void dump_registers() { out << " " << i << ": " << std::hex << std::setw(8) << std::setfill('_') << Reg[i].u; } out << " -- SF: " << SF << "; ZF: " << ZF << "; OF: " << OF; - trace(90, "run") << out.str() << end(); + trace(Callstack_depth+1, "run") << out.str() << end(); } //: start tracking supported opcodes @@ -409,6 +409,24 @@ if (key == "opcodes") { :(before "End Help Contents") cerr << " opcodes\n"; +//: Helpers for managing trace depths +//: +//: We're going to use trace depths primarily to segment code running at +//: different frames of the call stack. This will make it easy for the trace +//: browser to collapse over entire calls. +//: +//: Errors will be at depth 0. +//: Warnings will be at depth 1. +//: SubX instructions will occupy depth 2 and up to Max_depth, organized by +//: stack frames. Each instruction's internal details will be one level deeper +//: than its 'main' depth. So 'call' instruction details will be at the same +//: depth as the instructions of the function it calls. +:(before "End Globals") +extern const int Initial_callstack_depth = 2; +int Callstack_depth = Initial_callstack_depth; +:(before "End Reset") +Callstack_depth = Initial_callstack_depth; + :(before "End Includes") #include <iomanip> #define HEXBYTE std::hex << std::setw(2) << std::setfill('0') |