xref: /qemu/target/i386/emulate/x86_decode.c (revision c901905ea6703a2feb5867537a8559dc129447f7)
1c97d6d2cSSergio Andres Gomez Del Real /*
2c97d6d2cSSergio Andres Gomez Del Real  * Copyright (C) 2016 Veertu Inc,
3c97d6d2cSSergio Andres Gomez Del Real  * Copyright (C) 2017 Google Inc,
4c97d6d2cSSergio Andres Gomez Del Real  *
5c97d6d2cSSergio Andres Gomez Del Real  * This program is free software; you can redistribute it and/or
6996feed4SSergio Andres Gomez Del Real  * modify it under the terms of the GNU Lesser General Public
7996feed4SSergio Andres Gomez Del Real  * License as published by the Free Software Foundation; either
88af82b8eSChetan Pant  * version 2.1 of the License, or (at your option) any later version.
9c97d6d2cSSergio Andres Gomez Del Real  *
10c97d6d2cSSergio Andres Gomez Del Real  * This program is distributed in the hope that it will be useful,
11c97d6d2cSSergio Andres Gomez Del Real  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12996feed4SSergio Andres Gomez Del Real  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13996feed4SSergio Andres Gomez Del Real  * Lesser General Public License for more details.
14c97d6d2cSSergio Andres Gomez Del Real  *
15996feed4SSergio Andres Gomez Del Real  * You should have received a copy of the GNU Lesser General Public
16996feed4SSergio Andres Gomez Del Real  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
17c97d6d2cSSergio Andres Gomez Del Real  */
18c97d6d2cSSergio Andres Gomez Del Real 
19c97d6d2cSSergio Andres Gomez Del Real #include "qemu/osdep.h"
20c97d6d2cSSergio Andres Gomez Del Real 
21895f9fdfSPaolo Bonzini #include "panic.h"
22c97d6d2cSSergio Andres Gomez Del Real #include "x86_decode.h"
230860abbeSWei Liu #include "x86_emu.h"
24c97d6d2cSSergio Andres Gomez Del Real 
25c97d6d2cSSergio Andres Gomez Del Real #define OPCODE_ESCAPE   0xf
26c97d6d2cSSergio Andres Gomez Del Real 
27c97d6d2cSSergio Andres Gomez Del Real static void decode_invalid(CPUX86State *env, struct x86_decode *decode)
28c97d6d2cSSergio Andres Gomez Del Real {
292d5f696cSRoman Bolshakov     printf("%llx: failed to decode instruction ", env->eip);
30c97d6d2cSSergio Andres Gomez Del Real     for (int i = 0; i < decode->opcode_len; i++) {
31c97d6d2cSSergio Andres Gomez Del Real         printf("%x ", decode->opcode[i]);
32c97d6d2cSSergio Andres Gomez Del Real     }
33c97d6d2cSSergio Andres Gomez Del Real     printf("\n");
34c97d6d2cSSergio Andres Gomez Del Real     VM_PANIC("decoder failed\n");
35c97d6d2cSSergio Andres Gomez Del Real }
36c97d6d2cSSergio Andres Gomez Del Real 
37c97d6d2cSSergio Andres Gomez Del Real uint64_t sign(uint64_t val, int size)
38c97d6d2cSSergio Andres Gomez Del Real {
39c97d6d2cSSergio Andres Gomez Del Real     switch (size) {
40c97d6d2cSSergio Andres Gomez Del Real     case 1:
41c97d6d2cSSergio Andres Gomez Del Real         val = (int8_t)val;
42c97d6d2cSSergio Andres Gomez Del Real         break;
43c97d6d2cSSergio Andres Gomez Del Real     case 2:
44c97d6d2cSSergio Andres Gomez Del Real         val = (int16_t)val;
45c97d6d2cSSergio Andres Gomez Del Real         break;
46c97d6d2cSSergio Andres Gomez Del Real     case 4:
47c97d6d2cSSergio Andres Gomez Del Real         val = (int32_t)val;
48c97d6d2cSSergio Andres Gomez Del Real         break;
49c97d6d2cSSergio Andres Gomez Del Real     case 8:
50c97d6d2cSSergio Andres Gomez Del Real         val = (int64_t)val;
51c97d6d2cSSergio Andres Gomez Del Real         break;
52c97d6d2cSSergio Andres Gomez Del Real     default:
53c97d6d2cSSergio Andres Gomez Del Real         VM_PANIC_EX("%s invalid size %d\n", __func__, size);
54c97d6d2cSSergio Andres Gomez Del Real         break;
55c97d6d2cSSergio Andres Gomez Del Real     }
56c97d6d2cSSergio Andres Gomez Del Real     return val;
57c97d6d2cSSergio Andres Gomez Del Real }
58c97d6d2cSSergio Andres Gomez Del Real 
59c97d6d2cSSergio Andres Gomez Del Real static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode,
60c97d6d2cSSergio Andres Gomez Del Real                                     int size)
61c97d6d2cSSergio Andres Gomez Del Real {
6240b839cbSPhil Dennis-Jordan     uint64_t val = 0;
63c97d6d2cSSergio Andres Gomez Del Real 
64c97d6d2cSSergio Andres Gomez Del Real     switch (size) {
65c97d6d2cSSergio Andres Gomez Del Real     case 1:
66c97d6d2cSSergio Andres Gomez Del Real     case 2:
67c97d6d2cSSergio Andres Gomez Del Real     case 4:
68c97d6d2cSSergio Andres Gomez Del Real     case 8:
69c97d6d2cSSergio Andres Gomez Del Real         break;
70c97d6d2cSSergio Andres Gomez Del Real     default:
71c97d6d2cSSergio Andres Gomez Del Real         VM_PANIC_EX("%s invalid size %d\n", __func__, size);
72c97d6d2cSSergio Andres Gomez Del Real         break;
73c97d6d2cSSergio Andres Gomez Del Real     }
745d32173fSRoman Bolshakov     target_ulong va  = linear_rip(env_cpu(env), env->eip) + decode->len;
750860abbeSWei Liu     emul_ops->read_mem(env_cpu(env), &val, va, size);
76c97d6d2cSSergio Andres Gomez Del Real     decode->len += size;
77c97d6d2cSSergio Andres Gomez Del Real 
78c97d6d2cSSergio Andres Gomez Del Real     return val;
79c97d6d2cSSergio Andres Gomez Del Real }
80c97d6d2cSSergio Andres Gomez Del Real 
81c97d6d2cSSergio Andres Gomez Del Real static inline uint8_t decode_byte(CPUX86State *env, struct x86_decode *decode)
82c97d6d2cSSergio Andres Gomez Del Real {
83c97d6d2cSSergio Andres Gomez Del Real     return (uint8_t)decode_bytes(env, decode, 1);
84c97d6d2cSSergio Andres Gomez Del Real }
85c97d6d2cSSergio Andres Gomez Del Real 
86c97d6d2cSSergio Andres Gomez Del Real static inline uint16_t decode_word(CPUX86State *env, struct x86_decode *decode)
87c97d6d2cSSergio Andres Gomez Del Real {
88c97d6d2cSSergio Andres Gomez Del Real     return (uint16_t)decode_bytes(env, decode, 2);
89c97d6d2cSSergio Andres Gomez Del Real }
90c97d6d2cSSergio Andres Gomez Del Real 
91c97d6d2cSSergio Andres Gomez Del Real static inline uint32_t decode_dword(CPUX86State *env, struct x86_decode *decode)
92c97d6d2cSSergio Andres Gomez Del Real {
93c97d6d2cSSergio Andres Gomez Del Real     return (uint32_t)decode_bytes(env, decode, 4);
94c97d6d2cSSergio Andres Gomez Del Real }
95c97d6d2cSSergio Andres Gomez Del Real 
96c97d6d2cSSergio Andres Gomez Del Real static inline uint64_t decode_qword(CPUX86State *env, struct x86_decode *decode)
97c97d6d2cSSergio Andres Gomez Del Real {
98c97d6d2cSSergio Andres Gomez Del Real     return decode_bytes(env, decode, 8);
99c97d6d2cSSergio Andres Gomez Del Real }
100c97d6d2cSSergio Andres Gomez Del Real 
101c97d6d2cSSergio Andres Gomez Del Real static void decode_modrm_rm(CPUX86State *env, struct x86_decode *decode,
102c97d6d2cSSergio Andres Gomez Del Real                             struct x86_decode_op *op)
103c97d6d2cSSergio Andres Gomez Del Real {
104c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_RM;
105c97d6d2cSSergio Andres Gomez Del Real }
106c97d6d2cSSergio Andres Gomez Del Real 
107c97d6d2cSSergio Andres Gomez Del Real static void decode_modrm_reg(CPUX86State *env, struct x86_decode *decode,
108c97d6d2cSSergio Andres Gomez Del Real                              struct x86_decode_op *op)
109c97d6d2cSSergio Andres Gomez Del Real {
110c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_REG;
111c97d6d2cSSergio Andres Gomez Del Real     op->reg = decode->modrm.reg;
112b4e1af89SRoman Bolshakov     op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r,
113b4e1af89SRoman Bolshakov                           decode->operand_size);
114c97d6d2cSSergio Andres Gomez Del Real }
115c97d6d2cSSergio Andres Gomez Del Real 
116c97d6d2cSSergio Andres Gomez Del Real static void decode_rax(CPUX86State *env, struct x86_decode *decode,
117c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op)
118c97d6d2cSSergio Andres Gomez Del Real {
119c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_REG;
1206701d81dSPaolo Bonzini     op->reg = R_EAX;
1218c3b0e9eSCameron Esfahani     /* Since reg is always AX, REX prefix has no impact. */
1228c3b0e9eSCameron Esfahani     op->ptr = get_reg_ref(env, op->reg, false, 0,
123b4e1af89SRoman Bolshakov                           decode->operand_size);
124c97d6d2cSSergio Andres Gomez Del Real }
125c97d6d2cSSergio Andres Gomez Del Real 
126c97d6d2cSSergio Andres Gomez Del Real static inline void decode_immediate(CPUX86State *env, struct x86_decode *decode,
127c97d6d2cSSergio Andres Gomez Del Real                                     struct x86_decode_op *var, int size)
128c97d6d2cSSergio Andres Gomez Del Real {
129c97d6d2cSSergio Andres Gomez Del Real     var->type = X86_VAR_IMMEDIATE;
130c97d6d2cSSergio Andres Gomez Del Real     var->size = size;
131c97d6d2cSSergio Andres Gomez Del Real     switch (size) {
132c97d6d2cSSergio Andres Gomez Del Real     case 1:
133c97d6d2cSSergio Andres Gomez Del Real         var->val = decode_byte(env, decode);
134c97d6d2cSSergio Andres Gomez Del Real         break;
135c97d6d2cSSergio Andres Gomez Del Real     case 2:
136c97d6d2cSSergio Andres Gomez Del Real         var->val = decode_word(env, decode);
137c97d6d2cSSergio Andres Gomez Del Real         break;
138c97d6d2cSSergio Andres Gomez Del Real     case 4:
139c97d6d2cSSergio Andres Gomez Del Real         var->val = decode_dword(env, decode);
140c97d6d2cSSergio Andres Gomez Del Real         break;
141c97d6d2cSSergio Andres Gomez Del Real     case 8:
142c97d6d2cSSergio Andres Gomez Del Real         var->val = decode_qword(env, decode);
143c97d6d2cSSergio Andres Gomez Del Real         break;
144c97d6d2cSSergio Andres Gomez Del Real     default:
145c97d6d2cSSergio Andres Gomez Del Real         VM_PANIC_EX("bad size %d\n", size);
146c97d6d2cSSergio Andres Gomez Del Real     }
147c97d6d2cSSergio Andres Gomez Del Real }
148c97d6d2cSSergio Andres Gomez Del Real 
149c97d6d2cSSergio Andres Gomez Del Real static void decode_imm8(CPUX86State *env, struct x86_decode *decode,
150c97d6d2cSSergio Andres Gomez Del Real                         struct x86_decode_op *op)
151c97d6d2cSSergio Andres Gomez Del Real {
152c97d6d2cSSergio Andres Gomez Del Real     decode_immediate(env, decode, op, 1);
153c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_IMMEDIATE;
154c97d6d2cSSergio Andres Gomez Del Real }
155c97d6d2cSSergio Andres Gomez Del Real 
156c97d6d2cSSergio Andres Gomez Del Real static void decode_imm8_signed(CPUX86State *env, struct x86_decode *decode,
157c97d6d2cSSergio Andres Gomez Del Real                                struct x86_decode_op *op)
158c97d6d2cSSergio Andres Gomez Del Real {
159c97d6d2cSSergio Andres Gomez Del Real     decode_immediate(env, decode, op, 1);
160c97d6d2cSSergio Andres Gomez Del Real     op->val = sign(op->val, 1);
161c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_IMMEDIATE;
162c97d6d2cSSergio Andres Gomez Del Real }
163c97d6d2cSSergio Andres Gomez Del Real 
164c97d6d2cSSergio Andres Gomez Del Real static void decode_imm16(CPUX86State *env, struct x86_decode *decode,
165c97d6d2cSSergio Andres Gomez Del Real                          struct x86_decode_op *op)
166c97d6d2cSSergio Andres Gomez Del Real {
167c97d6d2cSSergio Andres Gomez Del Real     decode_immediate(env, decode, op, 2);
168c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_IMMEDIATE;
169c97d6d2cSSergio Andres Gomez Del Real }
170c97d6d2cSSergio Andres Gomez Del Real 
171c97d6d2cSSergio Andres Gomez Del Real 
172c97d6d2cSSergio Andres Gomez Del Real static void decode_imm(CPUX86State *env, struct x86_decode *decode,
173c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op)
174c97d6d2cSSergio Andres Gomez Del Real {
175c97d6d2cSSergio Andres Gomez Del Real     if (8 == decode->operand_size) {
176c97d6d2cSSergio Andres Gomez Del Real         decode_immediate(env, decode, op, 4);
177c97d6d2cSSergio Andres Gomez Del Real         op->val = sign(op->val, decode->operand_size);
178c97d6d2cSSergio Andres Gomez Del Real     } else {
179c97d6d2cSSergio Andres Gomez Del Real         decode_immediate(env, decode, op, decode->operand_size);
180c97d6d2cSSergio Andres Gomez Del Real     }
181c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_IMMEDIATE;
182c97d6d2cSSergio Andres Gomez Del Real }
183c97d6d2cSSergio Andres Gomez Del Real 
184c97d6d2cSSergio Andres Gomez Del Real static void decode_imm_signed(CPUX86State *env, struct x86_decode *decode,
185c97d6d2cSSergio Andres Gomez Del Real                               struct x86_decode_op *op)
186c97d6d2cSSergio Andres Gomez Del Real {
187c97d6d2cSSergio Andres Gomez Del Real     decode_immediate(env, decode, op, decode->operand_size);
188c97d6d2cSSergio Andres Gomez Del Real     op->val = sign(op->val, decode->operand_size);
189c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_IMMEDIATE;
190c97d6d2cSSergio Andres Gomez Del Real }
191c97d6d2cSSergio Andres Gomez Del Real 
192c97d6d2cSSergio Andres Gomez Del Real static void decode_imm_1(CPUX86State *env, struct x86_decode *decode,
193c97d6d2cSSergio Andres Gomez Del Real                          struct x86_decode_op *op)
194c97d6d2cSSergio Andres Gomez Del Real {
195c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_IMMEDIATE;
196c97d6d2cSSergio Andres Gomez Del Real     op->val = 1;
197c97d6d2cSSergio Andres Gomez Del Real }
198c97d6d2cSSergio Andres Gomez Del Real 
199c97d6d2cSSergio Andres Gomez Del Real static void decode_imm_0(CPUX86State *env, struct x86_decode *decode,
200c97d6d2cSSergio Andres Gomez Del Real                          struct x86_decode_op *op)
201c97d6d2cSSergio Andres Gomez Del Real {
202c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_IMMEDIATE;
203c97d6d2cSSergio Andres Gomez Del Real     op->val = 0;
204c97d6d2cSSergio Andres Gomez Del Real }
205c97d6d2cSSergio Andres Gomez Del Real 
206c97d6d2cSSergio Andres Gomez Del Real 
207c97d6d2cSSergio Andres Gomez Del Real static void decode_pushseg(CPUX86State *env, struct x86_decode *decode)
208c97d6d2cSSergio Andres Gomez Del Real {
209c97d6d2cSSergio Andres Gomez Del Real     uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
210c97d6d2cSSergio Andres Gomez Del Real 
211c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
212c97d6d2cSSergio Andres Gomez Del Real     switch (op) {
213c97d6d2cSSergio Andres Gomez Del Real     case 0xe:
2146701d81dSPaolo Bonzini         decode->op[0].reg = R_CS;
215c97d6d2cSSergio Andres Gomez Del Real         break;
216c97d6d2cSSergio Andres Gomez Del Real     case 0x16:
2176701d81dSPaolo Bonzini         decode->op[0].reg = R_SS;
218c97d6d2cSSergio Andres Gomez Del Real         break;
219c97d6d2cSSergio Andres Gomez Del Real     case 0x1e:
2206701d81dSPaolo Bonzini         decode->op[0].reg = R_DS;
221c97d6d2cSSergio Andres Gomez Del Real         break;
222c97d6d2cSSergio Andres Gomez Del Real     case 0x06:
2236701d81dSPaolo Bonzini         decode->op[0].reg = R_ES;
224c97d6d2cSSergio Andres Gomez Del Real         break;
225c97d6d2cSSergio Andres Gomez Del Real     case 0xa0:
2266701d81dSPaolo Bonzini         decode->op[0].reg = R_FS;
227c97d6d2cSSergio Andres Gomez Del Real         break;
228c97d6d2cSSergio Andres Gomez Del Real     case 0xa8:
2296701d81dSPaolo Bonzini         decode->op[0].reg = R_GS;
230c97d6d2cSSergio Andres Gomez Del Real         break;
231c97d6d2cSSergio Andres Gomez Del Real     }
232c97d6d2cSSergio Andres Gomez Del Real }
233c97d6d2cSSergio Andres Gomez Del Real 
234c97d6d2cSSergio Andres Gomez Del Real static void decode_popseg(CPUX86State *env, struct x86_decode *decode)
235c97d6d2cSSergio Andres Gomez Del Real {
236c97d6d2cSSergio Andres Gomez Del Real     uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
237c97d6d2cSSergio Andres Gomez Del Real 
238c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
239c97d6d2cSSergio Andres Gomez Del Real     switch (op) {
240c97d6d2cSSergio Andres Gomez Del Real     case 0xf:
2416701d81dSPaolo Bonzini         decode->op[0].reg = R_CS;
242c97d6d2cSSergio Andres Gomez Del Real         break;
243c97d6d2cSSergio Andres Gomez Del Real     case 0x17:
2446701d81dSPaolo Bonzini         decode->op[0].reg = R_SS;
245c97d6d2cSSergio Andres Gomez Del Real         break;
246c97d6d2cSSergio Andres Gomez Del Real     case 0x1f:
2476701d81dSPaolo Bonzini         decode->op[0].reg = R_DS;
248c97d6d2cSSergio Andres Gomez Del Real         break;
249c97d6d2cSSergio Andres Gomez Del Real     case 0x07:
2506701d81dSPaolo Bonzini         decode->op[0].reg = R_ES;
251c97d6d2cSSergio Andres Gomez Del Real         break;
252c97d6d2cSSergio Andres Gomez Del Real     case 0xa1:
2536701d81dSPaolo Bonzini         decode->op[0].reg = R_FS;
254c97d6d2cSSergio Andres Gomez Del Real         break;
255c97d6d2cSSergio Andres Gomez Del Real     case 0xa9:
2566701d81dSPaolo Bonzini         decode->op[0].reg = R_GS;
257c97d6d2cSSergio Andres Gomez Del Real         break;
258c97d6d2cSSergio Andres Gomez Del Real     }
259c97d6d2cSSergio Andres Gomez Del Real }
260c97d6d2cSSergio Andres Gomez Del Real 
261c97d6d2cSSergio Andres Gomez Del Real static void decode_incgroup(CPUX86State *env, struct x86_decode *decode)
262c97d6d2cSSergio Andres Gomez Del Real {
263c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
264c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].reg = decode->opcode[0] - 0x40;
265b4e1af89SRoman Bolshakov     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
266b4e1af89SRoman Bolshakov                                     decode->rex.b, decode->operand_size);
267c97d6d2cSSergio Andres Gomez Del Real }
268c97d6d2cSSergio Andres Gomez Del Real 
269c97d6d2cSSergio Andres Gomez Del Real static void decode_decgroup(CPUX86State *env, struct x86_decode *decode)
270c97d6d2cSSergio Andres Gomez Del Real {
271c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
272c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].reg = decode->opcode[0] - 0x48;
273b4e1af89SRoman Bolshakov     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
274b4e1af89SRoman Bolshakov                                     decode->rex.b, decode->operand_size);
275c97d6d2cSSergio Andres Gomez Del Real }
276c97d6d2cSSergio Andres Gomez Del Real 
277c97d6d2cSSergio Andres Gomez Del Real static void decode_incgroup2(CPUX86State *env, struct x86_decode *decode)
278c97d6d2cSSergio Andres Gomez Del Real {
279c97d6d2cSSergio Andres Gomez Del Real     if (!decode->modrm.reg) {
280c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_INC;
281c97d6d2cSSergio Andres Gomez Del Real     } else if (1 == decode->modrm.reg) {
282c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_DEC;
283c97d6d2cSSergio Andres Gomez Del Real     }
284c97d6d2cSSergio Andres Gomez Del Real }
285c97d6d2cSSergio Andres Gomez Del Real 
286c97d6d2cSSergio Andres Gomez Del Real static void decode_pushgroup(CPUX86State *env, struct x86_decode *decode)
287c97d6d2cSSergio Andres Gomez Del Real {
288c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
289c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].reg = decode->opcode[0] - 0x50;
290b4e1af89SRoman Bolshakov     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
291b4e1af89SRoman Bolshakov                                     decode->rex.b, decode->operand_size);
292c97d6d2cSSergio Andres Gomez Del Real }
293c97d6d2cSSergio Andres Gomez Del Real 
294c97d6d2cSSergio Andres Gomez Del Real static void decode_popgroup(CPUX86State *env, struct x86_decode *decode)
295c97d6d2cSSergio Andres Gomez Del Real {
296c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
297c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].reg = decode->opcode[0] - 0x58;
298b4e1af89SRoman Bolshakov     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
299b4e1af89SRoman Bolshakov                                     decode->rex.b, decode->operand_size);
300c97d6d2cSSergio Andres Gomez Del Real }
301c97d6d2cSSergio Andres Gomez Del Real 
302c97d6d2cSSergio Andres Gomez Del Real static void decode_jxx(CPUX86State *env, struct x86_decode *decode)
303c97d6d2cSSergio Andres Gomez Del Real {
304c97d6d2cSSergio Andres Gomez Del Real     decode->displacement = decode_bytes(env, decode, decode->operand_size);
305c97d6d2cSSergio Andres Gomez Del Real     decode->displacement_size = decode->operand_size;
306c97d6d2cSSergio Andres Gomez Del Real }
307c97d6d2cSSergio Andres Gomez Del Real 
308c97d6d2cSSergio Andres Gomez Del Real static void decode_farjmp(CPUX86State *env, struct x86_decode *decode)
309c97d6d2cSSergio Andres Gomez Del Real {
310c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_IMMEDIATE;
311c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].val = decode_bytes(env, decode, decode->operand_size);
312c97d6d2cSSergio Andres Gomez Del Real     decode->displacement = decode_word(env, decode);
313c97d6d2cSSergio Andres Gomez Del Real }
314c97d6d2cSSergio Andres Gomez Del Real 
315c97d6d2cSSergio Andres Gomez Del Real static void decode_addgroup(CPUX86State *env, struct x86_decode *decode)
316c97d6d2cSSergio Andres Gomez Del Real {
317c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd group[] = {
318c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_ADD,
319c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_OR,
320c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_ADC,
321c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SBB,
322c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_AND,
323c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SUB,
324c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_XOR,
325c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_CMP
326c97d6d2cSSergio Andres Gomez Del Real     };
327c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = group[decode->modrm.reg];
328c97d6d2cSSergio Andres Gomez Del Real }
329c97d6d2cSSergio Andres Gomez Del Real 
330c97d6d2cSSergio Andres Gomez Del Real static void decode_rotgroup(CPUX86State *env, struct x86_decode *decode)
331c97d6d2cSSergio Andres Gomez Del Real {
332c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd group[] = {
333c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_ROL,
334c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_ROR,
335c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_RCL,
336c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_RCR,
337c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SHL,
338c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SHR,
339c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SHL,
340c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SAR
341c97d6d2cSSergio Andres Gomez Del Real     };
342c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = group[decode->modrm.reg];
343c97d6d2cSSergio Andres Gomez Del Real }
344c97d6d2cSSergio Andres Gomez Del Real 
345c97d6d2cSSergio Andres Gomez Del Real static void decode_f7group(CPUX86State *env, struct x86_decode *decode)
346c97d6d2cSSergio Andres Gomez Del Real {
347c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd group[] = {
348c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_TST,
349c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_TST,
350c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_NOT,
351c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_NEG,
352c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_MUL,
353c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_IMUL_1,
354c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_DIV,
355c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_IDIV
356c97d6d2cSSergio Andres Gomez Del Real     };
357c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = group[decode->modrm.reg];
358c97d6d2cSSergio Andres Gomez Del Real     decode_modrm_rm(env, decode, &decode->op[0]);
359c97d6d2cSSergio Andres Gomez Del Real 
360c97d6d2cSSergio Andres Gomez Del Real     switch (decode->modrm.reg) {
361c97d6d2cSSergio Andres Gomez Del Real     case 0:
362c97d6d2cSSergio Andres Gomez Del Real     case 1:
363c97d6d2cSSergio Andres Gomez Del Real         decode_imm(env, decode, &decode->op[1]);
364c97d6d2cSSergio Andres Gomez Del Real         break;
365c97d6d2cSSergio Andres Gomez Del Real     case 2:
366c97d6d2cSSergio Andres Gomez Del Real         break;
367c97d6d2cSSergio Andres Gomez Del Real     case 3:
368c97d6d2cSSergio Andres Gomez Del Real         decode->op[1].type = X86_VAR_IMMEDIATE;
369c97d6d2cSSergio Andres Gomez Del Real         decode->op[1].val = 0;
370c97d6d2cSSergio Andres Gomez Del Real         break;
371c97d6d2cSSergio Andres Gomez Del Real     default:
372c97d6d2cSSergio Andres Gomez Del Real         break;
373c97d6d2cSSergio Andres Gomez Del Real     }
374c97d6d2cSSergio Andres Gomez Del Real }
375c97d6d2cSSergio Andres Gomez Del Real 
376c97d6d2cSSergio Andres Gomez Del Real static void decode_xchgroup(CPUX86State *env, struct x86_decode *decode)
377c97d6d2cSSergio Andres Gomez Del Real {
378c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
379c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].reg = decode->opcode[0] - 0x90;
380b4e1af89SRoman Bolshakov     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
381b4e1af89SRoman Bolshakov                                     decode->rex.b, decode->operand_size);
382c97d6d2cSSergio Andres Gomez Del Real }
383c97d6d2cSSergio Andres Gomez Del Real 
384c97d6d2cSSergio Andres Gomez Del Real static void decode_movgroup(CPUX86State *env, struct x86_decode *decode)
385c97d6d2cSSergio Andres Gomez Del Real {
386c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
387c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].reg = decode->opcode[0] - 0xb8;
388b4e1af89SRoman Bolshakov     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
389b4e1af89SRoman Bolshakov                                     decode->rex.b, decode->operand_size);
390c97d6d2cSSergio Andres Gomez Del Real     decode_immediate(env, decode, &decode->op[1], decode->operand_size);
391c97d6d2cSSergio Andres Gomez Del Real }
392c97d6d2cSSergio Andres Gomez Del Real 
393c97d6d2cSSergio Andres Gomez Del Real static void fetch_moffs(CPUX86State *env, struct x86_decode *decode,
394c97d6d2cSSergio Andres Gomez Del Real                         struct x86_decode_op *op)
395c97d6d2cSSergio Andres Gomez Del Real {
396c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_OFFSET;
397c97d6d2cSSergio Andres Gomez Del Real     op->ptr = decode_bytes(env, decode, decode->addressing_size);
398c97d6d2cSSergio Andres Gomez Del Real }
399c97d6d2cSSergio Andres Gomez Del Real 
400c97d6d2cSSergio Andres Gomez Del Real static void decode_movgroup8(CPUX86State *env, struct x86_decode *decode)
401c97d6d2cSSergio Andres Gomez Del Real {
402c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
403c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].reg = decode->opcode[0] - 0xb0;
404b4e1af89SRoman Bolshakov     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
405b4e1af89SRoman Bolshakov                                     decode->rex.b, decode->operand_size);
406c97d6d2cSSergio Andres Gomez Del Real     decode_immediate(env, decode, &decode->op[1], decode->operand_size);
407c97d6d2cSSergio Andres Gomez Del Real }
408c97d6d2cSSergio Andres Gomez Del Real 
409c97d6d2cSSergio Andres Gomez Del Real static void decode_rcx(CPUX86State *env, struct x86_decode *decode,
410c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op)
411c97d6d2cSSergio Andres Gomez Del Real {
412c97d6d2cSSergio Andres Gomez Del Real     op->type = X86_VAR_REG;
4136701d81dSPaolo Bonzini     op->reg = R_ECX;
414b4e1af89SRoman Bolshakov     op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.b,
415b4e1af89SRoman Bolshakov                           decode->operand_size);
416c97d6d2cSSergio Andres Gomez Del Real }
417c97d6d2cSSergio Andres Gomez Del Real 
418c97d6d2cSSergio Andres Gomez Del Real struct decode_tbl {
419c97d6d2cSSergio Andres Gomez Del Real     uint8_t opcode;
420c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd cmd;
421c97d6d2cSSergio Andres Gomez Del Real     uint8_t operand_size;
422c97d6d2cSSergio Andres Gomez Del Real     bool is_modrm;
423c97d6d2cSSergio Andres Gomez Del Real     void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
424c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op1);
425c97d6d2cSSergio Andres Gomez Del Real     void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
426c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op2);
427c97d6d2cSSergio Andres Gomez Del Real     void (*decode_op3)(CPUX86State *env, struct x86_decode *decode,
428c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op3);
429c97d6d2cSSergio Andres Gomez Del Real     void (*decode_op4)(CPUX86State *env, struct x86_decode *decode,
430c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op4);
431c97d6d2cSSergio Andres Gomez Del Real     void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
432c97d6d2cSSergio Andres Gomez Del Real };
433c97d6d2cSSergio Andres Gomez Del Real 
434c97d6d2cSSergio Andres Gomez Del Real struct decode_x87_tbl {
435c97d6d2cSSergio Andres Gomez Del Real     uint8_t opcode;
436c97d6d2cSSergio Andres Gomez Del Real     uint8_t modrm_reg;
437c97d6d2cSSergio Andres Gomez Del Real     uint8_t modrm_mod;
438c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd cmd;
439c97d6d2cSSergio Andres Gomez Del Real     uint8_t operand_size;
440c97d6d2cSSergio Andres Gomez Del Real     bool rev;
441c97d6d2cSSergio Andres Gomez Del Real     bool pop;
442c97d6d2cSSergio Andres Gomez Del Real     void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
443c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op1);
444c97d6d2cSSergio Andres Gomez Del Real     void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
445c97d6d2cSSergio Andres Gomez Del Real                        struct x86_decode_op *op2);
446c97d6d2cSSergio Andres Gomez Del Real     void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
447c97d6d2cSSergio Andres Gomez Del Real };
448c97d6d2cSSergio Andres Gomez Del Real 
449c97d6d2cSSergio Andres Gomez Del Real struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL,
450c97d6d2cSSergio Andres Gomez Del Real                                decode_invalid};
451c97d6d2cSSergio Andres Gomez Del Real 
45283ea23cdSRoman Bolshakov struct decode_tbl _decode_tbl1[256];
45383ea23cdSRoman Bolshakov struct decode_tbl _decode_tbl2[256];
45483ea23cdSRoman Bolshakov struct decode_x87_tbl _decode_tbl3[256];
455c97d6d2cSSergio Andres Gomez Del Real 
456c97d6d2cSSergio Andres Gomez Del Real static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode)
457c97d6d2cSSergio Andres Gomez Del Real {
458c97d6d2cSSergio Andres Gomez Del Real     struct decode_x87_tbl *decoder;
459c97d6d2cSSergio Andres Gomez Del Real 
460c97d6d2cSSergio Andres Gomez Del Real     decode->is_fpu = true;
461c97d6d2cSSergio Andres Gomez Del Real     int mode = decode->modrm.mod == 3 ? 1 : 0;
462c97d6d2cSSergio Andres Gomez Del Real     int index = ((decode->opcode[0] & 0xf) << 4) | (mode << 3) |
463c97d6d2cSSergio Andres Gomez Del Real                  decode->modrm.reg;
464c97d6d2cSSergio Andres Gomez Del Real 
465c97d6d2cSSergio Andres Gomez Del Real     decoder = &_decode_tbl3[index];
466c97d6d2cSSergio Andres Gomez Del Real 
467c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = decoder->cmd;
468c97d6d2cSSergio Andres Gomez Del Real     if (decoder->operand_size) {
469c97d6d2cSSergio Andres Gomez Del Real         decode->operand_size = decoder->operand_size;
470c97d6d2cSSergio Andres Gomez Del Real     }
471c97d6d2cSSergio Andres Gomez Del Real     decode->fpop_stack = decoder->pop;
472c97d6d2cSSergio Andres Gomez Del Real     decode->frev = decoder->rev;
473c97d6d2cSSergio Andres Gomez Del Real 
474c97d6d2cSSergio Andres Gomez Del Real     if (decoder->decode_op1) {
475c97d6d2cSSergio Andres Gomez Del Real         decoder->decode_op1(env, decode, &decode->op[0]);
476c97d6d2cSSergio Andres Gomez Del Real     }
477c97d6d2cSSergio Andres Gomez Del Real     if (decoder->decode_op2) {
478c97d6d2cSSergio Andres Gomez Del Real         decoder->decode_op2(env, decode, &decode->op[1]);
479c97d6d2cSSergio Andres Gomez Del Real     }
480c97d6d2cSSergio Andres Gomez Del Real     if (decoder->decode_postfix) {
481c97d6d2cSSergio Andres Gomez Del Real         decoder->decode_postfix(env, decode);
482c97d6d2cSSergio Andres Gomez Del Real     }
483c97d6d2cSSergio Andres Gomez Del Real 
484c97d6d2cSSergio Andres Gomez Del Real     VM_PANIC_ON_EX(!decode->cmd, "x87 opcode %x %x (%x %x) not decoded\n",
485c97d6d2cSSergio Andres Gomez Del Real                    decode->opcode[0], decode->modrm.modrm, decoder->modrm_reg,
486c97d6d2cSSergio Andres Gomez Del Real                    decoder->modrm_mod);
487c97d6d2cSSergio Andres Gomez Del Real }
488c97d6d2cSSergio Andres Gomez Del Real 
489c97d6d2cSSergio Andres Gomez Del Real static void decode_ffgroup(CPUX86State *env, struct x86_decode *decode)
490c97d6d2cSSergio Andres Gomez Del Real {
491c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd group[] = {
492c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INC,
493c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_DEC,
494c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT,
495c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT,
496c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT,
497c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT,
498c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_PUSH,
499c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVL,
500c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVL
501c97d6d2cSSergio Andres Gomez Del Real     };
502c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = group[decode->modrm.reg];
503c97d6d2cSSergio Andres Gomez Del Real }
504c97d6d2cSSergio Andres Gomez Del Real 
505c97d6d2cSSergio Andres Gomez Del Real static void decode_sldtgroup(CPUX86State *env, struct x86_decode *decode)
506c97d6d2cSSergio Andres Gomez Del Real {
507c97d6d2cSSergio Andres Gomez Del Real 
508c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd group[] = {
509c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SLDT,
510c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_STR,
511c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_LLDT,
512c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_LTR,
513c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_VERR,
514c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_VERW,
515c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVL,
516c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVL
517c97d6d2cSSergio Andres Gomez Del Real     };
518c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = group[decode->modrm.reg];
519c97d6d2cSSergio Andres Gomez Del Real }
520c97d6d2cSSergio Andres Gomez Del Real 
521c97d6d2cSSergio Andres Gomez Del Real static void decode_lidtgroup(CPUX86State *env, struct x86_decode *decode)
522c97d6d2cSSergio Andres Gomez Del Real {
523c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd group[] = {
524c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SGDT,
525c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SIDT,
526c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_LGDT,
527c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_LIDT,
528c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_SMSW,
529c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_LMSW,
530c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_LMSW,
531c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVLPG
532c97d6d2cSSergio Andres Gomez Del Real     };
533c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = group[decode->modrm.reg];
534c97d6d2cSSergio Andres Gomez Del Real     if (0xf9 == decode->modrm.modrm) {
535c97d6d2cSSergio Andres Gomez Del Real         decode->opcode[decode->len++] = decode->modrm.modrm;
536c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_RDTSCP;
537c97d6d2cSSergio Andres Gomez Del Real     }
538c97d6d2cSSergio Andres Gomez Del Real }
539c97d6d2cSSergio Andres Gomez Del Real 
540c97d6d2cSSergio Andres Gomez Del Real static void decode_btgroup(CPUX86State *env, struct x86_decode *decode)
541c97d6d2cSSergio Andres Gomez Del Real {
542c97d6d2cSSergio Andres Gomez Del Real     enum x86_decode_cmd group[] = {
543c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVL,
544c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVL,
545c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVL,
546c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_INVL,
547c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_BT,
548c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_BTS,
549c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_BTR,
550c97d6d2cSSergio Andres Gomez Del Real         X86_DECODE_CMD_BTC
551c97d6d2cSSergio Andres Gomez Del Real     };
552c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = group[decode->modrm.reg];
553c97d6d2cSSergio Andres Gomez Del Real }
554c97d6d2cSSergio Andres Gomez Del Real 
555c97d6d2cSSergio Andres Gomez Del Real static void decode_x87_general(CPUX86State *env, struct x86_decode *decode)
556c97d6d2cSSergio Andres Gomez Del Real {
557c97d6d2cSSergio Andres Gomez Del Real     decode->is_fpu = true;
558c97d6d2cSSergio Andres Gomez Del Real }
559c97d6d2cSSergio Andres Gomez Del Real 
560c97d6d2cSSergio Andres Gomez Del Real static void decode_x87_modrm_floatp(CPUX86State *env, struct x86_decode *decode,
561c97d6d2cSSergio Andres Gomez Del Real                                     struct x86_decode_op *op)
562c97d6d2cSSergio Andres Gomez Del Real {
563c97d6d2cSSergio Andres Gomez Del Real     op->type = X87_VAR_FLOATP;
564c97d6d2cSSergio Andres Gomez Del Real }
565c97d6d2cSSergio Andres Gomez Del Real 
566c97d6d2cSSergio Andres Gomez Del Real static void decode_x87_modrm_intp(CPUX86State *env, struct x86_decode *decode,
567c97d6d2cSSergio Andres Gomez Del Real                                   struct x86_decode_op *op)
568c97d6d2cSSergio Andres Gomez Del Real {
569c97d6d2cSSergio Andres Gomez Del Real     op->type = X87_VAR_INTP;
570c97d6d2cSSergio Andres Gomez Del Real }
571c97d6d2cSSergio Andres Gomez Del Real 
572c97d6d2cSSergio Andres Gomez Del Real static void decode_x87_modrm_bytep(CPUX86State *env, struct x86_decode *decode,
573c97d6d2cSSergio Andres Gomez Del Real                                    struct x86_decode_op *op)
574c97d6d2cSSergio Andres Gomez Del Real {
575c97d6d2cSSergio Andres Gomez Del Real     op->type = X87_VAR_BYTEP;
576c97d6d2cSSergio Andres Gomez Del Real }
577c97d6d2cSSergio Andres Gomez Del Real 
578c97d6d2cSSergio Andres Gomez Del Real static void decode_x87_modrm_st0(CPUX86State *env, struct x86_decode *decode,
579c97d6d2cSSergio Andres Gomez Del Real                                  struct x86_decode_op *op)
580c97d6d2cSSergio Andres Gomez Del Real {
581c97d6d2cSSergio Andres Gomez Del Real     op->type = X87_VAR_REG;
582c97d6d2cSSergio Andres Gomez Del Real     op->reg = 0;
583c97d6d2cSSergio Andres Gomez Del Real }
584c97d6d2cSSergio Andres Gomez Del Real 
585c97d6d2cSSergio Andres Gomez Del Real static void decode_decode_x87_modrm_st0(CPUX86State *env,
586c97d6d2cSSergio Andres Gomez Del Real                                         struct x86_decode *decode,
587c97d6d2cSSergio Andres Gomez Del Real                                         struct x86_decode_op *op)
588c97d6d2cSSergio Andres Gomez Del Real {
589c97d6d2cSSergio Andres Gomez Del Real     op->type = X87_VAR_REG;
590c97d6d2cSSergio Andres Gomez Del Real     op->reg = decode->modrm.modrm & 7;
591c97d6d2cSSergio Andres Gomez Del Real }
592c97d6d2cSSergio Andres Gomez Del Real 
593c97d6d2cSSergio Andres Gomez Del Real 
594c97d6d2cSSergio Andres Gomez Del Real static void decode_aegroup(CPUX86State *env, struct x86_decode *decode)
595c97d6d2cSSergio Andres Gomez Del Real {
596c97d6d2cSSergio Andres Gomez Del Real     decode->is_fpu = true;
597c97d6d2cSSergio Andres Gomez Del Real     switch (decode->modrm.reg) {
598c97d6d2cSSergio Andres Gomez Del Real     case 0:
599c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_FXSAVE;
600c97d6d2cSSergio Andres Gomez Del Real         decode_x87_modrm_bytep(env, decode, &decode->op[0]);
601c97d6d2cSSergio Andres Gomez Del Real         break;
602c97d6d2cSSergio Andres Gomez Del Real     case 1:
603c97d6d2cSSergio Andres Gomez Del Real         decode_x87_modrm_bytep(env, decode, &decode->op[0]);
604c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_FXRSTOR;
605c97d6d2cSSergio Andres Gomez Del Real         break;
606c97d6d2cSSergio Andres Gomez Del Real     case 5:
607c97d6d2cSSergio Andres Gomez Del Real         if (decode->modrm.modrm == 0xe8) {
608c97d6d2cSSergio Andres Gomez Del Real             decode->cmd = X86_DECODE_CMD_LFENCE;
609c97d6d2cSSergio Andres Gomez Del Real         } else {
610c97d6d2cSSergio Andres Gomez Del Real             VM_PANIC("xrstor");
611c97d6d2cSSergio Andres Gomez Del Real         }
612c97d6d2cSSergio Andres Gomez Del Real         break;
613c97d6d2cSSergio Andres Gomez Del Real     case 6:
614c97d6d2cSSergio Andres Gomez Del Real         VM_PANIC_ON(decode->modrm.modrm != 0xf0);
615c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_MFENCE;
616c97d6d2cSSergio Andres Gomez Del Real         break;
617c97d6d2cSSergio Andres Gomez Del Real     case 7:
618c97d6d2cSSergio Andres Gomez Del Real         if (decode->modrm.modrm == 0xf8) {
619c97d6d2cSSergio Andres Gomez Del Real             decode->cmd = X86_DECODE_CMD_SFENCE;
620c97d6d2cSSergio Andres Gomez Del Real         } else {
621c97d6d2cSSergio Andres Gomez Del Real             decode->cmd = X86_DECODE_CMD_CLFLUSH;
622c97d6d2cSSergio Andres Gomez Del Real         }
623c97d6d2cSSergio Andres Gomez Del Real         break;
624c97d6d2cSSergio Andres Gomez Del Real     default:
62574682782SPaolo Bonzini         VM_PANIC_EX("0xae: reg %d\n", decode->modrm.reg);
626c97d6d2cSSergio Andres Gomez Del Real         break;
627c97d6d2cSSergio Andres Gomez Del Real     }
628c97d6d2cSSergio Andres Gomez Del Real }
629c97d6d2cSSergio Andres Gomez Del Real 
630c97d6d2cSSergio Andres Gomez Del Real static void decode_bswap(CPUX86State *env, struct x86_decode *decode)
631c97d6d2cSSergio Andres Gomez Del Real {
632c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].type = X86_VAR_REG;
633c97d6d2cSSergio Andres Gomez Del Real     decode->op[0].reg = decode->opcode[1] - 0xc8;
634b4e1af89SRoman Bolshakov     decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
635b4e1af89SRoman Bolshakov                                     decode->rex.b, decode->operand_size);
636c97d6d2cSSergio Andres Gomez Del Real }
637c97d6d2cSSergio Andres Gomez Del Real 
638c97d6d2cSSergio Andres Gomez Del Real static void decode_d9_4(CPUX86State *env, struct x86_decode *decode)
639c97d6d2cSSergio Andres Gomez Del Real {
640c97d6d2cSSergio Andres Gomez Del Real     switch (decode->modrm.modrm) {
641c97d6d2cSSergio Andres Gomez Del Real     case 0xe0:
642c97d6d2cSSergio Andres Gomez Del Real         /* FCHS */
643c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_FCHS;
644c97d6d2cSSergio Andres Gomez Del Real         break;
645c97d6d2cSSergio Andres Gomez Del Real     case 0xe1:
646c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_FABS;
647c97d6d2cSSergio Andres Gomez Del Real         break;
648c97d6d2cSSergio Andres Gomez Del Real     case 0xe4:
64974682782SPaolo Bonzini         VM_PANIC("FTST");
650c97d6d2cSSergio Andres Gomez Del Real         break;
651c97d6d2cSSergio Andres Gomez Del Real     case 0xe5:
652c97d6d2cSSergio Andres Gomez Del Real         /* FXAM */
653c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_FXAM;
654c97d6d2cSSergio Andres Gomez Del Real         break;
655c97d6d2cSSergio Andres Gomez Del Real     default:
65674682782SPaolo Bonzini         VM_PANIC("FLDENV");
657c97d6d2cSSergio Andres Gomez Del Real         break;
658c97d6d2cSSergio Andres Gomez Del Real     }
659c97d6d2cSSergio Andres Gomez Del Real }
660c97d6d2cSSergio Andres Gomez Del Real 
661c97d6d2cSSergio Andres Gomez Del Real static void decode_db_4(CPUX86State *env, struct x86_decode *decode)
662c97d6d2cSSergio Andres Gomez Del Real {
663c97d6d2cSSergio Andres Gomez Del Real     switch (decode->modrm.modrm) {
664c97d6d2cSSergio Andres Gomez Del Real     case 0xe0:
66574682782SPaolo Bonzini         VM_PANIC_EX("unhandled FNENI: %x %x\n", decode->opcode[0],
666c97d6d2cSSergio Andres Gomez Del Real                     decode->modrm.modrm);
667c97d6d2cSSergio Andres Gomez Del Real         break;
668c97d6d2cSSergio Andres Gomez Del Real     case 0xe1:
66974682782SPaolo Bonzini         VM_PANIC_EX("unhandled FNDISI: %x %x\n", decode->opcode[0],
670c97d6d2cSSergio Andres Gomez Del Real                     decode->modrm.modrm);
671c97d6d2cSSergio Andres Gomez Del Real         break;
672c97d6d2cSSergio Andres Gomez Del Real     case 0xe2:
67374682782SPaolo Bonzini         VM_PANIC_EX("unhandled FCLEX: %x %x\n", decode->opcode[0],
674c97d6d2cSSergio Andres Gomez Del Real                     decode->modrm.modrm);
675c97d6d2cSSergio Andres Gomez Del Real         break;
676c97d6d2cSSergio Andres Gomez Del Real     case 0xe3:
677c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_FNINIT;
678c97d6d2cSSergio Andres Gomez Del Real         break;
679c97d6d2cSSergio Andres Gomez Del Real     case 0xe4:
680c97d6d2cSSergio Andres Gomez Del Real         decode->cmd = X86_DECODE_CMD_FNSETPM;
681c97d6d2cSSergio Andres Gomez Del Real         break;
682c97d6d2cSSergio Andres Gomez Del Real     default:
68374682782SPaolo Bonzini         VM_PANIC_EX("unhandled fpu opcode: %x %x\n", decode->opcode[0],
684c97d6d2cSSergio Andres Gomez Del Real                     decode->modrm.modrm);
685c97d6d2cSSergio Andres Gomez Del Real         break;
686c97d6d2cSSergio Andres Gomez Del Real     }
687c97d6d2cSSergio Andres Gomez Del Real }
688c97d6d2cSSergio Andres Gomez Del Real 
689c97d6d2cSSergio Andres Gomez Del Real 
690c97d6d2cSSergio Andres Gomez Del Real struct decode_tbl _1op_inst[] = {
691c97d6d2cSSergio Andres Gomez Del Real     {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
692*c901905eSPaolo Bonzini      NULL, NULL},
693c97d6d2cSSergio Andres Gomez Del Real     {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
694*c901905eSPaolo Bonzini      NULL, NULL},
695c97d6d2cSSergio Andres Gomez Del Real     {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
696*c901905eSPaolo Bonzini      NULL, NULL},
697c97d6d2cSSergio Andres Gomez Del Real     {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL,
698*c901905eSPaolo Bonzini      NULL, NULL},
699c97d6d2cSSergio Andres Gomez Del Real     {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL,
700*c901905eSPaolo Bonzini      NULL},
701c97d6d2cSSergio Andres Gomez Del Real     {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL,
702*c901905eSPaolo Bonzini      NULL},
703c97d6d2cSSergio Andres Gomez Del Real     {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL,
704*c901905eSPaolo Bonzini      decode_pushseg},
705c97d6d2cSSergio Andres Gomez Del Real     {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL,
706*c901905eSPaolo Bonzini      decode_popseg},
707c97d6d2cSSergio Andres Gomez Del Real     {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
708*c901905eSPaolo Bonzini      NULL, NULL},
709c97d6d2cSSergio Andres Gomez Del Real     {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
710*c901905eSPaolo Bonzini      NULL, NULL},
711c97d6d2cSSergio Andres Gomez Del Real     {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
712*c901905eSPaolo Bonzini      NULL, NULL},
713c97d6d2cSSergio Andres Gomez Del Real     {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm,
714*c901905eSPaolo Bonzini      NULL, NULL, NULL},
715c97d6d2cSSergio Andres Gomez Del Real     {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8,
716*c901905eSPaolo Bonzini      NULL, NULL, NULL},
717c97d6d2cSSergio Andres Gomez Del Real     {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm,
718*c901905eSPaolo Bonzini      NULL, NULL, NULL},
719c97d6d2cSSergio Andres Gomez Del Real 
720c97d6d2cSSergio Andres Gomez Del Real     {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
721*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
722c97d6d2cSSergio Andres Gomez Del Real     {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false,
723*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
724c97d6d2cSSergio Andres Gomez Del Real 
725c97d6d2cSSergio Andres Gomez Del Real     {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg,
726*c901905eSPaolo Bonzini      NULL, NULL, NULL},
727c97d6d2cSSergio Andres Gomez Del Real     {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg,
728*c901905eSPaolo Bonzini      NULL, NULL, NULL},
729c97d6d2cSSergio Andres Gomez Del Real     {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm,
730*c901905eSPaolo Bonzini      NULL, NULL, NULL},
731c97d6d2cSSergio Andres Gomez Del Real     {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm,
732*c901905eSPaolo Bonzini      NULL, NULL, NULL},
733c97d6d2cSSergio Andres Gomez Del Real     {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm,
734*c901905eSPaolo Bonzini      NULL, NULL, NULL},
735c97d6d2cSSergio Andres Gomez Del Real     {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm,
736*c901905eSPaolo Bonzini      NULL, NULL, NULL},
737c97d6d2cSSergio Andres Gomez Del Real 
738c97d6d2cSSergio Andres Gomez Del Real     {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
739*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
740c97d6d2cSSergio Andres Gomez Del Real     {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false,
741*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
742c97d6d2cSSergio Andres Gomez Del Real 
743c97d6d2cSSergio Andres Gomez Del Real     {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg,
744*c901905eSPaolo Bonzini      NULL, NULL, NULL},
745c97d6d2cSSergio Andres Gomez Del Real     {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg,
746*c901905eSPaolo Bonzini      NULL, NULL, NULL},
747c97d6d2cSSergio Andres Gomez Del Real     {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm,
748*c901905eSPaolo Bonzini      NULL, NULL, NULL},
749c97d6d2cSSergio Andres Gomez Del Real     {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm,
750*c901905eSPaolo Bonzini      NULL, NULL, NULL},
751c97d6d2cSSergio Andres Gomez Del Real     {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8,
752*c901905eSPaolo Bonzini      NULL, NULL, NULL},
753c97d6d2cSSergio Andres Gomez Del Real     {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm,
754*c901905eSPaolo Bonzini      NULL, NULL, NULL},
755c97d6d2cSSergio Andres Gomez Del Real 
756c97d6d2cSSergio Andres Gomez Del Real     {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
757*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
758c97d6d2cSSergio Andres Gomez Del Real     {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false,
759*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
760c97d6d2cSSergio Andres Gomez Del Real 
761c97d6d2cSSergio Andres Gomez Del Real     {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg,
762*c901905eSPaolo Bonzini      NULL, NULL, NULL},
763c97d6d2cSSergio Andres Gomez Del Real     {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg,
764*c901905eSPaolo Bonzini      NULL, NULL, NULL},
765c97d6d2cSSergio Andres Gomez Del Real     {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm,
766*c901905eSPaolo Bonzini      NULL, NULL, NULL},
767c97d6d2cSSergio Andres Gomez Del Real     {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm,
768*c901905eSPaolo Bonzini      NULL, NULL, NULL},
769c97d6d2cSSergio Andres Gomez Del Real     {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm,
770*c901905eSPaolo Bonzini      NULL, NULL, NULL},
771c97d6d2cSSergio Andres Gomez Del Real     {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm,
772*c901905eSPaolo Bonzini      NULL, NULL, NULL},
773c97d6d2cSSergio Andres Gomez Del Real     {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg,
774*c901905eSPaolo Bonzini      NULL, NULL, NULL},
775c97d6d2cSSergio Andres Gomez Del Real     {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg,
776*c901905eSPaolo Bonzini      NULL, NULL, NULL},
777c97d6d2cSSergio Andres Gomez Del Real     {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm,
778*c901905eSPaolo Bonzini      NULL, NULL, NULL},
779c97d6d2cSSergio Andres Gomez Del Real     {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm,
780*c901905eSPaolo Bonzini      NULL, NULL, NULL},
781c97d6d2cSSergio Andres Gomez Del Real     {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm,
782*c901905eSPaolo Bonzini      NULL, NULL, NULL},
783c97d6d2cSSergio Andres Gomez Del Real     {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm,
784*c901905eSPaolo Bonzini      NULL, NULL, NULL},
785c97d6d2cSSergio Andres Gomez Del Real     {0x2f, X86_DECODE_CMD_DAS, 0, false,
786*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
787c97d6d2cSSergio Andres Gomez Del Real     {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg,
788*c901905eSPaolo Bonzini      NULL, NULL, NULL},
789c97d6d2cSSergio Andres Gomez Del Real     {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg,
790*c901905eSPaolo Bonzini      NULL, NULL, NULL},
791c97d6d2cSSergio Andres Gomez Del Real     {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm,
792*c901905eSPaolo Bonzini      NULL, NULL, NULL},
793c97d6d2cSSergio Andres Gomez Del Real     {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm,
794*c901905eSPaolo Bonzini      NULL, NULL, NULL},
795c97d6d2cSSergio Andres Gomez Del Real     {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm,
796*c901905eSPaolo Bonzini      NULL, NULL, NULL},
797c97d6d2cSSergio Andres Gomez Del Real     {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm,
798*c901905eSPaolo Bonzini      NULL, NULL, NULL},
799c97d6d2cSSergio Andres Gomez Del Real 
800c97d6d2cSSergio Andres Gomez Del Real     {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg,
801*c901905eSPaolo Bonzini      NULL, NULL, NULL},
802c97d6d2cSSergio Andres Gomez Del Real     {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg,
803*c901905eSPaolo Bonzini      NULL, NULL, NULL},
804c97d6d2cSSergio Andres Gomez Del Real     {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm,
805*c901905eSPaolo Bonzini      NULL, NULL, NULL},
806c97d6d2cSSergio Andres Gomez Del Real     {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm,
807*c901905eSPaolo Bonzini      NULL, NULL, NULL},
808c97d6d2cSSergio Andres Gomez Del Real     {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8,
809*c901905eSPaolo Bonzini      NULL, NULL, NULL},
810c97d6d2cSSergio Andres Gomez Del Real     {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm,
811*c901905eSPaolo Bonzini      NULL, NULL, NULL},
812c97d6d2cSSergio Andres Gomez Del Real 
813c97d6d2cSSergio Andres Gomez Del Real     {0x3f, X86_DECODE_CMD_AAS, 0, false,
814*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
815c97d6d2cSSergio Andres Gomez Del Real 
816c97d6d2cSSergio Andres Gomez Del Real     {0x40, X86_DECODE_CMD_INC, 0, false,
817*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
818c97d6d2cSSergio Andres Gomez Del Real     {0x41, X86_DECODE_CMD_INC, 0, false,
819*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
820c97d6d2cSSergio Andres Gomez Del Real     {0x42, X86_DECODE_CMD_INC, 0, false,
821*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
822c97d6d2cSSergio Andres Gomez Del Real     {0x43, X86_DECODE_CMD_INC, 0, false,
823*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
824c97d6d2cSSergio Andres Gomez Del Real     {0x44, X86_DECODE_CMD_INC, 0, false,
825*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
826c97d6d2cSSergio Andres Gomez Del Real     {0x45, X86_DECODE_CMD_INC, 0, false,
827*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
828c97d6d2cSSergio Andres Gomez Del Real     {0x46, X86_DECODE_CMD_INC, 0, false,
829*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
830c97d6d2cSSergio Andres Gomez Del Real     {0x47, X86_DECODE_CMD_INC, 0, false,
831*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_incgroup},
832c97d6d2cSSergio Andres Gomez Del Real 
833c97d6d2cSSergio Andres Gomez Del Real     {0x48, X86_DECODE_CMD_DEC, 0, false,
834*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
835c97d6d2cSSergio Andres Gomez Del Real     {0x49, X86_DECODE_CMD_DEC, 0, false,
836*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
837c97d6d2cSSergio Andres Gomez Del Real     {0x4a, X86_DECODE_CMD_DEC, 0, false,
838*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
839c97d6d2cSSergio Andres Gomez Del Real     {0x4b, X86_DECODE_CMD_DEC, 0, false,
840*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
841c97d6d2cSSergio Andres Gomez Del Real     {0x4c, X86_DECODE_CMD_DEC, 0, false,
842*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
843c97d6d2cSSergio Andres Gomez Del Real     {0x4d, X86_DECODE_CMD_DEC, 0, false,
844*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
845c97d6d2cSSergio Andres Gomez Del Real     {0x4e, X86_DECODE_CMD_DEC, 0, false,
846*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
847c97d6d2cSSergio Andres Gomez Del Real     {0x4f, X86_DECODE_CMD_DEC, 0, false,
848*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_decgroup},
849c97d6d2cSSergio Andres Gomez Del Real 
850c97d6d2cSSergio Andres Gomez Del Real     {0x50, X86_DECODE_CMD_PUSH, 0, false,
851*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
852c97d6d2cSSergio Andres Gomez Del Real     {0x51, X86_DECODE_CMD_PUSH, 0, false,
853*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
854c97d6d2cSSergio Andres Gomez Del Real     {0x52, X86_DECODE_CMD_PUSH, 0, false,
855*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
856c97d6d2cSSergio Andres Gomez Del Real     {0x53, X86_DECODE_CMD_PUSH, 0, false,
857*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
858c97d6d2cSSergio Andres Gomez Del Real     {0x54, X86_DECODE_CMD_PUSH, 0, false,
859*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
860c97d6d2cSSergio Andres Gomez Del Real     {0x55, X86_DECODE_CMD_PUSH, 0, false,
861*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
862c97d6d2cSSergio Andres Gomez Del Real     {0x56, X86_DECODE_CMD_PUSH, 0, false,
863*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
864c97d6d2cSSergio Andres Gomez Del Real     {0x57, X86_DECODE_CMD_PUSH, 0, false,
865*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_pushgroup},
866c97d6d2cSSergio Andres Gomez Del Real 
867c97d6d2cSSergio Andres Gomez Del Real     {0x58, X86_DECODE_CMD_POP, 0, false,
868*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
869c97d6d2cSSergio Andres Gomez Del Real     {0x59, X86_DECODE_CMD_POP, 0, false,
870*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
871c97d6d2cSSergio Andres Gomez Del Real     {0x5a, X86_DECODE_CMD_POP, 0, false,
872*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
873c97d6d2cSSergio Andres Gomez Del Real     {0x5b, X86_DECODE_CMD_POP, 0, false,
874*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
875c97d6d2cSSergio Andres Gomez Del Real     {0x5c, X86_DECODE_CMD_POP, 0, false,
876*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
877c97d6d2cSSergio Andres Gomez Del Real     {0x5d, X86_DECODE_CMD_POP, 0, false,
878*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
879c97d6d2cSSergio Andres Gomez Del Real     {0x5e, X86_DECODE_CMD_POP, 0, false,
880*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
881c97d6d2cSSergio Andres Gomez Del Real     {0x5f, X86_DECODE_CMD_POP, 0, false,
882*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_popgroup},
883c97d6d2cSSergio Andres Gomez Del Real 
884c97d6d2cSSergio Andres Gomez Del Real     {0x60, X86_DECODE_CMD_PUSHA, 0, false,
885*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
886c97d6d2cSSergio Andres Gomez Del Real     {0x61, X86_DECODE_CMD_POPA, 0, false,
887*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
888c97d6d2cSSergio Andres Gomez Del Real 
889c97d6d2cSSergio Andres Gomez Del Real     {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm,
890*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
891c97d6d2cSSergio Andres Gomez Del Real     {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed,
892*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
893c97d6d2cSSergio Andres Gomez Del Real     {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg,
894*c901905eSPaolo Bonzini      decode_modrm_rm, decode_imm, NULL, NULL},
895c97d6d2cSSergio Andres Gomez Del Real     {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm,
896*c901905eSPaolo Bonzini      decode_imm8_signed, NULL, NULL},
897c97d6d2cSSergio Andres Gomez Del Real 
898c97d6d2cSSergio Andres Gomez Del Real     {0x6c, X86_DECODE_CMD_INS, 1, false,
899*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
900c97d6d2cSSergio Andres Gomez Del Real     {0x6d, X86_DECODE_CMD_INS, 0, false,
901*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
902c97d6d2cSSergio Andres Gomez Del Real     {0x6e, X86_DECODE_CMD_OUTS, 1, false,
903*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
904c97d6d2cSSergio Andres Gomez Del Real     {0x6f, X86_DECODE_CMD_OUTS, 0, false,
905*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
906c97d6d2cSSergio Andres Gomez Del Real 
907c97d6d2cSSergio Andres Gomez Del Real     {0x70, X86_DECODE_CMD_JXX, 1, false,
908*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
909c97d6d2cSSergio Andres Gomez Del Real     {0x71, X86_DECODE_CMD_JXX, 1, false,
910*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
911c97d6d2cSSergio Andres Gomez Del Real     {0x72, X86_DECODE_CMD_JXX, 1, false,
912*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
913c97d6d2cSSergio Andres Gomez Del Real     {0x73, X86_DECODE_CMD_JXX, 1, false,
914*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
915c97d6d2cSSergio Andres Gomez Del Real     {0x74, X86_DECODE_CMD_JXX, 1, false,
916*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
917c97d6d2cSSergio Andres Gomez Del Real     {0x75, X86_DECODE_CMD_JXX, 1, false,
918*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
919c97d6d2cSSergio Andres Gomez Del Real     {0x76, X86_DECODE_CMD_JXX, 1, false,
920*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
921c97d6d2cSSergio Andres Gomez Del Real     {0x77, X86_DECODE_CMD_JXX, 1, false,
922*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
923c97d6d2cSSergio Andres Gomez Del Real     {0x78, X86_DECODE_CMD_JXX, 1, false,
924*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
925c97d6d2cSSergio Andres Gomez Del Real     {0x79, X86_DECODE_CMD_JXX, 1, false,
926*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
927c97d6d2cSSergio Andres Gomez Del Real     {0x7a, X86_DECODE_CMD_JXX, 1, false,
928*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
929c97d6d2cSSergio Andres Gomez Del Real     {0x7b, X86_DECODE_CMD_JXX, 1, false,
930*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
931c97d6d2cSSergio Andres Gomez Del Real     {0x7c, X86_DECODE_CMD_JXX, 1, false,
932*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
933c97d6d2cSSergio Andres Gomez Del Real     {0x7d, X86_DECODE_CMD_JXX, 1, false,
934*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
935c97d6d2cSSergio Andres Gomez Del Real     {0x7e, X86_DECODE_CMD_JXX, 1, false,
936*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
937c97d6d2cSSergio Andres Gomez Del Real     {0x7f, X86_DECODE_CMD_JXX, 1, false,
938*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
939c97d6d2cSSergio Andres Gomez Del Real 
940c97d6d2cSSergio Andres Gomez Del Real     {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
941*c901905eSPaolo Bonzini      NULL, NULL, decode_addgroup},
942c97d6d2cSSergio Andres Gomez Del Real     {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm,
943*c901905eSPaolo Bonzini      NULL, NULL, decode_addgroup},
944c97d6d2cSSergio Andres Gomez Del Real     {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
945*c901905eSPaolo Bonzini      NULL, NULL, decode_addgroup},
946c97d6d2cSSergio Andres Gomez Del Real     {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed,
947*c901905eSPaolo Bonzini      NULL, NULL, decode_addgroup},
948c97d6d2cSSergio Andres Gomez Del Real     {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg,
949*c901905eSPaolo Bonzini      NULL, NULL, NULL},
950c97d6d2cSSergio Andres Gomez Del Real     {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg,
951*c901905eSPaolo Bonzini      NULL, NULL, NULL},
952c97d6d2cSSergio Andres Gomez Del Real     {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm,
953*c901905eSPaolo Bonzini      NULL, NULL, NULL},
954c97d6d2cSSergio Andres Gomez Del Real     {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm,
955*c901905eSPaolo Bonzini      NULL, NULL, NULL},
956c97d6d2cSSergio Andres Gomez Del Real     {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg,
957*c901905eSPaolo Bonzini      NULL, NULL, NULL},
958c97d6d2cSSergio Andres Gomez Del Real     {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg,
959*c901905eSPaolo Bonzini      NULL, NULL, NULL},
960c97d6d2cSSergio Andres Gomez Del Real     {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm,
961*c901905eSPaolo Bonzini      NULL, NULL, NULL},
962c97d6d2cSSergio Andres Gomez Del Real     {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm,
963*c901905eSPaolo Bonzini      NULL, NULL, NULL},
964c97d6d2cSSergio Andres Gomez Del Real     {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm,
965*c901905eSPaolo Bonzini      decode_modrm_reg, NULL, NULL, NULL},
966c97d6d2cSSergio Andres Gomez Del Real     {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm,
967*c901905eSPaolo Bonzini      NULL, NULL, NULL},
968c97d6d2cSSergio Andres Gomez Del Real     {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg,
969*c901905eSPaolo Bonzini      decode_modrm_rm, NULL, NULL, NULL},
970c97d6d2cSSergio Andres Gomez Del Real     {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm,
971*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
972c97d6d2cSSergio Andres Gomez Del Real 
973c97d6d2cSSergio Andres Gomez Del Real     {0x90, X86_DECODE_CMD_NOP, 0, false,
974*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
975c97d6d2cSSergio Andres Gomez Del Real     {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
976*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
977c97d6d2cSSergio Andres Gomez Del Real     {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
978*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
979c97d6d2cSSergio Andres Gomez Del Real     {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
980*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
981c97d6d2cSSergio Andres Gomez Del Real     {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
982*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
983c97d6d2cSSergio Andres Gomez Del Real     {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
984*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
985c97d6d2cSSergio Andres Gomez Del Real     {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
986*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
987c97d6d2cSSergio Andres Gomez Del Real     {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
988*c901905eSPaolo Bonzini      NULL, NULL, decode_xchgroup},
989c97d6d2cSSergio Andres Gomez Del Real 
990c97d6d2cSSergio Andres Gomez Del Real     {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL,
991*c901905eSPaolo Bonzini      NULL, NULL, NULL},
992c97d6d2cSSergio Andres Gomez Del Real     {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL,
993*c901905eSPaolo Bonzini      NULL, NULL, NULL},
994c97d6d2cSSergio Andres Gomez Del Real 
995c97d6d2cSSergio Andres Gomez Del Real     {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL,
996*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_farjmp},
997c97d6d2cSSergio Andres Gomez Del Real 
998c97d6d2cSSergio Andres Gomez Del Real     {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL,
999*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1000c97d6d2cSSergio Andres Gomez Del Real     /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL,
1001*c901905eSPaolo Bonzini      NULL, NULL, NULL},*/
1002c97d6d2cSSergio Andres Gomez Del Real     {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL,
1003*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1004c97d6d2cSSergio Andres Gomez Del Real     {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL,
1005*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1006c97d6d2cSSergio Andres Gomez Del Real 
1007c97d6d2cSSergio Andres Gomez Del Real     {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs,
1008*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1009c97d6d2cSSergio Andres Gomez Del Real     {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs,
1010*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1011c97d6d2cSSergio Andres Gomez Del Real     {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax,
1012*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1013c97d6d2cSSergio Andres Gomez Del Real     {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax,
1014*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1015c97d6d2cSSergio Andres Gomez Del Real 
1016c97d6d2cSSergio Andres Gomez Del Real     {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL,
1017*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1018c97d6d2cSSergio Andres Gomez Del Real     {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL,
1019*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1020c97d6d2cSSergio Andres Gomez Del Real     {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL,
1021*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1022c97d6d2cSSergio Andres Gomez Del Real     {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL,
1023*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1024c97d6d2cSSergio Andres Gomez Del Real     {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL,
1025*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1026c97d6d2cSSergio Andres Gomez Del Real     {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL,
1027*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1028c97d6d2cSSergio Andres Gomez Del Real     {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL,
1029*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1030c97d6d2cSSergio Andres Gomez Del Real     {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL,
1031*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1032c97d6d2cSSergio Andres Gomez Del Real     {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL,
1033*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1034c97d6d2cSSergio Andres Gomez Del Real     {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL,
1035*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1036c97d6d2cSSergio Andres Gomez Del Real 
1037c97d6d2cSSergio Andres Gomez Del Real     {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm,
1038*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1039c97d6d2cSSergio Andres Gomez Del Real     {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm,
1040*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1041c97d6d2cSSergio Andres Gomez Del Real 
1042c97d6d2cSSergio Andres Gomez Del Real     {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL,
1043*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
1044c97d6d2cSSergio Andres Gomez Del Real     {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL,
1045*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
1046c97d6d2cSSergio Andres Gomez Del Real     {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL,
1047*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
1048c97d6d2cSSergio Andres Gomez Del Real     {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL,
1049*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
1050c97d6d2cSSergio Andres Gomez Del Real     {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL,
1051*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
1052c97d6d2cSSergio Andres Gomez Del Real     {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL,
1053*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
1054c97d6d2cSSergio Andres Gomez Del Real     {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL,
1055*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
1056c97d6d2cSSergio Andres Gomez Del Real     {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL,
1057*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup8},
1058c97d6d2cSSergio Andres Gomez Del Real 
1059c97d6d2cSSergio Andres Gomez Del Real     {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL,
1060*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
1061c97d6d2cSSergio Andres Gomez Del Real     {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL,
1062*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
1063c97d6d2cSSergio Andres Gomez Del Real     {0xba, X86_DECODE_CMD_MOV, 0, false, NULL,
1064*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
1065c97d6d2cSSergio Andres Gomez Del Real     {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL,
1066*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
1067c97d6d2cSSergio Andres Gomez Del Real     {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL,
1068*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
1069c97d6d2cSSergio Andres Gomez Del Real     {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL,
1070*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
1071c97d6d2cSSergio Andres Gomez Del Real     {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL,
1072*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
1073c97d6d2cSSergio Andres Gomez Del Real     {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL,
1074*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_movgroup},
1075c97d6d2cSSergio Andres Gomez Del Real 
1076c97d6d2cSSergio Andres Gomez Del Real     {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
1077*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
1078c97d6d2cSSergio Andres Gomez Del Real     {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1079*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
1080c97d6d2cSSergio Andres Gomez Del Real 
1081c97d6d2cSSergio Andres Gomez Del Real     {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16,
1082*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1083c97d6d2cSSergio Andres Gomez Del Real     {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL,
1084*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1085c97d6d2cSSergio Andres Gomez Del Real 
1086c97d6d2cSSergio Andres Gomez Del Real     {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm,
1087*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1088c97d6d2cSSergio Andres Gomez Del Real     {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm,
1089*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1090c97d6d2cSSergio Andres Gomez Del Real 
1091c97d6d2cSSergio Andres Gomez Del Real     {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8,
1092*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1093c97d6d2cSSergio Andres Gomez Del Real     {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm,
1094*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1095c97d6d2cSSergio Andres Gomez Del Real 
1096c97d6d2cSSergio Andres Gomez Del Real     {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8,
1097*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1098c97d6d2cSSergio Andres Gomez Del Real     {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL,
1099*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1100c97d6d2cSSergio Andres Gomez Del Real     {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL,
1101*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1102c97d6d2cSSergio Andres Gomez Del Real     {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL,
1103*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1104c97d6d2cSSergio Andres Gomez Del Real     {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL,
1105*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1106c97d6d2cSSergio Andres Gomez Del Real     /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL,
1107*c901905eSPaolo Bonzini      NULL, NULL, NULL},*/
1108c97d6d2cSSergio Andres Gomez Del Real 
1109c97d6d2cSSergio Andres Gomez Del Real     {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1,
1110*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
1111c97d6d2cSSergio Andres Gomez Del Real     {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1,
1112*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
1113c97d6d2cSSergio Andres Gomez Del Real     {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx,
1114*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
1115c97d6d2cSSergio Andres Gomez Del Real     {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx,
1116*c901905eSPaolo Bonzini      NULL, NULL, decode_rotgroup},
1117c97d6d2cSSergio Andres Gomez Del Real 
1118c97d6d2cSSergio Andres Gomez Del Real     {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8,
1119*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1120c97d6d2cSSergio Andres Gomez Del Real     {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8,
1121*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1122c97d6d2cSSergio Andres Gomez Del Real 
1123c97d6d2cSSergio Andres Gomez Del Real     {0xd7, X86_DECODE_CMD_XLAT, 0, false,
1124*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1125c97d6d2cSSergio Andres Gomez Del Real 
1126c97d6d2cSSergio Andres Gomez Del Real     {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL,
1127*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
1128c97d6d2cSSergio Andres Gomez Del Real     {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL,
1129*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
1130c97d6d2cSSergio Andres Gomez Del Real     {0xda, X86_DECODE_CMD_INVL, 0, true, NULL,
1131*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
1132c97d6d2cSSergio Andres Gomez Del Real     {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL,
1133*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
1134c97d6d2cSSergio Andres Gomez Del Real     {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL,
1135*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
1136c97d6d2cSSergio Andres Gomez Del Real     {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL,
1137*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
1138c97d6d2cSSergio Andres Gomez Del Real     {0xde, X86_DECODE_CMD_INVL, 0, true, NULL,
1139*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
1140c97d6d2cSSergio Andres Gomez Del Real     {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL,
1141*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_x87_ins},
1142c97d6d2cSSergio Andres Gomez Del Real 
1143c97d6d2cSSergio Andres Gomez Del Real     {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1144*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1145c97d6d2cSSergio Andres Gomez Del Real     {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1146*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1147c97d6d2cSSergio Andres Gomez Del Real     {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1148*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1149c97d6d2cSSergio Andres Gomez Del Real 
1150c97d6d2cSSergio Andres Gomez Del Real     {0xe3, X86_DECODE_CMD_JCXZ, 1, false,
1151*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1152c97d6d2cSSergio Andres Gomez Del Real 
1153c97d6d2cSSergio Andres Gomez Del Real     {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8,
1154*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1155c97d6d2cSSergio Andres Gomez Del Real     {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8,
1156*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1157c97d6d2cSSergio Andres Gomez Del Real     {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8,
1158*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1159c97d6d2cSSergio Andres Gomez Del Real     {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8,
1160*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1161c97d6d2cSSergio Andres Gomez Del Real     {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed,
1162*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1163c97d6d2cSSergio Andres Gomez Del Real     {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed,
1164*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1165c97d6d2cSSergio Andres Gomez Del Real     {0xea, X86_DECODE_CMD_JMP_FAR, 0, false,
1166*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_farjmp},
1167c97d6d2cSSergio Andres Gomez Del Real     {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed,
1168*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1169c97d6d2cSSergio Andres Gomez Del Real     {0xec, X86_DECODE_CMD_IN, 1, false,
1170*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1171c97d6d2cSSergio Andres Gomez Del Real     {0xed, X86_DECODE_CMD_IN, 0, false,
1172*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1173c97d6d2cSSergio Andres Gomez Del Real     {0xee, X86_DECODE_CMD_OUT, 1, false,
1174*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1175c97d6d2cSSergio Andres Gomez Del Real     {0xef, X86_DECODE_CMD_OUT, 0, false,
1176*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1177c97d6d2cSSergio Andres Gomez Del Real 
1178c97d6d2cSSergio Andres Gomez Del Real     {0xf4, X86_DECODE_CMD_HLT, 0, false,
1179*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1180c97d6d2cSSergio Andres Gomez Del Real 
1181c97d6d2cSSergio Andres Gomez Del Real     {0xf5, X86_DECODE_CMD_CMC, 0, false,
1182*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1183c97d6d2cSSergio Andres Gomez Del Real 
1184c97d6d2cSSergio Andres Gomez Del Real     {0xf6, X86_DECODE_CMD_INVL, 1, true,
1185*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_f7group},
1186c97d6d2cSSergio Andres Gomez Del Real     {0xf7, X86_DECODE_CMD_INVL, 0, true,
1187*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_f7group},
1188c97d6d2cSSergio Andres Gomez Del Real 
1189c97d6d2cSSergio Andres Gomez Del Real     {0xf8, X86_DECODE_CMD_CLC, 0, false,
1190*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1191c97d6d2cSSergio Andres Gomez Del Real     {0xf9, X86_DECODE_CMD_STC, 0, false,
1192*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1193c97d6d2cSSergio Andres Gomez Del Real 
1194c97d6d2cSSergio Andres Gomez Del Real     {0xfa, X86_DECODE_CMD_CLI, 0, false,
1195*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1196c97d6d2cSSergio Andres Gomez Del Real     {0xfb, X86_DECODE_CMD_STI, 0, false,
1197*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1198c97d6d2cSSergio Andres Gomez Del Real     {0xfc, X86_DECODE_CMD_CLD, 0, false,
1199*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1200c97d6d2cSSergio Andres Gomez Del Real     {0xfd, X86_DECODE_CMD_STD, 0, false,
1201*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1202c97d6d2cSSergio Andres Gomez Del Real     {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm,
1203*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_incgroup2},
1204c97d6d2cSSergio Andres Gomez Del Real     {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1205*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_ffgroup},
1206c97d6d2cSSergio Andres Gomez Del Real };
1207c97d6d2cSSergio Andres Gomez Del Real 
1208c97d6d2cSSergio Andres Gomez Del Real struct decode_tbl _2op_inst[] = {
1209c97d6d2cSSergio Andres Gomez Del Real     {0x0, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1210*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_sldtgroup},
1211c97d6d2cSSergio Andres Gomez Del Real     {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1212*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_lidtgroup},
1213c97d6d2cSSergio Andres Gomez Del Real     {0x6, X86_DECODE_CMD_CLTS, 0, false,
1214*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1215c97d6d2cSSergio Andres Gomez Del Real     {0x9, X86_DECODE_CMD_WBINVD, 0, false,
1216*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1217c97d6d2cSSergio Andres Gomez Del Real     {0x18, X86_DECODE_CMD_PREFETCH, 0, true,
1218*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_x87_general},
1219c97d6d2cSSergio Andres Gomez Del Real     {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm,
1220*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1221c97d6d2cSSergio Andres Gomez Del Real     {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm,
1222*c901905eSPaolo Bonzini      decode_modrm_reg, NULL, NULL, NULL},
1223c97d6d2cSSergio Andres Gomez Del Real     {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm,
1224*c901905eSPaolo Bonzini      decode_modrm_reg, NULL, NULL, NULL},
1225c97d6d2cSSergio Andres Gomez Del Real     {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg,
1226*c901905eSPaolo Bonzini      decode_modrm_rm, NULL, NULL, NULL},
1227c97d6d2cSSergio Andres Gomez Del Real     {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg,
1228*c901905eSPaolo Bonzini      decode_modrm_rm, NULL, NULL, NULL},
1229c97d6d2cSSergio Andres Gomez Del Real     {0x30, X86_DECODE_CMD_WRMSR, 0, false,
1230*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1231c97d6d2cSSergio Andres Gomez Del Real     {0x31, X86_DECODE_CMD_RDTSC, 0, false,
1232*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1233c97d6d2cSSergio Andres Gomez Del Real     {0x32, X86_DECODE_CMD_RDMSR, 0, false,
1234*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1235c97d6d2cSSergio Andres Gomez Del Real     {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1236*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1237c97d6d2cSSergio Andres Gomez Del Real     {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1238*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1239c97d6d2cSSergio Andres Gomez Del Real     {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1240*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1241c97d6d2cSSergio Andres Gomez Del Real     {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1242*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1243c97d6d2cSSergio Andres Gomez Del Real     {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1244*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1245c97d6d2cSSergio Andres Gomez Del Real     {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1246*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1247c97d6d2cSSergio Andres Gomez Del Real     {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1248*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1249c97d6d2cSSergio Andres Gomez Del Real     {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1250*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1251c97d6d2cSSergio Andres Gomez Del Real     {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1252*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1253c97d6d2cSSergio Andres Gomez Del Real     {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1254*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1255c97d6d2cSSergio Andres Gomez Del Real     {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1256*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1257c97d6d2cSSergio Andres Gomez Del Real     {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1258*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1259c97d6d2cSSergio Andres Gomez Del Real     {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1260*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1261c97d6d2cSSergio Andres Gomez Del Real     {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1262*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1263c97d6d2cSSergio Andres Gomez Del Real     {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1264*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1265c97d6d2cSSergio Andres Gomez Del Real     {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1266*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1267c97d6d2cSSergio Andres Gomez Del Real     {0x77, X86_DECODE_CMD_EMMS, 0, false,
1268*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_x87_general},
1269c97d6d2cSSergio Andres Gomez Del Real     {0x82, X86_DECODE_CMD_JXX, 0, false,
1270*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1271c97d6d2cSSergio Andres Gomez Del Real     {0x83, X86_DECODE_CMD_JXX, 0, false,
1272*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1273c97d6d2cSSergio Andres Gomez Del Real     {0x84, X86_DECODE_CMD_JXX, 0, false,
1274*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1275c97d6d2cSSergio Andres Gomez Del Real     {0x85, X86_DECODE_CMD_JXX, 0, false,
1276*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1277c97d6d2cSSergio Andres Gomez Del Real     {0x86, X86_DECODE_CMD_JXX, 0, false,
1278*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1279c97d6d2cSSergio Andres Gomez Del Real     {0x87, X86_DECODE_CMD_JXX, 0, false,
1280*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1281c97d6d2cSSergio Andres Gomez Del Real     {0x88, X86_DECODE_CMD_JXX, 0, false,
1282*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1283c97d6d2cSSergio Andres Gomez Del Real     {0x89, X86_DECODE_CMD_JXX, 0, false,
1284*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1285c97d6d2cSSergio Andres Gomez Del Real     {0x8a, X86_DECODE_CMD_JXX, 0, false,
1286*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1287c97d6d2cSSergio Andres Gomez Del Real     {0x8b, X86_DECODE_CMD_JXX, 0, false,
1288*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1289c97d6d2cSSergio Andres Gomez Del Real     {0x8c, X86_DECODE_CMD_JXX, 0, false,
1290*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1291c97d6d2cSSergio Andres Gomez Del Real     {0x8d, X86_DECODE_CMD_JXX, 0, false,
1292*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1293c97d6d2cSSergio Andres Gomez Del Real     {0x8e, X86_DECODE_CMD_JXX, 0, false,
1294*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1295c97d6d2cSSergio Andres Gomez Del Real     {0x8f, X86_DECODE_CMD_JXX, 0, false,
1296*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_jxx},
1297c97d6d2cSSergio Andres Gomez Del Real     {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1298*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1299c97d6d2cSSergio Andres Gomez Del Real     {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1300*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1301c97d6d2cSSergio Andres Gomez Del Real     {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1302*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1303c97d6d2cSSergio Andres Gomez Del Real     {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1304*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1305c97d6d2cSSergio Andres Gomez Del Real     {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1306*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1307c97d6d2cSSergio Andres Gomez Del Real     {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1308*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1309c97d6d2cSSergio Andres Gomez Del Real     {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1310*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1311c97d6d2cSSergio Andres Gomez Del Real     {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1312*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1313c97d6d2cSSergio Andres Gomez Del Real     {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1314*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1315c97d6d2cSSergio Andres Gomez Del Real     {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1316*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1317c97d6d2cSSergio Andres Gomez Del Real     {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1318*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1319c97d6d2cSSergio Andres Gomez Del Real     {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1320*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1321c97d6d2cSSergio Andres Gomez Del Real     {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1322*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1323c97d6d2cSSergio Andres Gomez Del Real     {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1324*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1325c97d6d2cSSergio Andres Gomez Del Real     {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1326*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1327c97d6d2cSSergio Andres Gomez Del Real     {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1328*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1329c97d6d2cSSergio Andres Gomez Del Real 
1330c97d6d2cSSergio Andres Gomez Del Real     {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg,
1331*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1332c97d6d2cSSergio Andres Gomez Del Real     {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg,
1333*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1334c97d6d2cSSergio Andres Gomez Del Real 
1335c97d6d2cSSergio Andres Gomez Del Real     {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1336*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1337c97d6d2cSSergio Andres Gomez Del Real     {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1338*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1339c97d6d2cSSergio Andres Gomez Del Real     {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm,
1340*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1341c97d6d2cSSergio Andres Gomez Del Real     {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1342*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1343c97d6d2cSSergio Andres Gomez Del Real     {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1344*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1345c97d6d2cSSergio Andres Gomez Del Real     {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1346*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
1347c97d6d2cSSergio Andres Gomez Del Real     {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false,
1348*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
1349c97d6d2cSSergio Andres Gomez Del Real     {0xa2, X86_DECODE_CMD_CPUID, 0, false,
1350*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, NULL},
1351c97d6d2cSSergio Andres Gomez Del Real     {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg,
1352*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1353c97d6d2cSSergio Andres Gomez Del Real     {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1354*c901905eSPaolo Bonzini      decode_imm8, NULL, NULL},
1355c97d6d2cSSergio Andres Gomez Del Real     {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1356*c901905eSPaolo Bonzini      decode_rcx, NULL, NULL},
1357c97d6d2cSSergio Andres Gomez Del Real     {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1358*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_pushseg},
1359c97d6d2cSSergio Andres Gomez Del Real     {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false,
1360*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_popseg},
1361c97d6d2cSSergio Andres Gomez Del Real     {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg,
1362*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1363c97d6d2cSSergio Andres Gomez Del Real     {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1364*c901905eSPaolo Bonzini      decode_imm8, NULL, NULL},
1365c97d6d2cSSergio Andres Gomez Del Real     {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1366*c901905eSPaolo Bonzini      decode_rcx, NULL, NULL},
1367c97d6d2cSSergio Andres Gomez Del Real 
1368c97d6d2cSSergio Andres Gomez Del Real     {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1369*c901905eSPaolo Bonzini      NULL, NULL, NULL, decode_aegroup},
1370c97d6d2cSSergio Andres Gomez Del Real 
1371c97d6d2cSSergio Andres Gomez Del Real     {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm,
1372*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1373c97d6d2cSSergio Andres Gomez Del Real     {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm,
1374*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1375c97d6d2cSSergio Andres Gomez Del Real     {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg,
1376*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1377c97d6d2cSSergio Andres Gomez Del Real     {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1378*c901905eSPaolo Bonzini      NULL, NULL, decode_btgroup},
1379c97d6d2cSSergio Andres Gomez Del Real     {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg,
1380*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1381c97d6d2cSSergio Andres Gomez Del Real     {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm,
1382*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1383c97d6d2cSSergio Andres Gomez Del Real     {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm,
1384*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1385c97d6d2cSSergio Andres Gomez Del Real 
1386c97d6d2cSSergio Andres Gomez Del Real     {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg,
1387*c901905eSPaolo Bonzini      NULL, NULL, NULL},
1388c97d6d2cSSergio Andres Gomez Del Real 
1389c97d6d2cSSergio Andres Gomez Del Real     {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm,
1390*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL},
1391c97d6d2cSSergio Andres Gomez Del Real 
1392c97d6d2cSSergio Andres Gomez Del Real     {0xc8, X86_DECODE_CMD_BSWAP, 0, false,
1393*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
1394c97d6d2cSSergio Andres Gomez Del Real     {0xc9, X86_DECODE_CMD_BSWAP, 0, false,
1395*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
1396c97d6d2cSSergio Andres Gomez Del Real     {0xca, X86_DECODE_CMD_BSWAP, 0, false,
1397*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
1398c97d6d2cSSergio Andres Gomez Del Real     {0xcb, X86_DECODE_CMD_BSWAP, 0, false,
1399*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
1400c97d6d2cSSergio Andres Gomez Del Real     {0xcc, X86_DECODE_CMD_BSWAP, 0, false,
1401*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
1402c97d6d2cSSergio Andres Gomez Del Real     {0xcd, X86_DECODE_CMD_BSWAP, 0, false,
1403*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
1404c97d6d2cSSergio Andres Gomez Del Real     {0xce, X86_DECODE_CMD_BSWAP, 0, false,
1405*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
1406c97d6d2cSSergio Andres Gomez Del Real     {0xcf, X86_DECODE_CMD_BSWAP, 0, false,
1407*c901905eSPaolo Bonzini      NULL, NULL, NULL, NULL, decode_bswap},
1408c97d6d2cSSergio Andres Gomez Del Real };
1409c97d6d2cSSergio Andres Gomez Del Real 
1410c97d6d2cSSergio Andres Gomez Del Real struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL,
1411c97d6d2cSSergio Andres Gomez Del Real                                        NULL, decode_invalid, 0};
1412c97d6d2cSSergio Andres Gomez Del Real 
1413c97d6d2cSSergio Andres Gomez Del Real struct decode_x87_tbl _x87_inst[] = {
1414c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1415*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_decode_x87_modrm_st0, NULL},
1416c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1417*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
1418c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0,
1419*c901905eSPaolo Bonzini      decode_decode_x87_modrm_st0, NULL},
1420c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1421*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
1422c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0,
1423*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
1424c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1425*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
1426c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0,
1427*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
1428c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1429*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
1430c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0,
1431*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
1432c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1433*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
1434c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0,
1435*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
1436c97d6d2cSSergio Andres Gomez Del Real     {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1437*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL},
1438c97d6d2cSSergio Andres Gomez Del Real 
1439c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false,
1440*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
1441c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1442*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
1443c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0,
1444*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
1445c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false,
1446*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
1447c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false,
1448*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
1449c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1450*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
1451c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false,
1452*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
1453c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1454*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
1455c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false,
1456*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, decode_d9_4},
1457c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false,
1458*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
1459c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 5, 3, X86_DECODE_CMD_FLDxx, 10, false, false, NULL, NULL, NULL,
1460c97d6d2cSSergio Andres Gomez Del Real      RFLAGS_MASK_NONE},
1461c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false,
1462*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
1463c97d6d2cSSergio Andres Gomez Del Real 
1464c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false,
1465*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
1466c97d6d2cSSergio Andres Gomez Del Real     {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false,
1467*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
1468c97d6d2cSSergio Andres Gomez Del Real 
1469c97d6d2cSSergio Andres Gomez Del Real     {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1470*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1471c97d6d2cSSergio Andres Gomez Del Real     {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1472*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
1473c97d6d2cSSergio Andres Gomez Del Real     {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1474*c901905eSPaolo Bonzini      decode_decode_x87_modrm_st0, NULL},
1475c97d6d2cSSergio Andres Gomez Del Real     {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1476*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
1477c97d6d2cSSergio Andres Gomez Del Real     {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1478*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
1479c97d6d2cSSergio Andres Gomez Del Real     {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1480*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
1481c97d6d2cSSergio Andres Gomez Del Real     {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1482c97d6d2cSSergio Andres Gomez Del Real      RFLAGS_MASK_NONE},
1483c97d6d2cSSergio Andres Gomez Del Real     {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1484*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
1485c97d6d2cSSergio Andres Gomez Del Real     {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0,
1486*c901905eSPaolo Bonzini      decode_decode_x87_modrm_st0, NULL},
1487c97d6d2cSSergio Andres Gomez Del Real     {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1488*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
1489c97d6d2cSSergio Andres Gomez Del Real     {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1490c97d6d2cSSergio Andres Gomez Del Real      RFLAGS_MASK_NONE},
1491c97d6d2cSSergio Andres Gomez Del Real     {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1492*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
1493c97d6d2cSSergio Andres Gomez Del Real     {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1494c97d6d2cSSergio Andres Gomez Del Real      RFLAGS_MASK_NONE},
1495c97d6d2cSSergio Andres Gomez Del Real     {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1496*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL},
1497c97d6d2cSSergio Andres Gomez Del Real 
1498c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1499*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL},
1500c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1501*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
1502c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1503*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1504c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1505*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1506c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1507*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
1508c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1509*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1510c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1511*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
1512c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL,
1513*c901905eSPaolo Bonzini      decode_db_4},
1514c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1515c97d6d2cSSergio Andres Gomez Del Real      RFLAGS_MASK_NONE},
1516c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false,
1517*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1518c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false,
1519*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
1520c97d6d2cSSergio Andres Gomez Del Real     {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true,
1521*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
1522c97d6d2cSSergio Andres Gomez Del Real 
1523c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1524*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1525c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false,
1526*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
1527c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false,
1528*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1529c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false,
1530*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
1531c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false,
1532*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1533c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false,
1534*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
1535c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false,
1536*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1537c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false,
1538*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
1539c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false,
1540*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1541c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false,
1542*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
1543c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false,
1544*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1545c97d6d2cSSergio Andres Gomez Del Real     {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false,
1546*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL},
1547c97d6d2cSSergio Andres Gomez Del Real 
1548c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false,
1549*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
1550c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1551*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1552c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false,
1553*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
1554c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false,
1555*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
1556c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1557*c901905eSPaolo Bonzini      decode_x87_modrm_st0, NULL, NULL},
1558c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true,
1559*c901905eSPaolo Bonzini      decode_x87_modrm_floatp, NULL, NULL},
1560c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false,
1561*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1562c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false,
1563*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
1564c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true,
1565*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1566c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false,
1567*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
1568c97d6d2cSSergio Andres Gomez Del Real     {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false,
1569*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
1570c97d6d2cSSergio Andres Gomez Del Real 
1571c97d6d2cSSergio Andres Gomez Del Real     {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true,
1572*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1573c97d6d2cSSergio Andres Gomez Del Real     {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false,
1574*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
1575c97d6d2cSSergio Andres Gomez Del Real     {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true,
1576*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1577c97d6d2cSSergio Andres Gomez Del Real     {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false,
1578*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
1579c97d6d2cSSergio Andres Gomez Del Real     {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true,
1580*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1581c97d6d2cSSergio Andres Gomez Del Real     {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false,
1582*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
1583c97d6d2cSSergio Andres Gomez Del Real     {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true,
1584*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1585c97d6d2cSSergio Andres Gomez Del Real     {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false,
1586*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
1587c97d6d2cSSergio Andres Gomez Del Real     {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true,
1588*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1589c97d6d2cSSergio Andres Gomez Del Real     {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false,
1590*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
1591c97d6d2cSSergio Andres Gomez Del Real     {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true,
1592*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1593c97d6d2cSSergio Andres Gomez Del Real     {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false,
1594*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_intp, NULL},
1595c97d6d2cSSergio Andres Gomez Del Real 
1596c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false,
1597*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
1598c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1599*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1600c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true,
1601*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1602c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false,
1603*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
1604c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1605*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1606c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true,
1607*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
1608c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true,
1609*c901905eSPaolo Bonzini      decode_x87_modrm_bytep, NULL, NULL},
1610c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true,
1611*c901905eSPaolo Bonzini      decode_x87_modrm_st0, decode_x87_modrm_st0, NULL},
1612c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false,
1613*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
1614c97d6d2cSSergio Andres Gomez Del Real     {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true,
1615*c901905eSPaolo Bonzini      decode_x87_modrm_intp, NULL, NULL},
1616c97d6d2cSSergio Andres Gomez Del Real };
1617c97d6d2cSSergio Andres Gomez Del Real 
1618c97d6d2cSSergio Andres Gomez Del Real void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
1619c97d6d2cSSergio Andres Gomez Del Real                           struct x86_decode_op *op)
1620c97d6d2cSSergio Andres Gomez Del Real {
1621ff2de166SPaolo Bonzini     target_ulong ptr = 0;
16226701d81dSPaolo Bonzini     X86Seg seg = R_DS;
1623c97d6d2cSSergio Andres Gomez Del Real 
1624c97d6d2cSSergio Andres Gomez Del Real     if (!decode->modrm.mod && 6 == decode->modrm.rm) {
16251edead0fSRoman Bolshakov         ptr = decode->displacement;
1626c97d6d2cSSergio Andres Gomez Del Real         goto calc_addr;
1627c97d6d2cSSergio Andres Gomez Del Real     }
1628c97d6d2cSSergio Andres Gomez Del Real 
1629c97d6d2cSSergio Andres Gomez Del Real     if (decode->displacement_size) {
1630c97d6d2cSSergio Andres Gomez Del Real         ptr = sign(decode->displacement, decode->displacement_size);
1631c97d6d2cSSergio Andres Gomez Del Real     }
1632c97d6d2cSSergio Andres Gomez Del Real 
1633c97d6d2cSSergio Andres Gomez Del Real     switch (decode->modrm.rm) {
1634c97d6d2cSSergio Andres Gomez Del Real     case 0:
1635c97d6d2cSSergio Andres Gomez Del Real         ptr += BX(env) + SI(env);
1636c97d6d2cSSergio Andres Gomez Del Real         break;
1637c97d6d2cSSergio Andres Gomez Del Real     case 1:
1638c97d6d2cSSergio Andres Gomez Del Real         ptr += BX(env) + DI(env);
1639c97d6d2cSSergio Andres Gomez Del Real         break;
1640c97d6d2cSSergio Andres Gomez Del Real     case 2:
1641c97d6d2cSSergio Andres Gomez Del Real         ptr += BP(env) + SI(env);
16426701d81dSPaolo Bonzini         seg = R_SS;
1643c97d6d2cSSergio Andres Gomez Del Real         break;
1644c97d6d2cSSergio Andres Gomez Del Real     case 3:
1645c97d6d2cSSergio Andres Gomez Del Real         ptr += BP(env) + DI(env);
16466701d81dSPaolo Bonzini         seg = R_SS;
1647c97d6d2cSSergio Andres Gomez Del Real         break;
1648c97d6d2cSSergio Andres Gomez Del Real     case 4:
1649c97d6d2cSSergio Andres Gomez Del Real         ptr += SI(env);
1650c97d6d2cSSergio Andres Gomez Del Real         break;
1651c97d6d2cSSergio Andres Gomez Del Real     case 5:
1652c97d6d2cSSergio Andres Gomez Del Real         ptr += DI(env);
1653c97d6d2cSSergio Andres Gomez Del Real         break;
1654c97d6d2cSSergio Andres Gomez Del Real     case 6:
1655c97d6d2cSSergio Andres Gomez Del Real         ptr += BP(env);
16566701d81dSPaolo Bonzini         seg = R_SS;
1657c97d6d2cSSergio Andres Gomez Del Real         break;
1658c97d6d2cSSergio Andres Gomez Del Real     case 7:
1659c97d6d2cSSergio Andres Gomez Del Real         ptr += BX(env);
1660c97d6d2cSSergio Andres Gomez Del Real         break;
1661c97d6d2cSSergio Andres Gomez Del Real     }
1662c97d6d2cSSergio Andres Gomez Del Real calc_addr:
1663c97d6d2cSSergio Andres Gomez Del Real     if (X86_DECODE_CMD_LEA == decode->cmd) {
1664c97d6d2cSSergio Andres Gomez Del Real         op->ptr = (uint16_t)ptr;
1665c97d6d2cSSergio Andres Gomez Del Real     } else {
1666c97d6d2cSSergio Andres Gomez Del Real         op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg);
1667c97d6d2cSSergio Andres Gomez Del Real     }
1668c97d6d2cSSergio Andres Gomez Del Real }
1669c97d6d2cSSergio Andres Gomez Del Real 
16708c3b0e9eSCameron Esfahani target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present,
16718c3b0e9eSCameron Esfahani                          int is_extended, int size)
1672c97d6d2cSSergio Andres Gomez Del Real {
1673ff2de166SPaolo Bonzini     target_ulong ptr = 0;
1674c97d6d2cSSergio Andres Gomez Del Real 
1675c97d6d2cSSergio Andres Gomez Del Real     if (is_extended) {
16766701d81dSPaolo Bonzini         reg |= R_R8;
1677c97d6d2cSSergio Andres Gomez Del Real     }
1678c97d6d2cSSergio Andres Gomez Del Real 
1679c97d6d2cSSergio Andres Gomez Del Real     switch (size) {
1680c97d6d2cSSergio Andres Gomez Del Real     case 1:
16818c3b0e9eSCameron Esfahani         if (is_extended || reg < 4 || rex_present) {
1682ff2de166SPaolo Bonzini             ptr = (target_ulong)&RL(env, reg);
1683c97d6d2cSSergio Andres Gomez Del Real         } else {
1684ff2de166SPaolo Bonzini             ptr = (target_ulong)&RH(env, reg - 4);
1685c97d6d2cSSergio Andres Gomez Del Real         }
1686c97d6d2cSSergio Andres Gomez Del Real         break;
1687c97d6d2cSSergio Andres Gomez Del Real     default:
1688ff2de166SPaolo Bonzini         ptr = (target_ulong)&RRX(env, reg);
1689c97d6d2cSSergio Andres Gomez Del Real         break;
1690c97d6d2cSSergio Andres Gomez Del Real     }
1691c97d6d2cSSergio Andres Gomez Del Real     return ptr;
1692c97d6d2cSSergio Andres Gomez Del Real }
1693c97d6d2cSSergio Andres Gomez Del Real 
16948c3b0e9eSCameron Esfahani target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
16958c3b0e9eSCameron Esfahani                          int is_extended, int size)
1696c97d6d2cSSergio Andres Gomez Del Real {
1697ff2de166SPaolo Bonzini     target_ulong val = 0;
16988c3b0e9eSCameron Esfahani     memcpy(&val,
16998c3b0e9eSCameron Esfahani            (void *)get_reg_ref(env, reg, rex_present, is_extended, size),
17008c3b0e9eSCameron Esfahani            size);
1701c97d6d2cSSergio Andres Gomez Del Real     return val;
1702c97d6d2cSSergio Andres Gomez Del Real }
1703c97d6d2cSSergio Andres Gomez Del Real 
1704ff2de166SPaolo Bonzini static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode,
17056701d81dSPaolo Bonzini                           X86Seg *sel)
1706c97d6d2cSSergio Andres Gomez Del Real {
1707ff2de166SPaolo Bonzini     target_ulong base = 0;
1708ff2de166SPaolo Bonzini     target_ulong scaled_index = 0;
1709c97d6d2cSSergio Andres Gomez Del Real     int addr_size = decode->addressing_size;
1710c97d6d2cSSergio Andres Gomez Del Real     int base_reg = decode->sib.base;
1711c97d6d2cSSergio Andres Gomez Del Real     int index_reg = decode->sib.index;
1712c97d6d2cSSergio Andres Gomez Del Real 
17136701d81dSPaolo Bonzini     *sel = R_DS;
1714c97d6d2cSSergio Andres Gomez Del Real 
17156701d81dSPaolo Bonzini     if (decode->modrm.mod || base_reg != R_EBP) {
1716c97d6d2cSSergio Andres Gomez Del Real         if (decode->rex.b) {
17176701d81dSPaolo Bonzini             base_reg |= R_R8;
1718c97d6d2cSSergio Andres Gomez Del Real         }
17196701d81dSPaolo Bonzini         if (base_reg == R_ESP || base_reg == R_EBP) {
17206701d81dSPaolo Bonzini             *sel = R_SS;
1721c97d6d2cSSergio Andres Gomez Del Real         }
1722b4e1af89SRoman Bolshakov         base = get_reg_val(env, decode->sib.base, decode->rex.rex,
1723b4e1af89SRoman Bolshakov                            decode->rex.b, addr_size);
1724c97d6d2cSSergio Andres Gomez Del Real     }
1725c97d6d2cSSergio Andres Gomez Del Real 
1726c97d6d2cSSergio Andres Gomez Del Real     if (decode->rex.x) {
17276701d81dSPaolo Bonzini         index_reg |= R_R8;
1728c97d6d2cSSergio Andres Gomez Del Real     }
1729c97d6d2cSSergio Andres Gomez Del Real 
17306701d81dSPaolo Bonzini     if (index_reg != R_ESP) {
1731b4e1af89SRoman Bolshakov         scaled_index = get_reg_val(env, index_reg, decode->rex.rex,
1732b4e1af89SRoman Bolshakov                                    decode->rex.x, addr_size) <<
1733c97d6d2cSSergio Andres Gomez Del Real                                    decode->sib.scale;
1734c97d6d2cSSergio Andres Gomez Del Real     }
1735c97d6d2cSSergio Andres Gomez Del Real     return base + scaled_index;
1736c97d6d2cSSergio Andres Gomez Del Real }
1737c97d6d2cSSergio Andres Gomez Del Real 
1738c97d6d2cSSergio Andres Gomez Del Real void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
1739c97d6d2cSSergio Andres Gomez Del Real                           struct x86_decode_op *op)
1740c97d6d2cSSergio Andres Gomez Del Real {
17416701d81dSPaolo Bonzini     X86Seg seg = R_DS;
1742ff2de166SPaolo Bonzini     target_ulong ptr = 0;
1743c97d6d2cSSergio Andres Gomez Del Real     int addr_size = decode->addressing_size;
1744c97d6d2cSSergio Andres Gomez Del Real 
1745c97d6d2cSSergio Andres Gomez Del Real     if (decode->displacement_size) {
1746c97d6d2cSSergio Andres Gomez Del Real         ptr = sign(decode->displacement, decode->displacement_size);
1747c97d6d2cSSergio Andres Gomez Del Real     }
1748c97d6d2cSSergio Andres Gomez Del Real 
1749c97d6d2cSSergio Andres Gomez Del Real     if (4 == decode->modrm.rm) {
1750c97d6d2cSSergio Andres Gomez Del Real         ptr += get_sib_val(env, decode, &seg);
1751c97d6d2cSSergio Andres Gomez Del Real     } else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
175229a0af61SRichard Henderson         if (x86_is_long_mode(env_cpu(env))) {
17535d32173fSRoman Bolshakov             ptr += env->eip + decode->len;
1754c97d6d2cSSergio Andres Gomez Del Real         } else {
1755c97d6d2cSSergio Andres Gomez Del Real             ptr = decode->displacement;
1756c97d6d2cSSergio Andres Gomez Del Real         }
1757c97d6d2cSSergio Andres Gomez Del Real     } else {
17586701d81dSPaolo Bonzini         if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) {
17596701d81dSPaolo Bonzini             seg = R_SS;
1760c97d6d2cSSergio Andres Gomez Del Real         }
1761b4e1af89SRoman Bolshakov         ptr += get_reg_val(env, decode->modrm.rm, decode->rex.rex,
1762b4e1af89SRoman Bolshakov                            decode->rex.b, addr_size);
1763c97d6d2cSSergio Andres Gomez Del Real     }
1764c97d6d2cSSergio Andres Gomez Del Real 
1765c97d6d2cSSergio Andres Gomez Del Real     if (X86_DECODE_CMD_LEA == decode->cmd) {
1766c97d6d2cSSergio Andres Gomez Del Real         op->ptr = (uint32_t)ptr;
1767c97d6d2cSSergio Andres Gomez Del Real     } else {
1768c97d6d2cSSergio Andres Gomez Del Real         op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg);
1769c97d6d2cSSergio Andres Gomez Del Real     }
1770c97d6d2cSSergio Andres Gomez Del Real }
1771c97d6d2cSSergio Andres Gomez Del Real 
1772c97d6d2cSSergio Andres Gomez Del Real void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
1773c97d6d2cSSergio Andres Gomez Del Real                           struct x86_decode_op *op)
1774c97d6d2cSSergio Andres Gomez Del Real {
17756701d81dSPaolo Bonzini     X86Seg seg = R_DS;
1776c97d6d2cSSergio Andres Gomez Del Real     int32_t offset = 0;
1777c97d6d2cSSergio Andres Gomez Del Real     int mod = decode->modrm.mod;
1778c97d6d2cSSergio Andres Gomez Del Real     int rm = decode->modrm.rm;
1779ff2de166SPaolo Bonzini     target_ulong ptr;
1780c97d6d2cSSergio Andres Gomez Del Real     int src = decode->modrm.rm;
1781c97d6d2cSSergio Andres Gomez Del Real 
1782c97d6d2cSSergio Andres Gomez Del Real     if (decode->displacement_size) {
1783c97d6d2cSSergio Andres Gomez Del Real         offset = sign(decode->displacement, decode->displacement_size);
1784c97d6d2cSSergio Andres Gomez Del Real     }
1785c97d6d2cSSergio Andres Gomez Del Real 
1786c97d6d2cSSergio Andres Gomez Del Real     if (4 == rm) {
1787c97d6d2cSSergio Andres Gomez Del Real         ptr = get_sib_val(env, decode, &seg) + offset;
1788c97d6d2cSSergio Andres Gomez Del Real     } else if (0 == mod && 5 == rm) {
17895d32173fSRoman Bolshakov         ptr = env->eip + decode->len + (int32_t) offset;
1790c97d6d2cSSergio Andres Gomez Del Real     } else {
1791b4e1af89SRoman Bolshakov         ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) +
1792b4e1af89SRoman Bolshakov               (int64_t) offset;
1793c97d6d2cSSergio Andres Gomez Del Real     }
1794c97d6d2cSSergio Andres Gomez Del Real 
1795c97d6d2cSSergio Andres Gomez Del Real     if (X86_DECODE_CMD_LEA == decode->cmd) {
1796c97d6d2cSSergio Andres Gomez Del Real         op->ptr = ptr;
1797c97d6d2cSSergio Andres Gomez Del Real     } else {
1798c97d6d2cSSergio Andres Gomez Del Real         op->ptr = decode_linear_addr(env, decode, ptr, seg);
1799c97d6d2cSSergio Andres Gomez Del Real     }
1800c97d6d2cSSergio Andres Gomez Del Real }
1801c97d6d2cSSergio Andres Gomez Del Real 
1802c97d6d2cSSergio Andres Gomez Del Real 
1803c97d6d2cSSergio Andres Gomez Del Real void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
1804c97d6d2cSSergio Andres Gomez Del Real                         struct x86_decode_op *op)
1805c97d6d2cSSergio Andres Gomez Del Real {
1806c97d6d2cSSergio Andres Gomez Del Real     if (3 == decode->modrm.mod) {
1807c97d6d2cSSergio Andres Gomez Del Real         op->reg = decode->modrm.reg;
1808c97d6d2cSSergio Andres Gomez Del Real         op->type = X86_VAR_REG;
1809b4e1af89SRoman Bolshakov         op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex,
1810b4e1af89SRoman Bolshakov                               decode->rex.b, decode->operand_size);
1811c97d6d2cSSergio Andres Gomez Del Real         return;
1812c97d6d2cSSergio Andres Gomez Del Real     }
1813c97d6d2cSSergio Andres Gomez Del Real 
1814c97d6d2cSSergio Andres Gomez Del Real     switch (decode->addressing_size) {
1815c97d6d2cSSergio Andres Gomez Del Real     case 2:
1816c97d6d2cSSergio Andres Gomez Del Real         calc_modrm_operand16(env, decode, op);
1817c97d6d2cSSergio Andres Gomez Del Real         break;
1818c97d6d2cSSergio Andres Gomez Del Real     case 4:
1819c97d6d2cSSergio Andres Gomez Del Real         calc_modrm_operand32(env, decode, op);
1820c97d6d2cSSergio Andres Gomez Del Real         break;
1821c97d6d2cSSergio Andres Gomez Del Real     case 8:
1822c97d6d2cSSergio Andres Gomez Del Real         calc_modrm_operand64(env, decode, op);
1823c97d6d2cSSergio Andres Gomez Del Real         break;
1824c97d6d2cSSergio Andres Gomez Del Real     default:
1825c97d6d2cSSergio Andres Gomez Del Real         VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size);
1826c97d6d2cSSergio Andres Gomez Del Real         break;
1827c97d6d2cSSergio Andres Gomez Del Real     }
1828c97d6d2cSSergio Andres Gomez Del Real }
1829c97d6d2cSSergio Andres Gomez Del Real 
1830c97d6d2cSSergio Andres Gomez Del Real static void decode_prefix(CPUX86State *env, struct x86_decode *decode)
1831c97d6d2cSSergio Andres Gomez Del Real {
1832c97d6d2cSSergio Andres Gomez Del Real     while (1) {
18338c3b0e9eSCameron Esfahani         /*
18348c3b0e9eSCameron Esfahani          * REX prefix must come after legacy prefixes.
18358c3b0e9eSCameron Esfahani          * REX before legacy is ignored.
18368c3b0e9eSCameron Esfahani          * Clear rex to simulate this.
18378c3b0e9eSCameron Esfahani          */
1838c97d6d2cSSergio Andres Gomez Del Real         uint8_t byte = decode_byte(env, decode);
1839c97d6d2cSSergio Andres Gomez Del Real         switch (byte) {
1840c97d6d2cSSergio Andres Gomez Del Real         case PREFIX_LOCK:
1841c97d6d2cSSergio Andres Gomez Del Real             decode->lock = byte;
18428c3b0e9eSCameron Esfahani             decode->rex.rex = 0;
1843c97d6d2cSSergio Andres Gomez Del Real             break;
1844c97d6d2cSSergio Andres Gomez Del Real         case PREFIX_REPN:
1845c97d6d2cSSergio Andres Gomez Del Real         case PREFIX_REP:
1846c97d6d2cSSergio Andres Gomez Del Real             decode->rep = byte;
18478c3b0e9eSCameron Esfahani             decode->rex.rex = 0;
1848c97d6d2cSSergio Andres Gomez Del Real             break;
18498c3b0e9eSCameron Esfahani         case PREFIX_CS_SEG_OVERRIDE:
18508c3b0e9eSCameron Esfahani         case PREFIX_SS_SEG_OVERRIDE:
18518c3b0e9eSCameron Esfahani         case PREFIX_DS_SEG_OVERRIDE:
18528c3b0e9eSCameron Esfahani         case PREFIX_ES_SEG_OVERRIDE:
18538c3b0e9eSCameron Esfahani         case PREFIX_FS_SEG_OVERRIDE:
18548c3b0e9eSCameron Esfahani         case PREFIX_GS_SEG_OVERRIDE:
1855c97d6d2cSSergio Andres Gomez Del Real             decode->segment_override = byte;
18568c3b0e9eSCameron Esfahani             decode->rex.rex = 0;
1857c97d6d2cSSergio Andres Gomez Del Real             break;
1858c97d6d2cSSergio Andres Gomez Del Real         case PREFIX_OP_SIZE_OVERRIDE:
1859c97d6d2cSSergio Andres Gomez Del Real             decode->op_size_override = byte;
18608c3b0e9eSCameron Esfahani             decode->rex.rex = 0;
1861c97d6d2cSSergio Andres Gomez Del Real             break;
1862c97d6d2cSSergio Andres Gomez Del Real         case PREFIX_ADDR_SIZE_OVERRIDE:
1863c97d6d2cSSergio Andres Gomez Del Real             decode->addr_size_override = byte;
18648c3b0e9eSCameron Esfahani             decode->rex.rex = 0;
1865c97d6d2cSSergio Andres Gomez Del Real             break;
1866c97d6d2cSSergio Andres Gomez Del Real         case PREFIX_REX ... (PREFIX_REX + 0xf):
186729a0af61SRichard Henderson             if (x86_is_long_mode(env_cpu(env))) {
1868c97d6d2cSSergio Andres Gomez Del Real                 decode->rex.rex = byte;
1869c97d6d2cSSergio Andres Gomez Del Real                 break;
1870c97d6d2cSSergio Andres Gomez Del Real             }
1871c97d6d2cSSergio Andres Gomez Del Real             /* fall through when not in long mode */
1872c97d6d2cSSergio Andres Gomez Del Real         default:
1873c97d6d2cSSergio Andres Gomez Del Real             decode->len--;
1874c97d6d2cSSergio Andres Gomez Del Real             return;
1875c97d6d2cSSergio Andres Gomez Del Real         }
1876c97d6d2cSSergio Andres Gomez Del Real     }
1877c97d6d2cSSergio Andres Gomez Del Real }
1878c97d6d2cSSergio Andres Gomez Del Real 
1879c97d6d2cSSergio Andres Gomez Del Real void set_addressing_size(CPUX86State *env, struct x86_decode *decode)
1880c97d6d2cSSergio Andres Gomez Del Real {
1881c97d6d2cSSergio Andres Gomez Del Real     decode->addressing_size = -1;
188229a0af61SRichard Henderson     if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
1883c97d6d2cSSergio Andres Gomez Del Real         if (decode->addr_size_override) {
1884c97d6d2cSSergio Andres Gomez Del Real             decode->addressing_size = 4;
1885c97d6d2cSSergio Andres Gomez Del Real         } else {
1886c97d6d2cSSergio Andres Gomez Del Real             decode->addressing_size = 2;
1887c97d6d2cSSergio Andres Gomez Del Real         }
188829a0af61SRichard Henderson     } else if (!x86_is_long_mode(env_cpu(env))) {
1889c97d6d2cSSergio Andres Gomez Del Real         /* protected */
18900860abbeSWei Liu         x86_segment_descriptor cs;
18910860abbeSWei Liu         emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS);
1892c97d6d2cSSergio Andres Gomez Del Real         /* check db */
1893d54d3346SWei Liu         if (cs.db) {
1894c97d6d2cSSergio Andres Gomez Del Real             if (decode->addr_size_override) {
1895c97d6d2cSSergio Andres Gomez Del Real                 decode->addressing_size = 2;
1896c97d6d2cSSergio Andres Gomez Del Real             } else {
1897c97d6d2cSSergio Andres Gomez Del Real                 decode->addressing_size = 4;
1898c97d6d2cSSergio Andres Gomez Del Real             }
1899c97d6d2cSSergio Andres Gomez Del Real         } else {
1900c97d6d2cSSergio Andres Gomez Del Real             if (decode->addr_size_override) {
1901c97d6d2cSSergio Andres Gomez Del Real                 decode->addressing_size = 4;
1902c97d6d2cSSergio Andres Gomez Del Real             } else {
1903c97d6d2cSSergio Andres Gomez Del Real                 decode->addressing_size = 2;
1904c97d6d2cSSergio Andres Gomez Del Real             }
1905c97d6d2cSSergio Andres Gomez Del Real         }
1906c97d6d2cSSergio Andres Gomez Del Real     } else {
1907c97d6d2cSSergio Andres Gomez Del Real         /* long */
1908c97d6d2cSSergio Andres Gomez Del Real         if (decode->addr_size_override) {
1909c97d6d2cSSergio Andres Gomez Del Real             decode->addressing_size = 4;
1910c97d6d2cSSergio Andres Gomez Del Real         } else {
1911c97d6d2cSSergio Andres Gomez Del Real             decode->addressing_size = 8;
1912c97d6d2cSSergio Andres Gomez Del Real         }
1913c97d6d2cSSergio Andres Gomez Del Real     }
1914c97d6d2cSSergio Andres Gomez Del Real }
1915c97d6d2cSSergio Andres Gomez Del Real 
1916c97d6d2cSSergio Andres Gomez Del Real void set_operand_size(CPUX86State *env, struct x86_decode *decode)
1917c97d6d2cSSergio Andres Gomez Del Real {
1918c97d6d2cSSergio Andres Gomez Del Real     decode->operand_size = -1;
191929a0af61SRichard Henderson     if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) {
1920c97d6d2cSSergio Andres Gomez Del Real         if (decode->op_size_override) {
1921c97d6d2cSSergio Andres Gomez Del Real             decode->operand_size = 4;
1922c97d6d2cSSergio Andres Gomez Del Real         } else {
1923c97d6d2cSSergio Andres Gomez Del Real             decode->operand_size = 2;
1924c97d6d2cSSergio Andres Gomez Del Real         }
192529a0af61SRichard Henderson     } else if (!x86_is_long_mode(env_cpu(env))) {
1926c97d6d2cSSergio Andres Gomez Del Real         /* protected */
19270860abbeSWei Liu         x86_segment_descriptor cs;
19280860abbeSWei Liu         emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS);
1929c97d6d2cSSergio Andres Gomez Del Real         /* check db */
1930d54d3346SWei Liu         if (cs.db) {
1931c97d6d2cSSergio Andres Gomez Del Real             if (decode->op_size_override) {
1932c97d6d2cSSergio Andres Gomez Del Real                 decode->operand_size = 2;
1933c97d6d2cSSergio Andres Gomez Del Real             } else{
1934c97d6d2cSSergio Andres Gomez Del Real                 decode->operand_size = 4;
1935c97d6d2cSSergio Andres Gomez Del Real             }
1936c97d6d2cSSergio Andres Gomez Del Real         } else {
1937c97d6d2cSSergio Andres Gomez Del Real             if (decode->op_size_override) {
1938c97d6d2cSSergio Andres Gomez Del Real                 decode->operand_size = 4;
1939c97d6d2cSSergio Andres Gomez Del Real             } else {
1940c97d6d2cSSergio Andres Gomez Del Real                 decode->operand_size = 2;
1941c97d6d2cSSergio Andres Gomez Del Real             }
1942c97d6d2cSSergio Andres Gomez Del Real         }
1943c97d6d2cSSergio Andres Gomez Del Real     } else {
1944c97d6d2cSSergio Andres Gomez Del Real         /* long */
1945c97d6d2cSSergio Andres Gomez Del Real         if (decode->op_size_override) {
1946c97d6d2cSSergio Andres Gomez Del Real             decode->operand_size = 2;
1947c97d6d2cSSergio Andres Gomez Del Real         } else {
1948c97d6d2cSSergio Andres Gomez Del Real             decode->operand_size = 4;
1949c97d6d2cSSergio Andres Gomez Del Real         }
1950c97d6d2cSSergio Andres Gomez Del Real 
1951c97d6d2cSSergio Andres Gomez Del Real         if (decode->rex.w) {
1952c97d6d2cSSergio Andres Gomez Del Real             decode->operand_size = 8;
1953c97d6d2cSSergio Andres Gomez Del Real         }
1954c97d6d2cSSergio Andres Gomez Del Real     }
1955c97d6d2cSSergio Andres Gomez Del Real }
1956c97d6d2cSSergio Andres Gomez Del Real 
1957c97d6d2cSSergio Andres Gomez Del Real static void decode_sib(CPUX86State *env, struct x86_decode *decode)
1958c97d6d2cSSergio Andres Gomez Del Real {
1959c97d6d2cSSergio Andres Gomez Del Real     if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) &&
1960c97d6d2cSSergio Andres Gomez Del Real         (decode->addressing_size != 2)) {
1961c97d6d2cSSergio Andres Gomez Del Real         decode->sib.sib = decode_byte(env, decode);
1962c97d6d2cSSergio Andres Gomez Del Real         decode->sib_present = true;
1963c97d6d2cSSergio Andres Gomez Del Real     }
1964c97d6d2cSSergio Andres Gomez Del Real }
1965c97d6d2cSSergio Andres Gomez Del Real 
1966c97d6d2cSSergio Andres Gomez Del Real /* 16 bit modrm */
1967c97d6d2cSSergio Andres Gomez Del Real int disp16_tbl[4][8] = {
1968c97d6d2cSSergio Andres Gomez Del Real     {0, 0, 0, 0, 0, 0, 2, 0},
1969c97d6d2cSSergio Andres Gomez Del Real     {1, 1, 1, 1, 1, 1, 1, 1},
1970c97d6d2cSSergio Andres Gomez Del Real     {2, 2, 2, 2, 2, 2, 2, 2},
1971c97d6d2cSSergio Andres Gomez Del Real     {0, 0, 0, 0, 0, 0, 0, 0}
1972c97d6d2cSSergio Andres Gomez Del Real };
1973c97d6d2cSSergio Andres Gomez Del Real 
1974c97d6d2cSSergio Andres Gomez Del Real /* 32/64-bit modrm */
1975c97d6d2cSSergio Andres Gomez Del Real int disp32_tbl[4][8] = {
1976c97d6d2cSSergio Andres Gomez Del Real     {0, 0, 0, 0, -1, 4, 0, 0},
1977c97d6d2cSSergio Andres Gomez Del Real     {1, 1, 1, 1, 1, 1, 1, 1},
1978c97d6d2cSSergio Andres Gomez Del Real     {4, 4, 4, 4, 4, 4, 4, 4},
1979c97d6d2cSSergio Andres Gomez Del Real     {0, 0, 0, 0, 0, 0, 0, 0}
1980c97d6d2cSSergio Andres Gomez Del Real };
1981c97d6d2cSSergio Andres Gomez Del Real 
1982c97d6d2cSSergio Andres Gomez Del Real static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode)
1983c97d6d2cSSergio Andres Gomez Del Real {
1984c97d6d2cSSergio Andres Gomez Del Real     int addressing_size = decode->addressing_size;
1985c97d6d2cSSergio Andres Gomez Del Real     int mod = decode->modrm.mod;
1986c97d6d2cSSergio Andres Gomez Del Real     int rm = decode->modrm.rm;
1987c97d6d2cSSergio Andres Gomez Del Real 
1988c97d6d2cSSergio Andres Gomez Del Real     decode->displacement_size = 0;
1989c97d6d2cSSergio Andres Gomez Del Real     switch (addressing_size) {
1990c97d6d2cSSergio Andres Gomez Del Real     case 2:
1991c97d6d2cSSergio Andres Gomez Del Real         decode->displacement_size = disp16_tbl[mod][rm];
1992c97d6d2cSSergio Andres Gomez Del Real         if (decode->displacement_size) {
1993c97d6d2cSSergio Andres Gomez Del Real             decode->displacement = (uint16_t)decode_bytes(env, decode,
1994c97d6d2cSSergio Andres Gomez Del Real                                     decode->displacement_size);
1995c97d6d2cSSergio Andres Gomez Del Real         }
1996c97d6d2cSSergio Andres Gomez Del Real         break;
1997c97d6d2cSSergio Andres Gomez Del Real     case 4:
1998c97d6d2cSSergio Andres Gomez Del Real     case 8:
1999c97d6d2cSSergio Andres Gomez Del Real         if (-1 == disp32_tbl[mod][rm]) {
2000c97d6d2cSSergio Andres Gomez Del Real             if (5 == decode->sib.base) {
2001c97d6d2cSSergio Andres Gomez Del Real                 decode->displacement_size = 4;
2002c97d6d2cSSergio Andres Gomez Del Real             }
2003c97d6d2cSSergio Andres Gomez Del Real         } else {
2004c97d6d2cSSergio Andres Gomez Del Real             decode->displacement_size = disp32_tbl[mod][rm];
2005c97d6d2cSSergio Andres Gomez Del Real         }
2006c97d6d2cSSergio Andres Gomez Del Real 
2007c97d6d2cSSergio Andres Gomez Del Real         if (decode->displacement_size) {
2008c97d6d2cSSergio Andres Gomez Del Real             decode->displacement = (uint32_t)decode_bytes(env, decode,
2009c97d6d2cSSergio Andres Gomez Del Real                                                 decode->displacement_size);
2010c97d6d2cSSergio Andres Gomez Del Real         }
2011c97d6d2cSSergio Andres Gomez Del Real         break;
2012c97d6d2cSSergio Andres Gomez Del Real     }
2013c97d6d2cSSergio Andres Gomez Del Real }
2014c97d6d2cSSergio Andres Gomez Del Real 
2015c97d6d2cSSergio Andres Gomez Del Real static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode)
2016c97d6d2cSSergio Andres Gomez Del Real {
2017c97d6d2cSSergio Andres Gomez Del Real     decode->modrm.modrm = decode_byte(env, decode);
2018c97d6d2cSSergio Andres Gomez Del Real     decode->is_modrm = true;
2019c97d6d2cSSergio Andres Gomez Del Real 
2020c97d6d2cSSergio Andres Gomez Del Real     decode_sib(env, decode);
2021c97d6d2cSSergio Andres Gomez Del Real     decode_displacement(env, decode);
2022c97d6d2cSSergio Andres Gomez Del Real }
2023c97d6d2cSSergio Andres Gomez Del Real 
2024c97d6d2cSSergio Andres Gomez Del Real static inline void decode_opcode_general(CPUX86State *env,
2025c97d6d2cSSergio Andres Gomez Del Real                                          struct x86_decode *decode,
2026c97d6d2cSSergio Andres Gomez Del Real                                          uint8_t opcode,
2027c97d6d2cSSergio Andres Gomez Del Real                                          struct decode_tbl *inst_decoder)
2028c97d6d2cSSergio Andres Gomez Del Real {
2029c97d6d2cSSergio Andres Gomez Del Real     decode->cmd = inst_decoder->cmd;
2030c97d6d2cSSergio Andres Gomez Del Real     if (inst_decoder->operand_size) {
2031c97d6d2cSSergio Andres Gomez Del Real         decode->operand_size = inst_decoder->operand_size;
2032c97d6d2cSSergio Andres Gomez Del Real     }
2033c97d6d2cSSergio Andres Gomez Del Real 
2034c97d6d2cSSergio Andres Gomez Del Real     if (inst_decoder->is_modrm) {
2035c97d6d2cSSergio Andres Gomez Del Real         decode_modrm(env, decode);
2036c97d6d2cSSergio Andres Gomez Del Real     }
2037c97d6d2cSSergio Andres Gomez Del Real     if (inst_decoder->decode_op1) {
2038c97d6d2cSSergio Andres Gomez Del Real         inst_decoder->decode_op1(env, decode, &decode->op[0]);
2039c97d6d2cSSergio Andres Gomez Del Real     }
2040c97d6d2cSSergio Andres Gomez Del Real     if (inst_decoder->decode_op2) {
2041c97d6d2cSSergio Andres Gomez Del Real         inst_decoder->decode_op2(env, decode, &decode->op[1]);
2042c97d6d2cSSergio Andres Gomez Del Real     }
2043c97d6d2cSSergio Andres Gomez Del Real     if (inst_decoder->decode_op3) {
2044c97d6d2cSSergio Andres Gomez Del Real         inst_decoder->decode_op3(env, decode, &decode->op[2]);
2045c97d6d2cSSergio Andres Gomez Del Real     }
2046c97d6d2cSSergio Andres Gomez Del Real     if (inst_decoder->decode_op4) {
2047c97d6d2cSSergio Andres Gomez Del Real         inst_decoder->decode_op4(env, decode, &decode->op[3]);
2048c97d6d2cSSergio Andres Gomez Del Real     }
2049c97d6d2cSSergio Andres Gomez Del Real     if (inst_decoder->decode_postfix) {
2050c97d6d2cSSergio Andres Gomez Del Real         inst_decoder->decode_postfix(env, decode);
2051c97d6d2cSSergio Andres Gomez Del Real     }
2052c97d6d2cSSergio Andres Gomez Del Real }
2053c97d6d2cSSergio Andres Gomez Del Real 
2054c97d6d2cSSergio Andres Gomez Del Real static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode,
2055c97d6d2cSSergio Andres Gomez Del Real                                    uint8_t opcode)
2056c97d6d2cSSergio Andres Gomez Del Real {
2057c97d6d2cSSergio Andres Gomez Del Real     struct decode_tbl *inst_decoder = &_decode_tbl1[opcode];
2058c97d6d2cSSergio Andres Gomez Del Real     decode_opcode_general(env, decode, opcode, inst_decoder);
2059c97d6d2cSSergio Andres Gomez Del Real }
2060c97d6d2cSSergio Andres Gomez Del Real 
2061c97d6d2cSSergio Andres Gomez Del Real 
2062c97d6d2cSSergio Andres Gomez Del Real static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode,
2063c97d6d2cSSergio Andres Gomez Del Real                                    uint8_t opcode)
2064c97d6d2cSSergio Andres Gomez Del Real {
2065c97d6d2cSSergio Andres Gomez Del Real     struct decode_tbl *inst_decoder = &_decode_tbl2[opcode];
2066c97d6d2cSSergio Andres Gomez Del Real     decode_opcode_general(env, decode, opcode, inst_decoder);
2067c97d6d2cSSergio Andres Gomez Del Real }
2068c97d6d2cSSergio Andres Gomez Del Real 
2069c97d6d2cSSergio Andres Gomez Del Real static void decode_opcodes(CPUX86State *env, struct x86_decode *decode)
2070c97d6d2cSSergio Andres Gomez Del Real {
2071c97d6d2cSSergio Andres Gomez Del Real     uint8_t opcode;
2072c97d6d2cSSergio Andres Gomez Del Real 
2073c97d6d2cSSergio Andres Gomez Del Real     opcode = decode_byte(env, decode);
2074c97d6d2cSSergio Andres Gomez Del Real     decode->opcode[decode->opcode_len++] = opcode;
2075c97d6d2cSSergio Andres Gomez Del Real     if (opcode != OPCODE_ESCAPE) {
2076c97d6d2cSSergio Andres Gomez Del Real         decode_opcode_1(env, decode, opcode);
2077c97d6d2cSSergio Andres Gomez Del Real     } else {
2078c97d6d2cSSergio Andres Gomez Del Real         opcode = decode_byte(env, decode);
2079c97d6d2cSSergio Andres Gomez Del Real         decode->opcode[decode->opcode_len++] = opcode;
2080c97d6d2cSSergio Andres Gomez Del Real         decode_opcode_2(env, decode, opcode);
2081c97d6d2cSSergio Andres Gomez Del Real     }
2082c97d6d2cSSergio Andres Gomez Del Real }
2083c97d6d2cSSergio Andres Gomez Del Real 
2084c97d6d2cSSergio Andres Gomez Del Real uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
2085c97d6d2cSSergio Andres Gomez Del Real {
2086715f396dSPaolo Bonzini     memset(decode, 0, sizeof(*decode));
2087c97d6d2cSSergio Andres Gomez Del Real     decode_prefix(env, decode);
2088c97d6d2cSSergio Andres Gomez Del Real     set_addressing_size(env, decode);
2089c97d6d2cSSergio Andres Gomez Del Real     set_operand_size(env, decode);
2090c97d6d2cSSergio Andres Gomez Del Real 
2091c97d6d2cSSergio Andres Gomez Del Real     decode_opcodes(env, decode);
2092c97d6d2cSSergio Andres Gomez Del Real 
2093c97d6d2cSSergio Andres Gomez Del Real     return decode->len;
2094c97d6d2cSSergio Andres Gomez Del Real }
2095c97d6d2cSSergio Andres Gomez Del Real 
20960e4e622eSPhil Dennis-Jordan void init_decoder(void)
2097c97d6d2cSSergio Andres Gomez Del Real {
2098c97d6d2cSSergio Andres Gomez Del Real     int i;
2099c97d6d2cSSergio Andres Gomez Del Real 
21008c3b0e9eSCameron Esfahani     for (i = 0; i < ARRAY_SIZE(_decode_tbl1); i++) {
21018c3b0e9eSCameron Esfahani         memcpy(&_decode_tbl1[i], &invl_inst, sizeof(invl_inst));
2102c97d6d2cSSergio Andres Gomez Del Real     }
2103c97d6d2cSSergio Andres Gomez Del Real     for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
21048c3b0e9eSCameron Esfahani         memcpy(&_decode_tbl2[i], &invl_inst, sizeof(invl_inst));
2105c97d6d2cSSergio Andres Gomez Del Real     }
2106c97d6d2cSSergio Andres Gomez Del Real     for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) {
21078c3b0e9eSCameron Esfahani         memcpy(&_decode_tbl3[i], &invl_inst_x87, sizeof(invl_inst_x87));
2108c97d6d2cSSergio Andres Gomez Del Real 
2109c97d6d2cSSergio Andres Gomez Del Real     }
2110c97d6d2cSSergio Andres Gomez Del Real     for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) {
2111c97d6d2cSSergio Andres Gomez Del Real         _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i];
2112c97d6d2cSSergio Andres Gomez Del Real     }
2113c97d6d2cSSergio Andres Gomez Del Real     for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) {
2114c97d6d2cSSergio Andres Gomez Del Real         _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i];
2115c97d6d2cSSergio Andres Gomez Del Real     }
2116c97d6d2cSSergio Andres Gomez Del Real     for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) {
2117c97d6d2cSSergio Andres Gomez Del Real         int index = ((_x87_inst[i].opcode & 0xf) << 4) |
2118c97d6d2cSSergio Andres Gomez Del Real                     ((_x87_inst[i].modrm_mod & 1) << 3) |
2119c97d6d2cSSergio Andres Gomez Del Real                     _x87_inst[i].modrm_reg;
2120c97d6d2cSSergio Andres Gomez Del Real         _decode_tbl3[index] = _x87_inst[i];
2121c97d6d2cSSergio Andres Gomez Del Real     }
2122c97d6d2cSSergio Andres Gomez Del Real }
2123c97d6d2cSSergio Andres Gomez Del Real 
2124c97d6d2cSSergio Andres Gomez Del Real 
2125c97d6d2cSSergio Andres Gomez Del Real const char *decode_cmd_to_string(enum x86_decode_cmd cmd)
2126c97d6d2cSSergio Andres Gomez Del Real {
2127c97d6d2cSSergio Andres Gomez Del Real     static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG",
2128c97d6d2cSSergio Andres Gomez Del Real         "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT",
2129c97d6d2cSSergio Andres Gomez Del Real         "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD",
2130c97d6d2cSSergio Andres Gomez Del Real         "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST",
2131c97d6d2cSSergio Andres Gomez Del Real         "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR",
2132c97d6d2cSSergio Andres Gomez Del Real         "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG",
2133c97d6d2cSSergio Andres Gomez Del Real         "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN",
2134c97d6d2cSSergio Andres Gomez Del Real         "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW",
2135c97d6d2cSSergio Andres Gomez Del Real         "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR",
2136c97d6d2cSSergio Andres Gomez Del Real         "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR",
2137c97d6d2cSSergio Andres Gomez Del Real         "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL",
2138c97d6d2cSSergio Andres Gomez Del Real         "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS",
2139c97d6d2cSSergio Andres Gomez Del Real         "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT",
2140c97d6d2cSSergio Andres Gomez Del Real         "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA",
2141c97d6d2cSSergio Andres Gomez Del Real         "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT",
2142c97d6d2cSSergio Andres Gomez Del Real         "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES",
2143c97d6d2cSSergio Andres Gomez Del Real         "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT",
2144c97d6d2cSSergio Andres Gomez Del Real         "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW",
2145c97d6d2cSSergio Andres Gomez Del Real         "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV",
2146c97d6d2cSSergio Andres Gomez Del Real         "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE",
2147c97d6d2cSSergio Andres Gomez Del Real         "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW",
2148c97d6d2cSSergio Andres Gomez Del Real         "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"};
2149c97d6d2cSSergio Andres Gomez Del Real     return cmds[cmd];
2150c97d6d2cSSergio Andres Gomez Del Real }
2151c97d6d2cSSergio Andres Gomez Del Real 
2152ff2de166SPaolo Bonzini target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode,
2153ff2de166SPaolo Bonzini                                target_ulong addr, X86Seg seg)
2154c97d6d2cSSergio Andres Gomez Del Real {
2155c97d6d2cSSergio Andres Gomez Del Real     switch (decode->segment_override) {
21568c3b0e9eSCameron Esfahani     case PREFIX_CS_SEG_OVERRIDE:
21576701d81dSPaolo Bonzini         seg = R_CS;
2158c97d6d2cSSergio Andres Gomez Del Real         break;
21598c3b0e9eSCameron Esfahani     case PREFIX_SS_SEG_OVERRIDE:
21606701d81dSPaolo Bonzini         seg = R_SS;
2161c97d6d2cSSergio Andres Gomez Del Real         break;
21628c3b0e9eSCameron Esfahani     case PREFIX_DS_SEG_OVERRIDE:
21636701d81dSPaolo Bonzini         seg = R_DS;
2164c97d6d2cSSergio Andres Gomez Del Real         break;
21658c3b0e9eSCameron Esfahani     case PREFIX_ES_SEG_OVERRIDE:
21666701d81dSPaolo Bonzini         seg = R_ES;
2167c97d6d2cSSergio Andres Gomez Del Real         break;
21688c3b0e9eSCameron Esfahani     case PREFIX_FS_SEG_OVERRIDE:
21696701d81dSPaolo Bonzini         seg = R_FS;
2170c97d6d2cSSergio Andres Gomez Del Real         break;
21718c3b0e9eSCameron Esfahani     case PREFIX_GS_SEG_OVERRIDE:
21726701d81dSPaolo Bonzini         seg = R_GS;
2173c97d6d2cSSergio Andres Gomez Del Real         break;
2174c97d6d2cSSergio Andres Gomez Del Real     default:
2175c97d6d2cSSergio Andres Gomez Del Real         break;
2176c97d6d2cSSergio Andres Gomez Del Real     }
217729a0af61SRichard Henderson     return linear_addr_size(env_cpu(env), addr, decode->addressing_size, seg);
2178c97d6d2cSSergio Andres Gomez Del Real }
2179