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.


added profiling support
[palacios.git] / palacios / include / palacios / vmm_instr_emulator.h
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm_types.h>
21
22
23
24 #define MAKE_1OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst,  addr_t * flags) { \
25     uchar_t tmp_dst = *dst;                                             \
26                                                                         \
27     /* Some of the flags values are not copied out in a pushf, we save them here */ \
28     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
29                                                                         \
30     asm volatile (                                                              \
31          "pushf; "                                                      \
32          "push %2; "                                                    \
33          "popf; "                                                       \
34          #iname"b %0; "                                                 \
35          "pushf; "                                                      \
36          "pop %1; "                                                     \
37          "popf; "                                                       \
38          : "=q"(tmp_dst),"=q"(*flags)                                   \
39          : "q"(*flags), "0"(tmp_dst)                                    \
40          );                                                             \
41     *dst = tmp_dst;                                                     \
42     *flags |= flags_rsvd;                                               \
43                                                                         \
44   }
45
46 #define MAKE_1OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst,  addr_t * flags) { \
47     ushort_t tmp_dst = *dst;                                            \
48                                                                         \
49     /* Some of the flags values are not copied out in a pushf, we save them here */ \
50     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
51                                                                         \
52     asm volatile (                                                              \
53          "pushf; "                                                      \
54          "push %2; "                                                    \
55          "popf; "                                                       \
56          #iname"w %0; "                                                 \
57          "pushf; "                                                      \
58          "pop %1; "                                                     \
59          "popf; "                                                       \
60          : "=q"(tmp_dst),"=q"(*flags)                                   \
61          : "q"(*flags), "0"(tmp_dst)                                    \
62          );                                                             \
63     *dst = tmp_dst;                                                     \
64     *flags |= flags_rsvd;                                               \
65                                                                         \
66   }
67
68 #define MAKE_1OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst,  addr_t * flags) { \
69     uint_t tmp_dst = *dst;                                              \
70                                                                         \
71     /* Some of the flags values are not copied out in a pushf, we save them here */ \
72     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
73                                                                         \
74     asm volatile (                                                              \
75          "pushf; "                                                      \
76          "push %2; "                                                    \
77          "popf; "                                                       \
78          #iname"l %0; "                                                 \
79          "pushf; "                                                      \
80          "pop %1; "                                                     \
81          "popf; "                                                       \
82          : "=q"(tmp_dst),"=q"(*flags)                                   \
83          : "q"(*flags), "0"(tmp_dst)                                    \
84          );                                                             \
85     *dst = tmp_dst;                                                     \
86     *flags |= flags_rsvd;                                               \
87                                                                         \
88   }
89
90 #define MAKE_1OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst,  addr_t * flags) { \
91     ullong_t tmp_dst = *dst;                                            \
92                                                                         \
93     /* Some of the flags values are not copied out in a pushf, we save them here */ \
94     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
95                                                                         \
96     asm volatile (                                                              \
97          "pushfq; "                                                     \
98          "push %2; "                                                    \
99          "popfq; "                                                      \
100          #iname"q %0; "                                                 \
101          "pushfq; "                                                     \
102          "pop %1; "                                                     \
103          "popfq; "                                                      \
104          : "=q"(tmp_dst),"=q"(*flags)                                   \
105          : "q"(*flags), "0"(tmp_dst)                                    \
106          );                                                             \
107     *dst = tmp_dst;                                                     \
108     *flags |= flags_rsvd;                                               \
109                                                                         \
110   }
111
112
113
114 #define MAKE_1OP_8_INST(iname) static inline void iname##8(addr_t * dst) { \
115     uchar_t tmp_dst = *dst;                                             \
116                                                                         \
117     asm volatile (                                                      \
118                   #iname"b %0; "                                        \
119                   : "=q"(tmp_dst)                                       \
120                   : "0"(tmp_dst)                                        \
121                   );                                                    \
122     *dst = tmp_dst;                                                     \
123   }
124
125 #define MAKE_1OP_16_INST(iname) static inline void iname##16(addr_t * dst) { \
126     ushort_t tmp_dst = *dst;                                            \
127                                                                         \
128     asm volatile (                                                      \
129          #iname"w %0; "                                                 \
130          : "=q"(tmp_dst)                                                \
131          :  "0"(tmp_dst)                                                \
132          );                                                             \
133     *dst = tmp_dst;                                                     \
134   }
135
136 #define MAKE_1OP_32_INST(iname) static inline void iname##32(addr_t * dst) { \
137     uint_t tmp_dst = *dst;                                              \
138                                                                         \
139     asm volatile (                                                      \
140          #iname"l %0; "                                                 \
141          : "=q"(tmp_dst)                                                \
142          : "0"(tmp_dst)                                                 \
143          );                                                             \
144     *dst = tmp_dst;                                                     \
145   }
146
147 #define MAKE_1OP_64_INST(iname) static inline void iname##64(addr_t * dst) { \
148     ullong_t tmp_dst = *dst;                                            \
149                                                                         \
150     asm volatile (                                                      \
151                   #iname"q %0; "                                        \
152                   : "=q"(tmp_dst)                                       \
153                   : "0"(tmp_dst)                                        \
154                   );                                                    \
155     *dst = tmp_dst;                                                     \
156   }
157
158
159 #define MAKE_2OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \
160     uint64_t tmp_dst = *dst, tmp_src = *src;                                    \
161     addr_t tmp_flags = *flags;                                          \
162                                                                         \
163     /* Some of the flags values are not copied out in a pushf, we save them here */ \
164     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
165                                                                         \
166     asm volatile (                                                              \
167          "pushfq\r\n"                                                   \
168          "push %3\r\n"                                                  \
169          "popfq\r\n"                                                    \
170          #iname"q %2, %0\r\n"                                           \
171          "pushfq\r\n"                                                   \
172          "pop %1\r\n"                                                   \
173          "popfq\r\n"                                                    \
174          : "=q"(tmp_dst),"=q"(tmp_flags)                                \
175          : "q"(tmp_src),"q"(tmp_flags), "0"(tmp_dst)                    \
176          );                                                             \
177                                                                         \
178     *dst = tmp_dst;                                                     \
179     *flags = tmp_flags;                                                 \
180     *flags |= flags_rsvd;                                               \
181                                                                         \
182   }
183
184
185
186
187 #define MAKE_2OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \
188     uint32_t tmp_dst = *dst, tmp_src = *src;                            \
189                                                                         \
190     /* Some of the flags values are not copied out in a pushf, we save them here */ \
191     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
192                                                                         \
193     asm volatile (                                                      \
194          "pushf; "                                                      \
195          "push %3; "                                                    \
196          "popf; "                                                       \
197          #iname"l %2, %0; "                                             \
198          "pushf; "                                                      \
199          "pop %1; "                                                     \
200          "popf; "                                                       \
201          : "=q"(tmp_dst),"=q"(*flags)                                   \
202          : "q"(tmp_src),"q"(*flags), "0"(tmp_dst)                       \
203          );                                                             \
204     *dst = tmp_dst;                                                     \
205     *flags |= flags_rsvd;                                               \
206                                                                         \
207   }
208
209
210 #define MAKE_2OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \
211     ushort_t tmp_dst = *dst, tmp_src = *src;                            \
212                                                                         \
213     /* Some of the flags values are not copied out in a pushf, we save them here */ \
214     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
215                                                                         \
216     asm volatile (                                                      \
217          "pushf; "                                                      \
218          "push %3; "                                                    \
219          "popf; "                                                       \
220          #iname"w %2, %0; "                                             \
221          "pushf; "                                                      \
222          "pop %1; "                                                     \
223          "popf; "                                                       \
224          : "=q"(tmp_dst),"=q"(*flags)                                   \
225          : "q"(tmp_src),"q"(*flags), "0"(tmp_dst)                       \
226          );                                                             \
227     *dst = tmp_dst;                                                     \
228     *flags |= flags_rsvd;                                               \
229                                                                         \
230   }
231
232 #define MAKE_2OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \
233     uchar_t tmp_dst = *dst, tmp_src = *src;                             \
234                                                                         \
235     /* Some of the flags values are not copied out in a pushf, we save them here */ \
236     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
237                                                                         \
238     asm volatile (                                                      \
239          "pushf; "                                                      \
240          "push %3; "                                                    \
241          "popf; "                                                       \
242          #iname"b %2, %0; "                                             \
243          "pushf; "                                                      \
244          "pop %1; "                                                     \
245          "popf; "                                                       \
246          : "=q"(tmp_dst),"=q"(*flags)                                   \
247          : "q"(tmp_src),"q"(*flags), "0"(tmp_dst)                       \
248          );                                                             \
249     *dst = tmp_dst;                                                     \
250     *flags |= flags_rsvd;                                               \
251                                                                         \
252   }
253
254
255
256
257 #define MAKE_2OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \
258                                                                 addr_t * src, \
259                                                                 addr_t * ecx, addr_t * flags) { \
260     /* Some of the flags values are not copied out in a pushf, we save them here */ \
261     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
262                                                                         \
263     asm volatile (                                                      \
264          "pushf; "                                                      \
265          "push %4; "                                                    \
266          "popf; "                                                       \
267          "rep; "                                                        \
268          #iname"l; "                                                    \
269          "pushf; "                                                      \
270          "pop %0; "                                                     \
271          "popf; "                                                       \
272          : "=q"(*flags)                                                 \
273          : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags)                    \
274          );                                                             \
275                                                                         \
276     /*   : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/              \
277     *flags |= flags_rsvd;                                               \
278   }
279
280 #define MAKE_2OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \
281                                                                 addr_t * src, \
282                                                                 addr_t * ecx, addr_t * flags) { \
283      /* Some of the flags values are not copied out in a pushf, we save them here */ \
284     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
285                                                                         \
286     asm volatile (                                                      \
287          "pushf; "                                                      \
288          "push %4; "                                                    \
289          "popf; "                                                       \
290          "rep; "                                                        \
291          #iname"w; "                                                    \
292          "pushf; "                                                      \
293          "pop %0; "                                                     \
294          "popf; "                                                       \
295          : "=q"(*flags)                                                 \
296          : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags)                    \
297          );                                                             \
298     *flags |= flags_rsvd;                                               \
299   }
300
301
302
303 #define MAKE_2OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \
304                                                               addr_t * src, \
305                                                               addr_t * ecx, addr_t * flags) { \
306     /* Some of the flags values are not copied out in a pushf, we save them here */ \
307     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
308                                                                         \
309     asm volatile (                                                      \
310          "pushf; "                                                      \
311          "push %4; "                                                    \
312          "popf; "                                                       \
313          "rep; "                                                        \
314          #iname"b; "                                                    \
315          "pushf; "                                                      \
316          "pop %0; "                                                     \
317          "popf; "                                                       \
318          : "=q"(*flags)                                                 \
319          : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags)                    \
320          );                                                             \
321     *flags |= flags_rsvd;                                               \
322   }
323
324
325
326
327 #define MAKE_2OP_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
328     uint32_t tmp_dst = *dst, tmp_src = *src;                            \
329                                                                         \
330     asm volatile (                                                      \
331          #iname"l %1, %0; "                                             \
332          : "=q"(tmp_dst)                                                \
333          : "q"(tmp_src), "0"(tmp_dst)                                   \
334          );                                                             \
335     *dst = tmp_dst;                                                     \
336   }
337
338 #define MAKE_2OP_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
339     ushort_t tmp_dst = *dst, tmp_src = *src;                            \
340                                                                         \
341     asm volatile (                                                      \
342          #iname"w %1, %0; "                                             \
343          : "=q"(tmp_dst)                                                \
344          : "q"(tmp_src), "0"(tmp_dst)                                   \
345          );                                                             \
346     *dst = tmp_dst;                                                     \
347   }
348
349 #define MAKE_2OP_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
350     uchar_t tmp_dst = *dst, tmp_src = *src;                             \
351                                                                         \
352     asm volatile (                                                      \
353          #iname"b %1, %0; "                                             \
354          : "=q"(tmp_dst)                                                \
355          : "q"(tmp_src), "0"(tmp_dst)                                   \
356          );                                                             \
357     *dst = tmp_dst;                                                     \
358   }
359
360
361
362
363
364
365
366 MAKE_2OP_8FLAGS_INST(adc);
367 MAKE_2OP_8FLAGS_INST(add);
368 MAKE_2OP_8FLAGS_INST(and);
369 MAKE_2OP_8FLAGS_INST(or);
370 MAKE_2OP_8FLAGS_INST(xor);
371 MAKE_2OP_8FLAGS_INST(sub);
372
373
374 MAKE_1OP_8FLAGS_INST(inc);
375 MAKE_1OP_8FLAGS_INST(dec);
376 MAKE_1OP_8FLAGS_INST(neg);
377 MAKE_1OP_8FLAGS_INST(setb);
378 MAKE_1OP_8FLAGS_INST(setbe);
379 MAKE_1OP_8FLAGS_INST(setl);
380 MAKE_1OP_8FLAGS_INST(setle);
381 MAKE_1OP_8FLAGS_INST(setnb);
382 MAKE_1OP_8FLAGS_INST(setnbe);
383 MAKE_1OP_8FLAGS_INST(setnl);
384 MAKE_1OP_8FLAGS_INST(setnle);
385 MAKE_1OP_8FLAGS_INST(setno);
386 MAKE_1OP_8FLAGS_INST(setnp);
387 MAKE_1OP_8FLAGS_INST(setns);
388 MAKE_1OP_8FLAGS_INST(setnz);
389 MAKE_1OP_8FLAGS_INST(seto);
390 MAKE_1OP_8FLAGS_INST(setp);
391 MAKE_1OP_8FLAGS_INST(sets);
392 MAKE_1OP_8FLAGS_INST(setz);
393
394
395 MAKE_1OP_8_INST(not);
396
397 MAKE_2OP_8_INST(mov);
398 MAKE_2OP_8_INST(xchg);
399
400
401
402 MAKE_2OP_16FLAGS_INST(adc);
403 MAKE_2OP_16FLAGS_INST(add);
404 MAKE_2OP_16FLAGS_INST(and);
405 MAKE_2OP_16FLAGS_INST(or);
406 MAKE_2OP_16FLAGS_INST(xor);
407 MAKE_2OP_16FLAGS_INST(sub);
408
409
410 MAKE_1OP_16FLAGS_INST(inc);
411 MAKE_1OP_16FLAGS_INST(dec);
412 MAKE_1OP_16FLAGS_INST(neg);
413
414 MAKE_1OP_16_INST(not);
415
416 MAKE_2OP_16_INST(mov);
417 MAKE_2OP_16_INST(xchg);
418
419
420
421
422
423 MAKE_2OP_32FLAGS_INST(adc);
424 MAKE_2OP_32FLAGS_INST(add);
425 MAKE_2OP_32FLAGS_INST(and);
426 MAKE_2OP_32FLAGS_INST(or);
427 MAKE_2OP_32FLAGS_INST(xor);
428 MAKE_2OP_32FLAGS_INST(sub);
429
430
431 MAKE_1OP_32FLAGS_INST(inc);
432 MAKE_1OP_32FLAGS_INST(dec);
433 MAKE_1OP_32FLAGS_INST(neg);
434
435 MAKE_1OP_32_INST(not);
436
437 MAKE_2OP_32_INST(mov);
438 MAKE_2OP_32_INST(xchg);
439
440 MAKE_2OP_8STR_INST(movs);
441 MAKE_2OP_16STR_INST(movs);
442 MAKE_2OP_32STR_INST(movs);