SHARE
TWEET

Untitled

a guest Apr 13th, 2013 105 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.         }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top