about summary refs log blame commit diff stats
path: root/tools/browse_trace.cc
blob: 10a2507673f020cb504ca8418e7d25bf6c92cd6a (plain) (tree)
1
2
3
4
                                
 
           
                            

















































                                                                                               




                                                                                            
 



                                                                                                        
 






                                                                                                                                        
 





                                                                                                      
 
                    
                                         
                 


                                               
                                                        
 
                                   
                                                    




                            
 





                                                   
   






                                                 
   

















                                                                       
   


                                                                    
                                                                      













                                                                                                                                            
                                               











































                                                                                        









                                                                                                         
                                      


                                                                         

                       

                                                                                                   



                                                     






                                                                 
                             
   


                                     
                                                                                                                         



                                                                                                  
                   





                                         
                                                                                             



                                                                                                  
                   























                                                                                       
                
                         





                                         
     

                                                         
     




                                               
     




                                               
     


                                                          
     


                                                         
     















































                                                                                         
                                                           


                                                                  

                                                                     















                                                     
                                                                                                   

                                                                



                                                  
                                                 
                                               
                               






















                                                                 
                 







                                                                
                                                      


                                                    
                                       


                                     
                     


                                        


                                                    


                                        


                                                    


                                               

                                                   













                                                       
     
                          
                                          

                                         
                                                                        
                  
                                                                 
                                                            


                              
                                                                        
                                   
                                                                                               

                                      
                                                                          
                          
       
                             

                              
                                                

                             
                       

                              
                                               
                                                                   
                                                       
                                                                                               

                                      
                                                                          


                            
               
                              
                                    

                            
                                             
                                                

                                                     
                    

                                                       
                                                                                      
                                                
                                                                   


                                                                                 
                            
                                                             
                                                               

                                                                   


                                

                            
                                                                   
                                         

                                                     
                    

                                                                                
                                                                                      
                                                    
                                                                   
                                                    
       
                            
                                                             
                                                                 
                             


                            
                          





                                                                 

                          
                                          
                                                                 

                          
                                          
                                                                           
     
   
             
                
           
 
// Warning: zero automated tests

// Includes
#include "termbox/termbox.h"

#include <stdlib.h>
#define SIZE(X) (assert((X).size() < (1LL<<(sizeof(int)*8-2))), static_cast<int>((X).size()))

#include <assert.h>
#include <iostream>
using std::istream;
using std::ostream;
using std::iostream;
using std::cin;
using std::cout;
using std::cerr;
#include <iomanip>
#include <string.h>
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <set>
using std::set;
#include <sstream>
using std::ostringstream;
#include <fstream>
using std::ifstream;
using std::ofstream;
#include <map>
using std::map;
#include <utility>
using std::pair;
// End Includes

// Types
struct trace_line {
  string contents;
  string label;
  int depth;  // 0 is 'sea level'; positive integers are progressively 'deeper' and lower level
  trace_line(string c, string l, int d) {
    contents = c;
    label = l;
    depth = d;
  }
};

struct trace_stream {
  vector<trace_line> past_lines;
};

enum search_direction { FORWARD, BACKWARD };
// End Types

// from http://stackoverflow.com/questions/152643/idiomatic-c-for-reading-from-a-const-map
template<typename T> typename T::mapped_type& get(T& map, typename T::key_type const& key) {
  typename T::iterator iter(map.find(key));
  assert(iter != map.end());
  return iter->second;
}
template<typename T> typename T::mapped_type const& get(const T& map, typename T::key_type const& key) {
  typename T::const_iterator iter(map.find(key));
  assert(iter != map.end());
  return iter->second;
}
template<typename T> typename T::mapped_type const& put(T& map, typename T::key_type const& key, typename T::mapped_type const& value) {
  // map[key] requires mapped_type to have a zero-arg (default) constructor
  map.insert(std::make_pair(key, value)).first->second = value;
  return value;
}
template<typename T> bool contains_key(T& map, typename T::key_type const& key) {
  return map.find(key) != map.end();
}
template<typename T> typename T::mapped_type& get_or_insert(T& map, typename T::key_type const& key) {
  return map[key];
}

// Globals
trace_stream* Trace_stream = NULL;

ofstream Trace_file;
int Cursor_row = 0;  // screen coordinate
set<int> Visible;
int Top_of_screen = 0;  // trace coordinate
int Left_of_screen = 0;  // trace coordinate
int Last_printed_row = 0;  // screen coordinate
map<int, int> Trace_index;  // screen row -> trace index

string Current_search_pattern = "";
search_direction Current_search_direction = FORWARD;
// End Globals

bool has_data(istream& in) {
  return in && !in.eof();
}

void skip_whitespace_but_not_newline(istream& in) {
  while (true) {
    if (!has_data(in)) break;
    else if (in.peek() == '\n') break;
    else if (isspace(in.peek())) in.get();
    else break;
  }
}

void load_trace(const char* filename) {
  ifstream tin(filename);
  if (!tin) {
    cerr << "no such file: " << filename << '\n';
    exit(1);
  }
  Trace_stream = new trace_stream;
  while (has_data(tin)) {
    tin >> std::noskipws;
      skip_whitespace_but_not_newline(tin);
      if (!isdigit(tin.peek())) {
        string dummy;
        getline(tin, dummy);
        continue;
      }
    tin >> std::skipws;
    int depth;
    tin >> depth;
    string label;
    tin >> label;
    if (*--label.end() == ':') label.erase(--label.end());
    string line;
    getline(tin, line);
    Trace_stream->past_lines.push_back(trace_line(line, label, depth));
  }
  cerr << "lines read: " << Trace_stream->past_lines.size() << '\n';
}

void refresh_screen_rows() {  // Top_of_screen, Visible -> Trace_index
  int screen_row = 0, index = 0;
  Trace_index.clear();
  for (screen_row = 0, index = Top_of_screen;  screen_row < tb_height() && index < SIZE(Trace_stream->past_lines);  ++screen_row, ++index) {
    // skip lines without depth for now
    while (!contains_key(Visible, index)) {
      ++index;
      if (index >= SIZE(Trace_stream->past_lines)) goto done;
    }
    assert(index < SIZE(Trace_stream->past_lines));
    put(Trace_index, screen_row, index);
  }
done:;
}

void clear_line(int screen_row) {  // -> screen
  tb_set_cursor(0, screen_row);
  for (int col = 0;  col < tb_width();  ++col)
    tb_print(' ', TB_WHITE, TB_BLACK);
  tb_set_cursor(0, screen_row);
}

int read_key() {
  tb_event event;
  do {
    tb_poll_event(&event);
  } while (event.type != TB_EVENT_KEY);
  return event.key ? event.key : event.ch;
}

int lines_hidden(int screen_row) {
  assert(contains_key(Trace_index, screen_row));
  if (!contains_key(Trace_index, screen_row+1))
    return SIZE(Trace_stream->past_lines) - get(Trace_index, screen_row);
  else
    return get(Trace_index, screen_row+1) - get(Trace_index, screen_row);
}

bool in_range(const vector<pair<size_t, size_t> >& highlight_ranges, size_t idx) {
  for (int i = 0;  i < SIZE(highlight_ranges);  ++i) {
    if (idx >= highlight_ranges.at(i).first && idx < highlight_ranges.at(i).second)
      return true;
    if (idx < highlight_ranges.at(i).second) break;
  }
  return false;
}

vector<pair<size_t, size_t> > find_all_occurrences(const string& s, const string& pat) {
  vector<pair<size_t, size_t> > result;
  if (pat.empty()) return result;
  size_t idx = 0;
  while (true) {
    size_t next_idx = s.find(pat, idx);
    if (next_idx == string::npos) break;
    result.push_back(pair<size_t, size_t>(next_idx, next_idx+SIZE(pat)));
    idx = next_idx+SIZE(pat);
  }
  return result;
}

int bg_color(int depth, int trace_index, int screen_row) {
  if (screen_row == Cursor_row) {
    if (trace_index == 0) return /*subtle grey*/240;  // ignore the zero-depth sentinel at start of trace
    if (depth > 0) return /*subtle grey*/240;
    else return /*subtle red*/88;
  }
  if (trace_index == 0) return TB_BLACK;  // ignore the zero-depth sentinel at start of trace
  if (depth == 0) return /*red*/1;
  if (depth == 1) return /*orange*/166;
  // start at black, gradually lighten at deeper levels
  return TB_BLACK + ((depth-2) % 6)*2;
}

void render_line(int screen_row, const string& s, int bg) {  // -> screen
  int col = 0;
  int color = TB_WHITE;
  vector<pair<size_t, size_t> > highlight_ranges = find_all_occurrences(s, Current_search_pattern);
  tb_set_cursor(0, screen_row);
  for (col = 0;  col < tb_width();  ++col) {
    char c = ' ';
    if (col+Left_of_screen < SIZE(s))
      c = s.at(col+Left_of_screen);  // todo: unicode
    if (c == '\n') c = ';';  // replace newlines with semi-colons
    // escapes. hack: can't start a line with them.
    if (c == '\1') { color = /*red*/1;  continue; }
    if (c == '\2') { color = TB_WHITE;  continue; }
    if (in_range(highlight_ranges, col+Left_of_screen))
      tb_print(c, TB_BLACK, /*yellow*/11);
    else
      tb_print(c, color, bg);
  }
}

void search_next(const string& pat) {
  for (int trace_index = get(Trace_index, Cursor_row)+1;  trace_index < SIZE(Trace_stream->past_lines);  ++trace_index) {
    if (!contains_key(Visible, trace_index)) continue;
    const trace_line& line = Trace_stream->past_lines.at(trace_index);
    if (line.label.find(pat) == string::npos && line.contents.find(pat) == string::npos) continue;
    Top_of_screen = trace_index;
    Cursor_row = 0;
    refresh_screen_rows();
    return;
  }
}

void search_previous(const string& pat) {
  for (int trace_index = get(Trace_index, Cursor_row)-1;  trace_index >= 0;  --trace_index) {
    if (!contains_key(Visible, trace_index)) continue;
    const trace_line& line = Trace_stream->past_lines.at(trace_index);
    if (line.label.find(pat) == string::npos && line.contents.find(pat) == string::npos) continue;
    Top_of_screen = trace_index;
    Cursor_row = 0;
    refresh_screen_rows();
    return;
  }
}

void search(const string& pat, search_direction dir) {
  if (dir == FORWARD) search_next(pat);
  else search_previous(pat);
}

search_direction opposite(search_direction dir) {
  if (dir == FORWARD) return BACKWARD;
  else return FORWARD;
}

bool start_search_editor(search_direction dir) {
  const int bottom_screen_line = tb_height()-1;
  // run a little editor just in the last line of the screen
  clear_line(bottom_screen_line);
  int col = 0;  // screen column of cursor on bottom line. also used to update pattern.
  tb_set_cursor(col, bottom_screen_line);
  tb_print('/', TB_WHITE, TB_BLACK);
  ++col;
  string pattern;
  while (true) {
    int key = read_key();
    if (key == TB_KEY_ENTER) {
      if (!pattern.empty()) {
        Current_search_pattern = pattern;
        Current_search_direction = dir;
      }
      return true;
    }
    else if (key == TB_KEY_ESC || key == TB_KEY_CTRL_C) {
      return false;
    }
    else if (key == TB_KEY_ARROW_LEFT) {
      if (col > /*slash*/1) {
        --col;
        tb_set_cursor(col, bottom_screen_line);
      }
    }
    else if (key == TB_KEY_ARROW_RIGHT) {
      if (col-/*slash*/1 < SIZE(pattern)) {
        ++col;
        tb_set_cursor(col, bottom_screen_line);
      }
    }
    else if (key == TB_KEY_HOME || key == TB_KEY_CTRL_A) {
      col = /*skip slash*/1;
      tb_set_cursor(col, bottom_screen_line);
    }
    else if (key == TB_KEY_END || key == TB_KEY_CTRL_E) {
      col = SIZE(pattern)+/*skip slash*/1;
      tb_set_cursor(col, bottom_screen_line);
    }
    else if (key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2) {
      if (col > /*slash*/1) {
        assert(col <= SIZE(pattern)+1);
        --col;
        // update pattern
        pattern.erase(col-/*slash*/1, /*len*/1);
        // update screen
        tb_set_cursor(col, bottom_screen_line);
        for (int x = col;  x < SIZE(pattern)+/*skip slash*/1;  ++x)
          tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
        tb_print(' ', TB_WHITE, TB_BLACK);
        tb_set_cursor(col, bottom_screen_line);
      }
    }
    else if (key == TB_KEY_CTRL_K) {
      int old_pattern_size = SIZE(pattern);
      pattern.erase(col-/*slash*/1, SIZE(pattern) - (col-/*slash*/1));
      tb_set_cursor(col, bottom_screen_line);
      for (int x = col;  x < old_pattern_size+/*slash*/1;  ++x)
        tb_print(' ', TB_WHITE, TB_BLACK);
      tb_set_cursor(col, bottom_screen_line);
    }
    else if (key == TB_KEY_CTRL_U) {
      int old_pattern_size = SIZE(pattern);
      pattern.erase(0, col-/*slash*/1);
      col = /*skip slash*/1;
      tb_set_cursor(col, bottom_screen_line);
      for (int x = /*slash*/1;  x < SIZE(pattern)+/*skip slash*/1;  ++x)
        tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
      for (int x = SIZE(pattern)+/*slash*/1;  x < old_pattern_size+/*skip slash*/1;  ++x)
        tb_print(' ', TB_WHITE, TB_BLACK);
      tb_set_cursor(col, bottom_screen_line);
    }
    else if (key < 128) {  // ascii only
      // update pattern
      char c = static_cast<char>(key);
      assert(col-1 >= 0);
      assert(col-1 <= SIZE(pattern));
      pattern.insert(col-/*slash*/1, /*num*/1, c);
      // update screen
      for (int x = col;  x < SIZE(pattern)+/*skip slash*/1;  ++x)
        tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
      ++col;
      tb_set_cursor(col, bottom_screen_line);
    }
  }
}

void render() {  // Trace_index -> Last_printed_row, screen
  int screen_row = 0;
  for (screen_row = 0;  screen_row < tb_height();  ++screen_row) {
    if (!contains_key(Trace_index, screen_row)) break;
    int trace_index = get(Trace_index, screen_row);
    trace_line& curr_line = Trace_stream->past_lines.at(trace_index);
    ostringstream out;
    if (screen_row < tb_height()-1) {
      int delta = lines_hidden(screen_row);
      // home-brew escape sequence for red
      if (delta > 1) {
        if (delta > 999) out << static_cast<char>(1);
        out << std::setw(6) << delta << "| ";
        if (delta > 999) out << static_cast<char>(2);
      }
      else {
        out << "        ";
      }
    }
    else {
      out << "        ";
    }
    out << std::setw(2) << curr_line.depth << ' ' << curr_line.label << ": " << curr_line.contents;
    int bg = bg_color(curr_line.depth, trace_index, screen_row);
    render_line(screen_row, out.str(), bg);
  }
  // clear rest of screen
  Last_printed_row = screen_row-1;
  for (;  screen_row < tb_height();  ++screen_row)
    render_line(screen_row, "~", /*bg*/TB_BLACK);
  // move cursor back to display row at the end
  tb_set_cursor(0, Cursor_row);
}

int main(int argc, char* argv[]) {
  if (argc != 2) {
    cerr << "Usage: browse_trace <trace file>\n";
    return 1;
  }
  load_trace(argv[1]);
  if (!Trace_stream) return 1;
  cerr << "computing min depth to display\n";
  int min_depth = 9999;
  for (int i = 0;  i < SIZE(Trace_stream->past_lines);  ++i) {
    trace_line& curr_line = Trace_stream->past_lines.at(i);
    if (curr_line.depth < min_depth) min_depth = curr_line.depth;
  }
  cerr << "min depth is " << min_depth << '\n';
  cerr << "computing lines to display\n";
  for (int i = 0;  i < SIZE(Trace_stream->past_lines);  ++i) {
    if (Trace_stream->past_lines.at(i).depth == min_depth)
      Visible.insert(i);
  }
  tb_init();
  tb_clear();
  Cursor_row = 0;
  Top_of_screen = 0;
  refresh_screen_rows();
  while (true) {
    render();
    int key = read_key();
    if (key == 'q' || key == 'Q' || key == TB_KEY_CTRL_C) break;
    if (key == 'j' || key == TB_KEY_ARROW_DOWN) {
      // move cursor one line down
      if (Cursor_row < Last_printed_row) ++Cursor_row;
    }
    else if (key == 'k' || key == TB_KEY_ARROW_UP) {
      // move cursor one line up
      if (Cursor_row > 0) --Cursor_row;
    }
    else if (key == 't') {
      // move cursor to top of screen
      Cursor_row = 0;
    }
    else if (key == 'c') {
      // move cursor to center of screen
      Cursor_row = tb_height()/2;
      while (!contains_key(Trace_index, Cursor_row))
        --Cursor_row;
    }
    else if (key == 'b') {
      // move cursor to bottom of screen
      Cursor_row = tb_height()-1;
      while (!contains_key(Trace_index, Cursor_row))
        --Cursor_row;
    }
    else if (key == 'T') {
      // scroll line at cursor to top of screen
      Top_of_screen = get(Trace_index, Cursor_row);
      Cursor_row = 0;
      refresh_screen_rows();
    }
    else if (key == 'h' || key == TB_KEY_ARROW_LEFT) {
      // pan screen one character left
      if (Left_of_screen > 0) --Left_of_screen;
    }
    else if (key == 'l' || key == TB_KEY_ARROW_RIGHT) {
      // pan screen one character right
      ++Left_of_screen;
    }
    else if (key == 'H') {
      // pan screen one screen-width left
      Left_of_screen -= (tb_width() - 5);
      if (Left_of_screen < 0) Left_of_screen = 0;
    }
    else if (key == 'L') {
      // pan screen one screen-width right
      Left_of_screen += (tb_width() - 5);
    }
    else if (key == 'J' || key == TB_KEY_PGDN || key == TB_KEY_CTRL_F) {
      // page-down
      if (Trace_index.find(tb_height()-1) != Trace_index.end()) {
        Top_of_screen = get(Trace_index, tb_height()-1) + 1;
        refresh_screen_rows();
      }
    }
    else if (key == 'K' || key == TB_KEY_PGUP || key == TB_KEY_CTRL_B) {
      // page-up is more convoluted
      for (int screen_row = tb_height();  screen_row > 0 && Top_of_screen > 0;  --screen_row) {
        --Top_of_screen;
        if (Top_of_screen <= 0) break;
        while (Top_of_screen > 0 && !contains_key(Visible, Top_of_screen))
          --Top_of_screen;
      }
      if (Top_of_screen >= 0)
        refresh_screen_rows();
    }
    else if (key == 'g' || key == TB_KEY_HOME) {
        Top_of_screen = 0;
        Last_printed_row = 0;
        Cursor_row = 0;
        refresh_screen_rows();
    }
    else if (key == 'G' || key == TB_KEY_END) {
      // go to bottom of trace; largely like page-up, interestingly
      Top_of_screen = SIZE(Trace_stream->past_lines)-1;
      for (int screen_row = tb_height();  screen_row > 0 && Top_of_screen > 0;  --screen_row) {
        --Top_of_screen;
        if (Top_of_screen <= 0) break;
        while (Top_of_screen > 0 && !contains_key(Visible, Top_of_screen))
          --Top_of_screen;
      }
      refresh_screen_rows();
      render();
      // move cursor to bottom
      Cursor_row = Last_printed_row;
      refresh_screen_rows();
    }
    else if (key == TB_KEY_CARRIAGE_RETURN) {
      // expand lines under current by one level
      assert(contains_key(Trace_index, Cursor_row));
      int start_index = get(Trace_index, Cursor_row);
      int index = 0;
      // simultaneously compute end_index and min_depth
      int min_depth = 9999;
      for (index = start_index+1;  index < SIZE(Trace_stream->past_lines);  ++index) {
        if (contains_key(Visible, index)) break;
        trace_line& curr_line = Trace_stream->past_lines.at(index);
        assert(curr_line.depth > Trace_stream->past_lines.at(start_index).depth);
        if (curr_line.depth < min_depth) min_depth = curr_line.depth;
      }
      int end_index = index;
      // mark as visible all intervening indices at min_depth
      for (index = start_index;  index < end_index;  ++index) {
        trace_line& curr_line = Trace_stream->past_lines.at(index);
        if (curr_line.depth == min_depth) {
          Visible.insert(index);
        }
      }
      refresh_screen_rows();
    }
    else if (key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2) {
      // collapse all lines under current
      assert(contains_key(Trace_index, Cursor_row));
      int start_index = get(Trace_index, Cursor_row);
      int index = 0;
      // end_index is the next line at a depth same as or lower than start_index
      int initial_depth = Trace_stream->past_lines.at(start_index).depth;
      for (index = start_index+1;  index < SIZE(Trace_stream->past_lines);  ++index) {
        if (!contains_key(Visible, index)) continue;
        trace_line& curr_line = Trace_stream->past_lines.at(index);
        if (curr_line.depth <= initial_depth) break;
      }
      int end_index = index;
      // mark as visible all intervening indices at min_depth
      for (index = start_index+1;  index < end_index;  ++index) {
        Visible.erase(index);
      }
      refresh_screen_rows();
    }
    else if (key == '/') {
      if (start_search_editor(FORWARD))
        search(Current_search_pattern, Current_search_direction);
    }
    else if (key == '?') {
      if (start_search_editor(BACKWARD))
        search(Current_search_pattern, Current_search_direction);
    }
    else if (key == 'n') {
      if (!Current_search_pattern.empty())
        search(Current_search_pattern, Current_search_direction);
    }
    else if (key == 'N') {
      if (!Current_search_pattern.empty())
        search(Current_search_pattern, opposite(Current_search_direction));
    }
  }
  tb_clear();
  tb_shutdown();
  return 0;
}
;> 96 </span> <span class="Constant">&quot;run: storing 0xab\n&quot;</span> <span id="L97" class="LineNr"> 97 </span> <span class="Comment">// remaining bytes of EBX are *not* cleared</span> <span id="L98" class="LineNr"> 98 </span> <span class="Constant">&quot;run: <a href='010vm.cc.html#L13'>EBX</a> now contains 0xaabbccab\n&quot;</span> <span id="L99" class="LineNr"> 99 </span> <span class="Delimiter">);</span> <span id="L100" class="LineNr">100 </span><span class="Delimiter">}</span> <span id="L101" class="LineNr">101 </span> <span id="L102" class="LineNr">102 </span><span class="Delimiter">:(before &quot;End Single-Byte Opcodes&quot;)</span> <span id="L103" class="LineNr">103 </span><span class="Normal">case</span> <span class="Constant">0x8a</span>: <span class="Delimiter">{</span> <span class="Comment">// copy r/m8 to r8</span> <span id="L104" class="LineNr">104 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L105" class="LineNr">105 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> rdest = <span class="Delimiter">(</span>modrm&gt;&gt;<span class="Constant">3</span><span class="Delimiter">)</span>&amp;<span class="Constant">0x7</span><span class="Delimiter">;</span> <span id="L106" class="LineNr">106 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;copy r8/m8-at-r32 to &quot;</span> &lt;&lt; <a href='021byte_addressing.cc.html#L7'>rname_8bit</a><span class="Delimiter">(</span>rdest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L107" class="LineNr">107 </span> <span class="Comment">// use unsigned to zero-extend 8-bit value to 32 bits</span> <span id="L108" class="LineNr">108 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span>* src = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L109" class="LineNr">109 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L33'>reg_8bit</a><span class="Delimiter">(</span>rdest<span class="Delimiter">);</span> <span id="L110" class="LineNr">110 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing 0x&quot;</span> &lt;&lt; <a href='010vm.cc.html#L394'>HEXBYTE</a> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*src<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L111" class="LineNr">111 </span> *dest = *src<span class="Delimiter">;</span> <span class="Comment">// Read/write multiple elements of vector&lt;uint8_t&gt; at once. Assumes sizeof(int) == 4 on the host as well.</span> <span id="L112" class="LineNr">112 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> rdest_32bit = rdest &amp; <span class="Constant">0x3</span><span class="Delimiter">;</span> <span id="L113" class="LineNr">113 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <a href='013direct_addressing.cc.html#L136'>rname</a><span class="Delimiter">(</span>rdest_32bit<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; now contains 0x&quot;</span> &lt;&lt; <a href='010vm.cc.html#L395'>HEXWORD</a> &lt;&lt; <span class="Special"><a href='010vm.cc.html#L25'>Reg</a></span>[rdest_32bit]<span class="Delimiter">.</span>u &lt;&lt; end<span class="Delimiter">();</span> <span id="L114" class="LineNr">114 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L115" class="LineNr">115 </span><span class="Delimiter">}</span> <span id="L116" class="LineNr">116 </span> <span id="L117" class="LineNr">117 </span><span class="Delimiter">:(code)</span> <span id="L118" class="LineNr">118 </span><span class="Normal">void</span> <a href='021byte_addressing.cc.html#L118'>test_cannot_copy_byte_to_ESP_EBP_ESI_EDI</a><span class="Delimiter">()</span> <span class="Delimiter">{</span> <span id="L119" class="LineNr">119 </span> <span class="Special"><a href='010vm.cc.html#L25'>Reg</a></span>[ESI]<span class="Delimiter">.</span>u = <span class="Constant">0xaabbccdd</span><span class="Delimiter">;</span> <span id="L120" class="LineNr">120 </span> <span class="Special"><a href='010vm.cc.html#L25'>Reg</a></span>[EBX]<span class="Delimiter">.</span>u = <span class="Constant">0x11223344</span><span class="Delimiter">;</span> <span id="L121" class="LineNr">121 </span> <a href='011run.cc.html#L82'>run</a><span class="Delimiter">(</span> <span id="L122" class="LineNr">122 </span> <span class="Constant">&quot;== code 0x1\n&quot;</span> <span id="L123" class="LineNr">123 </span> <span class="Comment">// op ModR/M SIB displacement immediate</span> <span id="L124" class="LineNr">124 </span> <span class="Constant">&quot; 8a f3 \n&quot;</span> <span class="Comment">// copy just the byte at *EBX to 8-bit register '6'</span> <span id="L125" class="LineNr">125 </span> <span class="Comment">// ModR/M in binary: 11 (direct mode) 110 (dest 8-bit 'register 6') 011 (src EBX)</span> <span id="L126" class="LineNr">126 </span> <span class="Delimiter">);</span> <span id="L127" class="LineNr">127 </span> <a href='003trace.cc.html#L292'>CHECK_TRACE_CONTENTS</a><span class="Delimiter">(</span> <span id="L128" class="LineNr">128 </span> <span class="Comment">// ensure 8-bit register '6' is DH, not ESI</span> <span id="L129" class="LineNr">129 </span> <span class="Constant">&quot;run: copy r8/m8-at-r32 to DH\n&quot;</span> <span id="L130" class="LineNr">130 </span> <span class="Constant">&quot;run: storing 0x44\n&quot;</span> <span id="L131" class="LineNr">131 </span> <span class="Delimiter">);</span> <span id="L132" class="LineNr">132 </span> <span class="Comment">// ensure ESI is unchanged</span> <span id="L133" class="LineNr">133 </span> <a href='002test.cc.html#L31'>CHECK_EQ</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L25'>Reg</a></span>[ESI]<span class="Delimiter">.</span>u<span class="Delimiter">,</span> <span class="Constant">0xaabbccdd</span><span class="Delimiter">);</span> <span id="L134" class="LineNr">134 </span><span class="Delimiter">}</span> <span id="L135" class="LineNr">135 </span> <span id="L136" class="LineNr">136 </span><span class="Comment">//:</span> <span id="L137" class="LineNr">137 </span> <span id="L138" class="LineNr">138 </span><span class="Delimiter">:(before &quot;End Initialize Op Names&quot;)</span> <span id="L139" class="LineNr">139 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L342'>Name</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;c6&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;copy imm8 to r8/m8-at-r32 (mov)&quot;</span><span class="Delimiter">);</span> <span id="L140" class="LineNr">140 </span> <span id="L141" class="LineNr">141 </span><span class="Delimiter">:(code)</span> <span id="L142" class="LineNr">142 </span><span class="Normal">void</span> <a href='021byte_addressing.cc.html#L142'>test_copy_imm8_to_mem_at_r32</a><span class="Delimiter">()</span> <span class="Delimiter">{</span> <span id="L143" class="LineNr">143 </span> <span class="Special"><a href='010vm.cc.html#L25'>Reg</a></span>[EAX]<span class="Delimiter">.</span>i = <span class="Constant">0x2000</span><span class="Delimiter">;</span> <span id="L144" class="LineNr">144 </span> <a href='011run.cc.html#L82'>run</a><span class="Delimiter">(</span> <span id="L145" class="LineNr">145 </span> <span class="Constant">&quot;== code 0x1\n&quot;</span> <span id="L146" class="LineNr">146 </span> <span class="Comment">// op ModR/M SIB displacement immediate</span> <span id="L147" class="LineNr">147 </span> <span class="Constant">&quot; c6 00 dd \n&quot;</span> <span class="Comment">// copy to the byte at *EAX</span> <span id="L148" class="LineNr">148 </span> <span class="Comment">// ModR/M in binary: 00 (indirect mode) 000 (unused) 000 (dest EAX)</span> <span id="L149" class="LineNr">149 </span> <span class="Constant">&quot;== data 0x2000\n&quot;</span> <span id="L150" class="LineNr">150 </span> <span class="Constant">&quot;f0 cc bb aa\n&quot;</span> <span id="L151" class="LineNr">151 </span> <span class="Delimiter">);</span> <span id="L152" class="LineNr">152 </span> <a href='003trace.cc.html#L292'>CHECK_TRACE_CONTENTS</a><span class="Delimiter">(</span> <span id="L153" class="LineNr">153 </span> <span class="Constant">&quot;run: copy imm8 to r8/m8-at-r32\n&quot;</span> <span id="L154" class="LineNr">154 </span> <span class="Constant">&quot;run: effective address is 0x00002000 (<a href='010vm.cc.html#L10'>EAX</a>)\n&quot;</span> <span id="L155" class="LineNr">155 </span> <span class="Constant">&quot;run: storing 0xdd\n&quot;</span> <span id="L156" class="LineNr">156 </span> <span class="Delimiter">);</span> <span id="L157" class="LineNr">157 </span> <a href='002test.cc.html#L31'>CHECK_EQ</a><span class="Delimiter">(</span><span class="Constant">0xaabbccdd</span><span class="Delimiter">,</span> <a href='010vm.cc.html#L172'>read_mem_u32</a><span class="Delimiter">(</span><span class="Constant">0x2000</span><span class="Delimiter">));</span> <span id="L158" class="LineNr">158 </span><span class="Delimiter">}</span> <span id="L159" class="LineNr">159 </span> <span id="L160" class="LineNr">160 </span><span class="Delimiter">:(before &quot;End Single-Byte Opcodes&quot;)</span> <span id="L161" class="LineNr">161 </span><span class="Normal">case</span> <span class="Constant">0xc6</span>: <span class="Delimiter">{</span> <span class="Comment">// copy imm8 to r/m8</span> <span id="L162" class="LineNr">162 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L163" class="LineNr">163 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> src = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L164" class="LineNr">164 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;copy imm8 to r8/m8-at-r32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L165" class="LineNr">165 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;imm8 is 0x&quot;</span> &lt;&lt; <a href='010vm.cc.html#L395'>HEXWORD</a> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>src<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L166" class="LineNr">166 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> subop = <span class="Delimiter">(</span>modrm&gt;&gt;<span class="Constant">3</span><span class="Delimiter">)</span>&amp;<span class="Constant">0x7</span><span class="Delimiter">;</span> <span class="Comment">// middle 3 'reg opcode' bits</span> <span id="L167" class="LineNr">167 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>subop != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L168" class="LineNr">168 </span> cerr &lt;&lt; <span class="Constant">&quot;unrecognized subop for opcode c6: &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>subop<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; (only 0/copy currently implemented)\n&quot;</span><span class="Delimiter">;</span> <span id="L169" class="LineNr">169 </span> exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> <span id="L170" class="LineNr">170 </span> <span class="Delimiter">}</span> <span id="L171" class="LineNr">171 </span> <span class="Comment">// use unsigned to zero-extend 8-bit value to 32 bits</span> <span id="L172" class="LineNr">172 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L173" class="LineNr">173 </span> *dest = src<span class="Delimiter">;</span> <span class="Comment">// Write multiple elements of vector&lt;uint8_t&gt; at once. Assumes sizeof(int) == 4 on the host as well.</span> <span id="L174" class="LineNr">174 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing 0x&quot;</span> &lt;&lt; <a href='010vm.cc.html#L394'>HEXBYTE</a> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L175" class="LineNr">175 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L176" class="LineNr">176 </span><span class="Delimiter">}</span> <span id="L177" class="LineNr">177 </span> <span id="L178" class="LineNr">178 </span><span class="SalientComment">//:: set flags (setcc)</span> <span id="L179" class="LineNr">179 </span> <span id="L180" class="LineNr">180 </span><span class="Delimiter">:(before &quot;End Initialize Op Names&quot;)</span> <span id="L181" class="LineNr">181 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;94&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if equal, if <a href='010vm.cc.html#L80'>ZF</a> is set, 0 otherwise (setcc/setz/sete)&quot;</span><span class="Delimiter">);</span> <span id="L182" class="LineNr">182 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;95&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if not equal, if <a href='010vm.cc.html#L80'>ZF</a> is not set, 0 otherwise (setcc/setnz/setne)&quot;</span><span class="Delimiter">);</span> <span id="L183" class="LineNr">183 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;9f&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if greater (signed), if <a href='010vm.cc.html#L80'>ZF</a> is unset and SF == <a href='010vm.cc.html#L82'>OF</a>, 0 otherwise (setcc/setg/setnle)&quot;</span><span class="Delimiter">);</span> <span id="L184" class="LineNr">184 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;97&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if greater (unsigned), if <a href='010vm.cc.html#L80'>ZF</a> is unset and <a href='010vm.cc.html#L81'>CF</a> is unset, 0 otherwise (setcc/seta/setnbe)&quot;</span><span class="Delimiter">);</span> <span id="L185" class="LineNr">185 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;9d&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if greater or equal (signed), if SF == <a href='010vm.cc.html#L82'>OF</a>, 0 otherwise (setcc/setge/setnl)&quot;</span><span class="Delimiter">);</span> <span id="L186" class="LineNr">186 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;93&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if greater or equal (unsigned), if <a href='010vm.cc.html#L81'>CF</a> is unset, 0 otherwise (setcc/setae/setnb)&quot;</span><span class="Delimiter">);</span> <span id="L187" class="LineNr">187 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;9c&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if lesser (signed), if SF != <a href='010vm.cc.html#L82'>OF</a>, 0 otherwise (setcc/setl/setnge)&quot;</span><span class="Delimiter">);</span> <span id="L188" class="LineNr">188 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;92&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if lesser (unsigned), if <a href='010vm.cc.html#L81'>CF</a> is set, 0 otherwise (setcc/setb/setnae)&quot;</span><span class="Delimiter">);</span> <span id="L189" class="LineNr">189 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;9e&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if lesser or equal (signed), if <a href='010vm.cc.html#L80'>ZF</a> is set or SF != <a href='010vm.cc.html#L82'>OF</a>, 0 otherwise (setcc/setle/setng)&quot;</span><span class="Delimiter">);</span> <span id="L190" class="LineNr">190 </span><a href='001help.cc.html#L239'>put_new</a><span class="Delimiter">(</span><span class="Special"><a href='010vm.cc.html#L343'>Name_0f</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;96&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;set r8/m8-at-rm32 to 1 if lesser or equal (unsigned), if <a href='010vm.cc.html#L80'>ZF</a> is set or <a href='010vm.cc.html#L81'>CF</a> is set, 0 otherwise (setcc/setbe/setna)&quot;</span><span class="Delimiter">);</span> <span id="L191" class="LineNr">191 </span> <span id="L192" class="LineNr">192 </span><span class="Delimiter">:(before &quot;End Two-Byte Opcodes Starting With 0f&quot;)</span> <span id="L193" class="LineNr">193 </span><span class="Normal">case</span> <span class="Constant">0x94</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if ZF</span> <span id="L194" class="LineNr">194 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L195" class="LineNr">195 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L196" class="LineNr">196 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L197" class="LineNr">197 </span> *dest = <a href='010vm.cc.html#L80'>ZF</a><span class="Delimiter">;</span> <span id="L198" class="LineNr">198 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L199" class="LineNr">199 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L200" class="LineNr">200 </span><span class="Delimiter">}</span> <span id="L201" class="LineNr">201 </span><span class="Normal">case</span> <span class="Constant">0x95</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if !ZF</span> <span id="L202" class="LineNr">202 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L203" class="LineNr">203 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L204" class="LineNr">204 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L205" class="LineNr">205 </span> *dest = !ZF<span class="Delimiter">;</span> <span id="L206" class="LineNr">206 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L207" class="LineNr">207 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L208" class="LineNr">208 </span><span class="Delimiter">}</span> <span id="L209" class="LineNr">209 </span><span class="Normal">case</span> <span class="Constant">0x9f</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if !SF and !ZF</span> <span id="L210" class="LineNr">210 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L211" class="LineNr">211 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L212" class="LineNr">212 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L213" class="LineNr">213 </span> *dest = !ZF &amp;&amp; SF == <a href='010vm.cc.html#L82'>OF</a><span class="Delimiter">;</span> <span id="L214" class="LineNr">214 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L215" class="LineNr">215 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L216" class="LineNr">216 </span><span class="Delimiter">}</span> <span id="L217" class="LineNr">217 </span><span class="Normal">case</span> <span class="Constant">0x97</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if !CF and !ZF</span> <span id="L218" class="LineNr">218 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L219" class="LineNr">219 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L220" class="LineNr">220 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L221" class="LineNr">221 </span> *dest = <span class="Delimiter">(</span>!CF &amp;&amp; !ZF<span class="Delimiter">);</span> <span id="L222" class="LineNr">222 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L223" class="LineNr">223 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L224" class="LineNr">224 </span><span class="Delimiter">}</span> <span id="L225" class="LineNr">225 </span><span class="Normal">case</span> <span class="Constant">0x9d</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if !SF</span> <span id="L226" class="LineNr">226 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L227" class="LineNr">227 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L228" class="LineNr">228 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L229" class="LineNr">229 </span> *dest = <span class="Delimiter">(</span>SF == <a href='010vm.cc.html#L82'>OF</a><span class="Delimiter">);</span> <span id="L230" class="LineNr">230 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L231" class="LineNr">231 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L232" class="LineNr">232 </span><span class="Delimiter">}</span> <span id="L233" class="LineNr">233 </span><span class="Normal">case</span> <span class="Constant">0x93</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if !CF</span> <span id="L234" class="LineNr">234 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L235" class="LineNr">235 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L236" class="LineNr">236 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L237" class="LineNr">237 </span> *dest = !CF<span class="Delimiter">;</span> <span id="L238" class="LineNr">238 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L239" class="LineNr">239 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L240" class="LineNr">240 </span><span class="Delimiter">}</span> <span id="L241" class="LineNr">241 </span><span class="Normal">case</span> <span class="Constant">0x9c</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if SF and !ZF</span> <span id="L242" class="LineNr">242 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L243" class="LineNr">243 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L244" class="LineNr">244 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L245" class="LineNr">245 </span> *dest = <span class="Delimiter">(</span>SF != <a href='010vm.cc.html#L82'>OF</a><span class="Delimiter">);</span> <span id="L246" class="LineNr">246 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L247" class="LineNr">247 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L248" class="LineNr">248 </span><span class="Delimiter">}</span> <span id="L249" class="LineNr">249 </span><span class="Normal">case</span> <span class="Constant">0x92</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if CF</span> <span id="L250" class="LineNr">250 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L251" class="LineNr">251 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L252" class="LineNr">252 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L253" class="LineNr">253 </span> *dest = <a href='010vm.cc.html#L81'>CF</a><span class="Delimiter">;</span> <span id="L254" class="LineNr">254 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L255" class="LineNr">255 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L256" class="LineNr">256 </span><span class="Delimiter">}</span> <span id="L257" class="LineNr">257 </span><span class="Normal">case</span> <span class="Constant">0x9e</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if SF or ZF</span> <span id="L258" class="LineNr">258 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L259" class="LineNr">259 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L260" class="LineNr">260 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L261" class="LineNr">261 </span> *dest = <span class="Delimiter">(</span><a href='010vm.cc.html#L80'>ZF</a> || SF != <a href='010vm.cc.html#L82'>OF</a><span class="Delimiter">);</span> <span id="L262" class="LineNr">262 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L263" class="LineNr">263 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L264" class="LineNr">264 </span><span class="Delimiter">}</span> <span id="L265" class="LineNr">265 </span><span class="Normal">case</span> <span class="Constant">0x96</span>: <span class="Delimiter">{</span> <span class="Comment">// set r8/m8-at-rm32 if ZF or CF</span> <span id="L266" class="LineNr">266 </span> <span class="Normal">const</span> <span class="Normal">uint8_t</span> modrm = <a href='010vm.cc.html#L325'>next</a><span class="Delimiter">();</span> <span id="L267" class="LineNr">267 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;set r8/m8-at-rm32&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L268" class="LineNr">268 </span> <span class="Normal">uint8_t</span>* dest = <a href='021byte_addressing.cc.html#L21'>effective_byte_address</a><span class="Delimiter">(</span>modrm<span class="Delimiter">);</span> <span id="L269" class="LineNr">269 </span> *dest = <span class="Delimiter">(</span><a href='010vm.cc.html#L80'>ZF</a> || <a href='010vm.cc.html#L81'>CF</a><span class="Delimiter">);</span> <span id="L270" class="LineNr">270 </span> <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; <a href='010vm.cc.html#L397'>NUM</a><span class="Delimiter">(</span>*dest<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L271" class="LineNr">271 </span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span id="L272" class="LineNr">272 </span><span class="Delimiter">}</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->