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 /****************************/
401 /* 8 Bit instruction forms */
402 /****************************/
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);
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);
433 MAKE_1OP_8_INST(not);
435 MAKE_2OP_8_INST(mov);
436 MAKE_2OP_8_INST(xchg);
438 MAKE_2OP_8STR_INST(movs);
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);
452 MAKE_1OP_16FLAGS_INST(inc);
453 MAKE_1OP_16FLAGS_INST(dec);
454 MAKE_1OP_16FLAGS_INST(neg);
456 MAKE_1OP_16_INST(not);
458 MAKE_2OP_16_INST(mov);
459 MAKE_2OP_16_INST(xchg);
461 MAKE_2OP_16STR_INST(movs);
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);
474 MAKE_1OP_32FLAGS_INST(inc);
475 MAKE_1OP_32FLAGS_INST(dec);
476 MAKE_1OP_32FLAGS_INST(neg);
478 MAKE_1OP_32_INST(not);
480 MAKE_2OP_32_INST(mov);
481 MAKE_2OP_32_INST(xchg);
485 MAKE_2OP_32STR_INST(movs);
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);
499 MAKE_1OP_64FLAGS_INST(inc);
500 MAKE_1OP_64FLAGS_INST(dec);
501 MAKE_1OP_64FLAGS_INST(neg);
503 MAKE_1OP_64_INST(not);
506 MAKE_2OP_64_INST(mov);
508 MAKE_2OP_64_INST(xchg);