Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / misc / decoder_test / XED2 / examples / xed-ex1.cpp
1 /*BEGIN_LEGAL 
2 Intel Open Source License 
3
4 Copyright (c) 2002-2007 Intel Corporation 
5 All rights reserved. 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are
8 met:
9
10 Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.  Redistributions
12 in binary form must reproduce the above copyright notice, this list of
13 conditions and the following disclaimer in the documentation and/or
14 other materials provided with the distribution.  Neither the name of
15 the Intel Corporation nor the names of its contributors may be used to
16 endorse or promote products derived from this software without
17 specific prior written permission.
18  
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
23 ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 END_LEGAL */
31 /// @file xed-ex1.cpp
32 /// @author Mark Charney   <mark.charney@intel.com>
33
34 extern "C" {
35 #include "xed-interface.h"
36 }
37 #include "xed-examples-ostreams.H"
38 #include <iostream>
39 #include <iomanip>
40 #include <sstream>
41 #include <cassert>
42 using namespace std;
43
44 int main(int argc, char** argv);
45
46 void print_attributes(xed_decoded_inst_t* xedd) {
47     const xed_inst_t* xi = xed_decoded_inst_inst(xedd);
48     unsigned int i, nattributes  =  xed_attribute_max();
49     xed_uint32_t all_attributes = xed_inst_get_attributes(xi);
50     if (all_attributes == 0)
51         return;
52     cout << "ATTRIBUTES: ";
53     for(i=0;i<nattributes;i++) {
54         xed_attribute_enum_t attr = xed_attribute(i);
55         if (xed_inst_get_attribute(xi,attr))
56             cout << xed_attribute_enum_t2str(attr) << " ";
57     }
58     cout << endl;
59 }
60
61 void print_flags(xed_decoded_inst_t* xedd) {
62     unsigned int i, nflags;
63     if (xed_decoded_inst_uses_rflags(xedd)) {
64         cout << "FLAGS:" << endl;
65         const xed_simple_flag_t* rfi = xed_decoded_inst_get_rflags_info(xedd);
66         if (xed_simple_flag_reads_flags(rfi)) {
67             cout <<  "   reads-rflags ";
68         }
69         else if (xed_simple_flag_writes_flags(rfi)) {
70             //XED provides may-write and must-write information
71             if (xed_simple_flag_get_may_write(rfi)) {
72                 cout << "  may-write-rflags ";
73             }
74             if (xed_simple_flag_get_must_write(rfi)) {
75                 cout << "  must-write-rflags ";
76             }
77         }
78         nflags = xed_simple_flag_get_nflags(rfi);
79         for( i=0;i<nflags ;i++) {
80             const xed_flag_action_t* fa = xed_simple_flag_get_flag_action(rfi,i);
81             char buf[500];
82             xed_flag_action_print(fa,buf,500);
83             cout  <<  buf << " ";
84         }
85         cout << endl;
86         // or as as bit-union
87         const xed_flag_set_t* read_set    = xed_simple_flag_get_read_flag_set(rfi);
88         const xed_flag_set_t* written_set = xed_simple_flag_get_written_flag_set(rfi);
89         char buf[500];
90         xed_flag_set_print(read_set,buf,500);
91         cout << "  read: " << buf << endl;
92         xed_flag_set_print(written_set,buf,500);
93         cout << "  written: " << buf << endl;
94     }
95 }
96
97 void print_memops(xed_decoded_inst_t* xedd) {
98     unsigned int i, memops = xed_decoded_inst_number_of_memory_operands(xedd);
99     cout << "Memory Operands" << endl;
100     
101     for( i=0;i<memops ; i++)   {
102         xed_bool_t r_or_w = false;
103         cout << "  " << i << " ";
104         if ( xed_decoded_inst_mem_read(xedd,i)) {
105             cout << "read ";
106             r_or_w = true;
107         }
108         if (xed_decoded_inst_mem_written(xedd,i)) {
109             cout << "written ";
110             r_or_w = true;
111         }
112         if (!r_or_w) {
113             cout << "agen "; // LEA instructions
114         }
115         xed_reg_enum_t seg = xed_decoded_inst_get_seg_reg(xedd,i);
116         if (seg != XED_REG_INVALID) {
117             cout << "SEG= " << xed_reg_enum_t2str(seg) << " ";
118         }
119         xed_reg_enum_t base = xed_decoded_inst_get_base_reg(xedd,i);
120         if (base != XED_REG_INVALID) {
121             cout << "BASE= " << xed_reg_enum_t2str(base) << "/"
122                  <<  xed_reg_class_enum_t2str(xed_reg_class(base)) << " "; 
123         }
124         xed_reg_enum_t indx = xed_decoded_inst_get_index_reg(xedd,i);
125         if (i == 0 && indx != XED_REG_INVALID) {
126             cout << "INDEX= " << xed_reg_enum_t2str(indx)
127                  << "/" <<  xed_reg_class_enum_t2str(xed_reg_class(indx)) << " ";
128             if (xed_decoded_inst_get_scale(xedd,i) != 0) {
129                 // only have a scale if the index exists.
130                 cout << "SCALE= " <<  xed_decoded_inst_get_scale(xedd,i) << " ";
131             }
132         }
133         xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xedd,i);
134         if (disp_bits) {
135             cout  << "DISPLACEMENT_BYTES= " << disp_bits << " ";
136             xed_int64_t disp = xed_decoded_inst_get_memory_displacement(xedd,i);
137             cout << hex << setfill('0') << setw(16) << disp << setfill(' ') << dec;
138         }
139         cout << endl;
140     }
141     cout << "  MemopBytes = " << xed_decoded_inst_get_memory_operand_length(xedd,0) << endl;
142 }
143
144 void print_operands(xed_decoded_inst_t* xedd) {
145     unsigned int i, noperands;
146     cout << "Operands" << endl;
147     const xed_inst_t* xi = xed_decoded_inst_inst(xedd);
148     noperands = xed_inst_noperands(xi);
149     for( i=0; i < noperands ; i++) { 
150         const xed_operand_t* op = xed_inst_operand(xi,i);
151         xed_operand_enum_t op_name = xed_operand_name(op);
152         cout << i << " " << xed_operand_enum_t2str(op_name) << " ";
153         switch(op_name) {
154           case XED_OPERAND_AGEN:
155           case XED_OPERAND_MEM0:
156           case XED_OPERAND_MEM1:
157             // we print memops in a different function
158             break;
159           case XED_OPERAND_PTR:  // pointer (always in conjunction with a IMM0)
160           case XED_OPERAND_RELBR: { // branch displacements
161               xed_uint_t disp_bits = xed_decoded_inst_get_branch_displacement_width(xedd);
162               if (disp_bits) {
163                   cout  << "BRANCH_DISPLACEMENT_BYTES= " << disp_bits << " ";
164                   xed_int32_t disp = xed_decoded_inst_get_branch_displacement(xedd);
165                   cout << hex << setfill('0') << setw(8) << disp << setfill(' ') << dec;
166               }
167             }
168             break;
169
170           case XED_OPERAND_IMM0: { // immediates
171               xed_uint_t width = xed_decoded_inst_get_immediate_width(xedd);
172               if (xed_decoded_inst_get_immediate_is_signed(xedd)) {
173                   xed_int32_t x =xed_decoded_inst_get_signed_immediate(xedd);
174                   cout << hex << setfill('0') << setw(8) << x << setfill(' ') << dec 
175                        << '(' << width << ')';
176               }
177               else {
178                   xed_uint64_t x = xed_decoded_inst_get_unsigned_immediate(xedd); 
179                   cout << hex << setfill('0') << setw(16) << x << setfill(' ') << dec 
180                        << '(' << width << ')';
181               }
182               break;
183           }
184           case XED_OPERAND_IMM1: { // immediates
185               xed_uint8_t x = xed_decoded_inst_get_second_immediate(xedd);
186               cout << hex << setfill('0') << setw(2) << (int)x << setfill(' ') << dec;
187               break;
188           }
189
190           case XED_OPERAND_REG0:
191           case XED_OPERAND_REG1:
192           case XED_OPERAND_REG2:
193           case XED_OPERAND_REG3:
194           case XED_OPERAND_REG4:
195           case XED_OPERAND_REG5:
196           case XED_OPERAND_REG6:
197           case XED_OPERAND_REG7:
198           case XED_OPERAND_REG8:
199           case XED_OPERAND_REG9:
200           case XED_OPERAND_REG10:
201           case XED_OPERAND_REG11:
202           case XED_OPERAND_REG12:
203           case XED_OPERAND_REG13:
204           case XED_OPERAND_REG14:
205           case XED_OPERAND_REG15: {
206               xed_reg_enum_t r = xed_decoded_inst_get_reg(xedd, op_name);
207               cout << xed_operand_enum_t2str(op_name) << "=" << xed_reg_enum_t2str(r);
208               break;
209           }
210           default:
211             cout << "[Not currently printing value of field " << xed_operand_enum_t2str(op_name) << ']';
212             break;
213
214         }
215         cout << " " << xed_operand_visibility_enum_t2str(xed_operand_operand_visibility(op))
216              << " / " << xed_operand_action_enum_t2str(xed_operand_rw(op))
217              << " / " << xed_operand_width_enum_t2str(xed_operand_width(op));
218         cout << " bytes=" << xed_decoded_inst_operand_length(xedd,i);
219         cout << endl;
220     }
221 }
222
223 int main(int argc, char** argv) {
224     xed_state_t dstate;
225     xed_decoded_inst_t xedd;
226     int i, bytes = 0;
227     unsigned char itext[XED_MAX_INSTRUCTION_BYTES];
228     xed_bool_t long_mode = false;
229     unsigned int first_argv;
230
231     xed_tables_init();
232     xed_state_zero(&dstate);
233     if (argc > 2 && strcmp(argv[1], "-64") == 0) 
234         long_mode = true;
235
236     if (long_mode)  {
237         first_argv = 2;
238         dstate.mmode=XED_MACHINE_MODE_LONG_64;
239     }
240     else {
241         first_argv=1;
242         xed_state_init(&dstate,
243                        XED_MACHINE_MODE_LEGACY_32, 
244                        XED_ADDRESS_WIDTH_32b, 
245                        XED_ADDRESS_WIDTH_32b);
246     }
247
248     xed_decoded_inst_zero_set_mode(&xedd, &dstate);
249
250     for(  i=first_argv ;i < argc; i++) {
251         unsigned int x;
252         // sscanf is deprecated for MSVS8, so I'm using istringstreams
253         //sscanf(argv[i],"%x", &x);
254         istringstream s(argv[i]);
255         s >> hex >> x;
256         assert(bytes < XED_MAX_INSTRUCTION_BYTES);
257         itext[bytes++] = STATIC_CAST(xed_uint8_t,x);
258     }
259     if (bytes == 0) {
260         cout << "Must supply some hex bytes" << endl;
261         exit(1);
262     }
263
264     cout << "Attempting to decode: " << hex << setfill('0') ;
265     for(i=0;i<bytes;i++)
266         cout <<  setw(2) << static_cast<xed_uint_t>(itext[i]) << " ";
267     cout << endl << setfill(' ') << dec;
268
269     xed_error_enum_t xed_error = xed_decode(&xedd, 
270                                             REINTERPRET_CAST(const xed_uint8_t*,itext), 
271                                             bytes);
272     switch(xed_error)    {
273       case XED_ERROR_NONE:
274         break;
275       case XED_ERROR_BUFFER_TOO_SHORT:
276         cout << "Not enough bytes provided" << endl;
277         exit(1);
278       case XED_ERROR_GENERAL_ERROR:
279         cout << "Could not decode given input." << endl;
280         exit(1);
281       default:
282         cout << "Unhandled error code " << xed_error_enum_t2str(xed_error) << endl;
283         exit(1);
284     }
285         
286
287     cout << "iclass " 
288          << xed_iclass_enum_t2str(xed_decoded_inst_get_iclass(&xedd))  << "\t";
289     cout << "category " 
290          << xed_category_enum_t2str(xed_decoded_inst_get_category(&xedd))  << "\t";
291     cout << "ISA-extension " 
292          << xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xedd))  << endl;
293     cout << "instruction-length " 
294          << xed_decoded_inst_get_length(&xedd) << endl;
295     cout << "effective-operand-width " 
296          << xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xedd))  << endl;   
297     cout << "effective-address-width "
298          << xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xedd))  << endl; 
299     cout << "iform-enum-name " 
300          << xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xedd)) << endl;
301     cout << "iform-enum-name-dispatch (zero based) " 
302          << xed_decoded_inst_get_iform_enum_dispatch(&xedd) << endl;
303     cout << "iclass-max-iform-dispatch "
304          << xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xedd))  << endl;
305
306     // operands
307     print_operands(&xedd);
308     
309     // memops
310     print_memops(&xedd);
311     
312     // flags
313     print_flags(&xedd);
314
315     // attributes
316     print_attributes(&xedd);
317     return 0;
318 }