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_2OP_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
353 uint64_t tmp_dst = *dst, tmp_src = *src; \
358 : "q"(tmp_src), "0"(tmp_dst) \
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; \
369 : "q"(tmp_src), "0"(tmp_dst) \
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; \
380 : "q"(tmp_src), "0"(tmp_dst) \
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; \
391 : "q"(tmp_src), "0"(tmp_dst) \
400 #define MAKE_2OP_8EXT_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, uint_t dst_len) { \
401 if (dst_len == 2) { \
404 : "=q"(*(uint16_t *)dst) \
405 : "q"(*(uint8_t *)src), "0"(*(uint16_t *)dst) \
407 } else if (dst_len == 4) { \
410 : "=q"(*(uint32_t *)dst) \
411 : "q"(*(uint8_t *)src), "0"(*(uint32_t *)dst) \
413 } else if (dst_len == 8) { \
416 : "=q"(*(uint64_t *)dst) \
417 : "q"(*(uint8_t *)src), "0"(*(uint64_t *)dst) \
422 #define MAKE_2OP_16EXT_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, uint_t dst_len) { \
423 if (dst_len == 4) { \
426 : "=q"(*(uint32_t *)dst) \
427 : "q"(*(uint16_t *)src), "0"(*(uint32_t *)dst) \
429 } else if (dst_len == 8) { \
432 : "=q"(*(uint64_t *)dst) \
433 : "q"(*(uint16_t *)src), "0"(*(uint64_t *)dst) \
443 /****************************/
444 /* 8 Bit instruction forms */
445 /****************************/
447 MAKE_2OP_8FLAGS_INST(adc);
448 MAKE_2OP_8FLAGS_INST(add);
449 MAKE_2OP_8FLAGS_INST(and);
450 MAKE_2OP_8FLAGS_INST(or);
451 MAKE_2OP_8FLAGS_INST(xor);
452 MAKE_2OP_8FLAGS_INST(sub);
455 MAKE_1OP_8FLAGS_INST(inc);
456 MAKE_1OP_8FLAGS_INST(dec);
457 MAKE_1OP_8FLAGS_INST(neg);
458 MAKE_1OP_8FLAGS_INST(setb);
459 MAKE_1OP_8FLAGS_INST(setbe);
460 MAKE_1OP_8FLAGS_INST(setl);
461 MAKE_1OP_8FLAGS_INST(setle);
462 MAKE_1OP_8FLAGS_INST(setnb);
463 MAKE_1OP_8FLAGS_INST(setnbe);
464 MAKE_1OP_8FLAGS_INST(setnl);
465 MAKE_1OP_8FLAGS_INST(setnle);
466 MAKE_1OP_8FLAGS_INST(setno);
467 MAKE_1OP_8FLAGS_INST(setnp);
468 MAKE_1OP_8FLAGS_INST(setns);
469 MAKE_1OP_8FLAGS_INST(setnz);
470 MAKE_1OP_8FLAGS_INST(seto);
471 MAKE_1OP_8FLAGS_INST(setp);
472 MAKE_1OP_8FLAGS_INST(sets);
473 MAKE_1OP_8FLAGS_INST(setz);
476 MAKE_1OP_8_INST(not);
478 MAKE_2OP_8_INST(mov);
479 MAKE_2OP_8EXT_INST(movzx);
480 MAKE_2OP_8EXT_INST(movsx);
482 MAKE_2OP_8_INST(xchg);
484 MAKE_2OP_8STR_INST(movs);
487 /****************************/
488 /* 16 Bit instruction forms */
489 /****************************/
490 MAKE_2OP_16FLAGS_INST(adc);
491 MAKE_2OP_16FLAGS_INST(add);
492 MAKE_2OP_16FLAGS_INST(and);
493 MAKE_2OP_16FLAGS_INST(or);
494 MAKE_2OP_16FLAGS_INST(xor);
495 MAKE_2OP_16FLAGS_INST(sub);
498 MAKE_1OP_16FLAGS_INST(inc);
499 MAKE_1OP_16FLAGS_INST(dec);
500 MAKE_1OP_16FLAGS_INST(neg);
502 MAKE_1OP_16_INST(not);
504 MAKE_2OP_16_INST(mov);
505 MAKE_2OP_16EXT_INST(movzx);
506 MAKE_2OP_16EXT_INST(movsx);
507 MAKE_2OP_16_INST(xchg);
509 MAKE_2OP_16STR_INST(movs);
511 /****************************/
512 /* 32 Bit instruction forms */
513 /****************************/
514 MAKE_2OP_32FLAGS_INST(adc);
515 MAKE_2OP_32FLAGS_INST(add);
516 MAKE_2OP_32FLAGS_INST(and);
517 MAKE_2OP_32FLAGS_INST(or);
518 MAKE_2OP_32FLAGS_INST(xor);
519 MAKE_2OP_32FLAGS_INST(sub);
522 MAKE_1OP_32FLAGS_INST(inc);
523 MAKE_1OP_32FLAGS_INST(dec);
524 MAKE_1OP_32FLAGS_INST(neg);
526 MAKE_1OP_32_INST(not);
528 MAKE_2OP_32_INST(mov);
530 MAKE_2OP_32_INST(xchg);
534 MAKE_2OP_32STR_INST(movs);
538 /****************************/
539 /* 64 Bit instruction forms */
540 /****************************/
541 MAKE_2OP_64FLAGS_INST(adc);
542 MAKE_2OP_64FLAGS_INST(add);
543 MAKE_2OP_64FLAGS_INST(and);
544 MAKE_2OP_64FLAGS_INST(or);
545 MAKE_2OP_64FLAGS_INST(xor);
546 MAKE_2OP_64FLAGS_INST(sub);
548 MAKE_1OP_64FLAGS_INST(inc);
549 MAKE_1OP_64FLAGS_INST(dec);
550 MAKE_1OP_64FLAGS_INST(neg);
552 MAKE_1OP_64_INST(not);
555 MAKE_2OP_64_INST(mov);
558 MAKE_2OP_64_INST(xchg);