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.


cleaned up emulation interface
[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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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
258 #define MAKE_2OP_64STR_WINST(iname) static inline void iname##64(addr_t * dst, \
259                                                                  addr_t * src, \
260                                                                  addr_t * ecx, addr_t * flags) { \
261     /* Some of the flags values are not copied out in a pushf, we save them here */ \
262     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
263                                                                         \
264     asm volatile (                                                      \
265          "pushfq; "                                                     \
266          "pushq %4; "                                                   \
267          "popfq; "                                                      \
268          "rep; "                                                        \
269          #iname"q; "                                                    \
270          "pushfq; "                                                     \
271          "popq %0; "                                                    \
272          "popfq; "                                                      \
273          : "=q"(*flags)                                                 \
274          : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags)                    \
275          );                                                             \
276                                                                         \
277     /*   : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/              \
278     *flags |= flags_rsvd;                                               \
279   }
280
281
282 #define MAKE_2OP_32STR_WINST(iname) static inline void iname##32(addr_t * dst, \
283                                                                 addr_t * src, \
284                                                                 addr_t * ecx, addr_t * flags) { \
285     /* Some of the flags values are not copied out in a pushf, we save them here */ \
286     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
287                                                                         \
288     asm volatile (                                                      \
289          "pushf; "                                                      \
290          "push %4; "                                                    \
291          "popf; "                                                       \
292          "rep; "                                                        \
293          #iname"l; "                                                    \
294          "pushf; "                                                      \
295          "pop %0; "                                                     \
296          "popf; "                                                       \
297          : "=q"(*flags)                                                 \
298          : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags)                    \
299          );                                                             \
300                                                                         \
301     /*   : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/              \
302     *flags |= flags_rsvd;                                               \
303   }
304
305 #define MAKE_2OP_16STR_WINST(iname) static inline void iname##16(addr_t * dst, \
306                                                                 addr_t * src, \
307                                                                 addr_t * ecx, addr_t * flags) { \
308      /* Some of the flags values are not copied out in a pushf, we save them here */ \
309     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
310                                                                         \
311     asm volatile (                                                      \
312          "pushf; "                                                      \
313          "push %4; "                                                    \
314          "popf; "                                                       \
315          "rep; "                                                        \
316          #iname"w; "                                                    \
317          "pushf; "                                                      \
318          "pop %0; "                                                     \
319          "popf; "                                                       \
320          : "=q"(*flags)                                                 \
321          : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags)                    \
322          );                                                             \
323     *flags |= flags_rsvd;                                               \
324   }
325
326
327
328 #define MAKE_2OP_8STR_WINST(iname) static inline void iname##8(addr_t * dst, \
329                                                               addr_t * src, \
330                                                               addr_t * ecx, addr_t * flags) { \
331     /* Some of the flags values are not copied out in a pushf, we save them here */ \
332     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
333                                                                         \
334     asm volatile (                                                      \
335          "pushf; "                                                      \
336          "push %4; "                                                    \
337          "popf; "                                                       \
338          "rep; "                                                        \
339          #iname"b; "                                                    \
340          "pushf; "                                                      \
341          "pop %0; "                                                     \
342          "popf; "                                                       \
343          : "=q"(*flags)                                                 \
344          : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags)                    \
345          );                                                             \
346     *flags |= flags_rsvd;                                               \
347   }
348
349
350
351
352 #define MAKE_2OP_64_WINST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
353     uint32_t tmp_dst = *dst, tmp_src = *src;                            \
354                                                                         \
355     asm volatile (                                                      \
356          #iname"q %1, %0; "                                             \
357          : "=q"(tmp_dst)                                                \
358          : "q"(tmp_src), "0"(tmp_dst)                                   \
359          );                                                             \
360     *dst = tmp_dst;                                                     \
361   }
362
363 #define MAKE_2OP_32_WINST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
364     uint32_t tmp_dst = *dst, tmp_src = *src;                            \
365                                                                         \
366     asm volatile (                                                      \
367          #iname"l %1, %0; "                                             \
368          : "=q"(tmp_dst)                                                \
369          : "q"(tmp_src), "0"(tmp_dst)                                   \
370          );                                                             \
371     *dst = tmp_dst;                                                     \
372   }
373
374 #define MAKE_2OP_16_WINST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
375     ushort_t tmp_dst = *dst, tmp_src = *src;                            \
376                                                                         \
377     asm volatile (                                                      \
378          #iname"w %1, %0; "                                             \
379          : "=q"(tmp_dst)                                                \
380          : "q"(tmp_src), "0"(tmp_dst)                                   \
381          );                                                             \
382     *dst = tmp_dst;                                                     \
383   }
384
385 #define MAKE_2OP_8_WINST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
386     uchar_t tmp_dst = *dst, tmp_src = *src;                             \
387                                                                         \
388     asm volatile (                                                      \
389          #iname"b %1, %0; "                                             \
390          : "=q"(tmp_dst)                                                \
391          : "q"(tmp_src), "0"(tmp_dst)                                   \
392          );                                                             \
393     *dst = tmp_dst;                                                     \
394   }
395
396
397
398
399
400
401
402 MAKE_2OP_8FLAGS_WINST(adc);
403 MAKE_2OP_8FLAGS_WINST(add);
404 MAKE_2OP_8FLAGS_WINST(and);
405 MAKE_2OP_8FLAGS_WINST(or);
406 MAKE_2OP_8FLAGS_WINST(xor);
407 MAKE_2OP_8FLAGS_WINST(sub);
408
409
410 MAKE_1OP_8FLAGS_WINST(inc);
411 MAKE_1OP_8FLAGS_WINST(dec);
412 MAKE_1OP_8FLAGS_WINST(neg);
413 MAKE_1OP_8FLAGS_WINST(setb);
414 MAKE_1OP_8FLAGS_WINST(setbe);
415 MAKE_1OP_8FLAGS_WINST(setl);
416 MAKE_1OP_8FLAGS_WINST(setle);
417 MAKE_1OP_8FLAGS_WINST(setnb);
418 MAKE_1OP_8FLAGS_WINST(setnbe);
419 MAKE_1OP_8FLAGS_WINST(setnl);
420 MAKE_1OP_8FLAGS_WINST(setnle);
421 MAKE_1OP_8FLAGS_WINST(setno);
422 MAKE_1OP_8FLAGS_WINST(setnp);
423 MAKE_1OP_8FLAGS_WINST(setns);
424 MAKE_1OP_8FLAGS_WINST(setnz);
425 MAKE_1OP_8FLAGS_WINST(seto);
426 MAKE_1OP_8FLAGS_WINST(setp);
427 MAKE_1OP_8FLAGS_WINST(sets);
428 MAKE_1OP_8FLAGS_WINST(setz);
429
430
431 MAKE_1OP_8_WINST(not);
432
433 MAKE_2OP_8_WINST(mov);
434 MAKE_2OP_8_WINST(xchg);
435
436
437
438 MAKE_2OP_16FLAGS_WINST(adc);
439 MAKE_2OP_16FLAGS_WINST(add);
440 MAKE_2OP_16FLAGS_WINST(and);
441 MAKE_2OP_16FLAGS_WINST(or);
442 MAKE_2OP_16FLAGS_WINST(xor);
443 MAKE_2OP_16FLAGS_WINST(sub);
444
445
446 MAKE_1OP_16FLAGS_WINST(inc);
447 MAKE_1OP_16FLAGS_WINST(dec);
448 MAKE_1OP_16FLAGS_WINST(neg);
449
450 MAKE_1OP_16_WINST(not);
451
452 MAKE_2OP_16_WINST(mov);
453 MAKE_2OP_16_WINST(xchg);
454
455
456
457
458
459 MAKE_2OP_32FLAGS_WINST(adc);
460 MAKE_2OP_32FLAGS_WINST(add);
461 MAKE_2OP_32FLAGS_WINST(and);
462 MAKE_2OP_32FLAGS_WINST(or);
463 MAKE_2OP_32FLAGS_WINST(xor);
464 MAKE_2OP_32FLAGS_WINST(sub);
465
466
467 MAKE_1OP_32FLAGS_WINST(inc);
468 MAKE_1OP_32FLAGS_WINST(dec);
469 MAKE_1OP_32FLAGS_WINST(neg);
470
471 MAKE_1OP_32_WINST(not);
472
473 MAKE_2OP_32_WINST(mov);
474 MAKE_2OP_32_WINST(xchg);
475
476 MAKE_2OP_8STR_WINST(movs);
477 MAKE_2OP_16STR_WINST(movs);
478 MAKE_2OP_32STR_WINST(movs);