Advertisement
Guest User

Untitled

a guest
Apr 13th, 2013
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.35 KB | None | 0 0
  1. //clang++ -S -mllvm --x86-asm-syntax=intel test.cpp
  2.  
  3. #include <stddef.h>
  4.  
  5. namespace
  6. {
  7.     typedef char int8_t;
  8.     typedef short int16_t;
  9.     typedef int int32_t;
  10.     typedef unsigned char uint8_t;
  11.     typedef unsigned short uint16_t;
  12.     typedef unsigned int uint32_t;
  13. #if defined(USE_STATIC_ASSERT)
  14.     static_assert(sizeof( uint8_t) == 1, "wrong size" );
  15.     static_assert(sizeof( uint16_t) == 2, "wrong size" );
  16.     static_assert(sizeof( uint32_t) == 4, "wrong size" );
  17. #endif
  18.  
  19.     struct reg8_t
  20.     {
  21.         uint8_t low;
  22.         uint8_t high;
  23.     };
  24.  
  25.     union reg16_t
  26.     {
  27.         uint16_t value;
  28.         reg8_t part;
  29.     };
  30.  
  31.     struct registers_t
  32.     {
  33.         reg16_t reg16_ax;
  34.         reg16_t reg16_bx;
  35.         reg16_t reg16_cx;
  36.         reg16_t reg16_dx;
  37.  
  38.         uint16_t sp;
  39.         uint16_t bp;
  40.         uint16_t si;
  41.         uint16_t di;
  42.         uint16_t ip;
  43.  
  44.         uint16_t es;
  45.         uint16_t cs;
  46.         uint16_t ss;
  47.         uint16_t ds;
  48.     };
  49.  
  50.     typedef uint8_t memory_t[0x1FFFFF]; //max 20bits addressable ram
  51.  
  52.     struct storage_t
  53.     {
  54.         registers_t registers;
  55.         memory_t memory;
  56.     };
  57.  
  58.     static storage_t storage;
  59.  
  60.     static const void* const MEMORY_START_ADDRESS = &storage.memory[0];
  61.  
  62.     static const uint32_t offset32( const int& p_segment, const int& p_offset )
  63.     {
  64.         return ( p_segment * 16 + p_offset );
  65.     }
  66.  
  67.     static const size_t MCGA_OFFSET = offset32(0xA000,0);
  68.     static const size_t MCGA_SIZE = 0xFFFF;
  69.     static const void* const MCGA_MEM_BEGIN = &storage.memory[MCGA_OFFSET];
  70.     static const void* const MCGA_MEM_END = &storage.memory[MCGA_OFFSET+MCGA_SIZE]; //next byte after last visible pixel
  71.  
  72.     static const bool in_mcga_ram(const void* const p_ptr)
  73.     {
  74.         return (p_ptr >= MCGA_MEM_BEGIN && p_ptr < MCGA_MEM_END);
  75.     }
  76.  
  77.     static const uint8_t parity[0x100] =
  78.     {
  79.         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  80.         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  81.         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  82.         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  83.         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  84.         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  85.         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  86.         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  87.         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  88.         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  89.         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  90.         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  91.         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  92.         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  93.         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  94.         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
  95.     };
  96.  
  97.     //VS2010 optimizer "bug"
  98.     //global references to type less int aren't resolved
  99.     //but global ptr consts are resolved
  100.  
  101.     //registers and components available as global references
  102.     uint16_t& ax = storage.registers.reg16_ax.value;
  103.     uint16_t& bx = storage.registers.reg16_bx.value;
  104.     uint16_t& cx = storage.registers.reg16_cx.value;
  105.     uint16_t& dx = storage.registers.reg16_dx.value;
  106.  
  107.     uint8_t& al = storage.registers.reg16_ax.part.low;
  108.     uint8_t& ah = storage.registers.reg16_ax.part.high;
  109.  
  110.     uint8_t& bl = storage.registers.reg16_bx.part.low;
  111.     uint8_t& bh = storage.registers.reg16_bx.part.high;
  112.  
  113.     uint8_t& cl = storage.registers.reg16_cx.part.low;
  114.     uint8_t& ch = storage.registers.reg16_cx.part.high;
  115.  
  116.     uint8_t& dl = storage.registers.reg16_dx.part.low;
  117.     uint8_t& dh = storage.registers.reg16_dx.part.high;
  118.  
  119.     uint16_t& sp = storage.registers.sp;
  120.     uint16_t& bp = storage.registers.bp;
  121.     uint16_t& si = storage.registers.si;
  122.     uint16_t& di = storage.registers.di;
  123.     uint16_t& ip = storage.registers.ip;
  124.  
  125.     uint16_t& es = storage.registers.es;
  126.     uint16_t& cs = storage.registers.cs;
  127.     uint16_t& ss = storage.registers.ss;
  128.     uint16_t& ds = storage.registers.ds;
  129.  
  130.     static uint16_t useseg = 0;
  131.     static uint8_t segoverride = 0;
  132.  
  133.     static uint8_t cf = 0;
  134.     static uint8_t pf = 0;
  135.     static uint8_t af = 0;
  136.     static uint8_t zf = 0;
  137.     static uint8_t sf = 0;
  138.     static uint8_t of = 0;
  139.  
  140.     //static globals
  141.     static uint16_t* const modregrm_reg16[8]={&ax,&cx,&dx,&bx,&sp,&bp,&si,&di};
  142.     static uint8_t* const modregrm_reg8[8]={&al,&cl,&dl,&bl,&ah,&ch,&dh,&bh};
  143.  
  144.     template<typename ValueType>
  145.     struct bitsize_T
  146.     {
  147.     };
  148.  
  149.     template<>
  150.     struct bitsize_T<uint8_t>
  151.     {
  152.         static uint8_t* const P_reg(const int& p_nr)
  153.         {
  154.             return modregrm_reg8[p_nr];
  155.         }
  156.         static uint8_t& r_reg(const int& p_nr ){ return *P_reg(p_nr); }
  157.  
  158.         static const uint8_t SIGN_BITS = 0x80;
  159.         static const uint16_t CARRY_BITS = 0xFF00;
  160.         typedef uint16_t result_type;
  161.  
  162.         static const uint8_t& get_parity( const uint8_t& p_value )
  163.         {
  164.             return parity[p_value];
  165.         }
  166.  
  167.         static const uint16_t sign_extend( const uint8_t& p_value )
  168.         {
  169.             return static_cast<int16_t>(static_cast<int8_t>(p_value));
  170.         }
  171.     };
  172.  
  173.     template<>
  174.     struct bitsize_T<uint16_t>
  175.     {
  176.         static uint16_t* const P_reg(const int& p_nr)
  177.         {
  178.             return modregrm_reg16[p_nr];
  179.         }
  180.         static uint16_t& r_reg(const int& p_nr ){ return *P_reg(p_nr); }
  181.  
  182.         static const uint16_t SIGN_BITS = 0x8000;
  183.         static const uint32_t CARRY_BITS = 0xFFFF0000;
  184.         typedef uint32_t result_type;
  185.  
  186.         static const uint8_t& get_parity( const uint16_t& p_value )
  187.         {
  188.             return parity[p_value & 0xFF]; // & 0xFF needed - or better assert
  189.         }
  190.  
  191.         static const uint32_t sign_extend( const uint16_t& p_value )
  192.         {
  193.             return static_cast<int32_t>(static_cast<int16_t>(p_value));
  194.         }
  195.     };
  196.  
  197.     template<typename ValueType>
  198.     static ValueType* const P_mem( const int& p_offset )
  199.     {
  200.         return reinterpret_cast<ValueType*>(storage.memory + p_offset);
  201.     }
  202.  
  203.     template<typename ValueType>
  204.     static ValueType* const P_mem( const int& p_segment, const int& p_offset )
  205.     {
  206.         return P_mem<ValueType>(offset32(p_segment, p_offset));
  207.     }
  208.  
  209.     template<typename ValueType>
  210.     static ValueType& r_mem( const int& p_offset )
  211.     {
  212.         return *P_mem<ValueType>(p_offset);
  213.     }
  214.  
  215.     template<typename ValueType>
  216.     static ValueType& r_mem(const int& p_segment, const int& p_offset )
  217.     {
  218.         return *P_mem<ValueType>(p_segment,p_offset);
  219.     }
  220.  
  221.     //maybe they should not write, read the real mem - just observer the action
  222.  
  223.     template<typename ValueType>
  224.     static void write_mem( void* const p_ptr, const ValueType& p_value )
  225.     {
  226.         ValueType* const ptr = reinterpret_cast<ValueType*>( p_ptr );
  227.  
  228.         if( in_mcga_ram(p_ptr) )
  229.         {
  230.             //screen_update=true;
  231.         }
  232.     }
  233.  
  234.     template<typename ValueType>
  235.     static const ValueType& read_mem( ValueType* const p_ptr)
  236.     {
  237.         return *p_ptr;
  238.     }
  239.  
  240.     template<typename ValueType>
  241.     static const ValueType& read_cs_ip()
  242.     {
  243.         const ValueType& value = r_mem<ValueType>(cs,ip);
  244.         ip += sizeof(ValueType);
  245.         return value;
  246.     }
  247.  
  248.     //two parameter encoding - reg + reg/mem
  249.     template<typename ValueType>
  250.     static ValueType* const get_memory_target(const uint8_t& mode_value, const uint8_t& rm_value)
  251.     {
  252.         uint16_t disp = 0;
  253.  
  254.         switch (mode_value)
  255.         {
  256.         case 0:
  257.             if (rm_value == 6)
  258.             {
  259.                 disp = read_cs_ip<uint16_t>();
  260.             }
  261.             if (!segoverride && ((rm_value == 2) || (rm_value == 3)))
  262.             {  
  263.                 useseg = ss;
  264.             }
  265.             break;
  266.         case 1:
  267.             disp = bitsize_T<ValueType>::sign_extend(read_cs_ip<uint8_t>());
  268.             if (!segoverride && ((rm_value == 2) || (rm_value == 3) || (rm_value == 6)))
  269.             {
  270.                 useseg = ss;
  271.             }
  272.             break;
  273.         case 2:
  274.             disp = read_cs_ip<uint16_t>();
  275.             if (!segoverride && ((rm_value == 2) || (rm_value == 3) || (rm_value == 6)) )
  276.             {
  277.                 useseg = ss;
  278.             }
  279.             break;
  280.         }
  281.  
  282.         //getea
  283.  
  284.         uint32_t offset = 0;
  285.         switch (mode_value)
  286.         {
  287.         case 0:
  288.             switch (rm_value)
  289.             {
  290.             case 0: offset = bx + si; break;
  291.             case 1: offset = bx + di; break;
  292.             case 2: offset = bp + si; break;
  293.             case 3: offset = bp + di; break;
  294.             case 4: offset = si; break;
  295.             case 5: offset = di; break;
  296.             case 6: offset = disp; break;
  297.             case 7: offset = bx; break;
  298.             }
  299.             break;
  300.         case 1:
  301.         case 2:
  302.             switch (rm_value)
  303.             {
  304.             case 0: offset = bx + si + disp; break;
  305.             case 1: offset = bx + di + disp; break;
  306.             case 2: offset = bp + si + disp; break;
  307.             case 3: offset = bp + di + disp; break;
  308.             case 4: offset = si + disp; break;
  309.             case 5: offset = di + disp; break;
  310.             case 6: offset = bp + disp; break;
  311.             case 7: offset = bx + disp; break;
  312.             }
  313.             break;
  314.         }
  315.  
  316.         return P_mem<ValueType>(useseg,offset);
  317.     }
  318.  
  319.     template<typename ValueType>
  320.     struct modregrm_T
  321.     {
  322.         const uint8_t mode_value;
  323.         const uint8_t reg_value;
  324.         const uint8_t rm_value;
  325.  
  326.         ValueType* const reg_target;
  327.         ValueType* const rm_target;
  328.         const bool is_mem_target;
  329.  
  330.         modregrm_T(const ValueType& p_address_byte):
  331.             mode_value(p_address_byte >> 6),
  332.             reg_value((p_address_byte >> 3) & 7),
  333.             rm_value(p_address_byte & 7),
  334.             reg_target(bitsize_T<ValueType>::P_reg(reg_value)),
  335.             is_mem_target(mode_value < 3),
  336.             rm_target(is_mem_target ? get_memory_target<ValueType>(mode_value,rm_value) : bitsize_T<ValueType>::P_reg(rm_value))
  337.         {
  338.         }
  339.  
  340.         ValueType& reg() const
  341.         {
  342.             return *reg_target;
  343.         }
  344.  
  345.         const ValueType& rm() const
  346.         {
  347.             if(is_mem_target)
  348.             {
  349.                 *rm_target = read_mem<ValueType>(rm_target);
  350.             }
  351.             return *rm_target;
  352.         }
  353.  
  354.         void rm( const ValueType& p_value ) const
  355.         {
  356.             if(is_mem_target)
  357.             {
  358.                 write_mem<ValueType>(rm_target,p_value); // memory observation
  359.             }
  360.             *rm_target = p_value;
  361.         }
  362.     };
  363.  
  364.     //--------------------------------------------------------------
  365.     // base operations for 8 and 16bit
  366.     //--------------------------------------------------------------
  367.  
  368.     template<typename ValueType>
  369.     static void set_cf( const typename bitsize_T<ValueType>::result_type& p_dst )
  370.     {
  371.         cf = (p_dst & bitsize_T<ValueType>::CARRY_BITS) ? 1 : 0;
  372.     }
  373.  
  374.     template<typename ValueType>
  375.     static void set_of( const typename bitsize_T<ValueType>::result_type& p_dst, const ValueType& p_oper1, const ValueType& p_oper2 )
  376.     {
  377.         of = ((p_dst ^ p_oper1) & (p_oper1 ^ p_oper2) & bitsize_T<ValueType>::SIGN_BITS) ? 1 : 0;
  378.     }
  379.  
  380.     template<typename ValueType>
  381.     static void set_af( const typename bitsize_T<ValueType>::result_type& p_dst, const ValueType& p_oper1, const ValueType& p_oper2 )
  382.     {
  383.         af = ((p_oper1 ^ p_oper2 ^ p_dst) & 0x10) ? 1 : 0;
  384.     }
  385.  
  386.     template<typename ValueType>
  387.     static void set_zf( const ValueType& p_value )
  388.     {
  389.         zf = (!p_value) ? 1 : 0; //set or clear zero flag
  390.     }
  391.  
  392.     template<typename ValueType>
  393.     static void set_sf( const ValueType& p_value )
  394.     {
  395.         sf = (p_value & bitsize_T<ValueType>::SIGN_BITS) ? 1 : 0; //set or clear sign flag
  396.     }
  397.  
  398.     template<typename ValueType>
  399.     static void set_pf( const ValueType& p_value )
  400.     {
  401.         pf = bitsize_T<ValueType>::get_parity(p_value); //retrieve parity state from lookup table
  402.     }
  403.  
  404.     template<typename ValueType>
  405.     static void flag_szp(const ValueType& p_value)
  406.     {
  407.         set_zf<ValueType>(p_value);
  408.         set_sf<ValueType>(p_value);
  409.         set_pf<ValueType>(p_value);
  410.     }
  411.  
  412.     template<typename ValueType>
  413.     static void flag_sub_add(typename bitsize_T<ValueType>::result_type p_dst, const ValueType& p_oper1, const ValueType& p_oper2 )
  414.     {
  415.         flag_szp((ValueType)p_dst);
  416.  
  417.         set_cf<ValueType>(p_dst);
  418.         set_of<ValueType>(p_dst, p_oper1, p_oper2);
  419.         set_af<ValueType>(p_dst, p_oper1, p_oper2);
  420.     }
  421.  
  422.     //v1 = destination operand, v2 = source operand (only difference to add is "-")
  423.     template<typename ValueType>
  424.     static void flag_sub(const ValueType& p_oper1, const ValueType& p_oper2 )
  425.     {
  426.         typedef typename bitsize_T<ValueType>::result_type result_type;
  427.  
  428.         const result_type dst = (result_type)p_oper1 - (result_type)p_oper2;
  429.  
  430.         flag_sub_add( dst, p_oper1, p_oper2 );
  431.     }
  432.  
  433.     //v1 = destination operand, v2 = source operand (only difference to sub is "+")
  434.     template<typename ValueType>
  435.     static void flag_add(const ValueType& p_oper1, const ValueType& p_oper2 )
  436.     {
  437.         typedef typename bitsize_T<ValueType>::result_type result_type;
  438.         const result_type dst = (result_type)p_oper1 + (result_type)p_oper2;
  439.         flag_sub_add( dst, p_oper1, p_oper2 );
  440.     }
  441.  
  442.     //unsing a static void run - or operator() const results in identical code
  443.  
  444.     template<typename ValueType>
  445.     struct sub_T
  446.     {
  447.         void operator()( ValueType& p_oper1, const ValueType& p_oper2 ) const
  448.         {
  449.             flag_sub<ValueType>(p_oper1, p_oper2);
  450.             const ValueType res = p_oper1 - p_oper2;
  451.             p_oper1 = res;
  452.         }
  453.     };
  454.  
  455.     template<typename ValueType>
  456.     struct add_T
  457.     {
  458.         void operator()( ValueType& p_oper1, const ValueType& p_oper2 ) const
  459.         {
  460.             flag_add<ValueType>(p_oper1, p_oper2);
  461.             const ValueType res = p_oper1 + p_oper2;
  462.             p_oper1 = res;
  463.         }
  464.     };
  465.  
  466.     //--------------------------------------------------------------
  467.     // helper templates for interpreter-code
  468.     //--------------------------------------------------------------
  469.  
  470.     //(reg&, const reg/mem&)
  471.     //(reg/mem&, const reg&)
  472.     //(reg&, const imm&)
  473.     //(mem&, const imm&)
  474.  
  475.     //for operations that got moderegrm based (reg&, const reg/mem&) parameter set
  476.     //template template - Operation needs to be class
  477.     template <typename ValueType, template <typename> class Operation>
  478.     static void reg_rm_T()
  479.     {
  480.         const modregrm_T<ValueType> params(read_cs_ip<ValueType>());
  481.         Operation<ValueType>()(params.reg(), params.rm());
  482.     }
  483.  
  484.     //for operations that got moderegrm based (reg/mem&, const reg&) parameter set
  485.     //template template - Operation needs to be class
  486.     template <typename ValueType, template <typename> class Operation>
  487.     static void rm_reg_T()
  488.     {
  489.         const modregrm_T<ValueType> params(read_cs_ip<ValueType>());
  490.         ValueType oper1 = params.rm();
  491.         Operation<ValueType>()(oper1, params.reg());
  492.         params.rm(oper1);
  493.     };
  494.  
  495.     //for ref, imm parameter sets
  496.     template<typename ValueType, template <typename> class Operation>
  497.     static void ref_read_cs_ip(ValueType& p_ref)
  498.     {
  499.         Operation<ValueType>()(p_ref,read_cs_ip<ValueType>());
  500.     }
  501.  
  502.     //al, imm8
  503.     template<template <typename> class Operation>
  504.     static void al_read_cs_ip()
  505.     {
  506.         ref_read_cs_ip<uint8_t,Operation>(al);
  507.     }
  508.  
  509.     //ax, imm16
  510.     template<template <typename> class Operation>
  511.     static void ax_read_cs_ip()
  512.     {
  513.         ref_read_cs_ip<uint16_t,Operation>(ax);
  514.     }
  515.  
  516.     //--------------------------------------------------------------
  517.     //"user"-code
  518.     //--------------------------------------------------------------
  519.  
  520.     // memory access
  521.  
  522.     const uint8_t& byte(const uint16_t& p_segment, const uint16_t& p_offset)
  523.     {
  524.         return r_mem<uint8_t>(p_segment, p_offset);
  525.     }
  526.  
  527.     uint8_t* const byte_ptr(const uint16_t& p_segment, const uint16_t& p_offset)
  528.     {
  529.         return P_mem<uint8_t>(p_segment, p_offset);
  530.     }
  531.  
  532.     const uint16_t& word(const uint16_t& p_segment, const uint16_t& p_offset)
  533.     {
  534.         return r_mem<uint16_t>(p_segment, p_offset);
  535.     }
  536.  
  537.     uint16_t* const word_ptr(const uint16_t& p_segment, const uint16_t& p_offset)
  538.     {
  539.         return P_mem<uint16_t>(p_segment, p_offset);
  540.     }
  541.  
  542.     // mnemonics
  543.  
  544.     void nop()
  545.     {
  546.     }
  547.  
  548.     void sub(uint8_t* p_oper1, const uint8_t& p_oper2)
  549.     {
  550.         sub_T<uint8_t>()(*p_oper1, p_oper2);
  551.         write_mem<uint8_t>(p_oper1,*p_oper1); // memory observation
  552.     }
  553.  
  554.     void sub(uint16_t* p_oper1, const uint16_t& p_oper2)
  555.     {
  556.         sub_T<uint16_t>()(*p_oper1, p_oper2);
  557.         write_mem<uint16_t>(p_oper1,*p_oper1); // memory observation
  558.     }
  559.  
  560.     void sub(uint16_t& p_oper1, const uint16_t& p_oper2)
  561.     {
  562.         sub_T<uint16_t>()(p_oper1, p_oper2);
  563.     }
  564.  
  565.     void sub(uint8_t& p_oper1, const uint8_t& p_oper2)
  566.     {
  567.         sub_T<uint8_t>()(p_oper1, p_oper2);
  568.     }
  569.  
  570.     void add(uint16_t& p_oper1, const uint16_t& p_oper2)
  571.     {
  572.         add_T<uint16_t>()(p_oper1, p_oper2);
  573.     }
  574.  
  575.     void add(uint8_t& p_oper1, const uint8_t& p_oper2)
  576.     {
  577.         add_T<uint8_t>()(p_oper1, p_oper2);
  578.     }
  579.  
  580.     bool jgl()
  581.     {
  582.         return (zf != 0 && cf == 1);
  583.     }
  584.  
  585.     //random values from parameter pointers
  586.     static void set_random_start_values(int argc, char** argv, const size_t& p_dummy)
  587.     {
  588.         uint32_t random1 = *reinterpret_cast<int32_t*>(argv) + p_dummy;
  589.         uint32_t random2 = *reinterpret_cast<int32_t*>(&argc) + p_dummy;
  590.         ah = random1 & 0xFF;
  591.         al = (random1 >> 8) & 0xFF;
  592.         dh = (random1 >> 16) & 0xFF;
  593.         dl = (random1 >> 24) & 0xFF;
  594.         ch = random2 & 0xFF;
  595.         cl = (random2 >> 8) & 0xFF;
  596.         bh = (random2 >> 16) & 0xFF;
  597.         bl = (random2 >> 24) & 0xFF;
  598.         si = ((random1+random2) >> 16) & 0xFFFF;
  599.     }
  600.  
  601.     static uint32_t dummy = 0;
  602.  
  603.     //something to prevent optimizer from removing testcode
  604.     static void calc_dummy(size_t p_dummy)
  605.     {
  606.         dummy *= ax + bx + dx + cx + si + p_dummy;
  607.     }
  608. }
  609.  
  610. #include <cstdio>
  611.  
  612. namespace blub
  613. {
  614.     int free_test(int argc, char** argv)
  615.     {
  616.         const size_t TESTS = 10000;
  617.         for(size_t t = 0; t < TESTS; ++t)
  618.         {
  619.  
  620.             for(size_t x = 0; x < 10000; ++x )
  621.             {
  622.                 set_random_start_values(argc,argv,x);
  623.  
  624.                 //sub ax,dx
  625.                 storage.memory[0]=0x29;
  626.                 storage.memory[1]=0xD0;
  627.                 //nop
  628.                 storage.memory[2]=0x90;
  629.                 //sub cl,dl
  630.                 storage.memory[3]=0x28;
  631.                 storage.memory[4]=0xD9;
  632.                 //sub dx,[bx]
  633.                 storage.memory[5]=0x2B;
  634.                 storage.memory[6]=0x17;
  635.                 //sub bl,[si]
  636.                 storage.memory[7]=0x2A;
  637.                 storage.memory[8]=0x1C;
  638.                 //sub bl,[si+1]
  639.                 storage.memory[9]=0x2A;
  640.                 storage.memory[10]=0x5C;
  641.                 storage.memory[11]=0x01;
  642.                 //sub [si+1],al
  643.                 storage.memory[12]=0x28;
  644.                 storage.memory[13]=0x44;
  645.                 storage.memory[14]=0x01;
  646.                 //add dx,ax
  647.                 storage.memory[15]=0x01;
  648.                 storage.memory[16]=0xC2;
  649.                 //add cl,bl
  650.                 storage.memory[17]=0x00;
  651.                 storage.memory[18]=0xD9;
  652.  
  653.                 cs = 0;
  654.                 ip = 0;
  655.  
  656.                 //interpreter run
  657.                 while( offset32(cs,ip) < 19 )
  658.                 {
  659.                     const uint8_t opcode = read_cs_ip<uint8_t>();
  660.  
  661.                     switch( opcode )
  662.                     {
  663.                     case 0x00: { rm_reg_T<uint8_t,add_T>(); } break; // ADD Eb Gb
  664.                     case 0x01: { rm_reg_T<uint16_t,add_T>(); } break; // ADD Ev Gv
  665.                     case 0x04: { al_read_cs_ip<add_T>(); } break; // ADD al Ib
  666.                     case 0x05: { ax_read_cs_ip<add_T>(); } break; // ADD ax Iv
  667.                     case 0x28: { rm_reg_T<uint8_t,sub_T>(); } break; // SUB Eb Gb
  668.                     case 0x29: { rm_reg_T<uint16_t,sub_T>(); } break; // SUB Ev Gv
  669.                     case 0x2A: { reg_rm_T<uint8_t,sub_T>(); } break; // SUB Gb Eb
  670.                     case 0x2B: { reg_rm_T<uint16_t,sub_T>(); } break; // SUB Gv Ev
  671.                     case 0x90: break; // NOP
  672.                     }
  673.  
  674.                     //the optimizer needs something dependend to not remove the testcode
  675.                     calc_dummy(x);
  676.                 }
  677.  
  678.                
  679.                 //native run
  680.                 for(size_t i = 0; i<9; ++i)
  681.                 {
  682.                     switch(i)
  683.                     {
  684.                     case 0: sub(ax,dx); break;
  685.                     case 1: nop(); break;
  686.                     case 2: sub(cl,dl); break;
  687.                     case 3: sub(dx,word(ds,bx)); break;
  688.                     case 4: sub(bl,byte(ds,si)); break;
  689.                     case 5: sub(bl,byte(ds,si+1)); break;
  690.                     case 6: sub(byte_ptr(ds,si+1),al); break;
  691.                     case 7: add(dx,ax); break;
  692.                     case 8: add(cl,bl); break;
  693.                     }
  694.  
  695.                     //the optimizer needs something dependend to not remove the testcode
  696.                     calc_dummy(x);
  697.                 }
  698.                
  699.  
  700.             }
  701.         }
  702.  
  703.         return dummy; // this is also for the optimizer
  704.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement