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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
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.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm_types.h>
24 #define MAKE_1OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * flags) { \
25 uchar_t tmp_dst = *dst; \
27 /* Some of the flags values are not copied out in a pushf, we save them here */ \
28 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
38 : "=q"(tmp_dst),"=q"(*flags) \
39 : "q"(*flags), "0"(tmp_dst) \
42 *flags |= flags_rsvd; \
46 #define MAKE_1OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * flags) { \
47 ushort_t tmp_dst = *dst; \
49 /* Some of the flags values are not copied out in a pushf, we save them here */ \
50 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
60 : "=q"(tmp_dst),"=q"(*flags) \
61 : "q"(*flags), "0"(tmp_dst) \
64 *flags |= flags_rsvd; \
68 #define MAKE_1OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * flags) { \
69 uint_t tmp_dst = *dst; \
71 /* Some of the flags values are not copied out in a pushf, we save them here */ \
72 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
82 : "=q"(tmp_dst),"=q"(*flags) \
83 : "q"(*flags), "0"(tmp_dst) \
86 *flags |= flags_rsvd; \
90 #define MAKE_1OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * flags) { \
91 ullong_t tmp_dst = *dst; \
93 /* Some of the flags values are not copied out in a pushf, we save them here */ \
94 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
104 : "=q"(tmp_dst),"=q"(*flags) \
105 : "q"(*flags), "0"(tmp_dst) \
108 *flags |= flags_rsvd; \
114 #define MAKE_1OP_8_INST(iname) static inline void iname##8(addr_t * dst) { \
115 uchar_t tmp_dst = *dst; \
125 #define MAKE_1OP_16_INST(iname) static inline void iname##16(addr_t * dst) { \
126 ushort_t tmp_dst = *dst; \
136 #define MAKE_1OP_32_INST(iname) static inline void iname##32(addr_t * dst) { \
137 uint_t tmp_dst = *dst; \
147 #define MAKE_1OP_64_INST(iname) static inline void iname##64(addr_t * dst) { \
148 ullong_t tmp_dst = *dst; \
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; \
163 /* Some of the flags values are not copied out in a pushf, we save them here */ \
164 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
170 #iname"q %2, %0\r\n" \
174 : "=q"(tmp_dst),"=q"(tmp_flags) \
175 : "q"(tmp_src),"q"(tmp_flags), "0"(tmp_dst) \
179 *flags = tmp_flags; \
180 *flags |= flags_rsvd; \
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; \
190 /* Some of the flags values are not copied out in a pushf, we save them here */ \
191 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
201 : "=q"(tmp_dst),"=q"(*flags) \
202 : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \
205 *flags |= flags_rsvd; \
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; \
213 /* Some of the flags values are not copied out in a pushf, we save them here */ \
214 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
224 : "=q"(tmp_dst),"=q"(*flags) \
225 : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \
228 *flags |= flags_rsvd; \
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; \
235 /* Some of the flags values are not copied out in a pushf, we save them here */ \
236 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
246 : "=q"(tmp_dst),"=q"(*flags) \
247 : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \
250 *flags |= flags_rsvd; \
258 #define MAKE_2OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \
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; \
274 : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
277 /* : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/ \
278 *flags |= flags_rsvd; \
282 #define MAKE_2OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \
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; \
298 : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
301 /* : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/ \
302 *flags |= flags_rsvd; \
305 #define MAKE_2OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \
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; \
321 : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
323 *flags |= flags_rsvd; \
328 #define MAKE_2OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \
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; \
344 : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
346 *flags |= flags_rsvd; \
352 #define MAKE_1OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \
354 addr_t * ecx, addr_t * flags) { \
355 /* Some of the flags values are not copied out in a pushf, we save them here */ \
356 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
368 : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
371 *flags |= flags_rsvd; \
375 #define MAKE_1OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \
377 addr_t * ecx, addr_t * flags) { \
378 /* Some of the flags values are not copied out in a pushf, we save them here */ \
379 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
391 : "D"(*(uint32_t *)dst),"a"(*(uint32_t *)src),"c"(*(uint32_t *)ecx),"q"(*flags) \
394 *flags |= flags_rsvd; \
397 #define MAKE_1OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \
399 addr_t * ecx, addr_t * flags) { \
400 /* Some of the flags values are not copied out in a pushf, we save them here */ \
401 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
413 : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
415 *flags |= flags_rsvd; \
420 #define MAKE_1OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \
422 addr_t * ecx, addr_t * flags) { \
423 /* Some of the flags values are not copied out in a pushf, we save them here */ \
424 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
436 : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
438 *flags |= flags_rsvd; \
444 #define MAKE_2OP_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
445 uint64_t tmp_dst = *dst, tmp_src = *src; \
450 : "q"(tmp_src), "0"(tmp_dst) \
455 #define MAKE_2OP_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
456 uint32_t tmp_dst = *dst, tmp_src = *src; \
461 : "q"(tmp_src), "0"(tmp_dst) \
466 #define MAKE_2OP_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
467 ushort_t tmp_dst = *dst, tmp_src = *src; \
472 : "q"(tmp_src), "0"(tmp_dst) \
477 #define MAKE_2OP_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
478 uchar_t tmp_dst = *dst, tmp_src = *src; \
483 : "q"(tmp_src), "0"(tmp_dst) \
492 #define MAKE_2OP_8EXT_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, uint_t dst_len) { \
493 if (dst_len == 2) { \
496 : "=q"(*(uint16_t *)dst) \
497 : "q"(*(uint8_t *)src), "0"(*(uint16_t *)dst) \
499 } else if (dst_len == 4) { \
502 : "=q"(*(uint32_t *)dst) \
503 : "q"(*(uint8_t *)src), "0"(*(uint32_t *)dst) \
505 } else if (dst_len == 8) { \
508 : "=q"(*(uint64_t *)dst) \
509 : "q"(*(uint8_t *)src), "0"(*(uint64_t *)dst) \
514 #define MAKE_2OP_16EXT_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, uint_t dst_len) { \
515 if (dst_len == 4) { \
518 : "=q"(*(uint32_t *)dst) \
519 : "q"(*(uint16_t *)src), "0"(*(uint32_t *)dst) \
521 } else if (dst_len == 8) { \
524 : "=q"(*(uint64_t *)dst) \
525 : "q"(*(uint16_t *)src), "0"(*(uint64_t *)dst) \
533 #define MAKE_2OUT_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
536 : "=q"(*(uint64_t *)dst), "=q"(*(uint64_t *)src) \
537 : "0"(*(uint64_t *)dst), "1"(*(uint64_t *)src) \
541 #define MAKE_2OUT_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
544 : "=q"(*(uint32_t *)dst), "=q"(*(uint32_t *)src) \
545 : "0"(*(uint32_t *)dst), "1"(*(uint32_t *)src) \
549 #define MAKE_2OUT_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
552 : "=q"(*(uint16_t *)dst), "=q"(*(uint16_t *)src) \
553 : "0"(*(uint16_t *)dst), "1"(*(uint16_t *)src) \
557 #define MAKE_2OUT_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
560 : "=q"(*(uint8_t *)dst), "=q"(*(uint8_t *)src) \
561 : "0"(*(uint8_t *)dst), "1"(*(uint8_t *)src) \
570 /****************************/
571 /* 8 Bit instruction forms */
572 /****************************/
574 MAKE_2OP_8FLAGS_INST(adc);
575 MAKE_2OP_8FLAGS_INST(add);
576 MAKE_2OP_8FLAGS_INST(and);
577 MAKE_2OP_8FLAGS_INST(or);
578 MAKE_2OP_8FLAGS_INST(xor);
579 MAKE_2OP_8FLAGS_INST(sub);
582 MAKE_1OP_8FLAGS_INST(inc);
583 MAKE_1OP_8FLAGS_INST(dec);
584 MAKE_1OP_8FLAGS_INST(neg);
585 MAKE_1OP_8FLAGS_INST(setb);
586 MAKE_1OP_8FLAGS_INST(setbe);
587 MAKE_1OP_8FLAGS_INST(setl);
588 MAKE_1OP_8FLAGS_INST(setle);
589 MAKE_1OP_8FLAGS_INST(setnb);
590 MAKE_1OP_8FLAGS_INST(setnbe);
591 MAKE_1OP_8FLAGS_INST(setnl);
592 MAKE_1OP_8FLAGS_INST(setnle);
593 MAKE_1OP_8FLAGS_INST(setno);
594 MAKE_1OP_8FLAGS_INST(setnp);
595 MAKE_1OP_8FLAGS_INST(setns);
596 MAKE_1OP_8FLAGS_INST(setnz);
597 MAKE_1OP_8FLAGS_INST(seto);
598 MAKE_1OP_8FLAGS_INST(setp);
599 MAKE_1OP_8FLAGS_INST(sets);
600 MAKE_1OP_8FLAGS_INST(setz);
603 MAKE_1OP_8_INST(not);
605 MAKE_2OP_8_INST(mov);
606 MAKE_2OP_8EXT_INST(movzx);
607 MAKE_2OP_8EXT_INST(movsx);
609 MAKE_2OUT_8_INST(xchg);
611 MAKE_2OP_8STR_INST(movs);
612 MAKE_1OP_8STR_INST(stos);
613 MAKE_1OP_8STR_INST(scas);
616 /****************************/
617 /* 16 Bit instruction forms */
618 /****************************/
619 MAKE_2OP_16FLAGS_INST(adc);
620 MAKE_2OP_16FLAGS_INST(add);
621 MAKE_2OP_16FLAGS_INST(and);
622 MAKE_2OP_16FLAGS_INST(or);
623 MAKE_2OP_16FLAGS_INST(xor);
624 MAKE_2OP_16FLAGS_INST(sub);
627 MAKE_1OP_16FLAGS_INST(inc);
628 MAKE_1OP_16FLAGS_INST(dec);
629 MAKE_1OP_16FLAGS_INST(neg);
631 MAKE_1OP_16_INST(not);
633 MAKE_2OP_16_INST(mov);
634 MAKE_2OP_16EXT_INST(movzx);
635 MAKE_2OP_16EXT_INST(movsx);
636 MAKE_2OUT_16_INST(xchg);
638 MAKE_2OP_16STR_INST(movs);
639 MAKE_1OP_16STR_INST(stos);
640 MAKE_1OP_16STR_INST(scas);
643 /****************************/
644 /* 32 Bit instruction forms */
645 /****************************/
646 MAKE_2OP_32FLAGS_INST(adc);
647 MAKE_2OP_32FLAGS_INST(add);
648 MAKE_2OP_32FLAGS_INST(and);
649 MAKE_2OP_32FLAGS_INST(or);
650 MAKE_2OP_32FLAGS_INST(xor);
651 MAKE_2OP_32FLAGS_INST(sub);
654 MAKE_1OP_32FLAGS_INST(inc);
655 MAKE_1OP_32FLAGS_INST(dec);
656 MAKE_1OP_32FLAGS_INST(neg);
658 MAKE_1OP_32_INST(not);
660 MAKE_2OP_32_INST(mov);
662 MAKE_2OUT_32_INST(xchg);
666 MAKE_2OP_32STR_INST(movs);
667 MAKE_1OP_32STR_INST(stos);
668 MAKE_1OP_32STR_INST(scas);
674 /****************************/
675 /* 64 Bit instruction forms */
676 /****************************/
677 MAKE_2OP_64FLAGS_INST(adc);
678 MAKE_2OP_64FLAGS_INST(add);
679 MAKE_2OP_64FLAGS_INST(and);
680 MAKE_2OP_64FLAGS_INST(or);
681 MAKE_2OP_64FLAGS_INST(xor);
682 MAKE_2OP_64FLAGS_INST(sub);
684 MAKE_1OP_64FLAGS_INST(inc);
685 MAKE_1OP_64FLAGS_INST(dec);
686 MAKE_1OP_64FLAGS_INST(neg);
688 MAKE_1OP_64_INST(not);
691 MAKE_2OP_64_INST(mov);
692 MAKE_2OP_64STR_INST(movs);
693 MAKE_1OP_64STR_INST(stos);
694 MAKE_1OP_64STR_INST(scas);
696 MAKE_2OUT_64_INST(xchg);