1 /*
2  *  i386 translation
3  *
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <inttypes.h>
24 #include <signal.h>
25 
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "disas.h"
29 #include "tcg-op.h"
30 
31 #include "helper.h"
32 #define GEN_HELPER 1
33 #include "helper.h"
34 
35 #define PREFIX_REPZ   0x01
36 #define PREFIX_REPNZ  0x02
37 #define PREFIX_LOCK   0x04
38 #define PREFIX_DATA   0x08
39 #define PREFIX_ADR    0x10
40 
41 #ifdef TARGET_X86_64
42 #define X86_64_ONLY(x) x
43 #define X86_64_DEF(...)  __VA_ARGS__
44 #define CODE64(s) ((s)->code64)
45 #define REX_X(s) ((s)->rex_x)
46 #define REX_B(s) ((s)->rex_b)
47 /* XXX: gcc generates push/pop in some opcodes, so we cannot use them */
48 #if 1
49 #define BUGGY_64(x) NULL
50 #endif
51 #else
52 #define X86_64_ONLY(x) NULL
53 #define X86_64_DEF(...)
54 #define CODE64(s) 0
55 #define REX_X(s) 0
56 #define REX_B(s) 0
57 #endif
58 
59 //#define MACRO_TEST   1
60 
61 /* global register indexes */
62 static TCGv_ptr cpu_env;
63 static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst, cpu_cc_tmp;
64 static TCGv_i32 cpu_cc_op;
65 static TCGv cpu_regs[CPU_NB_REGS];
66 /* local temps */
67 static TCGv cpu_T[2], cpu_T3;
68 /* local register indexes (only used inside old micro ops) */
69 static TCGv cpu_tmp0, cpu_tmp4;
70 static TCGv_ptr cpu_ptr0, cpu_ptr1;
71 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
72 static TCGv_i64 cpu_tmp1_i64;
73 static TCGv cpu_tmp5;
74 
75 static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
76 
77 #include "gen-icount.h"
78 
79 #ifdef TARGET_X86_64
80 static int x86_64_hregs;
81 #endif
82 
83 typedef struct DisasContext {
84     /* current insn context */
85     int override; /* -1 if no override */
86     int prefix;
87     int aflag, dflag;
88     target_ulong pc; /* pc = eip + cs_base */
89     int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
90                    static state change (stop translation) */
91     /* current block context */
92     target_ulong cs_base; /* base of CS segment */
93     int pe;     /* protected mode */
94     int code32; /* 32 bit code segment */
95 #ifdef TARGET_X86_64
96     int lma;    /* long mode active */
97     int code64; /* 64 bit code segment */
98     int rex_x, rex_b;
99 #endif
100     int ss32;   /* 32 bit stack segment */
101     int cc_op;  /* current CC operation */
102     int addseg; /* non zero if either DS/ES/SS have a non zero base */
103     int f_st;   /* currently unused */
104     int vm86;   /* vm86 mode */
105     int cpl;
106     int iopl;
107     int tf;     /* TF cpu flag */
108     int singlestep_enabled; /* "hardware" single step enabled */
109     int jmp_opt; /* use direct block chaining for direct jumps */
110     int mem_index; /* select memory access functions */
111     uint64_t flags; /* all execution flags */
112     struct TranslationBlock *tb;
113     int popl_esp_hack; /* for correct popl with esp base handling */
114     int rip_offset; /* only used in x86_64, but left for simplicity */
115     int cpuid_features;
116     int cpuid_ext_features;
117     int cpuid_ext2_features;
118     int cpuid_ext3_features;
119 } DisasContext;
120 
121 static void gen_eob(DisasContext *s);
122 static void gen_jmp(DisasContext *s, target_ulong eip);
123 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
124 
125 /* i386 arith/logic operations */
126 enum {
127     OP_ADDL,
128     OP_ORL,
129     OP_ADCL,
130     OP_SBBL,
131     OP_ANDL,
132     OP_SUBL,
133     OP_XORL,
134     OP_CMPL,
135 };
136 
137 /* i386 shift ops */
138 enum {
139     OP_ROL,
140     OP_ROR,
141     OP_RCL,
142     OP_RCR,
143     OP_SHL,
144     OP_SHR,
145     OP_SHL1, /* undocumented */
146     OP_SAR = 7,
147 };
148 
149 enum {
150     JCC_O,
151     JCC_B,
152     JCC_Z,
153     JCC_BE,
154     JCC_S,
155     JCC_P,
156     JCC_L,
157     JCC_LE,
158 };
159 
160 /* operand size */
161 enum {
162     OT_BYTE = 0,
163     OT_WORD,
164     OT_LONG,
165     OT_QUAD,
166 };
167 
168 enum {
169     /* I386 int registers */
170     OR_EAX,   /* MUST be even numbered */
171     OR_ECX,
172     OR_EDX,
173     OR_EBX,
174     OR_ESP,
175     OR_EBP,
176     OR_ESI,
177     OR_EDI,
178 
179     OR_TMP0 = 16,    /* temporary operand register */
180     OR_TMP1,
181     OR_A0, /* temporary register used when doing address evaluation */
182 };
183 
gen_op_movl_T0_0(void)184 static inline void gen_op_movl_T0_0(void)
185 {
186     tcg_gen_movi_tl(cpu_T[0], 0);
187 }
188 
gen_op_movl_T0_im(int32_t val)189 static inline void gen_op_movl_T0_im(int32_t val)
190 {
191     tcg_gen_movi_tl(cpu_T[0], val);
192 }
193 
gen_op_movl_T0_imu(uint32_t val)194 static inline void gen_op_movl_T0_imu(uint32_t val)
195 {
196     tcg_gen_movi_tl(cpu_T[0], val);
197 }
198 
gen_op_movl_T1_im(int32_t val)199 static inline void gen_op_movl_T1_im(int32_t val)
200 {
201     tcg_gen_movi_tl(cpu_T[1], val);
202 }
203 
gen_op_movl_T1_imu(uint32_t val)204 static inline void gen_op_movl_T1_imu(uint32_t val)
205 {
206     tcg_gen_movi_tl(cpu_T[1], val);
207 }
208 
gen_op_movl_A0_im(uint32_t val)209 static inline void gen_op_movl_A0_im(uint32_t val)
210 {
211     tcg_gen_movi_tl(cpu_A0, val);
212 }
213 
214 #ifdef TARGET_X86_64
gen_op_movq_A0_im(int64_t val)215 static inline void gen_op_movq_A0_im(int64_t val)
216 {
217     tcg_gen_movi_tl(cpu_A0, val);
218 }
219 #endif
220 
gen_movtl_T0_im(target_ulong val)221 static inline void gen_movtl_T0_im(target_ulong val)
222 {
223     tcg_gen_movi_tl(cpu_T[0], val);
224 }
225 
gen_movtl_T1_im(target_ulong val)226 static inline void gen_movtl_T1_im(target_ulong val)
227 {
228     tcg_gen_movi_tl(cpu_T[1], val);
229 }
230 
gen_op_andl_T0_ffff(void)231 static inline void gen_op_andl_T0_ffff(void)
232 {
233     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
234 }
235 
gen_op_andl_T0_im(uint32_t val)236 static inline void gen_op_andl_T0_im(uint32_t val)
237 {
238     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
239 }
240 
gen_op_movl_T0_T1(void)241 static inline void gen_op_movl_T0_T1(void)
242 {
243     tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
244 }
245 
gen_op_andl_A0_ffff(void)246 static inline void gen_op_andl_A0_ffff(void)
247 {
248     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
249 }
250 
251 #ifdef TARGET_X86_64
252 
253 #define NB_OP_SIZES 4
254 
255 #else /* !TARGET_X86_64 */
256 
257 #define NB_OP_SIZES 3
258 
259 #endif /* !TARGET_X86_64 */
260 
261 #if defined(HOST_WORDS_BIGENDIAN)
262 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
263 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
264 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
265 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
266 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
267 #else
268 #define REG_B_OFFSET 0
269 #define REG_H_OFFSET 1
270 #define REG_W_OFFSET 0
271 #define REG_L_OFFSET 0
272 #define REG_LH_OFFSET 4
273 #endif
274 
gen_op_mov_reg_v(int ot,int reg,TCGv t0)275 static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
276 {
277     switch(ot) {
278     case OT_BYTE:
279         if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
280             tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
281         } else {
282             tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
283         }
284         break;
285     case OT_WORD:
286         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
287         break;
288     default: /* XXX this shouldn't be reached;  abort? */
289     case OT_LONG:
290         /* For x86_64, this sets the higher half of register to zero.
291            For i386, this is equivalent to a mov. */
292         tcg_gen_ext32u_tl(cpu_regs[reg], t0);
293         break;
294 #ifdef TARGET_X86_64
295     case OT_QUAD:
296         tcg_gen_mov_tl(cpu_regs[reg], t0);
297         break;
298 #endif
299     }
300 }
301 
gen_op_mov_reg_T0(int ot,int reg)302 static inline void gen_op_mov_reg_T0(int ot, int reg)
303 {
304     gen_op_mov_reg_v(ot, reg, cpu_T[0]);
305 }
306 
gen_op_mov_reg_T1(int ot,int reg)307 static inline void gen_op_mov_reg_T1(int ot, int reg)
308 {
309     gen_op_mov_reg_v(ot, reg, cpu_T[1]);
310 }
311 
gen_op_mov_reg_A0(int size,int reg)312 static inline void gen_op_mov_reg_A0(int size, int reg)
313 {
314     switch(size) {
315     case 0:
316         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_A0, 0, 16);
317         break;
318     default: /* XXX this shouldn't be reached;  abort? */
319     case 1:
320         /* For x86_64, this sets the higher half of register to zero.
321            For i386, this is equivalent to a mov. */
322         tcg_gen_ext32u_tl(cpu_regs[reg], cpu_A0);
323         break;
324 #ifdef TARGET_X86_64
325     case 2:
326         tcg_gen_mov_tl(cpu_regs[reg], cpu_A0);
327         break;
328 #endif
329     }
330 }
331 
gen_op_mov_v_reg(int ot,TCGv t0,int reg)332 static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
333 {
334     switch(ot) {
335     case OT_BYTE:
336         if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
337             goto std_case;
338         } else {
339             tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
340             tcg_gen_ext8u_tl(t0, t0);
341         }
342         break;
343     default:
344     std_case:
345         tcg_gen_mov_tl(t0, cpu_regs[reg]);
346         break;
347     }
348 }
349 
gen_op_mov_TN_reg(int ot,int t_index,int reg)350 static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
351 {
352     gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
353 }
354 
gen_op_movl_A0_reg(int reg)355 static inline void gen_op_movl_A0_reg(int reg)
356 {
357     tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
358 }
359 
gen_op_addl_A0_im(int32_t val)360 static inline void gen_op_addl_A0_im(int32_t val)
361 {
362     tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
363 #ifdef TARGET_X86_64
364     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
365 #endif
366 }
367 
368 #ifdef TARGET_X86_64
gen_op_addq_A0_im(int64_t val)369 static inline void gen_op_addq_A0_im(int64_t val)
370 {
371     tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
372 }
373 #endif
374 
gen_add_A0_im(DisasContext * s,int val)375 static void gen_add_A0_im(DisasContext *s, int val)
376 {
377 #ifdef TARGET_X86_64
378     if (CODE64(s))
379         gen_op_addq_A0_im(val);
380     else
381 #endif
382         gen_op_addl_A0_im(val);
383 }
384 
gen_op_addl_T0_T1(void)385 static inline void gen_op_addl_T0_T1(void)
386 {
387     tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
388 }
389 
gen_op_jmp_T0(void)390 static inline void gen_op_jmp_T0(void)
391 {
392     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
393 }
394 
gen_op_add_reg_im(int size,int reg,int32_t val)395 static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
396 {
397     switch(size) {
398     case 0:
399         tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
400         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16);
401         break;
402     case 1:
403         tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
404         /* For x86_64, this sets the higher half of register to zero.
405            For i386, this is equivalent to a nop. */
406         tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
407         tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
408         break;
409 #ifdef TARGET_X86_64
410     case 2:
411         tcg_gen_addi_tl(cpu_regs[reg], cpu_regs[reg], val);
412         break;
413 #endif
414     }
415 }
416 
gen_op_add_reg_T0(int size,int reg)417 static inline void gen_op_add_reg_T0(int size, int reg)
418 {
419     switch(size) {
420     case 0:
421         tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
422         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16);
423         break;
424     case 1:
425         tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
426         /* For x86_64, this sets the higher half of register to zero.
427            For i386, this is equivalent to a nop. */
428         tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
429         tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
430         break;
431 #ifdef TARGET_X86_64
432     case 2:
433         tcg_gen_add_tl(cpu_regs[reg], cpu_regs[reg], cpu_T[0]);
434         break;
435 #endif
436     }
437 }
438 
gen_op_set_cc_op(int32_t val)439 static inline void gen_op_set_cc_op(int32_t val)
440 {
441     tcg_gen_movi_i32(cpu_cc_op, val);
442 }
443 
gen_op_addl_A0_reg_sN(int shift,int reg)444 static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
445 {
446     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
447     if (shift != 0)
448         tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
449     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
450     /* For x86_64, this sets the higher half of register to zero.
451        For i386, this is equivalent to a nop. */
452     tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
453 }
454 
gen_op_movl_A0_seg(int reg)455 static inline void gen_op_movl_A0_seg(int reg)
456 {
457     tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
458 }
459 
gen_op_addl_A0_seg(int reg)460 static inline void gen_op_addl_A0_seg(int reg)
461 {
462     tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
463     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
464 #ifdef TARGET_X86_64
465     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
466 #endif
467 }
468 
469 #ifdef TARGET_X86_64
gen_op_movq_A0_seg(int reg)470 static inline void gen_op_movq_A0_seg(int reg)
471 {
472     tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
473 }
474 
gen_op_addq_A0_seg(int reg)475 static inline void gen_op_addq_A0_seg(int reg)
476 {
477     tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
478     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
479 }
480 
gen_op_movq_A0_reg(int reg)481 static inline void gen_op_movq_A0_reg(int reg)
482 {
483     tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
484 }
485 
gen_op_addq_A0_reg_sN(int shift,int reg)486 static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
487 {
488     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
489     if (shift != 0)
490         tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
491     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
492 }
493 #endif
494 
gen_op_lds_T0_A0(int idx)495 static inline void gen_op_lds_T0_A0(int idx)
496 {
497     int mem_index = (idx >> 2) - 1;
498     switch(idx & 3) {
499     case 0:
500         tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);
501         break;
502     case 1:
503         tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);
504         break;
505     default:
506     case 2:
507         tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);
508         break;
509     }
510 }
511 
gen_op_ld_v(int idx,TCGv t0,TCGv a0)512 static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0)
513 {
514     int mem_index = (idx >> 2) - 1;
515     switch(idx & 3) {
516     case 0:
517         tcg_gen_qemu_ld8u(t0, a0, mem_index);
518         break;
519     case 1:
520         tcg_gen_qemu_ld16u(t0, a0, mem_index);
521         break;
522     case 2:
523         tcg_gen_qemu_ld32u(t0, a0, mem_index);
524         break;
525     default:
526     case 3:
527         /* Should never happen on 32-bit targets.  */
528 #ifdef TARGET_X86_64
529         tcg_gen_qemu_ld64(t0, a0, mem_index);
530 #endif
531         break;
532     }
533 }
534 
535 /* XXX: always use ldu or lds */
gen_op_ld_T0_A0(int idx)536 static inline void gen_op_ld_T0_A0(int idx)
537 {
538     gen_op_ld_v(idx, cpu_T[0], cpu_A0);
539 }
540 
gen_op_ldu_T0_A0(int idx)541 static inline void gen_op_ldu_T0_A0(int idx)
542 {
543     gen_op_ld_v(idx, cpu_T[0], cpu_A0);
544 }
545 
gen_op_ld_T1_A0(int idx)546 static inline void gen_op_ld_T1_A0(int idx)
547 {
548     gen_op_ld_v(idx, cpu_T[1], cpu_A0);
549 }
550 
gen_op_st_v(int idx,TCGv t0,TCGv a0)551 static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0)
552 {
553     int mem_index = (idx >> 2) - 1;
554     switch(idx & 3) {
555     case 0:
556         tcg_gen_qemu_st8(t0, a0, mem_index);
557         break;
558     case 1:
559         tcg_gen_qemu_st16(t0, a0, mem_index);
560         break;
561     case 2:
562         tcg_gen_qemu_st32(t0, a0, mem_index);
563         break;
564     default:
565     case 3:
566         /* Should never happen on 32-bit targets.  */
567 #ifdef TARGET_X86_64
568         tcg_gen_qemu_st64(t0, a0, mem_index);
569 #endif
570         break;
571     }
572 }
573 
gen_op_st_T0_A0(int idx)574 static inline void gen_op_st_T0_A0(int idx)
575 {
576     gen_op_st_v(idx, cpu_T[0], cpu_A0);
577 }
578 
gen_op_st_T1_A0(int idx)579 static inline void gen_op_st_T1_A0(int idx)
580 {
581     gen_op_st_v(idx, cpu_T[1], cpu_A0);
582 }
583 
gen_jmp_im(target_ulong pc)584 static inline void gen_jmp_im(target_ulong pc)
585 {
586     tcg_gen_movi_tl(cpu_tmp0, pc);
587     tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
588 }
589 
gen_string_movl_A0_ESI(DisasContext * s)590 static inline void gen_string_movl_A0_ESI(DisasContext *s)
591 {
592     int override;
593 
594     override = s->override;
595 #ifdef TARGET_X86_64
596     if (s->aflag == 2) {
597         if (override >= 0) {
598             gen_op_movq_A0_seg(override);
599             gen_op_addq_A0_reg_sN(0, R_ESI);
600         } else {
601             gen_op_movq_A0_reg(R_ESI);
602         }
603     } else
604 #endif
605     if (s->aflag) {
606         /* 32 bit address */
607         if (s->addseg && override < 0)
608             override = R_DS;
609         if (override >= 0) {
610             gen_op_movl_A0_seg(override);
611             gen_op_addl_A0_reg_sN(0, R_ESI);
612         } else {
613             gen_op_movl_A0_reg(R_ESI);
614         }
615     } else {
616         /* 16 address, always override */
617         if (override < 0)
618             override = R_DS;
619         gen_op_movl_A0_reg(R_ESI);
620         gen_op_andl_A0_ffff();
621         gen_op_addl_A0_seg(override);
622     }
623 }
624 
gen_string_movl_A0_EDI(DisasContext * s)625 static inline void gen_string_movl_A0_EDI(DisasContext *s)
626 {
627 #ifdef TARGET_X86_64
628     if (s->aflag == 2) {
629         gen_op_movq_A0_reg(R_EDI);
630     } else
631 #endif
632     if (s->aflag) {
633         if (s->addseg) {
634             gen_op_movl_A0_seg(R_ES);
635             gen_op_addl_A0_reg_sN(0, R_EDI);
636         } else {
637             gen_op_movl_A0_reg(R_EDI);
638         }
639     } else {
640         gen_op_movl_A0_reg(R_EDI);
641         gen_op_andl_A0_ffff();
642         gen_op_addl_A0_seg(R_ES);
643     }
644 }
645 
gen_op_movl_T0_Dshift(int ot)646 static inline void gen_op_movl_T0_Dshift(int ot)
647 {
648     tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df));
649     tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
650 };
651 
gen_extu(int ot,TCGv reg)652 static void gen_extu(int ot, TCGv reg)
653 {
654     switch(ot) {
655     case OT_BYTE:
656         tcg_gen_ext8u_tl(reg, reg);
657         break;
658     case OT_WORD:
659         tcg_gen_ext16u_tl(reg, reg);
660         break;
661     case OT_LONG:
662         tcg_gen_ext32u_tl(reg, reg);
663         break;
664     default:
665         break;
666     }
667 }
668 
gen_exts(int ot,TCGv reg)669 static void gen_exts(int ot, TCGv reg)
670 {
671     switch(ot) {
672     case OT_BYTE:
673         tcg_gen_ext8s_tl(reg, reg);
674         break;
675     case OT_WORD:
676         tcg_gen_ext16s_tl(reg, reg);
677         break;
678     case OT_LONG:
679         tcg_gen_ext32s_tl(reg, reg);
680         break;
681     default:
682         break;
683     }
684 }
685 
gen_op_jnz_ecx(int size,int label1)686 static inline void gen_op_jnz_ecx(int size, int label1)
687 {
688     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
689     gen_extu(size + 1, cpu_tmp0);
690     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
691 }
692 
gen_op_jz_ecx(int size,int label1)693 static inline void gen_op_jz_ecx(int size, int label1)
694 {
695     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
696     gen_extu(size + 1, cpu_tmp0);
697     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
698 }
699 
gen_helper_in_func(int ot,TCGv v,TCGv_i32 n)700 static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n)
701 {
702     switch (ot) {
703     case 0: gen_helper_inb(v, n); break;
704     case 1: gen_helper_inw(v, n); break;
705     case 2: gen_helper_inl(v, n); break;
706     }
707 
708 }
709 
gen_helper_out_func(int ot,TCGv_i32 v,TCGv_i32 n)710 static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n)
711 {
712     switch (ot) {
713     case 0: gen_helper_outb(v, n); break;
714     case 1: gen_helper_outw(v, n); break;
715     case 2: gen_helper_outl(v, n); break;
716     }
717 
718 }
719 
gen_check_io(DisasContext * s,int ot,target_ulong cur_eip,uint32_t svm_flags)720 static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
721                          uint32_t svm_flags)
722 {
723     int state_saved;
724     target_ulong next_eip;
725 
726     state_saved = 0;
727     if (s->pe && (s->cpl > s->iopl || s->vm86)) {
728         if (s->cc_op != CC_OP_DYNAMIC)
729             gen_op_set_cc_op(s->cc_op);
730         gen_jmp_im(cur_eip);
731         state_saved = 1;
732         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
733         switch (ot) {
734         case 0: gen_helper_check_iob(cpu_tmp2_i32); break;
735         case 1: gen_helper_check_iow(cpu_tmp2_i32); break;
736         case 2: gen_helper_check_iol(cpu_tmp2_i32); break;
737         }
738     }
739     if(s->flags & HF_SVMI_MASK) {
740         if (!state_saved) {
741             if (s->cc_op != CC_OP_DYNAMIC)
742                 gen_op_set_cc_op(s->cc_op);
743             gen_jmp_im(cur_eip);
744         }
745         svm_flags |= (1 << (4 + ot));
746         next_eip = s->pc - s->cs_base;
747         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
748         gen_helper_svm_check_io(cpu_tmp2_i32, tcg_const_i32(svm_flags),
749                                 tcg_const_i32(next_eip - cur_eip));
750     }
751 }
752 
gen_movs(DisasContext * s,int ot)753 static inline void gen_movs(DisasContext *s, int ot)
754 {
755     gen_string_movl_A0_ESI(s);
756     gen_op_ld_T0_A0(ot + s->mem_index);
757     gen_string_movl_A0_EDI(s);
758     gen_op_st_T0_A0(ot + s->mem_index);
759     gen_op_movl_T0_Dshift(ot);
760     gen_op_add_reg_T0(s->aflag, R_ESI);
761     gen_op_add_reg_T0(s->aflag, R_EDI);
762 }
763 
gen_update_cc_op(DisasContext * s)764 static inline void gen_update_cc_op(DisasContext *s)
765 {
766     if (s->cc_op != CC_OP_DYNAMIC) {
767         gen_op_set_cc_op(s->cc_op);
768         s->cc_op = CC_OP_DYNAMIC;
769     }
770 }
771 
gen_op_update1_cc(void)772 static void gen_op_update1_cc(void)
773 {
774     tcg_gen_discard_tl(cpu_cc_src);
775     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
776 }
777 
gen_op_update2_cc(void)778 static void gen_op_update2_cc(void)
779 {
780     tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
781     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
782 }
783 
gen_op_cmpl_T0_T1_cc(void)784 static inline void gen_op_cmpl_T0_T1_cc(void)
785 {
786     tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
787     tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
788 }
789 
gen_op_testl_T0_T1_cc(void)790 static inline void gen_op_testl_T0_T1_cc(void)
791 {
792     tcg_gen_discard_tl(cpu_cc_src);
793     tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
794 }
795 
gen_op_update_neg_cc(void)796 static void gen_op_update_neg_cc(void)
797 {
798     tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
799     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
800 }
801 
802 /* compute eflags.C to reg */
gen_compute_eflags_c(TCGv reg)803 static void gen_compute_eflags_c(TCGv reg)
804 {
805     gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_cc_op);
806     tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
807 }
808 
809 /* compute all eflags to cc_src */
gen_compute_eflags(TCGv reg)810 static void gen_compute_eflags(TCGv reg)
811 {
812     gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_cc_op);
813     tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
814 }
815 
gen_setcc_slow_T0(DisasContext * s,int jcc_op)816 static inline void gen_setcc_slow_T0(DisasContext *s, int jcc_op)
817 {
818     if (s->cc_op != CC_OP_DYNAMIC)
819         gen_op_set_cc_op(s->cc_op);
820     switch(jcc_op) {
821     case JCC_O:
822         gen_compute_eflags(cpu_T[0]);
823         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 11);
824         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
825         break;
826     case JCC_B:
827         gen_compute_eflags_c(cpu_T[0]);
828         break;
829     case JCC_Z:
830         gen_compute_eflags(cpu_T[0]);
831         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 6);
832         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
833         break;
834     case JCC_BE:
835         gen_compute_eflags(cpu_tmp0);
836         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 6);
837         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
838         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
839         break;
840     case JCC_S:
841         gen_compute_eflags(cpu_T[0]);
842         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 7);
843         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
844         break;
845     case JCC_P:
846         gen_compute_eflags(cpu_T[0]);
847         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 2);
848         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
849         break;
850     case JCC_L:
851         gen_compute_eflags(cpu_tmp0);
852         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 11); /* CC_O */
853         tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 7); /* CC_S */
854         tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
855         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
856         break;
857     default:
858     case JCC_LE:
859         gen_compute_eflags(cpu_tmp0);
860         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 11); /* CC_O */
861         tcg_gen_shri_tl(cpu_tmp4, cpu_tmp0, 7); /* CC_S */
862         tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 6); /* CC_Z */
863         tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
864         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
865         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
866         break;
867     }
868 }
869 
870 /* return true if setcc_slow is not needed (WARNING: must be kept in
871    sync with gen_jcc1) */
is_fast_jcc_case(DisasContext * s,int b)872 static int is_fast_jcc_case(DisasContext *s, int b)
873 {
874     int jcc_op;
875     jcc_op = (b >> 1) & 7;
876     switch(s->cc_op) {
877         /* we optimize the cmp/jcc case */
878     case CC_OP_SUBB:
879     case CC_OP_SUBW:
880     case CC_OP_SUBL:
881     case CC_OP_SUBQ:
882         if (jcc_op == JCC_O || jcc_op == JCC_P)
883             goto slow_jcc;
884         break;
885 
886         /* some jumps are easy to compute */
887     case CC_OP_ADDB:
888     case CC_OP_ADDW:
889     case CC_OP_ADDL:
890     case CC_OP_ADDQ:
891 
892     case CC_OP_LOGICB:
893     case CC_OP_LOGICW:
894     case CC_OP_LOGICL:
895     case CC_OP_LOGICQ:
896 
897     case CC_OP_INCB:
898     case CC_OP_INCW:
899     case CC_OP_INCL:
900     case CC_OP_INCQ:
901 
902     case CC_OP_DECB:
903     case CC_OP_DECW:
904     case CC_OP_DECL:
905     case CC_OP_DECQ:
906 
907     case CC_OP_SHLB:
908     case CC_OP_SHLW:
909     case CC_OP_SHLL:
910     case CC_OP_SHLQ:
911         if (jcc_op != JCC_Z && jcc_op != JCC_S)
912             goto slow_jcc;
913         break;
914     default:
915     slow_jcc:
916         return 0;
917     }
918     return 1;
919 }
920 
921 /* generate a conditional jump to label 'l1' according to jump opcode
922    value 'b'. In the fast case, T0 is guaranted not to be used. */
gen_jcc1(DisasContext * s,int cc_op,int b,int l1)923 static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
924 {
925     int inv, jcc_op, size, cond;
926     TCGv t0;
927 
928     inv = b & 1;
929     jcc_op = (b >> 1) & 7;
930 
931     switch(cc_op) {
932         /* we optimize the cmp/jcc case */
933     case CC_OP_SUBB:
934     case CC_OP_SUBW:
935     case CC_OP_SUBL:
936     case CC_OP_SUBQ:
937 
938         size = cc_op - CC_OP_SUBB;
939         switch(jcc_op) {
940         case JCC_Z:
941         fast_jcc_z:
942             switch(size) {
943             case 0:
944                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xff);
945                 t0 = cpu_tmp0;
946                 break;
947             case 1:
948                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffff);
949                 t0 = cpu_tmp0;
950                 break;
951 #ifdef TARGET_X86_64
952             case 2:
953                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffffffff);
954                 t0 = cpu_tmp0;
955                 break;
956 #endif
957             default:
958                 t0 = cpu_cc_dst;
959                 break;
960             }
961             tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
962             break;
963         case JCC_S:
964         fast_jcc_s:
965             switch(size) {
966             case 0:
967                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80);
968                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0,
969                                    0, l1);
970                 break;
971             case 1:
972                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x8000);
973                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0,
974                                    0, l1);
975                 break;
976 #ifdef TARGET_X86_64
977             case 2:
978                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80000000);
979                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0,
980                                    0, l1);
981                 break;
982 #endif
983             default:
984                 tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst,
985                                    0, l1);
986                 break;
987             }
988             break;
989 
990         case JCC_B:
991             cond = inv ? TCG_COND_GEU : TCG_COND_LTU;
992             goto fast_jcc_b;
993         case JCC_BE:
994             cond = inv ? TCG_COND_GTU : TCG_COND_LEU;
995         fast_jcc_b:
996             tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
997             switch(size) {
998             case 0:
999                 t0 = cpu_tmp0;
1000                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xff);
1001                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xff);
1002                 break;
1003             case 1:
1004                 t0 = cpu_tmp0;
1005                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffff);
1006                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xffff);
1007                 break;
1008 #ifdef TARGET_X86_64
1009             case 2:
1010                 t0 = cpu_tmp0;
1011                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffffffff);
1012                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xffffffff);
1013                 break;
1014 #endif
1015             default:
1016                 t0 = cpu_cc_src;
1017                 break;
1018             }
1019             tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
1020             break;
1021 
1022         case JCC_L:
1023             cond = inv ? TCG_COND_GE : TCG_COND_LT;
1024             goto fast_jcc_l;
1025         case JCC_LE:
1026             cond = inv ? TCG_COND_GT : TCG_COND_LE;
1027         fast_jcc_l:
1028             tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
1029             switch(size) {
1030             case 0:
1031                 t0 = cpu_tmp0;
1032                 tcg_gen_ext8s_tl(cpu_tmp4, cpu_tmp4);
1033                 tcg_gen_ext8s_tl(t0, cpu_cc_src);
1034                 break;
1035             case 1:
1036                 t0 = cpu_tmp0;
1037                 tcg_gen_ext16s_tl(cpu_tmp4, cpu_tmp4);
1038                 tcg_gen_ext16s_tl(t0, cpu_cc_src);
1039                 break;
1040 #ifdef TARGET_X86_64
1041             case 2:
1042                 t0 = cpu_tmp0;
1043                 tcg_gen_ext32s_tl(cpu_tmp4, cpu_tmp4);
1044                 tcg_gen_ext32s_tl(t0, cpu_cc_src);
1045                 break;
1046 #endif
1047             default:
1048                 t0 = cpu_cc_src;
1049                 break;
1050             }
1051             tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
1052             break;
1053 
1054         default:
1055             goto slow_jcc;
1056         }
1057         break;
1058 
1059         /* some jumps are easy to compute */
1060     case CC_OP_ADDB:
1061     case CC_OP_ADDW:
1062     case CC_OP_ADDL:
1063     case CC_OP_ADDQ:
1064 
1065     case CC_OP_ADCB:
1066     case CC_OP_ADCW:
1067     case CC_OP_ADCL:
1068     case CC_OP_ADCQ:
1069 
1070     case CC_OP_SBBB:
1071     case CC_OP_SBBW:
1072     case CC_OP_SBBL:
1073     case CC_OP_SBBQ:
1074 
1075     case CC_OP_LOGICB:
1076     case CC_OP_LOGICW:
1077     case CC_OP_LOGICL:
1078     case CC_OP_LOGICQ:
1079 
1080     case CC_OP_INCB:
1081     case CC_OP_INCW:
1082     case CC_OP_INCL:
1083     case CC_OP_INCQ:
1084 
1085     case CC_OP_DECB:
1086     case CC_OP_DECW:
1087     case CC_OP_DECL:
1088     case CC_OP_DECQ:
1089 
1090     case CC_OP_SHLB:
1091     case CC_OP_SHLW:
1092     case CC_OP_SHLL:
1093     case CC_OP_SHLQ:
1094 
1095     case CC_OP_SARB:
1096     case CC_OP_SARW:
1097     case CC_OP_SARL:
1098     case CC_OP_SARQ:
1099         switch(jcc_op) {
1100         case JCC_Z:
1101             size = (cc_op - CC_OP_ADDB) & 3;
1102             goto fast_jcc_z;
1103         case JCC_S:
1104             size = (cc_op - CC_OP_ADDB) & 3;
1105             goto fast_jcc_s;
1106         default:
1107             goto slow_jcc;
1108         }
1109         break;
1110     default:
1111     slow_jcc:
1112         gen_setcc_slow_T0(s, jcc_op);
1113         tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE,
1114                            cpu_T[0], 0, l1);
1115         break;
1116     }
1117 }
1118 
1119 /* XXX: does not work with gdbstub "ice" single step - not a
1120    serious problem */
gen_jz_ecx_string(DisasContext * s,target_ulong next_eip)1121 static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1122 {
1123     int l1, l2;
1124 
1125     l1 = gen_new_label();
1126     l2 = gen_new_label();
1127     gen_op_jnz_ecx(s->aflag, l1);
1128     gen_set_label(l2);
1129     gen_jmp_tb(s, next_eip, 1);
1130     gen_set_label(l1);
1131     return l2;
1132 }
1133 
gen_stos(DisasContext * s,int ot)1134 static inline void gen_stos(DisasContext *s, int ot)
1135 {
1136     gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1137     gen_string_movl_A0_EDI(s);
1138     gen_op_st_T0_A0(ot + s->mem_index);
1139     gen_op_movl_T0_Dshift(ot);
1140     gen_op_add_reg_T0(s->aflag, R_EDI);
1141 }
1142 
gen_lods(DisasContext * s,int ot)1143 static inline void gen_lods(DisasContext *s, int ot)
1144 {
1145     gen_string_movl_A0_ESI(s);
1146     gen_op_ld_T0_A0(ot + s->mem_index);
1147     gen_op_mov_reg_T0(ot, R_EAX);
1148     gen_op_movl_T0_Dshift(ot);
1149     gen_op_add_reg_T0(s->aflag, R_ESI);
1150 }
1151 
gen_scas(DisasContext * s,int ot)1152 static inline void gen_scas(DisasContext *s, int ot)
1153 {
1154     gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
1155     gen_string_movl_A0_EDI(s);
1156     gen_op_ld_T1_A0(ot + s->mem_index);
1157     gen_op_cmpl_T0_T1_cc();
1158     gen_op_movl_T0_Dshift(ot);
1159     gen_op_add_reg_T0(s->aflag, R_EDI);
1160 }
1161 
gen_cmps(DisasContext * s,int ot)1162 static inline void gen_cmps(DisasContext *s, int ot)
1163 {
1164     gen_string_movl_A0_ESI(s);
1165     gen_op_ld_T0_A0(ot + s->mem_index);
1166     gen_string_movl_A0_EDI(s);
1167     gen_op_ld_T1_A0(ot + s->mem_index);
1168     gen_op_cmpl_T0_T1_cc();
1169     gen_op_movl_T0_Dshift(ot);
1170     gen_op_add_reg_T0(s->aflag, R_ESI);
1171     gen_op_add_reg_T0(s->aflag, R_EDI);
1172 }
1173 
gen_ins(DisasContext * s,int ot)1174 static inline void gen_ins(DisasContext *s, int ot)
1175 {
1176     if (use_icount)
1177         gen_io_start();
1178     gen_string_movl_A0_EDI(s);
1179     /* Note: we must do this dummy write first to be restartable in
1180        case of page fault. */
1181     gen_op_movl_T0_0();
1182     gen_op_st_T0_A0(ot + s->mem_index);
1183     gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1184     tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1185     tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1186     gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
1187     gen_op_st_T0_A0(ot + s->mem_index);
1188     gen_op_movl_T0_Dshift(ot);
1189     gen_op_add_reg_T0(s->aflag, R_EDI);
1190     if (use_icount)
1191         gen_io_end();
1192 }
1193 
gen_outs(DisasContext * s,int ot)1194 static inline void gen_outs(DisasContext *s, int ot)
1195 {
1196     if (use_icount)
1197         gen_io_start();
1198     gen_string_movl_A0_ESI(s);
1199     gen_op_ld_T0_A0(ot + s->mem_index);
1200 
1201     gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1202     tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1203     tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1204     tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1205     gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1206 
1207     gen_op_movl_T0_Dshift(ot);
1208     gen_op_add_reg_T0(s->aflag, R_ESI);
1209     if (use_icount)
1210         gen_io_end();
1211 }
1212 
1213 /* same method as Valgrind : we generate jumps to current or next
1214    instruction */
1215 #define GEN_REPZ(op)                                                          \
1216 static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1217                                  target_ulong cur_eip, target_ulong next_eip) \
1218 {                                                                             \
1219     int l2;\
1220     gen_update_cc_op(s);                                                      \
1221     l2 = gen_jz_ecx_string(s, next_eip);                                      \
1222     gen_ ## op(s, ot);                                                        \
1223     gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1224     /* a loop would cause two single step exceptions if ECX = 1               \
1225        before rep string_insn */                                              \
1226     if (!s->jmp_opt)                                                          \
1227         gen_op_jz_ecx(s->aflag, l2);                                          \
1228     gen_jmp(s, cur_eip);                                                      \
1229 }
1230 
1231 #define GEN_REPZ2(op)                                                         \
1232 static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1233                                    target_ulong cur_eip,                      \
1234                                    target_ulong next_eip,                     \
1235                                    int nz)                                    \
1236 {                                                                             \
1237     int l2;\
1238     gen_update_cc_op(s);                                                      \
1239     l2 = gen_jz_ecx_string(s, next_eip);                                      \
1240     gen_ ## op(s, ot);                                                        \
1241     gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
1242     gen_op_set_cc_op(CC_OP_SUBB + ot);                                        \
1243     gen_jcc1(s, CC_OP_SUBB + ot, (JCC_Z << 1) | (nz ^ 1), l2);                \
1244     if (!s->jmp_opt)                                                          \
1245         gen_op_jz_ecx(s->aflag, l2);                                          \
1246     gen_jmp(s, cur_eip);                                                      \
1247 }
1248 
1249 GEN_REPZ(movs)
GEN_REPZ(stos)1250 GEN_REPZ(stos)
1251 GEN_REPZ(lods)
1252 GEN_REPZ(ins)
1253 GEN_REPZ(outs)
1254 GEN_REPZ2(scas)
1255 GEN_REPZ2(cmps)
1256 
1257 static void gen_helper_fp_arith_ST0_FT0(int op)
1258 {
1259     switch (op) {
1260     case 0: gen_helper_fadd_ST0_FT0(); break;
1261     case 1: gen_helper_fmul_ST0_FT0(); break;
1262     case 2: gen_helper_fcom_ST0_FT0(); break;
1263     case 3: gen_helper_fcom_ST0_FT0(); break;
1264     case 4: gen_helper_fsub_ST0_FT0(); break;
1265     case 5: gen_helper_fsubr_ST0_FT0(); break;
1266     case 6: gen_helper_fdiv_ST0_FT0(); break;
1267     case 7: gen_helper_fdivr_ST0_FT0(); break;
1268     }
1269 }
1270 
1271 /* NOTE the exception in "r" op ordering */
gen_helper_fp_arith_STN_ST0(int op,int opreg)1272 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1273 {
1274     TCGv_i32 tmp = tcg_const_i32(opreg);
1275     switch (op) {
1276     case 0: gen_helper_fadd_STN_ST0(tmp); break;
1277     case 1: gen_helper_fmul_STN_ST0(tmp); break;
1278     case 4: gen_helper_fsubr_STN_ST0(tmp); break;
1279     case 5: gen_helper_fsub_STN_ST0(tmp); break;
1280     case 6: gen_helper_fdivr_STN_ST0(tmp); break;
1281     case 7: gen_helper_fdiv_STN_ST0(tmp); break;
1282     }
1283 }
1284 
1285 /* if d == OR_TMP0, it means memory operand (address in A0) */
gen_op(DisasContext * s1,int op,int ot,int d)1286 static void gen_op(DisasContext *s1, int op, int ot, int d)
1287 {
1288     if (d != OR_TMP0) {
1289         gen_op_mov_TN_reg(ot, 0, d);
1290     } else {
1291         gen_op_ld_T0_A0(ot + s1->mem_index);
1292     }
1293     switch(op) {
1294     case OP_ADCL:
1295         if (s1->cc_op != CC_OP_DYNAMIC)
1296             gen_op_set_cc_op(s1->cc_op);
1297         gen_compute_eflags_c(cpu_tmp4);
1298         tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1299         tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1300         if (d != OR_TMP0)
1301             gen_op_mov_reg_T0(ot, d);
1302         else
1303             gen_op_st_T0_A0(ot + s1->mem_index);
1304         tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1305         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1306         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
1307         tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
1308         tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_ADDB + ot);
1309         s1->cc_op = CC_OP_DYNAMIC;
1310         break;
1311     case OP_SBBL:
1312         if (s1->cc_op != CC_OP_DYNAMIC)
1313             gen_op_set_cc_op(s1->cc_op);
1314         gen_compute_eflags_c(cpu_tmp4);
1315         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1316         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1317         if (d != OR_TMP0)
1318             gen_op_mov_reg_T0(ot, d);
1319         else
1320             gen_op_st_T0_A0(ot + s1->mem_index);
1321         tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1322         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1323         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
1324         tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
1325         tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_SUBB + ot);
1326         s1->cc_op = CC_OP_DYNAMIC;
1327         break;
1328     case OP_ADDL:
1329         gen_op_addl_T0_T1();
1330         if (d != OR_TMP0)
1331             gen_op_mov_reg_T0(ot, d);
1332         else
1333             gen_op_st_T0_A0(ot + s1->mem_index);
1334         gen_op_update2_cc();
1335         s1->cc_op = CC_OP_ADDB + ot;
1336         break;
1337     case OP_SUBL:
1338         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1339         if (d != OR_TMP0)
1340             gen_op_mov_reg_T0(ot, d);
1341         else
1342             gen_op_st_T0_A0(ot + s1->mem_index);
1343         gen_op_update2_cc();
1344         s1->cc_op = CC_OP_SUBB + ot;
1345         break;
1346     default:
1347     case OP_ANDL:
1348         tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1349         if (d != OR_TMP0)
1350             gen_op_mov_reg_T0(ot, d);
1351         else
1352             gen_op_st_T0_A0(ot + s1->mem_index);
1353         gen_op_update1_cc();
1354         s1->cc_op = CC_OP_LOGICB + ot;
1355         break;
1356     case OP_ORL:
1357         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1358         if (d != OR_TMP0)
1359             gen_op_mov_reg_T0(ot, d);
1360         else
1361             gen_op_st_T0_A0(ot + s1->mem_index);
1362         gen_op_update1_cc();
1363         s1->cc_op = CC_OP_LOGICB + ot;
1364         break;
1365     case OP_XORL:
1366         tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1367         if (d != OR_TMP0)
1368             gen_op_mov_reg_T0(ot, d);
1369         else
1370             gen_op_st_T0_A0(ot + s1->mem_index);
1371         gen_op_update1_cc();
1372         s1->cc_op = CC_OP_LOGICB + ot;
1373         break;
1374     case OP_CMPL:
1375         gen_op_cmpl_T0_T1_cc();
1376         s1->cc_op = CC_OP_SUBB + ot;
1377         break;
1378     }
1379 }
1380 
1381 /* if d == OR_TMP0, it means memory operand (address in A0) */
gen_inc(DisasContext * s1,int ot,int d,int c)1382 static void gen_inc(DisasContext *s1, int ot, int d, int c)
1383 {
1384     if (d != OR_TMP0)
1385         gen_op_mov_TN_reg(ot, 0, d);
1386     else
1387         gen_op_ld_T0_A0(ot + s1->mem_index);
1388     if (s1->cc_op != CC_OP_DYNAMIC)
1389         gen_op_set_cc_op(s1->cc_op);
1390     if (c > 0) {
1391         tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1392         s1->cc_op = CC_OP_INCB + ot;
1393     } else {
1394         tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1395         s1->cc_op = CC_OP_DECB + ot;
1396     }
1397     if (d != OR_TMP0)
1398         gen_op_mov_reg_T0(ot, d);
1399     else
1400         gen_op_st_T0_A0(ot + s1->mem_index);
1401     gen_compute_eflags_c(cpu_cc_src);
1402     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1403 }
1404 
gen_shift_rm_T1(DisasContext * s,int ot,int op1,int is_right,int is_arith)1405 static void gen_shift_rm_T1(DisasContext *s, int ot, int op1,
1406                             int is_right, int is_arith)
1407 {
1408     target_ulong mask;
1409     int shift_label;
1410     TCGv t0, t1;
1411 
1412     if (ot == OT_QUAD)
1413         mask = 0x3f;
1414     else
1415         mask = 0x1f;
1416 
1417     /* load */
1418     if (op1 == OR_TMP0)
1419         gen_op_ld_T0_A0(ot + s->mem_index);
1420     else
1421         gen_op_mov_TN_reg(ot, 0, op1);
1422 
1423     tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1424 
1425     tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1);
1426 
1427     if (is_right) {
1428         if (is_arith) {
1429             gen_exts(ot, cpu_T[0]);
1430             tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1431             tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1432         } else {
1433             gen_extu(ot, cpu_T[0]);
1434             tcg_gen_shr_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1435             tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1436         }
1437     } else {
1438         tcg_gen_shl_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1439         tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1440     }
1441 
1442     /* store */
1443     if (op1 == OR_TMP0)
1444         gen_op_st_T0_A0(ot + s->mem_index);
1445     else
1446         gen_op_mov_reg_T0(ot, op1);
1447 
1448     /* update eflags if non zero shift */
1449     if (s->cc_op != CC_OP_DYNAMIC)
1450         gen_op_set_cc_op(s->cc_op);
1451 
1452     /* XXX: inefficient */
1453     t0 = tcg_temp_local_new();
1454     t1 = tcg_temp_local_new();
1455 
1456     tcg_gen_mov_tl(t0, cpu_T[0]);
1457     tcg_gen_mov_tl(t1, cpu_T3);
1458 
1459     shift_label = gen_new_label();
1460     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, shift_label);
1461 
1462     tcg_gen_mov_tl(cpu_cc_src, t1);
1463     tcg_gen_mov_tl(cpu_cc_dst, t0);
1464     if (is_right)
1465         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1466     else
1467         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1468 
1469     gen_set_label(shift_label);
1470     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1471 
1472     tcg_temp_free(t0);
1473     tcg_temp_free(t1);
1474 }
1475 
gen_shift_rm_im(DisasContext * s,int ot,int op1,int op2,int is_right,int is_arith)1476 static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
1477                             int is_right, int is_arith)
1478 {
1479     int mask;
1480 
1481     if (ot == OT_QUAD)
1482         mask = 0x3f;
1483     else
1484         mask = 0x1f;
1485 
1486     /* load */
1487     if (op1 == OR_TMP0)
1488         gen_op_ld_T0_A0(ot + s->mem_index);
1489     else
1490         gen_op_mov_TN_reg(ot, 0, op1);
1491 
1492     op2 &= mask;
1493     if (op2 != 0) {
1494         if (is_right) {
1495             if (is_arith) {
1496                 gen_exts(ot, cpu_T[0]);
1497                 tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1498                 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1499             } else {
1500                 gen_extu(ot, cpu_T[0]);
1501                 tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1502                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1503             }
1504         } else {
1505             tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1506             tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1507         }
1508     }
1509 
1510     /* store */
1511     if (op1 == OR_TMP0)
1512         gen_op_st_T0_A0(ot + s->mem_index);
1513     else
1514         gen_op_mov_reg_T0(ot, op1);
1515 
1516     /* update eflags if non zero shift */
1517     if (op2 != 0) {
1518         tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1519         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1520         if (is_right)
1521             s->cc_op = CC_OP_SARB + ot;
1522         else
1523             s->cc_op = CC_OP_SHLB + ot;
1524     }
1525 }
1526 
tcg_gen_lshift(TCGv ret,TCGv arg1,target_long arg2)1527 static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
1528 {
1529     if (arg2 >= 0)
1530         tcg_gen_shli_tl(ret, arg1, arg2);
1531     else
1532         tcg_gen_shri_tl(ret, arg1, -arg2);
1533 }
1534 
gen_rot_rm_T1(DisasContext * s,int ot,int op1,int is_right)1535 static void gen_rot_rm_T1(DisasContext *s, int ot, int op1,
1536                           int is_right)
1537 {
1538     target_ulong mask;
1539     int label1, label2, data_bits;
1540     TCGv t0, t1, t2, a0;
1541 
1542     /* XXX: inefficient, but we must use local temps */
1543     t0 = tcg_temp_local_new();
1544     t1 = tcg_temp_local_new();
1545     t2 = tcg_temp_local_new();
1546     a0 = tcg_temp_local_new();
1547 
1548     if (ot == OT_QUAD)
1549         mask = 0x3f;
1550     else
1551         mask = 0x1f;
1552 
1553     /* load */
1554     if (op1 == OR_TMP0) {
1555         tcg_gen_mov_tl(a0, cpu_A0);
1556         gen_op_ld_v(ot + s->mem_index, t0, a0);
1557     } else {
1558         gen_op_mov_v_reg(ot, t0, op1);
1559     }
1560 
1561     tcg_gen_mov_tl(t1, cpu_T[1]);
1562 
1563     tcg_gen_andi_tl(t1, t1, mask);
1564 
1565     /* Must test zero case to avoid using undefined behaviour in TCG
1566        shifts. */
1567     label1 = gen_new_label();
1568     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1);
1569 
1570     if (ot <= OT_WORD)
1571         tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1);
1572     else
1573         tcg_gen_mov_tl(cpu_tmp0, t1);
1574 
1575     gen_extu(ot, t0);
1576     tcg_gen_mov_tl(t2, t0);
1577 
1578     data_bits = 8 << ot;
1579     /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1580        fix TCG definition) */
1581     if (is_right) {
1582         tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
1583         tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1584         tcg_gen_shl_tl(t0, t0, cpu_tmp0);
1585     } else {
1586         tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
1587         tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
1588         tcg_gen_shr_tl(t0, t0, cpu_tmp0);
1589     }
1590     tcg_gen_or_tl(t0, t0, cpu_tmp4);
1591 
1592     gen_set_label(label1);
1593     /* store */
1594     if (op1 == OR_TMP0) {
1595         gen_op_st_v(ot + s->mem_index, t0, a0);
1596     } else {
1597         gen_op_mov_reg_v(ot, op1, t0);
1598     }
1599 
1600     /* update eflags */
1601     if (s->cc_op != CC_OP_DYNAMIC)
1602         gen_op_set_cc_op(s->cc_op);
1603 
1604     label2 = gen_new_label();
1605     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
1606 
1607     gen_compute_eflags(cpu_cc_src);
1608     tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1609     tcg_gen_xor_tl(cpu_tmp0, t2, t0);
1610     tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1611     tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1612     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1613     if (is_right) {
1614         tcg_gen_shri_tl(t0, t0, data_bits - 1);
1615     }
1616     tcg_gen_andi_tl(t0, t0, CC_C);
1617     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1618 
1619     tcg_gen_discard_tl(cpu_cc_dst);
1620     tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1621 
1622     gen_set_label(label2);
1623     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1624 
1625     tcg_temp_free(t0);
1626     tcg_temp_free(t1);
1627     tcg_temp_free(t2);
1628     tcg_temp_free(a0);
1629 }
1630 
gen_rot_rm_im(DisasContext * s,int ot,int op1,int op2,int is_right)1631 static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
1632                           int is_right)
1633 {
1634     int mask;
1635     int data_bits;
1636     TCGv t0, t1, a0;
1637 
1638     /* XXX: inefficient, but we must use local temps */
1639     t0 = tcg_temp_local_new();
1640     t1 = tcg_temp_local_new();
1641     a0 = tcg_temp_local_new();
1642 
1643     if (ot == OT_QUAD)
1644         mask = 0x3f;
1645     else
1646         mask = 0x1f;
1647 
1648     /* load */
1649     if (op1 == OR_TMP0) {
1650         tcg_gen_mov_tl(a0, cpu_A0);
1651         gen_op_ld_v(ot + s->mem_index, t0, a0);
1652     } else {
1653         gen_op_mov_v_reg(ot, t0, op1);
1654     }
1655 
1656     gen_extu(ot, t0);
1657     tcg_gen_mov_tl(t1, t0);
1658 
1659     op2 &= mask;
1660     data_bits = 8 << ot;
1661     if (op2 != 0) {
1662         int shift = op2 & ((1 << (3 + ot)) - 1);
1663         if (is_right) {
1664             tcg_gen_shri_tl(cpu_tmp4, t0, shift);
1665             tcg_gen_shli_tl(t0, t0, data_bits - shift);
1666         }
1667         else {
1668             tcg_gen_shli_tl(cpu_tmp4, t0, shift);
1669             tcg_gen_shri_tl(t0, t0, data_bits - shift);
1670         }
1671         tcg_gen_or_tl(t0, t0, cpu_tmp4);
1672     }
1673 
1674     /* store */
1675     if (op1 == OR_TMP0) {
1676         gen_op_st_v(ot + s->mem_index, t0, a0);
1677     } else {
1678         gen_op_mov_reg_v(ot, op1, t0);
1679     }
1680 
1681     if (op2 != 0) {
1682         /* update eflags */
1683         if (s->cc_op != CC_OP_DYNAMIC)
1684             gen_op_set_cc_op(s->cc_op);
1685 
1686         gen_compute_eflags(cpu_cc_src);
1687         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1688         tcg_gen_xor_tl(cpu_tmp0, t1, t0);
1689         tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1690         tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1691         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1692         if (is_right) {
1693             tcg_gen_shri_tl(t0, t0, data_bits - 1);
1694         }
1695         tcg_gen_andi_tl(t0, t0, CC_C);
1696         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
1697 
1698         tcg_gen_discard_tl(cpu_cc_dst);
1699         tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1700         s->cc_op = CC_OP_EFLAGS;
1701     }
1702 
1703     tcg_temp_free(t0);
1704     tcg_temp_free(t1);
1705     tcg_temp_free(a0);
1706 }
1707 
1708 /* XXX: add faster immediate = 1 case */
gen_rotc_rm_T1(DisasContext * s,int ot,int op1,int is_right)1709 static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1,
1710                            int is_right)
1711 {
1712     int label1;
1713 
1714     if (s->cc_op != CC_OP_DYNAMIC)
1715         gen_op_set_cc_op(s->cc_op);
1716 
1717     /* load */
1718     if (op1 == OR_TMP0)
1719         gen_op_ld_T0_A0(ot + s->mem_index);
1720     else
1721         gen_op_mov_TN_reg(ot, 0, op1);
1722 
1723     if (is_right) {
1724         switch (ot) {
1725         case 0: gen_helper_rcrb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1726         case 1: gen_helper_rcrw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1727         case 2: gen_helper_rcrl(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1728 #ifdef TARGET_X86_64
1729         case 3: gen_helper_rcrq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1730 #endif
1731         }
1732     } else {
1733         switch (ot) {
1734         case 0: gen_helper_rclb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1735         case 1: gen_helper_rclw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1736         case 2: gen_helper_rcll(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1737 #ifdef TARGET_X86_64
1738         case 3: gen_helper_rclq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
1739 #endif
1740         }
1741     }
1742     /* store */
1743     if (op1 == OR_TMP0)
1744         gen_op_st_T0_A0(ot + s->mem_index);
1745     else
1746         gen_op_mov_reg_T0(ot, op1);
1747 
1748     /* update eflags */
1749     label1 = gen_new_label();
1750     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_tmp, -1, label1);
1751 
1752     tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp);
1753     tcg_gen_discard_tl(cpu_cc_dst);
1754     tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1755 
1756     gen_set_label(label1);
1757     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1758 }
1759 
1760 /* XXX: add faster immediate case */
gen_shiftd_rm_T1_T3(DisasContext * s,int ot,int op1,int is_right)1761 static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1,
1762                                 int is_right)
1763 {
1764     int label1, label2, data_bits;
1765     target_ulong mask;
1766     TCGv t0, t1, t2, a0;
1767 
1768     t0 = tcg_temp_local_new();
1769     t1 = tcg_temp_local_new();
1770     t2 = tcg_temp_local_new();
1771     a0 = tcg_temp_local_new();
1772 
1773     if (ot == OT_QUAD)
1774         mask = 0x3f;
1775     else
1776         mask = 0x1f;
1777 
1778     /* load */
1779     if (op1 == OR_TMP0) {
1780         tcg_gen_mov_tl(a0, cpu_A0);
1781         gen_op_ld_v(ot + s->mem_index, t0, a0);
1782     } else {
1783         gen_op_mov_v_reg(ot, t0, op1);
1784     }
1785 
1786     tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
1787 
1788     tcg_gen_mov_tl(t1, cpu_T[1]);
1789     tcg_gen_mov_tl(t2, cpu_T3);
1790 
1791     /* Must test zero case to avoid using undefined behaviour in TCG
1792        shifts. */
1793     label1 = gen_new_label();
1794     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
1795 
1796     tcg_gen_addi_tl(cpu_tmp5, t2, -1);
1797     if (ot == OT_WORD) {
1798         /* Note: we implement the Intel behaviour for shift count > 16 */
1799         if (is_right) {
1800             tcg_gen_andi_tl(t0, t0, 0xffff);
1801             tcg_gen_shli_tl(cpu_tmp0, t1, 16);
1802             tcg_gen_or_tl(t0, t0, cpu_tmp0);
1803             tcg_gen_ext32u_tl(t0, t0);
1804 
1805             tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1806 
1807             /* only needed if count > 16, but a test would complicate */
1808             tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1809             tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
1810 
1811             tcg_gen_shr_tl(t0, t0, t2);
1812 
1813             tcg_gen_or_tl(t0, t0, cpu_tmp0);
1814         } else {
1815             /* XXX: not optimal */
1816             tcg_gen_andi_tl(t0, t0, 0xffff);
1817             tcg_gen_shli_tl(t1, t1, 16);
1818             tcg_gen_or_tl(t1, t1, t0);
1819             tcg_gen_ext32u_tl(t1, t1);
1820 
1821             tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1822             tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
1823             tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0);
1824             tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp5);
1825 
1826             tcg_gen_shl_tl(t0, t0, t2);
1827             tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
1828             tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1829             tcg_gen_or_tl(t0, t0, t1);
1830         }
1831     } else {
1832         data_bits = 8 << ot;
1833         if (is_right) {
1834             if (ot == OT_LONG)
1835                 tcg_gen_ext32u_tl(t0, t0);
1836 
1837             tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
1838 
1839             tcg_gen_shr_tl(t0, t0, t2);
1840             tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1841             tcg_gen_shl_tl(t1, t1, cpu_tmp5);
1842             tcg_gen_or_tl(t0, t0, t1);
1843 
1844         } else {
1845             if (ot == OT_LONG)
1846                 tcg_gen_ext32u_tl(t1, t1);
1847 
1848             tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
1849 
1850             tcg_gen_shl_tl(t0, t0, t2);
1851             tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
1852             tcg_gen_shr_tl(t1, t1, cpu_tmp5);
1853             tcg_gen_or_tl(t0, t0, t1);
1854         }
1855     }
1856     tcg_gen_mov_tl(t1, cpu_tmp4);
1857 
1858     gen_set_label(label1);
1859     /* store */
1860     if (op1 == OR_TMP0) {
1861         gen_op_st_v(ot + s->mem_index, t0, a0);
1862     } else {
1863         gen_op_mov_reg_v(ot, op1, t0);
1864     }
1865 
1866     /* update eflags */
1867     if (s->cc_op != CC_OP_DYNAMIC)
1868         gen_op_set_cc_op(s->cc_op);
1869 
1870     label2 = gen_new_label();
1871     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
1872 
1873     tcg_gen_mov_tl(cpu_cc_src, t1);
1874     tcg_gen_mov_tl(cpu_cc_dst, t0);
1875     if (is_right) {
1876         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1877     } else {
1878         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1879     }
1880     gen_set_label(label2);
1881     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1882 
1883     tcg_temp_free(t0);
1884     tcg_temp_free(t1);
1885     tcg_temp_free(t2);
1886     tcg_temp_free(a0);
1887 }
1888 
gen_shift(DisasContext * s1,int op,int ot,int d,int s)1889 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
1890 {
1891     if (s != OR_TMP1)
1892         gen_op_mov_TN_reg(ot, 1, s);
1893     switch(op) {
1894     case OP_ROL:
1895         gen_rot_rm_T1(s1, ot, d, 0);
1896         break;
1897     case OP_ROR:
1898         gen_rot_rm_T1(s1, ot, d, 1);
1899         break;
1900     case OP_SHL:
1901     case OP_SHL1:
1902         gen_shift_rm_T1(s1, ot, d, 0, 0);
1903         break;
1904     case OP_SHR:
1905         gen_shift_rm_T1(s1, ot, d, 1, 0);
1906         break;
1907     case OP_SAR:
1908         gen_shift_rm_T1(s1, ot, d, 1, 1);
1909         break;
1910     case OP_RCL:
1911         gen_rotc_rm_T1(s1, ot, d, 0);
1912         break;
1913     case OP_RCR:
1914         gen_rotc_rm_T1(s1, ot, d, 1);
1915         break;
1916     }
1917 }
1918 
gen_shifti(DisasContext * s1,int op,int ot,int d,int c)1919 static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
1920 {
1921     switch(op) {
1922     case OP_ROL:
1923         gen_rot_rm_im(s1, ot, d, c, 0);
1924         break;
1925     case OP_ROR:
1926         gen_rot_rm_im(s1, ot, d, c, 1);
1927         break;
1928     case OP_SHL:
1929     case OP_SHL1:
1930         gen_shift_rm_im(s1, ot, d, c, 0, 0);
1931         break;
1932     case OP_SHR:
1933         gen_shift_rm_im(s1, ot, d, c, 1, 0);
1934         break;
1935     case OP_SAR:
1936         gen_shift_rm_im(s1, ot, d, c, 1, 1);
1937         break;
1938     default:
1939         /* currently not optimized */
1940         gen_op_movl_T1_im(c);
1941         gen_shift(s1, op, ot, d, OR_TMP1);
1942         break;
1943     }
1944 }
1945 
gen_lea_modrm(DisasContext * s,int modrm,int * reg_ptr,int * offset_ptr)1946 static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
1947 {
1948     target_long disp;
1949     int havesib;
1950     int base;
1951     int index;
1952     int scale;
1953     int opreg;
1954     int mod, rm, code, override, must_add_seg;
1955 
1956     override = s->override;
1957     must_add_seg = s->addseg;
1958     if (override >= 0)
1959         must_add_seg = 1;
1960     mod = (modrm >> 6) & 3;
1961     rm = modrm & 7;
1962 
1963     if (s->aflag) {
1964 
1965         havesib = 0;
1966         base = rm;
1967         index = 0;
1968         scale = 0;
1969 
1970         if (base == 4) {
1971             havesib = 1;
1972             code = ldub_code(s->pc++);
1973             scale = (code >> 6) & 3;
1974             index = ((code >> 3) & 7) | REX_X(s);
1975             base = (code & 7);
1976         }
1977         base |= REX_B(s);
1978 
1979         switch (mod) {
1980         case 0:
1981             if ((base & 7) == 5) {
1982                 base = -1;
1983                 disp = (int32_t)ldl_code(s->pc);
1984                 s->pc += 4;
1985                 if (CODE64(s) && !havesib) {
1986                     disp += s->pc + s->rip_offset;
1987                 }
1988             } else {
1989                 disp = 0;
1990             }
1991             break;
1992         case 1:
1993             disp = (int8_t)ldub_code(s->pc++);
1994             break;
1995         default:
1996         case 2:
1997             disp = (int32_t)ldl_code(s->pc);
1998             s->pc += 4;
1999             break;
2000         }
2001 
2002         if (base >= 0) {
2003             /* for correct popl handling with esp */
2004             if (base == 4 && s->popl_esp_hack)
2005                 disp += s->popl_esp_hack;
2006 #ifdef TARGET_X86_64
2007             if (s->aflag == 2) {
2008                 gen_op_movq_A0_reg(base);
2009                 if (disp != 0) {
2010                     gen_op_addq_A0_im(disp);
2011                 }
2012             } else
2013 #endif
2014             {
2015                 gen_op_movl_A0_reg(base);
2016                 if (disp != 0)
2017                     gen_op_addl_A0_im(disp);
2018             }
2019         } else {
2020 #ifdef TARGET_X86_64
2021             if (s->aflag == 2) {
2022                 gen_op_movq_A0_im(disp);
2023             } else
2024 #endif
2025             {
2026                 gen_op_movl_A0_im(disp);
2027             }
2028         }
2029         /* index == 4 means no index */
2030         if (havesib && (index != 4)) {
2031 #ifdef TARGET_X86_64
2032             if (s->aflag == 2) {
2033                 gen_op_addq_A0_reg_sN(scale, index);
2034             } else
2035 #endif
2036             {
2037                 gen_op_addl_A0_reg_sN(scale, index);
2038             }
2039         }
2040         if (must_add_seg) {
2041             if (override < 0) {
2042                 if (base == R_EBP || base == R_ESP)
2043                     override = R_SS;
2044                 else
2045                     override = R_DS;
2046             }
2047 #ifdef TARGET_X86_64
2048             if (s->aflag == 2) {
2049                 gen_op_addq_A0_seg(override);
2050             } else
2051 #endif
2052             {
2053                 gen_op_addl_A0_seg(override);
2054             }
2055         }
2056     } else {
2057         switch (mod) {
2058         case 0:
2059             if (rm == 6) {
2060                 disp = lduw_code(s->pc);
2061                 s->pc += 2;
2062                 gen_op_movl_A0_im(disp);
2063                 rm = 0; /* avoid SS override */
2064                 goto no_rm;
2065             } else {
2066                 disp = 0;
2067             }
2068             break;
2069         case 1:
2070             disp = (int8_t)ldub_code(s->pc++);
2071             break;
2072         default:
2073         case 2:
2074             disp = lduw_code(s->pc);
2075             s->pc += 2;
2076             break;
2077         }
2078         switch(rm) {
2079         case 0:
2080             gen_op_movl_A0_reg(R_EBX);
2081             gen_op_addl_A0_reg_sN(0, R_ESI);
2082             break;
2083         case 1:
2084             gen_op_movl_A0_reg(R_EBX);
2085             gen_op_addl_A0_reg_sN(0, R_EDI);
2086             break;
2087         case 2:
2088             gen_op_movl_A0_reg(R_EBP);
2089             gen_op_addl_A0_reg_sN(0, R_ESI);
2090             break;
2091         case 3:
2092             gen_op_movl_A0_reg(R_EBP);
2093             gen_op_addl_A0_reg_sN(0, R_EDI);
2094             break;
2095         case 4:
2096             gen_op_movl_A0_reg(R_ESI);
2097             break;
2098         case 5:
2099             gen_op_movl_A0_reg(R_EDI);
2100             break;
2101         case 6:
2102             gen_op_movl_A0_reg(R_EBP);
2103             break;
2104         default:
2105         case 7:
2106             gen_op_movl_A0_reg(R_EBX);
2107             break;
2108         }
2109         if (disp != 0)
2110             gen_op_addl_A0_im(disp);
2111         gen_op_andl_A0_ffff();
2112     no_rm:
2113         if (must_add_seg) {
2114             if (override < 0) {
2115                 if (rm == 2 || rm == 3 || rm == 6)
2116                     override = R_SS;
2117                 else
2118                     override = R_DS;
2119             }
2120             gen_op_addl_A0_seg(override);
2121         }
2122     }
2123 
2124     opreg = OR_A0;
2125     disp = 0;
2126     *reg_ptr = opreg;
2127     *offset_ptr = disp;
2128 }
2129 
gen_nop_modrm(DisasContext * s,int modrm)2130 static void gen_nop_modrm(DisasContext *s, int modrm)
2131 {
2132     int mod, rm, base, code;
2133 
2134     mod = (modrm >> 6) & 3;
2135     if (mod == 3)
2136         return;
2137     rm = modrm & 7;
2138 
2139     if (s->aflag) {
2140 
2141         base = rm;
2142 
2143         if (base == 4) {
2144             code = ldub_code(s->pc++);
2145             base = (code & 7);
2146         }
2147 
2148         switch (mod) {
2149         case 0:
2150             if (base == 5) {
2151                 s->pc += 4;
2152             }
2153             break;
2154         case 1:
2155             s->pc++;
2156             break;
2157         default:
2158         case 2:
2159             s->pc += 4;
2160             break;
2161         }
2162     } else {
2163         switch (mod) {
2164         case 0:
2165             if (rm == 6) {
2166                 s->pc += 2;
2167             }
2168             break;
2169         case 1:
2170             s->pc++;
2171             break;
2172         default:
2173         case 2:
2174             s->pc += 2;
2175             break;
2176         }
2177     }
2178 }
2179 
2180 /* used for LEA and MOV AX, mem */
gen_add_A0_ds_seg(DisasContext * s)2181 static void gen_add_A0_ds_seg(DisasContext *s)
2182 {
2183     int override, must_add_seg;
2184     must_add_seg = s->addseg;
2185     override = R_DS;
2186     if (s->override >= 0) {
2187         override = s->override;
2188         must_add_seg = 1;
2189     }
2190     if (must_add_seg) {
2191 #ifdef TARGET_X86_64
2192         if (CODE64(s)) {
2193             gen_op_addq_A0_seg(override);
2194         } else
2195 #endif
2196         {
2197             gen_op_addl_A0_seg(override);
2198         }
2199     }
2200 }
2201 
2202 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2203    OR_TMP0 */
gen_ldst_modrm(DisasContext * s,int modrm,int ot,int reg,int is_store)2204 static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
2205 {
2206     int mod, rm, opreg, disp;
2207 
2208     mod = (modrm >> 6) & 3;
2209     rm = (modrm & 7) | REX_B(s);
2210     if (mod == 3) {
2211         if (is_store) {
2212             if (reg != OR_TMP0)
2213                 gen_op_mov_TN_reg(ot, 0, reg);
2214             gen_op_mov_reg_T0(ot, rm);
2215         } else {
2216             gen_op_mov_TN_reg(ot, 0, rm);
2217             if (reg != OR_TMP0)
2218                 gen_op_mov_reg_T0(ot, reg);
2219         }
2220     } else {
2221         gen_lea_modrm(s, modrm, &opreg, &disp);
2222         if (is_store) {
2223             if (reg != OR_TMP0)
2224                 gen_op_mov_TN_reg(ot, 0, reg);
2225             gen_op_st_T0_A0(ot + s->mem_index);
2226         } else {
2227             gen_op_ld_T0_A0(ot + s->mem_index);
2228             if (reg != OR_TMP0)
2229                 gen_op_mov_reg_T0(ot, reg);
2230         }
2231     }
2232 }
2233 
insn_get(DisasContext * s,int ot)2234 static inline uint32_t insn_get(DisasContext *s, int ot)
2235 {
2236     uint32_t ret;
2237 
2238     switch(ot) {
2239     case OT_BYTE:
2240         ret = ldub_code(s->pc);
2241         s->pc++;
2242         break;
2243     case OT_WORD:
2244         ret = lduw_code(s->pc);
2245         s->pc += 2;
2246         break;
2247     default:
2248     case OT_LONG:
2249         ret = ldl_code(s->pc);
2250         s->pc += 4;
2251         break;
2252     }
2253     return ret;
2254 }
2255 
insn_const_size(unsigned int ot)2256 static inline int insn_const_size(unsigned int ot)
2257 {
2258     if (ot <= OT_LONG)
2259         return 1 << ot;
2260     else
2261         return 4;
2262 }
2263 
gen_goto_tb(DisasContext * s,int tb_num,target_ulong eip)2264 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2265 {
2266     TranslationBlock *tb;
2267     target_ulong pc;
2268 
2269     pc = s->cs_base + eip;
2270     tb = s->tb;
2271     /* NOTE: we handle the case where the TB spans two pages here */
2272     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2273         (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
2274         /* jump to same page: we can use a direct jump */
2275         tcg_gen_goto_tb(tb_num);
2276         gen_jmp_im(eip);
2277         tcg_gen_exit_tb((long)tb + tb_num);
2278     } else {
2279         /* jump to another page: currently not optimized */
2280         gen_jmp_im(eip);
2281         gen_eob(s);
2282     }
2283 }
2284 
gen_jcc(DisasContext * s,int b,target_ulong val,target_ulong next_eip)2285 static inline void gen_jcc(DisasContext *s, int b,
2286                            target_ulong val, target_ulong next_eip)
2287 {
2288     int l1, l2, cc_op;
2289 
2290     cc_op = s->cc_op;
2291     gen_update_cc_op(s);
2292     if (s->jmp_opt) {
2293         l1 = gen_new_label();
2294         gen_jcc1(s, cc_op, b, l1);
2295 
2296         gen_goto_tb(s, 0, next_eip);
2297 
2298         gen_set_label(l1);
2299         gen_goto_tb(s, 1, val);
2300         s->is_jmp = DISAS_TB_JUMP;
2301     } else {
2302 
2303         l1 = gen_new_label();
2304         l2 = gen_new_label();
2305         gen_jcc1(s, cc_op, b, l1);
2306 
2307         gen_jmp_im(next_eip);
2308         tcg_gen_br(l2);
2309 
2310         gen_set_label(l1);
2311         gen_jmp_im(val);
2312         gen_set_label(l2);
2313         gen_eob(s);
2314     }
2315 }
2316 
gen_setcc(DisasContext * s,int b)2317 static void gen_setcc(DisasContext *s, int b)
2318 {
2319     int inv, jcc_op, l1;
2320     TCGv t0;
2321 
2322     if (is_fast_jcc_case(s, b)) {
2323         /* nominal case: we use a jump */
2324         /* XXX: make it faster by adding new instructions in TCG */
2325         t0 = tcg_temp_local_new();
2326         tcg_gen_movi_tl(t0, 0);
2327         l1 = gen_new_label();
2328         gen_jcc1(s, s->cc_op, b ^ 1, l1);
2329         tcg_gen_movi_tl(t0, 1);
2330         gen_set_label(l1);
2331         tcg_gen_mov_tl(cpu_T[0], t0);
2332         tcg_temp_free(t0);
2333     } else {
2334         /* slow case: it is more efficient not to generate a jump,
2335            although it is questionnable whether this optimization is
2336            worth to */
2337         inv = b & 1;
2338         jcc_op = (b >> 1) & 7;
2339         gen_setcc_slow_T0(s, jcc_op);
2340         if (inv) {
2341             tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1);
2342         }
2343     }
2344 }
2345 
gen_op_movl_T0_seg(int seg_reg)2346 static inline void gen_op_movl_T0_seg(int seg_reg)
2347 {
2348     tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
2349                      offsetof(CPUX86State,segs[seg_reg].selector));
2350 }
2351 
gen_op_movl_seg_T0_vm(int seg_reg)2352 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2353 {
2354     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2355     tcg_gen_st32_tl(cpu_T[0], cpu_env,
2356                     offsetof(CPUX86State,segs[seg_reg].selector));
2357     tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2358     tcg_gen_st_tl(cpu_T[0], cpu_env,
2359                   offsetof(CPUX86State,segs[seg_reg].base));
2360 }
2361 
2362 /* move T0 to seg_reg and compute if the CPU state may change. Never
2363    call this function with seg_reg == R_CS */
gen_movl_seg_T0(DisasContext * s,int seg_reg,target_ulong cur_eip)2364 static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
2365 {
2366     if (s->pe && !s->vm86) {
2367         /* XXX: optimize by finding processor state dynamically */
2368         if (s->cc_op != CC_OP_DYNAMIC)
2369             gen_op_set_cc_op(s->cc_op);
2370         gen_jmp_im(cur_eip);
2371         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2372         gen_helper_load_seg(tcg_const_i32(seg_reg), cpu_tmp2_i32);
2373         /* abort translation because the addseg value may change or
2374            because ss32 may change. For R_SS, translation must always
2375            stop as a special handling must be done to disable hardware
2376            interrupts for the next instruction */
2377         if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2378             s->is_jmp = DISAS_TB_JUMP;
2379     } else {
2380         gen_op_movl_seg_T0_vm(seg_reg);
2381         if (seg_reg == R_SS)
2382             s->is_jmp = DISAS_TB_JUMP;
2383     }
2384 }
2385 
svm_is_rep(int prefixes)2386 static inline int svm_is_rep(int prefixes)
2387 {
2388     return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2389 }
2390 
2391 static inline void
gen_svm_check_intercept_param(DisasContext * s,target_ulong pc_start,uint32_t type,uint64_t param)2392 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2393                               uint32_t type, uint64_t param)
2394 {
2395     /* no SVM activated; fast case */
2396     if (likely(!(s->flags & HF_SVMI_MASK)))
2397         return;
2398     if (s->cc_op != CC_OP_DYNAMIC)
2399         gen_op_set_cc_op(s->cc_op);
2400     gen_jmp_im(pc_start - s->cs_base);
2401     gen_helper_svm_check_intercept_param(tcg_const_i32(type),
2402                                          tcg_const_i64(param));
2403 }
2404 
2405 static inline void
gen_svm_check_intercept(DisasContext * s,target_ulong pc_start,uint64_t type)2406 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2407 {
2408     gen_svm_check_intercept_param(s, pc_start, type, 0);
2409 }
2410 
gen_stack_update(DisasContext * s,int addend)2411 static inline void gen_stack_update(DisasContext *s, int addend)
2412 {
2413 #ifdef TARGET_X86_64
2414     if (CODE64(s)) {
2415         gen_op_add_reg_im(2, R_ESP, addend);
2416     } else
2417 #endif
2418     if (s->ss32) {
2419         gen_op_add_reg_im(1, R_ESP, addend);
2420     } else {
2421         gen_op_add_reg_im(0, R_ESP, addend);
2422     }
2423 }
2424 
2425 /* generate a push. It depends on ss32, addseg and dflag */
gen_push_T0(DisasContext * s)2426 static void gen_push_T0(DisasContext *s)
2427 {
2428 #ifdef TARGET_X86_64
2429     if (CODE64(s)) {
2430         gen_op_movq_A0_reg(R_ESP);
2431         if (s->dflag) {
2432             gen_op_addq_A0_im(-8);
2433             gen_op_st_T0_A0(OT_QUAD + s->mem_index);
2434         } else {
2435             gen_op_addq_A0_im(-2);
2436             gen_op_st_T0_A0(OT_WORD + s->mem_index);
2437         }
2438         gen_op_mov_reg_A0(2, R_ESP);
2439     } else
2440 #endif
2441     {
2442         gen_op_movl_A0_reg(R_ESP);
2443         if (!s->dflag)
2444             gen_op_addl_A0_im(-2);
2445         else
2446             gen_op_addl_A0_im(-4);
2447         if (s->ss32) {
2448             if (s->addseg) {
2449                 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2450                 gen_op_addl_A0_seg(R_SS);
2451             }
2452         } else {
2453             gen_op_andl_A0_ffff();
2454             tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2455             gen_op_addl_A0_seg(R_SS);
2456         }
2457         gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
2458         if (s->ss32 && !s->addseg)
2459             gen_op_mov_reg_A0(1, R_ESP);
2460         else
2461             gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
2462     }
2463 }
2464 
2465 /* generate a push. It depends on ss32, addseg and dflag */
2466 /* slower version for T1, only used for call Ev */
gen_push_T1(DisasContext * s)2467 static void gen_push_T1(DisasContext *s)
2468 {
2469 #ifdef TARGET_X86_64
2470     if (CODE64(s)) {
2471         gen_op_movq_A0_reg(R_ESP);
2472         if (s->dflag) {
2473             gen_op_addq_A0_im(-8);
2474             gen_op_st_T1_A0(OT_QUAD + s->mem_index);
2475         } else {
2476             gen_op_addq_A0_im(-2);
2477             gen_op_st_T0_A0(OT_WORD + s->mem_index);
2478         }
2479         gen_op_mov_reg_A0(2, R_ESP);
2480     } else
2481 #endif
2482     {
2483         gen_op_movl_A0_reg(R_ESP);
2484         if (!s->dflag)
2485             gen_op_addl_A0_im(-2);
2486         else
2487             gen_op_addl_A0_im(-4);
2488         if (s->ss32) {
2489             if (s->addseg) {
2490                 gen_op_addl_A0_seg(R_SS);
2491             }
2492         } else {
2493             gen_op_andl_A0_ffff();
2494             gen_op_addl_A0_seg(R_SS);
2495         }
2496         gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
2497 
2498         if (s->ss32 && !s->addseg)
2499             gen_op_mov_reg_A0(1, R_ESP);
2500         else
2501             gen_stack_update(s, (-2) << s->dflag);
2502     }
2503 }
2504 
2505 /* two step pop is necessary for precise exceptions */
gen_pop_T0(DisasContext * s)2506 static void gen_pop_T0(DisasContext *s)
2507 {
2508 #ifdef TARGET_X86_64
2509     if (CODE64(s)) {
2510         gen_op_movq_A0_reg(R_ESP);
2511         gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
2512     } else
2513 #endif
2514     {
2515         gen_op_movl_A0_reg(R_ESP);
2516         if (s->ss32) {
2517             if (s->addseg)
2518                 gen_op_addl_A0_seg(R_SS);
2519         } else {
2520             gen_op_andl_A0_ffff();
2521             gen_op_addl_A0_seg(R_SS);
2522         }
2523         gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
2524     }
2525 }
2526 
gen_pop_update(DisasContext * s)2527 static void gen_pop_update(DisasContext *s)
2528 {
2529 #ifdef TARGET_X86_64
2530     if (CODE64(s) && s->dflag) {
2531         gen_stack_update(s, 8);
2532     } else
2533 #endif
2534     {
2535         gen_stack_update(s, 2 << s->dflag);
2536     }
2537 }
2538 
gen_stack_A0(DisasContext * s)2539 static void gen_stack_A0(DisasContext *s)
2540 {
2541     gen_op_movl_A0_reg(R_ESP);
2542     if (!s->ss32)
2543         gen_op_andl_A0_ffff();
2544     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2545     if (s->addseg)
2546         gen_op_addl_A0_seg(R_SS);
2547 }
2548 
2549 /* NOTE: wrap around in 16 bit not fully handled */
gen_pusha(DisasContext * s)2550 static void gen_pusha(DisasContext *s)
2551 {
2552     int i;
2553     gen_op_movl_A0_reg(R_ESP);
2554     gen_op_addl_A0_im(-16 <<  s->dflag);
2555     if (!s->ss32)
2556         gen_op_andl_A0_ffff();
2557     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2558     if (s->addseg)
2559         gen_op_addl_A0_seg(R_SS);
2560     for(i = 0;i < 8; i++) {
2561         gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
2562         gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
2563         gen_op_addl_A0_im(2 <<  s->dflag);
2564     }
2565     gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2566 }
2567 
2568 /* NOTE: wrap around in 16 bit not fully handled */
gen_popa(DisasContext * s)2569 static void gen_popa(DisasContext *s)
2570 {
2571     int i;
2572     gen_op_movl_A0_reg(R_ESP);
2573     if (!s->ss32)
2574         gen_op_andl_A0_ffff();
2575     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2576     tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
2577     if (s->addseg)
2578         gen_op_addl_A0_seg(R_SS);
2579     for(i = 0;i < 8; i++) {
2580         /* ESP is not reloaded */
2581         if (i != 3) {
2582             gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
2583             gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
2584         }
2585         gen_op_addl_A0_im(2 <<  s->dflag);
2586     }
2587     gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2588 }
2589 
gen_enter(DisasContext * s,int esp_addend,int level)2590 static void gen_enter(DisasContext *s, int esp_addend, int level)
2591 {
2592     int ot, opsize;
2593 
2594     level &= 0x1f;
2595 #ifdef TARGET_X86_64
2596     if (CODE64(s)) {
2597         ot = s->dflag ? OT_QUAD : OT_WORD;
2598         opsize = 1 << ot;
2599 
2600         gen_op_movl_A0_reg(R_ESP);
2601         gen_op_addq_A0_im(-opsize);
2602         tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2603 
2604         /* push bp */
2605         gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2606         gen_op_st_T0_A0(ot + s->mem_index);
2607         if (level) {
2608             /* XXX: must save state */
2609             gen_helper_enter64_level(tcg_const_i32(level),
2610                                      tcg_const_i32((ot == OT_QUAD)),
2611                                      cpu_T[1]);
2612         }
2613         gen_op_mov_reg_T1(ot, R_EBP);
2614         tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2615         gen_op_mov_reg_T1(OT_QUAD, R_ESP);
2616     } else
2617 #endif
2618     {
2619         ot = s->dflag + OT_WORD;
2620         opsize = 2 << s->dflag;
2621 
2622         gen_op_movl_A0_reg(R_ESP);
2623         gen_op_addl_A0_im(-opsize);
2624         if (!s->ss32)
2625             gen_op_andl_A0_ffff();
2626         tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2627         if (s->addseg)
2628             gen_op_addl_A0_seg(R_SS);
2629         /* push bp */
2630         gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
2631         gen_op_st_T0_A0(ot + s->mem_index);
2632         if (level) {
2633             /* XXX: must save state */
2634             gen_helper_enter_level(tcg_const_i32(level),
2635                                    tcg_const_i32(s->dflag),
2636                                    cpu_T[1]);
2637         }
2638         gen_op_mov_reg_T1(ot, R_EBP);
2639         tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2640         gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
2641     }
2642 }
2643 
gen_exception(DisasContext * s,int trapno,target_ulong cur_eip)2644 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2645 {
2646     if (s->cc_op != CC_OP_DYNAMIC)
2647         gen_op_set_cc_op(s->cc_op);
2648     gen_jmp_im(cur_eip);
2649     gen_helper_raise_exception(tcg_const_i32(trapno));
2650     s->is_jmp = DISAS_TB_JUMP;
2651 }
2652 
2653 /* an interrupt is different from an exception because of the
2654    privilege checks */
gen_interrupt(DisasContext * s,int intno,target_ulong cur_eip,target_ulong next_eip)2655 static void gen_interrupt(DisasContext *s, int intno,
2656                           target_ulong cur_eip, target_ulong next_eip)
2657 {
2658     if (s->cc_op != CC_OP_DYNAMIC)
2659         gen_op_set_cc_op(s->cc_op);
2660     gen_jmp_im(cur_eip);
2661     gen_helper_raise_interrupt(tcg_const_i32(intno),
2662                                tcg_const_i32(next_eip - cur_eip));
2663     s->is_jmp = DISAS_TB_JUMP;
2664 }
2665 
gen_debug(DisasContext * s,target_ulong cur_eip)2666 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2667 {
2668     if (s->cc_op != CC_OP_DYNAMIC)
2669         gen_op_set_cc_op(s->cc_op);
2670     gen_jmp_im(cur_eip);
2671     gen_helper_debug();
2672     s->is_jmp = DISAS_TB_JUMP;
2673 }
2674 
2675 /* generate a generic end of block. Trace exception is also generated
2676    if needed */
gen_eob(DisasContext * s)2677 static void gen_eob(DisasContext *s)
2678 {
2679     if (s->cc_op != CC_OP_DYNAMIC)
2680         gen_op_set_cc_op(s->cc_op);
2681     if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2682         gen_helper_reset_inhibit_irq();
2683     }
2684     if (s->tb->flags & HF_RF_MASK) {
2685         gen_helper_reset_rf();
2686     }
2687     if (s->singlestep_enabled) {
2688         gen_helper_debug();
2689     } else if (s->tf) {
2690 	gen_helper_single_step();
2691     } else {
2692         tcg_gen_exit_tb(0);
2693     }
2694     s->is_jmp = DISAS_TB_JUMP;
2695 }
2696 
2697 /* generate a jump to eip. No segment change must happen before as a
2698    direct call to the next block may occur */
gen_jmp_tb(DisasContext * s,target_ulong eip,int tb_num)2699 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2700 {
2701     if (s->jmp_opt) {
2702         gen_update_cc_op(s);
2703         gen_goto_tb(s, tb_num, eip);
2704         s->is_jmp = DISAS_TB_JUMP;
2705     } else {
2706         gen_jmp_im(eip);
2707         gen_eob(s);
2708     }
2709 }
2710 
gen_jmp(DisasContext * s,target_ulong eip)2711 static void gen_jmp(DisasContext *s, target_ulong eip)
2712 {
2713     gen_jmp_tb(s, eip, 0);
2714 }
2715 
gen_ldq_env_A0(int idx,int offset)2716 static inline void gen_ldq_env_A0(int idx, int offset)
2717 {
2718     int mem_index = (idx >> 2) - 1;
2719     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2720     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2721 }
2722 
gen_stq_env_A0(int idx,int offset)2723 static inline void gen_stq_env_A0(int idx, int offset)
2724 {
2725     int mem_index = (idx >> 2) - 1;
2726     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2727     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2728 }
2729 
gen_ldo_env_A0(int idx,int offset)2730 static inline void gen_ldo_env_A0(int idx, int offset)
2731 {
2732     int mem_index = (idx >> 2) - 1;
2733     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2734     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2735     tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2736     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2737     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2738 }
2739 
gen_sto_env_A0(int idx,int offset)2740 static inline void gen_sto_env_A0(int idx, int offset)
2741 {
2742     int mem_index = (idx >> 2) - 1;
2743     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2744     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2745     tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2746     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2747     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2748 }
2749 
gen_op_movo(int d_offset,int s_offset)2750 static inline void gen_op_movo(int d_offset, int s_offset)
2751 {
2752     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2753     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2754     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2755     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2756 }
2757 
gen_op_movq(int d_offset,int s_offset)2758 static inline void gen_op_movq(int d_offset, int s_offset)
2759 {
2760     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2761     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2762 }
2763 
gen_op_movl(int d_offset,int s_offset)2764 static inline void gen_op_movl(int d_offset, int s_offset)
2765 {
2766     tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2767     tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2768 }
2769 
gen_op_movq_env_0(int d_offset)2770 static inline void gen_op_movq_env_0(int d_offset)
2771 {
2772     tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2773     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2774 }
2775 
2776 #define SSE_SPECIAL ((void *)1)
2777 #define SSE_DUMMY ((void *)2)
2778 
2779 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2780 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2781                      gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2782 
2783 static void *sse_op_table1[256][4] = {
2784     /* 3DNow! extensions */
2785     [0x0e] = { SSE_DUMMY }, /* femms */
2786     [0x0f] = { SSE_DUMMY }, /* pf... */
2787     /* pure SSE operations */
2788     [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2789     [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2790     [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2791     [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2792     [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2793     [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2794     [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2795     [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2796 
2797     [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2798     [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2799     [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2800     [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2801     [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2802     [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2803     [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2804     [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2805     [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2806     [0x51] = SSE_FOP(sqrt),
2807     [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2808     [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2809     [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2810     [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2811     [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2812     [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2813     [0x58] = SSE_FOP(add),
2814     [0x59] = SSE_FOP(mul),
2815     [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2816                gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2817     [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2818     [0x5c] = SSE_FOP(sub),
2819     [0x5d] = SSE_FOP(min),
2820     [0x5e] = SSE_FOP(div),
2821     [0x5f] = SSE_FOP(max),
2822 
2823     [0xc2] = SSE_FOP(cmpeq),
2824     [0xc6] = { gen_helper_shufps, gen_helper_shufpd },
2825 
2826     [0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2827     [0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
2828 
2829     /* MMX ops and their SSE extensions */
2830     [0x60] = MMX_OP2(punpcklbw),
2831     [0x61] = MMX_OP2(punpcklwd),
2832     [0x62] = MMX_OP2(punpckldq),
2833     [0x63] = MMX_OP2(packsswb),
2834     [0x64] = MMX_OP2(pcmpgtb),
2835     [0x65] = MMX_OP2(pcmpgtw),
2836     [0x66] = MMX_OP2(pcmpgtl),
2837     [0x67] = MMX_OP2(packuswb),
2838     [0x68] = MMX_OP2(punpckhbw),
2839     [0x69] = MMX_OP2(punpckhwd),
2840     [0x6a] = MMX_OP2(punpckhdq),
2841     [0x6b] = MMX_OP2(packssdw),
2842     [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2843     [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2844     [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2845     [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2846     [0x70] = { gen_helper_pshufw_mmx,
2847                gen_helper_pshufd_xmm,
2848                gen_helper_pshufhw_xmm,
2849                gen_helper_pshuflw_xmm },
2850     [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2851     [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2852     [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2853     [0x74] = MMX_OP2(pcmpeqb),
2854     [0x75] = MMX_OP2(pcmpeqw),
2855     [0x76] = MMX_OP2(pcmpeql),
2856     [0x77] = { SSE_DUMMY }, /* emms */
2857     [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2858     [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2859     [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2860     [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2861     [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2862     [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2863     [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2864     [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2865     [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2866     [0xd1] = MMX_OP2(psrlw),
2867     [0xd2] = MMX_OP2(psrld),
2868     [0xd3] = MMX_OP2(psrlq),
2869     [0xd4] = MMX_OP2(paddq),
2870     [0xd5] = MMX_OP2(pmullw),
2871     [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2872     [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2873     [0xd8] = MMX_OP2(psubusb),
2874     [0xd9] = MMX_OP2(psubusw),
2875     [0xda] = MMX_OP2(pminub),
2876     [0xdb] = MMX_OP2(pand),
2877     [0xdc] = MMX_OP2(paddusb),
2878     [0xdd] = MMX_OP2(paddusw),
2879     [0xde] = MMX_OP2(pmaxub),
2880     [0xdf] = MMX_OP2(pandn),
2881     [0xe0] = MMX_OP2(pavgb),
2882     [0xe1] = MMX_OP2(psraw),
2883     [0xe2] = MMX_OP2(psrad),
2884     [0xe3] = MMX_OP2(pavgw),
2885     [0xe4] = MMX_OP2(pmulhuw),
2886     [0xe5] = MMX_OP2(pmulhw),
2887     [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2888     [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2889     [0xe8] = MMX_OP2(psubsb),
2890     [0xe9] = MMX_OP2(psubsw),
2891     [0xea] = MMX_OP2(pminsw),
2892     [0xeb] = MMX_OP2(por),
2893     [0xec] = MMX_OP2(paddsb),
2894     [0xed] = MMX_OP2(paddsw),
2895     [0xee] = MMX_OP2(pmaxsw),
2896     [0xef] = MMX_OP2(pxor),
2897     [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2898     [0xf1] = MMX_OP2(psllw),
2899     [0xf2] = MMX_OP2(pslld),
2900     [0xf3] = MMX_OP2(psllq),
2901     [0xf4] = MMX_OP2(pmuludq),
2902     [0xf5] = MMX_OP2(pmaddwd),
2903     [0xf6] = MMX_OP2(psadbw),
2904     [0xf7] = MMX_OP2(maskmov),
2905     [0xf8] = MMX_OP2(psubb),
2906     [0xf9] = MMX_OP2(psubw),
2907     [0xfa] = MMX_OP2(psubl),
2908     [0xfb] = MMX_OP2(psubq),
2909     [0xfc] = MMX_OP2(paddb),
2910     [0xfd] = MMX_OP2(paddw),
2911     [0xfe] = MMX_OP2(paddl),
2912 };
2913 
2914 static void *sse_op_table2[3 * 8][2] = {
2915     [0 + 2] = MMX_OP2(psrlw),
2916     [0 + 4] = MMX_OP2(psraw),
2917     [0 + 6] = MMX_OP2(psllw),
2918     [8 + 2] = MMX_OP2(psrld),
2919     [8 + 4] = MMX_OP2(psrad),
2920     [8 + 6] = MMX_OP2(pslld),
2921     [16 + 2] = MMX_OP2(psrlq),
2922     [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2923     [16 + 6] = MMX_OP2(psllq),
2924     [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2925 };
2926 
2927 static void *sse_op_table3[4 * 3] = {
2928     gen_helper_cvtsi2ss,
2929     gen_helper_cvtsi2sd,
2930     X86_64_ONLY(gen_helper_cvtsq2ss),
2931     X86_64_ONLY(gen_helper_cvtsq2sd),
2932 
2933     gen_helper_cvttss2si,
2934     gen_helper_cvttsd2si,
2935     X86_64_ONLY(gen_helper_cvttss2sq),
2936     X86_64_ONLY(gen_helper_cvttsd2sq),
2937 
2938     gen_helper_cvtss2si,
2939     gen_helper_cvtsd2si,
2940     X86_64_ONLY(gen_helper_cvtss2sq),
2941     X86_64_ONLY(gen_helper_cvtsd2sq),
2942 };
2943 
2944 static void *sse_op_table4[8][4] = {
2945     SSE_FOP(cmpeq),
2946     SSE_FOP(cmplt),
2947     SSE_FOP(cmple),
2948     SSE_FOP(cmpunord),
2949     SSE_FOP(cmpneq),
2950     SSE_FOP(cmpnlt),
2951     SSE_FOP(cmpnle),
2952     SSE_FOP(cmpord),
2953 };
2954 
2955 static void *sse_op_table5[256] = {
2956     [0x0c] = gen_helper_pi2fw,
2957     [0x0d] = gen_helper_pi2fd,
2958     [0x1c] = gen_helper_pf2iw,
2959     [0x1d] = gen_helper_pf2id,
2960     [0x8a] = gen_helper_pfnacc,
2961     [0x8e] = gen_helper_pfpnacc,
2962     [0x90] = gen_helper_pfcmpge,
2963     [0x94] = gen_helper_pfmin,
2964     [0x96] = gen_helper_pfrcp,
2965     [0x97] = gen_helper_pfrsqrt,
2966     [0x9a] = gen_helper_pfsub,
2967     [0x9e] = gen_helper_pfadd,
2968     [0xa0] = gen_helper_pfcmpgt,
2969     [0xa4] = gen_helper_pfmax,
2970     [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2971     [0xa7] = gen_helper_movq, /* pfrsqit1 */
2972     [0xaa] = gen_helper_pfsubr,
2973     [0xae] = gen_helper_pfacc,
2974     [0xb0] = gen_helper_pfcmpeq,
2975     [0xb4] = gen_helper_pfmul,
2976     [0xb6] = gen_helper_movq, /* pfrcpit2 */
2977     [0xb7] = gen_helper_pmulhrw_mmx,
2978     [0xbb] = gen_helper_pswapd,
2979     [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2980 };
2981 
2982 struct sse_op_helper_s {
2983     void *op[2]; uint32_t ext_mask;
2984 };
2985 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2986 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2987 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2988 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2989 static struct sse_op_helper_s sse_op_table6[256] = {
2990     [0x00] = SSSE3_OP(pshufb),
2991     [0x01] = SSSE3_OP(phaddw),
2992     [0x02] = SSSE3_OP(phaddd),
2993     [0x03] = SSSE3_OP(phaddsw),
2994     [0x04] = SSSE3_OP(pmaddubsw),
2995     [0x05] = SSSE3_OP(phsubw),
2996     [0x06] = SSSE3_OP(phsubd),
2997     [0x07] = SSSE3_OP(phsubsw),
2998     [0x08] = SSSE3_OP(psignb),
2999     [0x09] = SSSE3_OP(psignw),
3000     [0x0a] = SSSE3_OP(psignd),
3001     [0x0b] = SSSE3_OP(pmulhrsw),
3002     [0x10] = SSE41_OP(pblendvb),
3003     [0x14] = SSE41_OP(blendvps),
3004     [0x15] = SSE41_OP(blendvpd),
3005     [0x17] = SSE41_OP(ptest),
3006     [0x1c] = SSSE3_OP(pabsb),
3007     [0x1d] = SSSE3_OP(pabsw),
3008     [0x1e] = SSSE3_OP(pabsd),
3009     [0x20] = SSE41_OP(pmovsxbw),
3010     [0x21] = SSE41_OP(pmovsxbd),
3011     [0x22] = SSE41_OP(pmovsxbq),
3012     [0x23] = SSE41_OP(pmovsxwd),
3013     [0x24] = SSE41_OP(pmovsxwq),
3014     [0x25] = SSE41_OP(pmovsxdq),
3015     [0x28] = SSE41_OP(pmuldq),
3016     [0x29] = SSE41_OP(pcmpeqq),
3017     [0x2a] = SSE41_SPECIAL, /* movntqda */
3018     [0x2b] = SSE41_OP(packusdw),
3019     [0x30] = SSE41_OP(pmovzxbw),
3020     [0x31] = SSE41_OP(pmovzxbd),
3021     [0x32] = SSE41_OP(pmovzxbq),
3022     [0x33] = SSE41_OP(pmovzxwd),
3023     [0x34] = SSE41_OP(pmovzxwq),
3024     [0x35] = SSE41_OP(pmovzxdq),
3025     [0x37] = SSE42_OP(pcmpgtq),
3026     [0x38] = SSE41_OP(pminsb),
3027     [0x39] = SSE41_OP(pminsd),
3028     [0x3a] = SSE41_OP(pminuw),
3029     [0x3b] = SSE41_OP(pminud),
3030     [0x3c] = SSE41_OP(pmaxsb),
3031     [0x3d] = SSE41_OP(pmaxsd),
3032     [0x3e] = SSE41_OP(pmaxuw),
3033     [0x3f] = SSE41_OP(pmaxud),
3034     [0x40] = SSE41_OP(pmulld),
3035     [0x41] = SSE41_OP(phminposuw),
3036 };
3037 
3038 static struct sse_op_helper_s sse_op_table7[256] = {
3039     [0x08] = SSE41_OP(roundps),
3040     [0x09] = SSE41_OP(roundpd),
3041     [0x0a] = SSE41_OP(roundss),
3042     [0x0b] = SSE41_OP(roundsd),
3043     [0x0c] = SSE41_OP(blendps),
3044     [0x0d] = SSE41_OP(blendpd),
3045     [0x0e] = SSE41_OP(pblendw),
3046     [0x0f] = SSSE3_OP(palignr),
3047     [0x14] = SSE41_SPECIAL, /* pextrb */
3048     [0x15] = SSE41_SPECIAL, /* pextrw */
3049     [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3050     [0x17] = SSE41_SPECIAL, /* extractps */
3051     [0x20] = SSE41_SPECIAL, /* pinsrb */
3052     [0x21] = SSE41_SPECIAL, /* insertps */
3053     [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3054     [0x40] = SSE41_OP(dpps),
3055     [0x41] = SSE41_OP(dppd),
3056     [0x42] = SSE41_OP(mpsadbw),
3057     [0x60] = SSE42_OP(pcmpestrm),
3058     [0x61] = SSE42_OP(pcmpestri),
3059     [0x62] = SSE42_OP(pcmpistrm),
3060     [0x63] = SSE42_OP(pcmpistri),
3061 };
3062 
gen_sse(DisasContext * s,int b,target_ulong pc_start,int rex_r)3063 static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
3064 {
3065     int b1, op1_offset, op2_offset, is_xmm, val, ot;
3066     int modrm, mod, rm, reg, reg_addr, offset_addr;
3067     void *sse_op2;
3068 
3069     b &= 0xff;
3070     if (s->prefix & PREFIX_DATA)
3071         b1 = 1;
3072     else if (s->prefix & PREFIX_REPZ)
3073         b1 = 2;
3074     else if (s->prefix & PREFIX_REPNZ)
3075         b1 = 3;
3076     else
3077         b1 = 0;
3078     sse_op2 = sse_op_table1[b][b1];
3079     if (!sse_op2)
3080         goto illegal_op;
3081     if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3082         is_xmm = 1;
3083     } else {
3084         if (b1 == 0) {
3085             /* MMX case */
3086             is_xmm = 0;
3087         } else {
3088             is_xmm = 1;
3089         }
3090     }
3091     /* simple MMX/SSE operation */