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.


fixed data type for 64 bit instruction form
[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
258 #define MAKE_2OP_64STR_INST(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_INST(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_INST(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_INST(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_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
353     uint64_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_INST(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_INST(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_INST(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 /* 8 Bit instruction forms  */
402 /****************************/
403
404 MAKE_2OP_8FLAGS_INST(adc);
405 MAKE_2OP_8FLAGS_INST(add);
406 MAKE_2OP_8FLAGS_INST(and);
407 MAKE_2OP_8FLAGS_INST(or);
408 MAKE_2OP_8FLAGS_INST(xor);
409 MAKE_2OP_8FLAGS_INST(sub);
410
411
412 MAKE_1OP_8FLAGS_INST(inc);
413 MAKE_1OP_8FLAGS_INST(dec);
414 MAKE_1OP_8FLAGS_INST(neg);
415 MAKE_1OP_8FLAGS_INST(setb);
416 MAKE_1OP_8FLAGS_INST(setbe);
417 MAKE_1OP_8FLAGS_INST(setl);
418 MAKE_1OP_8FLAGS_INST(setle);
419 MAKE_1OP_8FLAGS_INST(setnb);
420 MAKE_1OP_8FLAGS_INST(setnbe);
421 MAKE_1OP_8FLAGS_INST(setnl);
422 MAKE_1OP_8FLAGS_INST(setnle);
423 MAKE_1OP_8FLAGS_INST(setno);
424 MAKE_1OP_8FLAGS_INST(setnp);
425 MAKE_1OP_8FLAGS_INST(setns);
426 MAKE_1OP_8FLAGS_INST(setnz);
427 MAKE_1OP_8FLAGS_INST(seto);
428 MAKE_1OP_8FLAGS_INST(setp);
429 MAKE_1OP_8FLAGS_INST(sets);
430 MAKE_1OP_8FLAGS_INST(setz);
431
432
433 MAKE_1OP_8_INST(not);
434
435 MAKE_2OP_8_INST(mov);
436 MAKE_2OP_8_INST(xchg);
437
438 MAKE_2OP_8STR_INST(movs);
439
440
441 /****************************/
442 /* 16 Bit instruction forms */
443 /****************************/
444 MAKE_2OP_16FLAGS_INST(adc);
445 MAKE_2OP_16FLAGS_INST(add);
446 MAKE_2OP_16FLAGS_INST(and);
447 MAKE_2OP_16FLAGS_INST(or);
448 MAKE_2OP_16FLAGS_INST(xor);
449 MAKE_2OP_16FLAGS_INST(sub);
450
451
452 MAKE_1OP_16FLAGS_INST(inc);
453 MAKE_1OP_16FLAGS_INST(dec);
454 MAKE_1OP_16FLAGS_INST(neg);
455
456 MAKE_1OP_16_INST(not);
457
458 MAKE_2OP_16_INST(mov);
459 MAKE_2OP_16_INST(xchg);
460
461 MAKE_2OP_16STR_INST(movs);
462
463 /****************************/
464 /* 32 Bit instruction forms */
465 /****************************/
466 MAKE_2OP_32FLAGS_INST(adc);
467 MAKE_2OP_32FLAGS_INST(add);
468 MAKE_2OP_32FLAGS_INST(and);
469 MAKE_2OP_32FLAGS_INST(or);
470 MAKE_2OP_32FLAGS_INST(xor);
471 MAKE_2OP_32FLAGS_INST(sub);
472
473
474 MAKE_1OP_32FLAGS_INST(inc);
475 MAKE_1OP_32FLAGS_INST(dec);
476 MAKE_1OP_32FLAGS_INST(neg);
477
478 MAKE_1OP_32_INST(not);
479
480 MAKE_2OP_32_INST(mov);
481 MAKE_2OP_32_INST(xchg);
482
483
484
485 MAKE_2OP_32STR_INST(movs);
486
487 #ifdef __V3_64BIT__
488
489 /****************************/
490 /* 64 Bit instruction forms */
491 /****************************/
492 MAKE_2OP_64FLAGS_INST(adc);
493 MAKE_2OP_64FLAGS_INST(add);
494 MAKE_2OP_64FLAGS_INST(and);
495 MAKE_2OP_64FLAGS_INST(or);
496 MAKE_2OP_64FLAGS_INST(xor);
497 MAKE_2OP_64FLAGS_INST(sub);
498
499 MAKE_1OP_64FLAGS_INST(inc);
500 MAKE_1OP_64FLAGS_INST(dec);
501 MAKE_1OP_64FLAGS_INST(neg);
502
503 MAKE_1OP_64_INST(not);
504
505
506 MAKE_2OP_64_INST(mov);
507
508 MAKE_2OP_64_INST(xchg);
509
510
511 #endif