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 /* Some of the flags values are not copied out in a pushf, we save them here */ \
26 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
36 : "=q"(*(uint8_t *)dst),"=q"(*flags) \
37 : "q"(*flags), "0"(*(uint8_t *)dst) \
39 *flags |= flags_rsvd; \
43 #define MAKE_1OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * flags) { \
44 /* Some of the flags values are not copied out in a pushf, we save them here */ \
45 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
55 : "=q"(*(uint16_t *)dst),"=q"(*flags) \
56 : "q"(*flags), "0"(*(uint16_t *)dst) \
58 *flags |= flags_rsvd; \
62 #define MAKE_1OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * flags) { \
63 /* Some of the flags values are not copied out in a pushf, we save them here */ \
64 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
74 : "=q"(*(uint32_t *)dst),"=q"(*flags) \
75 : "q"(*flags), "0"(*(uint32_t *)dst) \
77 *flags |= flags_rsvd; \
81 #define MAKE_1OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * flags) { \
82 /* Some of the flags values are not copied out in a pushf, we save them here */ \
83 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
93 : "=q"(*(uint64_t *)dst),"=q"(*flags) \
94 : "q"(*flags), "0"(*(uint64_t *)dst) \
96 *flags |= flags_rsvd; \
102 #define MAKE_1OP_8_INST(iname) static inline void iname##8(addr_t * dst) { \
105 : "=q"(*(uint8_t *)dst) \
106 : "0"(*(uint8_t *)dst) \
110 #define MAKE_1OP_16_INST(iname) static inline void iname##16(addr_t * dst) { \
113 : "=q"(*(uint16_t *)dst) \
114 : "0"(*(uint16_t *)dst) \
118 #define MAKE_1OP_32_INST(iname) static inline void iname##32(addr_t * dst) { \
121 : "=q"(*(uint32_t *)dst) \
122 : "0"(*(uint32_t *)dst) \
126 #define MAKE_1OP_64_INST(iname) static inline void iname##64(addr_t * dst) { \
129 : "=q"(*(uint64_t *)dst) \
130 : "0"(*(uint64_t *)dst) \
135 #define MAKE_2OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \
136 /* Some of the flags values are not copied out in a pushf, we save them here */ \
137 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
143 #iname"q %2, %0\r\n" \
147 : "=q"(*(uint64_t *)dst),"=q"(*flags) \
148 : "q"(*(uint64_t *)src),"q"(*flags), "0"(*(uint64_t *)dst) \
150 *flags |= flags_rsvd; \
157 #define MAKE_2OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \
158 /* Some of the flags values are not copied out in a pushf, we save them here */ \
159 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
169 : "=q"(*(uint32_t *)dst),"=q"(*flags) \
170 : "q"(*(uint32_t *)src),"q"(*flags), "0"(*(uint32_t *)dst) \
172 *flags |= flags_rsvd; \
176 #define MAKE_2OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \
177 /* Some of the flags values are not copied out in a pushf, we save them here */ \
178 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
188 : "=q"(*(uint16_t *)dst),"=q"(*flags) \
189 : "q"(*(uint16_t *)src),"q"(*flags), "0"(*(uint16_t *)dst) \
191 *flags |= flags_rsvd; \
194 #define MAKE_2OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \
195 /* Some of the flags values are not copied out in a pushf, we save them here */ \
196 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
206 : "=q"(*(uint8_t *)dst),"=q"(*flags) \
207 : "q"(*(uint8_t *)src),"q"(*flags), "0"(*(uint8_t *)dst) \
209 *flags |= flags_rsvd; \
216 #define MAKE_2OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \
218 addr_t * ecx, addr_t * flags) { \
219 /* Some of the flags values are not copied out in a pushf, we save them here */ \
220 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
232 : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
234 *flags |= flags_rsvd; \
238 #define MAKE_2OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \
240 addr_t * ecx, addr_t * flags) { \
241 /* Some of the flags values are not copied out in a pushf, we save them here */ \
242 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
254 : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
256 *flags |= flags_rsvd; \
259 #define MAKE_2OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \
261 addr_t * ecx, addr_t * flags) { \
262 /* Some of the flags values are not copied out in a pushf, we save them here */ \
263 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
275 : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
277 *flags |= flags_rsvd; \
282 #define MAKE_2OP_8STR_INST(iname) static inline void iname##8(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) \
300 *flags |= flags_rsvd; \
306 #define MAKE_1OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \
308 addr_t * ecx, addr_t * flags) { \
309 /* Some of the flags values are not copied out in a pushf, we save them here */ \
310 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
322 : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
325 *flags |= flags_rsvd; \
329 #define MAKE_1OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \
331 addr_t * ecx, addr_t * flags) { \
332 /* Some of the flags values are not copied out in a pushf, we save them here */ \
333 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
345 : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
347 *flags |= flags_rsvd; \
350 #define MAKE_1OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \
352 addr_t * ecx, addr_t * flags) { \
353 /* Some of the flags values are not copied out in a pushf, we save them here */ \
354 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
366 : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
368 *flags |= flags_rsvd; \
373 #define MAKE_1OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \
375 addr_t * ecx, addr_t * flags) { \
376 /* Some of the flags values are not copied out in a pushf, we save them here */ \
377 addr_t flags_rsvd = *flags & ~0xfffe7fff; \
389 : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
391 *flags |= flags_rsvd; \
397 #define MAKE_2OP_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
400 : "=q"(*(uint64_t *)dst) \
401 : "q"(*(uint64_t *)src), "0"(*(uint64_t *)dst) \
405 #define MAKE_2OP_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
408 : "=q"(*(uint32_t *)dst) \
409 : "q"(*(uint32_t *)src), "0"(*(uint32_t *)dst) \
413 #define MAKE_2OP_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
416 : "=q"(*(uint16_t *)dst) \
417 : "q"(*(uint16_t *)src), "0"(*(uint16_t *)dst) \
421 #define MAKE_2OP_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
424 : "=q"(*(uint8_t *)dst) \
425 : "q"(*(uint8_t *)src), "0"(*(uint8_t *)dst) \
433 #define MAKE_2OP_8EXT_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, uint_t dst_len) { \
434 if (dst_len == 2) { \
437 : "=q"(*(uint16_t *)dst) \
438 : "q"(*(uint8_t *)src), "0"(*(uint16_t *)dst) \
440 } else if (dst_len == 4) { \
443 : "=q"(*(uint32_t *)dst) \
444 : "q"(*(uint8_t *)src), "0"(*(uint32_t *)dst) \
446 } else if (dst_len == 8) { \
449 : "=q"(*(uint64_t *)dst) \
450 : "q"(*(uint8_t *)src), "0"(*(uint64_t *)dst) \
455 #define MAKE_2OP_16EXT_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, uint_t dst_len) { \
456 if (dst_len == 4) { \
459 : "=q"(*(uint32_t *)dst) \
460 : "q"(*(uint16_t *)src), "0"(*(uint32_t *)dst) \
462 } else if (dst_len == 8) { \
465 : "=q"(*(uint64_t *)dst) \
466 : "q"(*(uint16_t *)src), "0"(*(uint64_t *)dst) \
474 #define MAKE_2OUT_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
477 : "=q"(*(uint64_t *)dst), "=q"(*(uint64_t *)src) \
478 : "0"(*(uint64_t *)dst), "1"(*(uint64_t *)src) \
482 #define MAKE_2OUT_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
485 : "=q"(*(uint32_t *)dst), "=q"(*(uint32_t *)src) \
486 : "0"(*(uint32_t *)dst), "1"(*(uint32_t *)src) \
490 #define MAKE_2OUT_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
493 : "=q"(*(uint16_t *)dst), "=q"(*(uint16_t *)src) \
494 : "0"(*(uint16_t *)dst), "1"(*(uint16_t *)src) \
498 #define MAKE_2OUT_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
501 : "=q"(*(uint8_t *)dst), "=q"(*(uint8_t *)src) \
502 : "0"(*(uint8_t *)dst), "1"(*(uint8_t *)src) \
511 /****************************/
512 /* 8 Bit instruction forms */
513 /****************************/
515 MAKE_2OP_8FLAGS_INST(adc);
516 MAKE_2OP_8FLAGS_INST(add);
517 MAKE_2OP_8FLAGS_INST(and);
518 MAKE_2OP_8FLAGS_INST(or);
519 MAKE_2OP_8FLAGS_INST(xor);
520 MAKE_2OP_8FLAGS_INST(sub);
523 MAKE_1OP_8FLAGS_INST(inc);
524 MAKE_1OP_8FLAGS_INST(dec);
525 MAKE_1OP_8FLAGS_INST(neg);
526 MAKE_1OP_8FLAGS_INST(setb);
527 MAKE_1OP_8FLAGS_INST(setbe);
528 MAKE_1OP_8FLAGS_INST(setl);
529 MAKE_1OP_8FLAGS_INST(setle);
530 MAKE_1OP_8FLAGS_INST(setnb);
531 MAKE_1OP_8FLAGS_INST(setnbe);
532 MAKE_1OP_8FLAGS_INST(setnl);
533 MAKE_1OP_8FLAGS_INST(setnle);
534 MAKE_1OP_8FLAGS_INST(setno);
535 MAKE_1OP_8FLAGS_INST(setnp);
536 MAKE_1OP_8FLAGS_INST(setns);
537 MAKE_1OP_8FLAGS_INST(setnz);
538 MAKE_1OP_8FLAGS_INST(seto);
539 MAKE_1OP_8FLAGS_INST(setp);
540 MAKE_1OP_8FLAGS_INST(sets);
541 MAKE_1OP_8FLAGS_INST(setz);
544 MAKE_1OP_8_INST(not);
546 MAKE_2OP_8_INST(mov);
547 MAKE_2OP_8EXT_INST(movzx);
548 MAKE_2OP_8EXT_INST(movsx);
550 MAKE_2OUT_8_INST(xchg);
552 MAKE_2OP_8STR_INST(movs);
553 MAKE_1OP_8STR_INST(stos);
554 MAKE_1OP_8STR_INST(scas);
557 /****************************/
558 /* 16 Bit instruction forms */
559 /****************************/
560 MAKE_2OP_16FLAGS_INST(adc);
561 MAKE_2OP_16FLAGS_INST(add);
562 MAKE_2OP_16FLAGS_INST(and);
563 MAKE_2OP_16FLAGS_INST(or);
564 MAKE_2OP_16FLAGS_INST(xor);
565 MAKE_2OP_16FLAGS_INST(sub);
568 MAKE_1OP_16FLAGS_INST(inc);
569 MAKE_1OP_16FLAGS_INST(dec);
570 MAKE_1OP_16FLAGS_INST(neg);
572 MAKE_1OP_16_INST(not);
574 MAKE_2OP_16_INST(mov);
575 MAKE_2OP_16EXT_INST(movzx);
576 MAKE_2OP_16EXT_INST(movsx);
577 MAKE_2OUT_16_INST(xchg);
579 MAKE_2OP_16STR_INST(movs);
580 MAKE_1OP_16STR_INST(stos);
581 MAKE_1OP_16STR_INST(scas);
584 /****************************/
585 /* 32 Bit instruction forms */
586 /****************************/
587 MAKE_2OP_32FLAGS_INST(adc);
588 MAKE_2OP_32FLAGS_INST(add);
589 MAKE_2OP_32FLAGS_INST(and);
590 MAKE_2OP_32FLAGS_INST(or);
591 MAKE_2OP_32FLAGS_INST(xor);
592 MAKE_2OP_32FLAGS_INST(sub);
595 MAKE_1OP_32FLAGS_INST(inc);
596 MAKE_1OP_32FLAGS_INST(dec);
597 MAKE_1OP_32FLAGS_INST(neg);
599 MAKE_1OP_32_INST(not);
601 MAKE_2OP_32_INST(mov);
603 MAKE_2OUT_32_INST(xchg);
607 MAKE_2OP_32STR_INST(movs);
608 MAKE_1OP_32STR_INST(stos);
609 MAKE_1OP_32STR_INST(scas);
615 /****************************/
616 /* 64 Bit instruction forms */
617 /****************************/
618 MAKE_2OP_64FLAGS_INST(adc);
619 MAKE_2OP_64FLAGS_INST(add);
620 MAKE_2OP_64FLAGS_INST(and);
621 MAKE_2OP_64FLAGS_INST(or);
622 MAKE_2OP_64FLAGS_INST(xor);
623 MAKE_2OP_64FLAGS_INST(sub);
625 MAKE_1OP_64FLAGS_INST(inc);
626 MAKE_1OP_64FLAGS_INST(dec);
627 MAKE_1OP_64FLAGS_INST(neg);
629 MAKE_1OP_64_INST(not);
632 MAKE_2OP_64_INST(mov);
633 MAKE_2OP_64STR_INST(movs);
634 MAKE_1OP_64STR_INST(stos);
635 MAKE_1OP_64STR_INST(scas);
637 MAKE_2OUT_64_INST(xchg);