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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(iname) static inline void iname##8(addr_t * dst) { \
115 uchar_t tmp_dst = *dst; \
125 #define MAKE_1OP_16_WINST(iname) static inline void iname##16(addr_t * dst) { \
126 ushort_t tmp_dst = *dst; \
136 #define MAKE_1OP_32_WINST(iname) static inline void iname##32(addr_t * dst) { \
137 uint_t tmp_dst = *dst; \
147 #define MAKE_1OP_64_WINST(iname) static inline void iname##64(addr_t * dst) { \
148 ullong_t tmp_dst = *dst; \
159 #define MAKE_2OP_64FLAGS_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(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_WINST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
353 uint32_t tmp_dst = *dst, tmp_src = *src; \
358 : "q"(tmp_src), "0"(tmp_dst) \
363 #define MAKE_2OP_32_WINST(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_WINST(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_WINST(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) \
402 MAKE_2OP_8FLAGS_WINST(adc);
403 MAKE_2OP_8FLAGS_WINST(add);
404 MAKE_2OP_8FLAGS_WINST(and);
405 MAKE_2OP_8FLAGS_WINST(or);
406 MAKE_2OP_8FLAGS_WINST(xor);
407 MAKE_2OP_8FLAGS_WINST(sub);
410 MAKE_1OP_8FLAGS_WINST(inc);
411 MAKE_1OP_8FLAGS_WINST(dec);
412 MAKE_1OP_8FLAGS_WINST(neg);
413 MAKE_1OP_8FLAGS_WINST(setb);
414 MAKE_1OP_8FLAGS_WINST(setbe);
415 MAKE_1OP_8FLAGS_WINST(setl);
416 MAKE_1OP_8FLAGS_WINST(setle);
417 MAKE_1OP_8FLAGS_WINST(setnb);
418 MAKE_1OP_8FLAGS_WINST(setnbe);
419 MAKE_1OP_8FLAGS_WINST(setnl);
420 MAKE_1OP_8FLAGS_WINST(setnle);
421 MAKE_1OP_8FLAGS_WINST(setno);
422 MAKE_1OP_8FLAGS_WINST(setnp);
423 MAKE_1OP_8FLAGS_WINST(setns);
424 MAKE_1OP_8FLAGS_WINST(setnz);
425 MAKE_1OP_8FLAGS_WINST(seto);
426 MAKE_1OP_8FLAGS_WINST(setp);
427 MAKE_1OP_8FLAGS_WINST(sets);
428 MAKE_1OP_8FLAGS_WINST(setz);
431 MAKE_1OP_8_WINST(not);
433 MAKE_2OP_8_WINST(mov);
434 MAKE_2OP_8_WINST(xchg);
438 MAKE_2OP_16FLAGS_WINST(adc);
439 MAKE_2OP_16FLAGS_WINST(add);
440 MAKE_2OP_16FLAGS_WINST(and);
441 MAKE_2OP_16FLAGS_WINST(or);
442 MAKE_2OP_16FLAGS_WINST(xor);
443 MAKE_2OP_16FLAGS_WINST(sub);
446 MAKE_1OP_16FLAGS_WINST(inc);
447 MAKE_1OP_16FLAGS_WINST(dec);
448 MAKE_1OP_16FLAGS_WINST(neg);
450 MAKE_1OP_16_WINST(not);
452 MAKE_2OP_16_WINST(mov);
453 MAKE_2OP_16_WINST(xchg);
459 MAKE_2OP_32FLAGS_WINST(adc);
460 MAKE_2OP_32FLAGS_WINST(add);
461 MAKE_2OP_32FLAGS_WINST(and);
462 MAKE_2OP_32FLAGS_WINST(or);
463 MAKE_2OP_32FLAGS_WINST(xor);
464 MAKE_2OP_32FLAGS_WINST(sub);
467 MAKE_1OP_32FLAGS_WINST(inc);
468 MAKE_1OP_32FLAGS_WINST(dec);
469 MAKE_1OP_32FLAGS_WINST(neg);
471 MAKE_1OP_32_WINST(not);
473 MAKE_2OP_32_WINST(mov);
474 MAKE_2OP_32_WINST(xchg);
476 MAKE_2OP_8STR_WINST(movs);
477 MAKE_2OP_16STR_WINST(movs);
478 MAKE_2OP_32STR_WINST(movs);