Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


working instruction emulation
[palacios.git] / palacios / include / palacios / vmm_instr_emulator.h
1 #include <palacios/vmm_types.h>
2
3
4
5 #define MAKE_1OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst,  addr_t * flags) { \
6     uchar_t tmp_dst = *dst;                                             \
7                                                                         \
8     /* Some of the flags values are not copied out in a pushf, we save them here */ \
9     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
10                                                                         \
11     asm volatile (                                                              \
12          "pushf; "                                                      \
13          "push %2; "                                                    \
14          "popf; "                                                       \
15          #iname"b %0; "                                                 \
16          "pushf; "                                                      \
17          "pop %1; "                                                     \
18          "popf; "                                                       \
19          : "=q"(tmp_dst),"=q"(*flags)                                   \
20          : "q"(*flags), "0"(tmp_dst)                                    \
21          );                                                             \
22     *dst = tmp_dst;                                                     \
23     *flags |= flags_rsvd;                                               \
24                                                                         \
25   }
26
27 #define MAKE_1OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst,  addr_t * flags) { \
28     ushort_t tmp_dst = *dst;                                            \
29                                                                         \
30     /* Some of the flags values are not copied out in a pushf, we save them here */ \
31     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
32                                                                         \
33     asm volatile (                                                              \
34          "pushf; "                                                      \
35          "push %2; "                                                    \
36          "popf; "                                                       \
37          #iname"w %0; "                                                 \
38          "pushf; "                                                      \
39          "pop %1; "                                                     \
40          "popf; "                                                       \
41          : "=q"(tmp_dst),"=q"(*flags)                                   \
42          : "q"(*flags), "0"(tmp_dst)                                    \
43          );                                                             \
44     *dst = tmp_dst;                                                     \
45     *flags |= flags_rsvd;                                               \
46                                                                         \
47   }
48
49 #define MAKE_1OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst,  addr_t * flags) { \
50     uint_t tmp_dst = *dst;                                              \
51                                                                         \
52     /* Some of the flags values are not copied out in a pushf, we save them here */ \
53     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
54                                                                         \
55     asm volatile (                                                              \
56          "pushf; "                                                      \
57          "push %2; "                                                    \
58          "popf; "                                                       \
59          #iname"l %0; "                                                 \
60          "pushf; "                                                      \
61          "pop %1; "                                                     \
62          "popf; "                                                       \
63          : "=q"(tmp_dst),"=q"(*flags)                                   \
64          : "q"(*flags), "0"(tmp_dst)                                    \
65          );                                                             \
66     *dst = tmp_dst;                                                     \
67     *flags |= flags_rsvd;                                               \
68                                                                         \
69   }
70
71 #define MAKE_1OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst,  addr_t * flags) { \
72     ullong_t tmp_dst = *dst;                                            \
73                                                                         \
74     /* Some of the flags values are not copied out in a pushf, we save them here */ \
75     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
76                                                                         \
77     asm volatile (                                                              \
78          "pushfq; "                                                     \
79          "push %2; "                                                    \
80          "popfq; "                                                      \
81          #iname"q %0; "                                                 \
82          "pushfq; "                                                     \
83          "pop %1; "                                                     \
84          "popfq; "                                                      \
85          : "=q"(tmp_dst),"=q"(*flags)                                   \
86          : "q"(*flags), "0"(tmp_dst)                                    \
87          );                                                             \
88     *dst = tmp_dst;                                                     \
89     *flags |= flags_rsvd;                                               \
90                                                                         \
91   }
92
93
94
95 #define MAKE_1OP_8_INST(iname) static inline void iname##8(addr_t * dst) { \
96     uchar_t tmp_dst = *dst;                                             \
97                                                                         \
98     asm volatile (                                                      \
99                   #iname"b %0; "                                        \
100                   : "=q"(tmp_dst)                                       \
101                   : "0"(tmp_dst)                                        \
102                   );                                                    \
103     *dst = tmp_dst;                                                     \
104   }
105
106 #define MAKE_1OP_16_INST(iname) static inline void iname##16(addr_t * dst) { \
107     ushort_t tmp_dst = *dst;                                            \
108                                                                         \
109     asm volatile (                                                      \
110          #iname"w %0; "                                                 \
111          : "=q"(tmp_dst)                                                \
112          :  "0"(tmp_dst)                                                \
113          );                                                             \
114     *dst = tmp_dst;                                                     \
115   }
116
117 #define MAKE_1OP_32_INST(iname) static inline void iname##32(addr_t * dst) { \
118     uint_t tmp_dst = *dst;                                              \
119                                                                         \
120     asm volatile (                                                      \
121          #iname"l %0; "                                                 \
122          : "=q"(tmp_dst)                                                \
123          : "0"(tmp_dst)                                                 \
124          );                                                             \
125     *dst = tmp_dst;                                                     \
126   }
127
128 #define MAKE_1OP_64_INST(iname) static inline void iname##64(addr_t * dst) { \
129     ullong_t tmp_dst = *dst;                                            \
130                                                                         \
131     asm volatile (                                                      \
132                   #iname"q %0; "                                        \
133                   : "=q"(tmp_dst)                                       \
134                   : "0"(tmp_dst)                                        \
135                   );                                                    \
136     *dst = tmp_dst;                                                     \
137   }
138
139
140 #define MAKE_2OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \
141     uint64_t tmp_dst = *dst, tmp_src = *src;                                    \
142     addr_t tmp_flags = *flags;                                          \
143                                                                         \
144     /* Some of the flags values are not copied out in a pushf, we save them here */ \
145     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
146                                                                         \
147     asm volatile (                                                              \
148          "pushfq\r\n"                                                   \
149          "push %3\r\n"                                                  \
150          "popfq\r\n"                                                    \
151          #iname"q %2, %0\r\n"                                           \
152          "pushfq\r\n"                                                   \
153          "pop %1\r\n"                                                   \
154          "popfq\r\n"                                                    \
155          : "=q"(tmp_dst),"=q"(tmp_flags)                                \
156          : "q"(tmp_src),"q"(tmp_flags), "0"(tmp_dst)                    \
157          );                                                             \
158                                                                         \
159     *dst = tmp_dst;                                                     \
160     *flags = tmp_flags;                                                 \
161     *flags |= flags_rsvd;                                               \
162                                                                         \
163   }
164
165
166
167
168 #define MAKE_2OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \
169     uint32_t tmp_dst = *dst, tmp_src = *src;                            \
170                                                                         \
171     /* Some of the flags values are not copied out in a pushf, we save them here */ \
172     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
173                                                                         \
174     asm volatile (                                                      \
175          "pushf; "                                                      \
176          "push %3; "                                                    \
177          "popf; "                                                       \
178          #iname"l %2, %0; "                                             \
179          "pushf; "                                                      \
180          "pop %1; "                                                     \
181          "popf; "                                                       \
182          : "=q"(tmp_dst),"=q"(*flags)                                   \
183          : "q"(tmp_src),"q"(*flags), "0"(tmp_dst)                       \
184          );                                                             \
185     *dst = tmp_dst;                                                     \
186     *flags |= flags_rsvd;                                               \
187                                                                         \
188   }
189
190
191 #define MAKE_2OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \
192     ushort_t tmp_dst = *dst, tmp_src = *src;                            \
193                                                                         \
194     /* Some of the flags values are not copied out in a pushf, we save them here */ \
195     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
196                                                                         \
197     asm volatile (                                                      \
198          "pushf; "                                                      \
199          "push %3; "                                                    \
200          "popf; "                                                       \
201          #iname"w %2, %0; "                                             \
202          "pushf; "                                                      \
203          "pop %1; "                                                     \
204          "popf; "                                                       \
205          : "=q"(tmp_dst),"=q"(*flags)                                   \
206          : "q"(tmp_src),"q"(*flags), "0"(tmp_dst)                       \
207          );                                                             \
208     *dst = tmp_dst;                                                     \
209     *flags |= flags_rsvd;                                               \
210                                                                         \
211   }
212
213 #define MAKE_2OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \
214     uchar_t tmp_dst = *dst, tmp_src = *src;                             \
215                                                                         \
216     /* Some of the flags values are not copied out in a pushf, we save them here */ \
217     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
218                                                                         \
219     asm volatile (                                                      \
220          "pushf; "                                                      \
221          "push %3; "                                                    \
222          "popf; "                                                       \
223          #iname"b %2, %0; "                                             \
224          "pushf; "                                                      \
225          "pop %1; "                                                     \
226          "popf; "                                                       \
227          : "=q"(tmp_dst),"=q"(*flags)                                   \
228          : "q"(tmp_src),"q"(*flags), "0"(tmp_dst)                       \
229          );                                                             \
230     *dst = tmp_dst;                                                     \
231     *flags |= flags_rsvd;                                               \
232                                                                         \
233   }
234
235
236
237
238 #define MAKE_2OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \
239                                                                 addr_t * src, \
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;                           \
243                                                                         \
244     asm volatile (                                                      \
245          "pushf; "                                                      \
246          "push %4; "                                                    \
247          "popf; "                                                       \
248          "rep; "                                                        \
249          #iname"l; "                                                    \
250          "pushf; "                                                      \
251          "pop %0; "                                                     \
252          "popf; "                                                       \
253          : "=b"(*flags)                                                 \
254          : "D"(*dst),"S"(*src),"c"(*ecx),"b"(*flags)                    \
255          );                                                             \
256                                                                         \
257     /*   : "=D"(*dst),"=S"(*src),"=c"(*ecx),"=q"(*flags)*/              \
258     *flags |= flags_rsvd;                                               \
259   }
260
261 #define MAKE_2OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \
262                                                                 addr_t * src, \
263                                                                 addr_t * ecx, addr_t * flags) { \
264      /* Some of the flags values are not copied out in a pushf, we save them here */ \
265     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
266                                                                         \
267     asm volatile (                                                      \
268          "pushf; "                                                      \
269          "push %4; "                                                    \
270          "popf; "                                                       \
271          "rep; "                                                        \
272          #iname"w; "                                                    \
273          "pushf; "                                                      \
274          "pop %0; "                                                     \
275          "popf; "                                                       \
276          : "=b"(*flags)                                                 \
277          : "D"(*dst),"S"(*src),"c"(*ecx),"b"(*flags)                    \
278          );                                                             \
279     *flags |= flags_rsvd;                                               \
280   }
281
282
283
284 #define MAKE_2OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \
285                                                               addr_t * src, \
286                                                               addr_t * ecx, addr_t * flags) { \
287     /* Some of the flags values are not copied out in a pushf, we save them here */ \
288     addr_t flags_rsvd = *flags & ~0xfffe7fff;                           \
289                                                                         \
290     asm volatile (                                                      \
291          "pushf; "                                                      \
292          "push %4; "                                                    \
293          "popf; "                                                       \
294          "rep; "                                                        \
295          #iname"b; "                                                    \
296          "pushf; "                                                      \
297          "pop %0; "                                                     \
298          "popf; "                                                       \
299          : "=b"(*flags)                                                 \
300          : "D"(*dst),"S"(*src),"c"(*ecx),"b"(*flags)                    \
301          );                                                             \
302     *flags |= flags_rsvd;                                               \
303   }
304
305
306
307
308 #define MAKE_2OP_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
309     uint32_t tmp_dst = *dst, tmp_src = *src;                            \
310                                                                         \
311     asm volatile (                                                      \
312          #iname"l %1, %0; "                                             \
313          : "=q"(tmp_dst)                                                \
314          : "q"(tmp_src), "0"(tmp_dst)                                   \
315          );                                                             \
316     *dst = tmp_dst;                                                     \
317   }
318
319 #define MAKE_2OP_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
320     ushort_t tmp_dst = *dst, tmp_src = *src;                            \
321                                                                         \
322     asm volatile (                                                      \
323          #iname"w %1, %0; "                                             \
324          : "=q"(tmp_dst)                                                \
325          : "q"(tmp_src), "0"(tmp_dst)                                   \
326          );                                                             \
327     *dst = tmp_dst;                                                     \
328   }
329
330 #define MAKE_2OP_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
331     uchar_t tmp_dst = *dst, tmp_src = *src;                             \
332                                                                         \
333     asm volatile (                                                      \
334          #iname"b %1, %0; "                                             \
335          : "=q"(tmp_dst)                                                \
336          : "q"(tmp_src), "0"(tmp_dst)                                   \
337          );                                                             \
338     *dst = tmp_dst;                                                     \
339   }
340
341
342
343
344
345
346
347 MAKE_2OP_8FLAGS_INST(adc);
348 MAKE_2OP_8FLAGS_INST(add);
349 MAKE_2OP_8FLAGS_INST(and);
350 MAKE_2OP_8FLAGS_INST(or);
351 MAKE_2OP_8FLAGS_INST(xor);
352 MAKE_2OP_8FLAGS_INST(sub);
353
354
355 MAKE_1OP_8FLAGS_INST(inc);
356 MAKE_1OP_8FLAGS_INST(dec);
357 MAKE_1OP_8FLAGS_INST(neg);
358 MAKE_1OP_8FLAGS_INST(setb);
359 MAKE_1OP_8FLAGS_INST(setbe);
360 MAKE_1OP_8FLAGS_INST(setl);
361 MAKE_1OP_8FLAGS_INST(setle);
362 MAKE_1OP_8FLAGS_INST(setnb);
363 MAKE_1OP_8FLAGS_INST(setnbe);
364 MAKE_1OP_8FLAGS_INST(setnl);
365 MAKE_1OP_8FLAGS_INST(setnle);
366 MAKE_1OP_8FLAGS_INST(setno);
367 MAKE_1OP_8FLAGS_INST(setnp);
368 MAKE_1OP_8FLAGS_INST(setns);
369 MAKE_1OP_8FLAGS_INST(setnz);
370 MAKE_1OP_8FLAGS_INST(seto);
371 MAKE_1OP_8FLAGS_INST(setp);
372 MAKE_1OP_8FLAGS_INST(sets);
373 MAKE_1OP_8FLAGS_INST(setz);
374
375
376 MAKE_1OP_8_INST(not);
377
378 MAKE_2OP_8_INST(mov);
379 MAKE_2OP_8_INST(xchg);
380
381
382
383 MAKE_2OP_16FLAGS_INST(adc);
384 MAKE_2OP_16FLAGS_INST(add);
385 MAKE_2OP_16FLAGS_INST(and);
386 MAKE_2OP_16FLAGS_INST(or);
387 MAKE_2OP_16FLAGS_INST(xor);
388 MAKE_2OP_16FLAGS_INST(sub);
389
390
391 MAKE_1OP_16FLAGS_INST(inc);
392 MAKE_1OP_16FLAGS_INST(dec);
393 MAKE_1OP_16FLAGS_INST(neg);
394
395 MAKE_1OP_16_INST(not);
396
397 MAKE_2OP_16_INST(mov);
398 MAKE_2OP_16_INST(xchg);
399
400
401
402
403
404 MAKE_2OP_32FLAGS_INST(adc);
405 MAKE_2OP_32FLAGS_INST(add);
406 MAKE_2OP_32FLAGS_INST(and);
407 MAKE_2OP_32FLAGS_INST(or);
408 MAKE_2OP_32FLAGS_INST(xor);
409 MAKE_2OP_32FLAGS_INST(sub);
410
411
412 MAKE_1OP_32FLAGS_INST(inc);
413 MAKE_1OP_32FLAGS_INST(dec);
414 MAKE_1OP_32FLAGS_INST(neg);
415
416 MAKE_1OP_32_INST(not);
417
418 MAKE_2OP_32_INST(mov);
419 MAKE_2OP_32_INST(xchg);
420
421 MAKE_2OP_8STR_INST(movs);
422 MAKE_2OP_16STR_INST(movs);
423 MAKE_2OP_32STR_INST(movs);