X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Finclude%2Fpalacios%2Fvmm_instr_emulator.h;h=84b07a41f80d86ec67f9f866126cbb34f3ce6243;hb=HEAD;hp=132970b08668a08017789a24b4aa403850259bd5;hpb=757000c47f1ce82cba12d1a9a06cd3b5e8b0b505;p=palacios.git diff --git a/palacios/include/palacios/vmm_instr_emulator.h b/palacios/include/palacios/vmm_instr_emulator.h index 132970b..84b07a4 100644 --- a/palacios/include/palacios/vmm_instr_emulator.h +++ b/palacios/include/palacios/vmm_instr_emulator.h @@ -21,458 +21,620 @@ -#define MAKE_1OP_8FLAGS_WINST(iname) static inline void iname##8(addr_t * dst, addr_t * flags) { \ - uchar_t tmp_dst = *dst; \ - \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %2; " \ - "popf; " \ - #iname"b %0; " \ - "pushf; " \ - "pop %1; " \ - "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(*flags), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - *flags |= flags_rsvd; \ - \ - } - -#define MAKE_1OP_16FLAGS_WINST(iname) static inline void iname##16(addr_t * dst, addr_t * flags) { \ - ushort_t tmp_dst = *dst; \ - \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %2; " \ - "popf; " \ - #iname"w %0; " \ - "pushf; " \ - "pop %1; " \ - "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(*flags), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - *flags |= flags_rsvd; \ - \ - } - -#define MAKE_1OP_32FLAGS_WINST(iname) static inline void iname##32(addr_t * dst, addr_t * flags) { \ - uint_t tmp_dst = *dst; \ - \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %2; " \ - "popf; " \ - #iname"l %0; " \ - "pushf; " \ - "pop %1; " \ - "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(*flags), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - *flags |= flags_rsvd; \ - \ - } - -#define MAKE_1OP_64FLAGS_WINST(iname) static inline void iname##64(addr_t * dst, addr_t * flags) { \ - ullong_t tmp_dst = *dst; \ - \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushfq; " \ - "push %2; " \ - "popfq; " \ - #iname"q %0; " \ - "pushfq; " \ - "pop %1; " \ - "popfq; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(*flags), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - *flags |= flags_rsvd; \ - \ - } - - - -#define MAKE_1OP_8_WINST(iname) static inline void iname##8(addr_t * dst) { \ - uchar_t tmp_dst = *dst; \ - \ - asm volatile ( \ - #iname"b %0; " \ - : "=q"(tmp_dst) \ - : "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - } - -#define MAKE_1OP_16_WINST(iname) static inline void iname##16(addr_t * dst) { \ - ushort_t tmp_dst = *dst; \ - \ - asm volatile ( \ - #iname"w %0; " \ - : "=q"(tmp_dst) \ - : "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - } - -#define MAKE_1OP_32_WINST(iname) static inline void iname##32(addr_t * dst) { \ - uint_t tmp_dst = *dst; \ - \ - asm volatile ( \ - #iname"l %0; " \ - : "=q"(tmp_dst) \ - : "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - } - -#define MAKE_1OP_64_WINST(iname) static inline void iname##64(addr_t * dst) { \ - ullong_t tmp_dst = *dst; \ - \ - asm volatile ( \ - #iname"q %0; " \ - : "=q"(tmp_dst) \ - : "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - } - - -#define MAKE_2OP_64FLAGS_WINST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \ - uint64_t tmp_dst = *dst, tmp_src = *src; \ - addr_t tmp_flags = *flags; \ - \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushfq\r\n" \ - "push %3\r\n" \ - "popfq\r\n" \ - #iname"q %2, %0\r\n" \ - "pushfq\r\n" \ - "pop %1\r\n" \ - "popfq\r\n" \ - : "=q"(tmp_dst),"=q"(tmp_flags) \ - : "q"(tmp_src),"q"(tmp_flags), "0"(tmp_dst) \ - ); \ - \ - *dst = tmp_dst; \ - *flags = tmp_flags; \ - *flags |= flags_rsvd; \ - \ - } - - - - -#define MAKE_2OP_32FLAGS_WINST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \ - uint32_t tmp_dst = *dst, tmp_src = *src; \ - \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %3; " \ - "popf; " \ - #iname"l %2, %0; " \ - "pushf; " \ - "pop %1; " \ - "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - *flags |= flags_rsvd; \ - \ - } - - -#define MAKE_2OP_16FLAGS_WINST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \ - ushort_t tmp_dst = *dst, tmp_src = *src; \ - \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %3; " \ - "popf; " \ - #iname"w %2, %0; " \ - "pushf; " \ - "pop %1; " \ - "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - *flags |= flags_rsvd; \ - \ - } - -#define MAKE_2OP_8FLAGS_WINST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \ - uchar_t tmp_dst = *dst, tmp_src = *src; \ - \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %3; " \ - "popf; " \ - #iname"b %2, %0; " \ - "pushf; " \ - "pop %1; " \ - "popf; " \ - : "=q"(tmp_dst),"=q"(*flags) \ - : "q"(tmp_src),"q"(*flags), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - *flags |= flags_rsvd; \ - \ - } - - - - - -#define MAKE_2OP_64STR_WINST(iname) static inline void iname##64(addr_t * dst, \ +#define MAKE_1OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %2; " \ + "popf; " \ + #iname"b %0; " \ + "pushf; " \ + "pop %1; " \ + "popf; " \ + : "=q"(*(uint8_t *)dst),"=q"(*flags) \ + : "q"(*flags), "0"(*(uint8_t *)dst) \ + ); \ + *flags |= flags_rsvd; \ + \ + } + +#define MAKE_1OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %2; " \ + "popf; " \ + #iname"w %0; " \ + "pushf; " \ + "pop %1; " \ + "popf; " \ + : "=q"(*(uint16_t *)dst),"=q"(*flags) \ + : "q"(*flags), "0"(*(uint16_t *)dst) \ + ); \ + *flags |= flags_rsvd; \ + \ + } + +#define MAKE_1OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %2; " \ + "popf; " \ + #iname"l %0; " \ + "pushf; " \ + "pop %1; " \ + "popf; " \ + : "=q"(*(uint32_t *)dst),"=q"(*flags) \ + : "q"(*flags), "0"(*(uint32_t *)dst) \ + ); \ + *flags |= flags_rsvd; \ + \ + } + +#define MAKE_1OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushfq; " \ + "push %2; " \ + "popfq; " \ + #iname"q %0; " \ + "pushfq; " \ + "pop %1; " \ + "popfq; " \ + : "=q"(*(uint64_t *)dst),"=q"(*flags) \ + : "q"(*flags), "0"(*(uint64_t *)dst) \ + ); \ + *flags |= flags_rsvd; \ + \ + } + + + +#define MAKE_1OP_8_INST(iname) static inline void iname##8(addr_t * dst) { \ + asm volatile ( \ + #iname"b %0; " \ + : "=q"(*(uint8_t *)dst) \ + : "0"(*(uint8_t *)dst) \ + ); \ + } + +#define MAKE_1OP_16_INST(iname) static inline void iname##16(addr_t * dst) { \ + asm volatile ( \ + #iname"w %0; " \ + : "=q"(*(uint16_t *)dst) \ + : "0"(*(uint16_t *)dst) \ + ); \ + } + +#define MAKE_1OP_32_INST(iname) static inline void iname##32(addr_t * dst) { \ + asm volatile ( \ + #iname"l %0; " \ + : "=q"(*(uint32_t *)dst) \ + : "0"(*(uint32_t *)dst) \ + ); \ + } + +#define MAKE_1OP_64_INST(iname) static inline void iname##64(addr_t * dst) { \ + asm volatile ( \ + #iname"q %0; " \ + : "=q"(*(uint64_t *)dst) \ + : "0"(*(uint64_t *)dst) \ + ); \ + } + + +#define MAKE_2OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushfq\r\n" \ + "push %3\r\n" \ + "popfq\r\n" \ + #iname"q %2, %0\r\n" \ + "pushfq\r\n" \ + "pop %1\r\n" \ + "popfq\r\n" \ + : "=q"(*(uint64_t *)dst),"=q"(*flags) \ + : "q"(*(uint64_t *)src),"q"(*flags), "0"(*(uint64_t *)dst) \ + ); \ + *flags |= flags_rsvd; \ + \ + } + + + + +#define MAKE_2OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %3; " \ + "popf; " \ + #iname"l %2, %0; " \ + "pushf; " \ + "pop %1; " \ + "popf; " \ + : "=q"(*(uint32_t *)dst),"=q"(*flags) \ + : "q"(*(uint32_t *)src),"q"(*flags), "0"(*(uint32_t *)dst) \ + ); \ + *flags |= flags_rsvd; \ + } + + +#define MAKE_2OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %3; " \ + "popf; " \ + #iname"w %2, %0; " \ + "pushf; " \ + "pop %1; " \ + "popf; " \ + : "=q"(*(uint16_t *)dst),"=q"(*flags) \ + : "q"(*(uint16_t *)src),"q"(*flags), "0"(*(uint16_t *)dst) \ + ); \ + *flags |= flags_rsvd; \ + } + +#define MAKE_2OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %3; " \ + "popf; " \ + #iname"b %2, %0; " \ + "pushf; " \ + "pop %1; " \ + "popf; " \ + : "=q"(*(uint8_t *)dst),"=q"(*flags) \ + : "q"(*(uint8_t *)src),"q"(*flags), "0"(*(uint8_t *)dst) \ + ); \ + *flags |= flags_rsvd; \ + } + + + + + +#define MAKE_2OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \ addr_t * src, \ addr_t * ecx, addr_t * flags) { \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushfq; " \ - "pushq %4; " \ - "popfq; " \ - "rep; " \ - #iname"q; " \ - "pushfq; " \ - "popq %0; " \ - "popfq; " \ - : "=q"(*flags) \ - : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ - ); \ - \ - /* : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/ \ - *flags |= flags_rsvd; \ - } - - -#define MAKE_2OP_32STR_WINST(iname) static inline void iname##32(addr_t * dst, \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushfq; " \ + "pushq %4; " \ + "popfq; " \ + "rep; " \ + #iname"q; " \ + "pushfq; " \ + "popq %0; " \ + "popfq; " \ + : "=q"(*flags) \ + : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ + ); \ + *flags |= flags_rsvd; \ + } + + +#define MAKE_2OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \ addr_t * src, \ addr_t * ecx, addr_t * flags) { \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %4; " \ - "popf; " \ - "rep; " \ - #iname"l; " \ - "pushf; " \ - "pop %0; " \ - "popf; " \ - : "=q"(*flags) \ - : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ - ); \ - \ - /* : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/ \ - *flags |= flags_rsvd; \ - } - -#define MAKE_2OP_16STR_WINST(iname) static inline void iname##16(addr_t * dst, \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %4; " \ + "popf; " \ + "rep; " \ + #iname"l; " \ + "pushf; " \ + "pop %0; " \ + "popf; " \ + : "=q"(*flags) \ + : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ + ); \ + *flags |= flags_rsvd; \ + } + +#define MAKE_2OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \ addr_t * src, \ addr_t * ecx, addr_t * flags) { \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %4; " \ - "popf; " \ - "rep; " \ - #iname"w; " \ - "pushf; " \ - "pop %0; " \ - "popf; " \ - : "=q"(*flags) \ - : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ - ); \ - *flags |= flags_rsvd; \ - } - - - -#define MAKE_2OP_8STR_WINST(iname) static inline void iname##8(addr_t * dst, \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %4; " \ + "popf; " \ + "rep; " \ + #iname"w; " \ + "pushf; " \ + "pop %0; " \ + "popf; " \ + : "=q"(*flags) \ + : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ + ); \ + *flags |= flags_rsvd; \ + } + + + +#define MAKE_2OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \ addr_t * src, \ addr_t * ecx, addr_t * flags) { \ - /* Some of the flags values are not copied out in a pushf, we save them here */ \ - addr_t flags_rsvd = *flags & ~0xfffe7fff; \ - \ - asm volatile ( \ - "pushf; " \ - "push %4; " \ - "popf; " \ - "rep; " \ - #iname"b; " \ - "pushf; " \ - "pop %0; " \ - "popf; " \ - : "=q"(*flags) \ - : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ - ); \ - *flags |= flags_rsvd; \ - } - - - - -#define MAKE_2OP_64_WINST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \ - uint32_t tmp_dst = *dst, tmp_src = *src; \ - \ - asm volatile ( \ - #iname"q %1, %0; " \ - : "=q"(tmp_dst) \ - : "q"(tmp_src), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - } - -#define MAKE_2OP_32_WINST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \ - uint32_t tmp_dst = *dst, tmp_src = *src; \ - \ - asm volatile ( \ - #iname"l %1, %0; " \ - : "=q"(tmp_dst) \ - : "q"(tmp_src), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - } - -#define MAKE_2OP_16_WINST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \ - ushort_t tmp_dst = *dst, tmp_src = *src; \ - \ - asm volatile ( \ - #iname"w %1, %0; " \ - : "=q"(tmp_dst) \ - : "q"(tmp_src), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - } - -#define MAKE_2OP_8_WINST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \ - uchar_t tmp_dst = *dst, tmp_src = *src; \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ \ - asm volatile ( \ - #iname"b %1, %0; " \ - : "=q"(tmp_dst) \ - : "q"(tmp_src), "0"(tmp_dst) \ - ); \ - *dst = tmp_dst; \ - } - - - - - - - -MAKE_2OP_8FLAGS_WINST(adc); -MAKE_2OP_8FLAGS_WINST(add); -MAKE_2OP_8FLAGS_WINST(and); -MAKE_2OP_8FLAGS_WINST(or); -MAKE_2OP_8FLAGS_WINST(xor); -MAKE_2OP_8FLAGS_WINST(sub); - - -MAKE_1OP_8FLAGS_WINST(inc); -MAKE_1OP_8FLAGS_WINST(dec); -MAKE_1OP_8FLAGS_WINST(neg); -MAKE_1OP_8FLAGS_WINST(setb); -MAKE_1OP_8FLAGS_WINST(setbe); -MAKE_1OP_8FLAGS_WINST(setl); -MAKE_1OP_8FLAGS_WINST(setle); -MAKE_1OP_8FLAGS_WINST(setnb); -MAKE_1OP_8FLAGS_WINST(setnbe); -MAKE_1OP_8FLAGS_WINST(setnl); -MAKE_1OP_8FLAGS_WINST(setnle); -MAKE_1OP_8FLAGS_WINST(setno); -MAKE_1OP_8FLAGS_WINST(setnp); -MAKE_1OP_8FLAGS_WINST(setns); -MAKE_1OP_8FLAGS_WINST(setnz); -MAKE_1OP_8FLAGS_WINST(seto); -MAKE_1OP_8FLAGS_WINST(setp); -MAKE_1OP_8FLAGS_WINST(sets); -MAKE_1OP_8FLAGS_WINST(setz); - - -MAKE_1OP_8_WINST(not); + asm volatile ( \ + "pushf; " \ + "push %4; " \ + "popf; " \ + "rep; " \ + #iname"b; " \ + "pushf; " \ + "pop %0; " \ + "popf; " \ + : "=q"(*flags) \ + : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \ + ); \ + *flags |= flags_rsvd; \ + } -MAKE_2OP_8_WINST(mov); -MAKE_2OP_8_WINST(xchg); -MAKE_2OP_16FLAGS_WINST(adc); -MAKE_2OP_16FLAGS_WINST(add); -MAKE_2OP_16FLAGS_WINST(and); -MAKE_2OP_16FLAGS_WINST(or); -MAKE_2OP_16FLAGS_WINST(xor); -MAKE_2OP_16FLAGS_WINST(sub); - - -MAKE_1OP_16FLAGS_WINST(inc); -MAKE_1OP_16FLAGS_WINST(dec); -MAKE_1OP_16FLAGS_WINST(neg); - -MAKE_1OP_16_WINST(not); - -MAKE_2OP_16_WINST(mov); -MAKE_2OP_16_WINST(xchg); - - - - - -MAKE_2OP_32FLAGS_WINST(adc); -MAKE_2OP_32FLAGS_WINST(add); -MAKE_2OP_32FLAGS_WINST(and); -MAKE_2OP_32FLAGS_WINST(or); -MAKE_2OP_32FLAGS_WINST(xor); -MAKE_2OP_32FLAGS_WINST(sub); - - -MAKE_1OP_32FLAGS_WINST(inc); -MAKE_1OP_32FLAGS_WINST(dec); -MAKE_1OP_32FLAGS_WINST(neg); - -MAKE_1OP_32_WINST(not); - -MAKE_2OP_32_WINST(mov); -MAKE_2OP_32_WINST(xchg); - -MAKE_2OP_8STR_WINST(movs); -MAKE_2OP_16STR_WINST(movs); -MAKE_2OP_32STR_WINST(movs); +#define MAKE_1OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \ + addr_t * src, \ + addr_t * ecx, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushfq; " \ + "pushq %4; " \ + "popfq; " \ + "rep; " \ + #iname"q; " \ + "pushfq; " \ + "popq %0; " \ + "popfq; " \ + : "=q"(*flags) \ + : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \ + ); \ + \ + *flags |= flags_rsvd; \ + } + + +#define MAKE_1OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \ + addr_t * src, \ + addr_t * ecx, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %4; " \ + "popf; " \ + "rep; " \ + #iname"l; " \ + "pushf; " \ + "pop %0; " \ + "popf; " \ + : "=q"(*flags) \ + : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \ + ); \ + *flags |= flags_rsvd; \ + } + +#define MAKE_1OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \ + addr_t * src, \ + addr_t * ecx, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %4; " \ + "popf; " \ + "rep; " \ + #iname"w; " \ + "pushf; " \ + "pop %0; " \ + "popf; " \ + : "=q"(*flags) \ + : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \ + ); \ + *flags |= flags_rsvd; \ + } + + + +#define MAKE_1OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \ + addr_t * src, \ + addr_t * ecx, addr_t * flags) { \ + /* Some of the flags values are not copied out in a pushf, we save them here */ \ + addr_t flags_rsvd = *flags & ~0xfffe7fff; \ + \ + asm volatile ( \ + "pushf; " \ + "push %4; " \ + "popf; " \ + "rep; " \ + #iname"b; " \ + "pushf; " \ + "pop %0; " \ + "popf; " \ + : "=q"(*flags) \ + : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \ + ); \ + *flags |= flags_rsvd; \ + } + + + + +#define MAKE_2OP_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \ + asm volatile ( \ + #iname"q %1, %0; " \ + : "=q"(*(uint64_t *)dst) \ + : "q"(*(uint64_t *)src), "0"(*(uint64_t *)dst) \ + ); \ + } + +#define MAKE_2OP_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \ + asm volatile ( \ + #iname"l %1, %0; " \ + : "=q"(*(uint32_t *)dst) \ + : "q"(*(uint32_t *)src), "0"(*(uint32_t *)dst) \ + ); \ + } + +#define MAKE_2OP_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \ + asm volatile ( \ + #iname"w %1, %0; " \ + : "=q"(*(uint16_t *)dst) \ + : "q"(*(uint16_t *)src), "0"(*(uint16_t *)dst) \ + ); \ + } + +#define MAKE_2OP_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \ + asm volatile ( \ + #iname"b %1, %0; " \ + : "=q"(*(uint8_t *)dst) \ + : "q"(*(uint8_t *)src), "0"(*(uint8_t *)dst) \ + ); \ + } + + + + + +#define MAKE_2OP_8EXT_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, uint_t dst_len) { \ + if (dst_len == 2) { \ + asm volatile ( \ + #iname" %1, %0; " \ + : "=q"(*(uint16_t *)dst) \ + : "q"(*(uint8_t *)src), "0"(*(uint16_t *)dst) \ + ); \ + } else if (dst_len == 4) { \ + asm volatile ( \ + #iname" %1, %0; " \ + : "=q"(*(uint32_t *)dst) \ + : "q"(*(uint8_t *)src), "0"(*(uint32_t *)dst) \ + ); \ + } else if (dst_len == 8) { \ + asm volatile ( \ + #iname" %1, %0; " \ + : "=q"(*(uint64_t *)dst) \ + : "q"(*(uint8_t *)src), "0"(*(uint64_t *)dst) \ + ); \ + } \ + } + +#define MAKE_2OP_16EXT_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, uint_t dst_len) { \ + if (dst_len == 4) { \ + asm volatile ( \ + #iname" %1, %0; " \ + : "=q"(*(uint32_t *)dst) \ + : "q"(*(uint16_t *)src), "0"(*(uint32_t *)dst) \ + ); \ + } else if (dst_len == 8) { \ + asm volatile ( \ + #iname" %1, %0; " \ + : "=q"(*(uint64_t *)dst) \ + : "q"(*(uint16_t *)src), "0"(*(uint64_t *)dst) \ + ); \ + } \ + } + + + + +#define MAKE_2OUT_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \ + asm volatile ( \ + #iname"q %1, %0; " \ + : "=q"(*(uint64_t *)dst), "=q"(*(uint64_t *)src) \ + : "0"(*(uint64_t *)dst), "1"(*(uint64_t *)src) \ + ); \ + } + +#define MAKE_2OUT_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \ + asm volatile ( \ + #iname"l %1, %0; " \ + : "=q"(*(uint32_t *)dst), "=q"(*(uint32_t *)src) \ + : "0"(*(uint32_t *)dst), "1"(*(uint32_t *)src) \ + ); \ + } + +#define MAKE_2OUT_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \ + asm volatile ( \ + #iname"w %1, %0; " \ + : "=q"(*(uint16_t *)dst), "=q"(*(uint16_t *)src) \ + : "0"(*(uint16_t *)dst), "1"(*(uint16_t *)src) \ + ); \ + } + +#define MAKE_2OUT_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \ + asm volatile ( \ + #iname"b %1, %0; " \ + : "=q"(*(uint8_t *)dst), "=q"(*(uint8_t *)src) \ + : "0"(*(uint8_t *)dst), "1"(*(uint8_t *)src) \ + ); \ + } + + + + + + +/****************************/ +/* 8 Bit instruction forms */ +/****************************/ + +MAKE_2OP_8FLAGS_INST(adc); +MAKE_2OP_8FLAGS_INST(add); +MAKE_2OP_8FLAGS_INST(and); +MAKE_2OP_8FLAGS_INST(or); +MAKE_2OP_8FLAGS_INST(xor); +MAKE_2OP_8FLAGS_INST(sub); + + +MAKE_1OP_8FLAGS_INST(inc); +MAKE_1OP_8FLAGS_INST(dec); +MAKE_1OP_8FLAGS_INST(neg); +MAKE_1OP_8FLAGS_INST(setb); +MAKE_1OP_8FLAGS_INST(setbe); +MAKE_1OP_8FLAGS_INST(setl); +MAKE_1OP_8FLAGS_INST(setle); +MAKE_1OP_8FLAGS_INST(setnb); +MAKE_1OP_8FLAGS_INST(setnbe); +MAKE_1OP_8FLAGS_INST(setnl); +MAKE_1OP_8FLAGS_INST(setnle); +MAKE_1OP_8FLAGS_INST(setno); +MAKE_1OP_8FLAGS_INST(setnp); +MAKE_1OP_8FLAGS_INST(setns); +MAKE_1OP_8FLAGS_INST(setnz); +MAKE_1OP_8FLAGS_INST(seto); +MAKE_1OP_8FLAGS_INST(setp); +MAKE_1OP_8FLAGS_INST(sets); +MAKE_1OP_8FLAGS_INST(setz); + + +MAKE_1OP_8_INST(not); + +MAKE_2OP_8_INST(mov); +MAKE_2OP_8EXT_INST(movzx); +MAKE_2OP_8EXT_INST(movsx); + +MAKE_2OUT_8_INST(xchg); + +MAKE_2OP_8STR_INST(movs); +MAKE_1OP_8STR_INST(stos); +MAKE_1OP_8STR_INST(scas); + + +/****************************/ +/* 16 Bit instruction forms */ +/****************************/ +MAKE_2OP_16FLAGS_INST(adc); +MAKE_2OP_16FLAGS_INST(add); +MAKE_2OP_16FLAGS_INST(and); +MAKE_2OP_16FLAGS_INST(or); +MAKE_2OP_16FLAGS_INST(xor); +MAKE_2OP_16FLAGS_INST(sub); + + +MAKE_1OP_16FLAGS_INST(inc); +MAKE_1OP_16FLAGS_INST(dec); +MAKE_1OP_16FLAGS_INST(neg); + +MAKE_1OP_16_INST(not); + +MAKE_2OP_16_INST(mov); +MAKE_2OP_16EXT_INST(movzx); +MAKE_2OP_16EXT_INST(movsx); +MAKE_2OUT_16_INST(xchg); + +MAKE_2OP_16STR_INST(movs); +MAKE_1OP_16STR_INST(stos); +MAKE_1OP_16STR_INST(scas); + + +/****************************/ +/* 32 Bit instruction forms */ +/****************************/ +MAKE_2OP_32FLAGS_INST(adc); +MAKE_2OP_32FLAGS_INST(add); +MAKE_2OP_32FLAGS_INST(and); +MAKE_2OP_32FLAGS_INST(or); +MAKE_2OP_32FLAGS_INST(xor); +MAKE_2OP_32FLAGS_INST(sub); + + +MAKE_1OP_32FLAGS_INST(inc); +MAKE_1OP_32FLAGS_INST(dec); +MAKE_1OP_32FLAGS_INST(neg); + +MAKE_1OP_32_INST(not); + +MAKE_2OP_32_INST(mov); + +MAKE_2OUT_32_INST(xchg); + + + +MAKE_2OP_32STR_INST(movs); +MAKE_1OP_32STR_INST(stos); +MAKE_1OP_32STR_INST(scas); + + + +#ifdef __V3_64BIT__ + +/****************************/ +/* 64 Bit instruction forms */ +/****************************/ +MAKE_2OP_64FLAGS_INST(adc); +MAKE_2OP_64FLAGS_INST(add); +MAKE_2OP_64FLAGS_INST(and); +MAKE_2OP_64FLAGS_INST(or); +MAKE_2OP_64FLAGS_INST(xor); +MAKE_2OP_64FLAGS_INST(sub); + +MAKE_1OP_64FLAGS_INST(inc); +MAKE_1OP_64FLAGS_INST(dec); +MAKE_1OP_64FLAGS_INST(neg); + +MAKE_1OP_64_INST(not); + + +MAKE_2OP_64_INST(mov); +MAKE_2OP_64STR_INST(movs); +MAKE_1OP_64STR_INST(stos); +MAKE_1OP_64STR_INST(scas); + +MAKE_2OUT_64_INST(xchg); + + +#endif