Lines 1-4
Link Here
|
1 |
/* -*- c-basic-offset: 3 -*- */ |
1 |
|
2 |
/*--------------------------------------------------------------------*/ |
2 |
/*--------------------------------------------------------------------*/ |
3 |
/*--- The JITter: translate x86 code to ucode. ---*/ |
3 |
/*--- The JITter: translate x86 code to ucode. ---*/ |
4 |
/*--- vg_to_ucode.c ---*/ |
4 |
/*--- vg_to_ucode.c ---*/ |
Lines 8-14
Link Here
|
8 |
This file is part of Valgrind, an extensible x86 protected-mode |
8 |
This file is part of Valgrind, an extensible x86 protected-mode |
9 |
emulator for monitoring program execution on x86-Unixes. |
9 |
emulator for monitoring program execution on x86-Unixes. |
10 |
|
10 |
|
11 |
Copyright (C) 2000-2003 Julian Seward |
11 |
Copyright (C) 2000-2004 Julian Seward |
12 |
jseward@acm.org |
12 |
jseward@acm.org |
13 |
|
13 |
|
14 |
This program is free software; you can redistribute it and/or |
14 |
This program is free software; you can redistribute it and/or |
Lines 33-42
Link Here
|
33 |
|
33 |
|
34 |
|
34 |
|
35 |
/*------------------------------------------------------------*/ |
35 |
/*------------------------------------------------------------*/ |
36 |
/*--- Renamings of frequently-used global functions. ---*/ |
36 |
/*--- Debugging output ---*/ |
|
|
37 |
/*------------------------------------------------------------*/ |
38 |
|
39 |
#define DIP(format, args...) \ |
40 |
if (VG_(print_codegen)) \ |
41 |
VG_(printf)(format, ## args) |
42 |
|
43 |
#define DIS(buf, format, args...) \ |
44 |
if (VG_(print_codegen)) \ |
45 |
VG_(sprintf)(buf, format, ## args) |
46 |
|
47 |
/*------------------------------------------------------------*/ |
48 |
/*--- CPU feature set stuff ---*/ |
49 |
/*--- This is a little out of place here, but it will do ---*/ |
50 |
/*--- for now. ---*/ |
37 |
/*------------------------------------------------------------*/ |
51 |
/*------------------------------------------------------------*/ |
38 |
|
52 |
|
39 |
#define dis VG_(print_codegen) |
53 |
#define VG_CPU_VENDOR_GENERIC 0 |
|
|
54 |
#define VG_CPU_VENDOR_INTEL 1 |
55 |
#define VG_CPU_VENDOR_AMD 2 |
56 |
|
57 |
static Int cpu_vendor = VG_CPU_VENDOR_GENERIC; |
58 |
|
59 |
static const struct cpu_vendor { |
60 |
const Char *vendorstr; |
61 |
Int vendorid; |
62 |
} cpu_vendors[] = { |
63 |
{ "GenuineIntel", VG_CPU_VENDOR_INTEL }, |
64 |
{ "AuthenticAMD", VG_CPU_VENDOR_AMD }, |
65 |
}; |
66 |
|
67 |
static Int cpuid_level = -2; /* -2 -> not initialized */ |
68 |
static UInt cpu_features[VG_N_FEATURE_WORDS]; |
69 |
|
70 |
/* Standard macro to see if a specific flag is changeable */ |
71 |
static inline Bool flag_is_changeable(UInt flag) |
72 |
{ |
73 |
UInt f1, f2; |
74 |
|
75 |
asm("pushfl\n\t" |
76 |
"pushfl\n\t" |
77 |
"popl %0\n\t" |
78 |
"movl %0,%1\n\t" |
79 |
"xorl %2,%0\n\t" |
80 |
"pushl %0\n\t" |
81 |
"popfl\n\t" |
82 |
"pushfl\n\t" |
83 |
"popl %0\n\t" |
84 |
"popfl\n\t" |
85 |
: "=&r" (f1), "=&r" (f2) |
86 |
: "ir" (flag)); |
87 |
|
88 |
return ((f1^f2) & flag) != 0; |
89 |
} |
90 |
|
91 |
|
92 |
/* Probe for the CPUID instruction */ |
93 |
static Bool has_cpuid(void) |
94 |
{ |
95 |
return flag_is_changeable(EFlagID); |
96 |
} |
97 |
|
98 |
static inline UInt cpuid_eax(UInt eax) |
99 |
{ |
100 |
asm("cpuid" : "=a" (eax) : "0" (eax) : "bx", "cx", "dx"); |
101 |
return eax; |
102 |
} |
103 |
|
104 |
static inline void cpuid(UInt eax, |
105 |
UInt *eax_ret, UInt *ebx_ret, UInt *ecx_ret, UInt *edx_ret) |
106 |
{ |
107 |
UInt ebx, ecx, edx; |
108 |
|
109 |
asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "0" (eax)); |
110 |
|
111 |
if (eax_ret) |
112 |
*eax_ret = eax; |
113 |
if (ebx_ret) |
114 |
*ebx_ret = ebx; |
115 |
if (ecx_ret) |
116 |
*ecx_ret = ecx; |
117 |
if (edx_ret) |
118 |
*edx_ret = edx; |
119 |
} |
120 |
|
121 |
static void get_cpu_features(void) |
122 |
{ |
123 |
Char vendorstr[13]; |
124 |
Int i; |
125 |
|
126 |
if (!has_cpuid()) { |
127 |
cpuid_level = -1; |
128 |
return; |
129 |
} |
130 |
|
131 |
cpu_features[VG_INT_FEAT] |= (1 << (VG_X86_FEAT_CPUID%32)); |
132 |
|
133 |
cpuid(0, &cpuid_level, (UInt *)&vendorstr[0], (UInt *)&vendorstr[8], (UInt *)&vendorstr[4]); |
134 |
vendorstr[12] = '\0'; |
135 |
|
136 |
for(i = 0; i < sizeof(cpu_vendors)/sizeof(*cpu_vendors); i++) |
137 |
if (VG_(memcmp)(vendorstr, cpu_vendors[i].vendorstr, 12) == 0) { |
138 |
cpu_vendor = cpu_vendors[i].vendorid; |
139 |
break; |
140 |
} |
141 |
|
142 |
if (cpuid_level >= 1) |
143 |
cpuid(1, NULL, NULL, &cpu_features[VG_EXT_FEAT], &cpu_features[VG_X86_FEAT]); |
144 |
|
145 |
switch(cpu_vendor) { |
146 |
case VG_CPU_VENDOR_AMD: |
147 |
/* get AMD-specific flags */ |
148 |
cpuid(0x80000001, NULL, NULL, NULL, &cpu_features[VG_AMD_FEAT]); |
149 |
break; |
150 |
|
151 |
default: |
152 |
break; |
153 |
} |
154 |
} |
155 |
|
156 |
Bool VG_(cpu_has_feature)(UInt feature) |
157 |
{ |
158 |
UInt word = feature / 32; |
159 |
UInt bit = feature % 32; |
160 |
|
161 |
if (cpuid_level == -2) |
162 |
get_cpu_features(); |
163 |
|
164 |
vg_assert(word >= 0 && word < VG_N_FEATURE_WORDS); |
165 |
|
166 |
return !!(cpu_features[word] & (1 << bit)); |
167 |
} |
168 |
|
169 |
/* The set of features we're willing to support for the client |
170 |
|
171 |
This includes supported instruction set extensions, plus any |
172 |
extensions which don't have any user-mode visible effect (but the |
173 |
client may find interesting). |
174 |
*/ |
175 |
#define VG_X86_SUPPORTED_FEATURES \ |
176 |
((1 << VG_X86_FEAT_FPU) | \ |
177 |
(1 << VG_X86_FEAT_VME) | \ |
178 |
(1 << VG_X86_FEAT_DE) | \ |
179 |
(1 << VG_X86_FEAT_PSE) | \ |
180 |
(1 << VG_X86_FEAT_TSC) | \ |
181 |
(0 << VG_X86_FEAT_MSR) | \ |
182 |
(1 << VG_X86_FEAT_PAE) | \ |
183 |
(1 << VG_X86_FEAT_MCE) | \ |
184 |
(1 << VG_X86_FEAT_CX8) | \ |
185 |
(1 << VG_X86_FEAT_APIC) | \ |
186 |
(0 << VG_X86_FEAT_SEP) | \ |
187 |
(1 << VG_X86_FEAT_MTRR) | \ |
188 |
(1 << VG_X86_FEAT_PGE) | \ |
189 |
(1 << VG_X86_FEAT_MCA) | \ |
190 |
(1 << VG_X86_FEAT_CMOV) | \ |
191 |
(1 << VG_X86_FEAT_PAT) | \ |
192 |
(1 << VG_X86_FEAT_PSE36) | \ |
193 |
(0 << VG_X86_FEAT_CLFSH) | \ |
194 |
(1 << VG_X86_FEAT_DS) | \ |
195 |
(1 << VG_X86_FEAT_ACPI) | \ |
196 |
(1 << VG_X86_FEAT_MMX) | \ |
197 |
(1 << VG_X86_FEAT_FXSR) | \ |
198 |
(1 << VG_X86_FEAT_SSE) | \ |
199 |
(1 << VG_X86_FEAT_SSE2) | \ |
200 |
(1 << VG_X86_FEAT_SS) | \ |
201 |
(1 << VG_X86_FEAT_HT) | \ |
202 |
(1 << VG_X86_FEAT_TM) | \ |
203 |
(0 << VG_X86_FEAT_IA64) | \ |
204 |
(1 << VG_X86_FEAT_PBE)) |
205 |
|
206 |
#define VG_AMD_SUPPORTED_FEATURES \ |
207 |
((0 << (VG_AMD_FEAT_SYSCALL % 32)) | \ |
208 |
(0 << (VG_AMD_FEAT_NXP % 32)) | \ |
209 |
(1 << (VG_AMD_FEAT_MMXEXT % 32)) | \ |
210 |
(0 << (VG_AMD_FEAT_FFXSR % 32)) | \ |
211 |
(0 << (VG_AMD_FEAT_LONGMODE % 32)) | \ |
212 |
(0 << (VG_AMD_FEAT_3DNOWEXT % 32)) | \ |
213 |
(0 << (VG_AMD_FEAT_3DNOW % 32)) | \ |
214 |
/* Common bits between standard features and AMD features */ \ |
215 |
(1 << VG_X86_FEAT_FPU) | \ |
216 |
(1 << VG_X86_FEAT_VME) | \ |
217 |
(1 << VG_X86_FEAT_DE) | \ |
218 |
(1 << VG_X86_FEAT_PSE) | \ |
219 |
(1 << VG_X86_FEAT_TSC) | \ |
220 |
(0 << VG_X86_FEAT_MSR) | \ |
221 |
(1 << VG_X86_FEAT_PAE) | \ |
222 |
(1 << VG_X86_FEAT_MCE) | \ |
223 |
(1 << VG_X86_FEAT_CX8) | \ |
224 |
(1 << VG_X86_FEAT_APIC) | \ |
225 |
(1 << VG_X86_FEAT_MTRR) | \ |
226 |
(1 << VG_X86_FEAT_PGE) | \ |
227 |
(1 << VG_X86_FEAT_MCA) | \ |
228 |
(1 << VG_X86_FEAT_CMOV) | \ |
229 |
(1 << VG_X86_FEAT_PAT) | \ |
230 |
(1 << VG_X86_FEAT_PSE36) | \ |
231 |
(1 << VG_X86_FEAT_MMX) | \ |
232 |
(1 << VG_X86_FEAT_FXSR)) |
233 |
|
234 |
|
235 |
/* |
236 |
For simulating the cpuid instruction, we will |
237 |
issue a "real" cpuid instruction and then mask out |
238 |
the bits of the features we do not support currently (3dnow mostly). |
239 |
We also claim to not support most CPUID operations. |
240 |
|
241 |
Dirk Mueller <mueller@kde.org> |
242 |
|
243 |
http://www.sandpile.org/ia32/cpuid.htm |
244 |
|
245 |
references: |
246 |
|
247 |
pre-MMX pentium: |
248 |
|
249 |
<werner> cpuid words (0): 0x1 0x756e6547 0x6c65746e 0x49656e69 |
250 |
<werner> cpuid words (1): 0x52b 0x0 0x0 0x1bf |
251 |
|
252 |
Updated to be more extensible about future vendor extensions and |
253 |
vendor-specific parts of CPUID. |
254 |
*/ |
255 |
void VG_(helperc_CPUID)(UInt op, UInt *eax_ret, UInt *ebx_ret, UInt *ecx_ret, UInt *edx_ret) |
256 |
{ |
257 |
UInt eax, ebx, ecx, edx; |
258 |
|
259 |
if (cpuid_level == -2) |
260 |
get_cpu_features(); /* for cpu_vendor */ |
261 |
|
262 |
cpuid(op, &eax, &ebx, &ecx, &edx); |
263 |
|
264 |
/* Common mangling */ |
265 |
switch(op) { |
266 |
case 1: |
267 |
edx &= VG_X86_SUPPORTED_FEATURES; |
268 |
break; |
269 |
|
270 |
case 0xd8000000: { |
271 |
/* Implement some private information at 0xd8000000 */ |
272 |
static const Char valgrind_vendor[] = "ValgrindVCPU"; |
273 |
|
274 |
eax = 0xd8000000; /* max request */ |
275 |
ebx = *(UInt *)&valgrind_vendor[0]; |
276 |
ecx = *(UInt *)&valgrind_vendor[8]; |
277 |
edx = *(UInt *)&valgrind_vendor[4]; |
278 |
} |
279 |
break; |
280 |
} |
281 |
|
282 |
/* Vendor-specific mangling of the results */ |
283 |
switch(cpu_vendor) { |
284 |
case VG_CPU_VENDOR_INTEL: |
285 |
switch(op) { |
286 |
case 1: |
287 |
ecx = 0; /* mask out all extended features for now */ |
288 |
break; |
289 |
|
290 |
case 0x80000001: |
291 |
ebx = ecx = edx = 0; |
292 |
break; |
293 |
} |
294 |
break; |
295 |
|
296 |
case VG_CPU_VENDOR_AMD: |
297 |
switch(op) { |
298 |
case 0x80000001: |
299 |
edx &= VG_AMD_SUPPORTED_FEATURES; |
300 |
break; |
301 |
} |
302 |
break; |
303 |
} |
304 |
|
305 |
*eax_ret = eax; |
306 |
*ebx_ret = ebx; |
307 |
*ecx_ret = ecx; |
308 |
*edx_ret = edx; |
309 |
} |
40 |
|
310 |
|
41 |
|
311 |
|
42 |
/*------------------------------------------------------------*/ |
312 |
/*------------------------------------------------------------*/ |
Lines 259-265
Link Here
|
259 |
return 0; /*notreached*/ |
529 |
return 0; /*notreached*/ |
260 |
} |
530 |
} |
261 |
|
531 |
|
262 |
|
|
|
263 |
/*------------------------------------------------------------*/ |
532 |
/*------------------------------------------------------------*/ |
264 |
/*--- Flag-related helpers. ---*/ |
533 |
/*--- Flag-related helpers. ---*/ |
265 |
/*------------------------------------------------------------*/ |
534 |
/*------------------------------------------------------------*/ |
Lines 298-303
Link Here
|
298 |
LAST_UINSTR(cb).cond = cond; |
567 |
LAST_UINSTR(cb).cond = cond; |
299 |
} |
568 |
} |
300 |
|
569 |
|
|
|
570 |
/*------------------------------------------------------------*/ |
571 |
/*--- JMP helpers ---*/ |
572 |
/*------------------------------------------------------------*/ |
573 |
|
574 |
static __inline__ |
575 |
void jmp_lit( UCodeBlock* cb, Addr d32 ) |
576 |
{ |
577 |
uInstr1 (cb, JMP, 0, Literal, 0); |
578 |
uLiteral(cb, d32); |
579 |
uCond (cb, CondAlways); |
580 |
} |
581 |
|
582 |
static __inline__ |
583 |
void jmp_treg( UCodeBlock* cb, Int t ) |
584 |
{ |
585 |
uInstr1 (cb, JMP, 0, TempReg, t); |
586 |
uCond (cb, CondAlways); |
587 |
} |
588 |
|
589 |
static __inline__ |
590 |
void jcc_lit( UCodeBlock* cb, Addr d32, Condcode cond ) |
591 |
{ |
592 |
uInstr1 (cb, JMP, 0, Literal, 0); |
593 |
uLiteral (cb, d32); |
594 |
uCond (cb, cond); |
595 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
596 |
} |
597 |
|
301 |
|
598 |
|
302 |
/*------------------------------------------------------------*/ |
599 |
/*------------------------------------------------------------*/ |
303 |
/*--- Disassembling addressing modes ---*/ |
600 |
/*--- Disassembling addressing modes ---*/ |
Lines 352-359
Link Here
|
352 |
temporary, and the number of bytes in the address mode, are |
649 |
temporary, and the number of bytes in the address mode, are |
353 |
returned, as a pair (length << 24) | temp. Note that this fn should |
650 |
returned, as a pair (length << 24) | temp. Note that this fn should |
354 |
not be called if the R/M part of the address denotes a register |
651 |
not be called if the R/M part of the address denotes a register |
355 |
instead of memory. If buf is non-NULL, text of the addressing mode |
652 |
instead of memory. If VG_(print_codegen) is true, text of the addressing |
356 |
is placed therein. */ |
653 |
mode is placed therein. */ |
357 |
|
654 |
|
358 |
static |
655 |
static |
359 |
UInt disAMode ( UCodeBlock* cb, UChar sorb, Addr eip0, UChar* buf ) |
656 |
UInt disAMode ( UCodeBlock* cb, UChar sorb, Addr eip0, UChar* buf ) |
Lines 378-385
Link Here
|
378 |
{ UChar rm = mod_reg_rm; |
675 |
{ UChar rm = mod_reg_rm; |
379 |
uInstr2(cb, GET, 4, ArchReg, rm, TempReg, tmp); |
676 |
uInstr2(cb, GET, 4, ArchReg, rm, TempReg, tmp); |
380 |
handleSegOverride(cb, sorb, tmp); |
677 |
handleSegOverride(cb, sorb, tmp); |
381 |
if (buf) VG_(sprintf)(buf,"%s(%s)", sorbTxt(sorb), |
678 |
DIS(buf, "%s(%s)", sorbTxt(sorb), nameIReg(4,rm)); |
382 |
nameIReg(4,rm)); |
|
|
383 |
return (1<<24 | tmp); |
679 |
return (1<<24 | tmp); |
384 |
} |
680 |
} |
385 |
|
681 |
|
Lines 393-402
Link Here
|
393 |
UInt d = getSDisp8((Addr)eip); eip++; |
689 |
UInt d = getSDisp8((Addr)eip); eip++; |
394 |
uInstr2(cb, GET, 4, ArchReg, rm, TempReg, tmq); |
690 |
uInstr2(cb, GET, 4, ArchReg, rm, TempReg, tmq); |
395 |
uInstr2(cb, LEA1, 4, TempReg, tmq, TempReg, tmp); |
691 |
uInstr2(cb, LEA1, 4, TempReg, tmq, TempReg, tmp); |
396 |
LAST_UINSTR(cb).lit32 = d; |
692 |
uLiteral(cb, d); |
397 |
handleSegOverride(cb, sorb, tmp); |
693 |
handleSegOverride(cb, sorb, tmp); |
398 |
if (buf) VG_(sprintf)(buf,"%s%d(%s)", sorbTxt(sorb), |
694 |
DIS(buf, "%s%d(%s)", sorbTxt(sorb), d, nameIReg(4,rm)); |
399 |
d, nameIReg(4,rm)); |
|
|
400 |
return (2<<24 | tmp); |
695 |
return (2<<24 | tmp); |
401 |
} |
696 |
} |
402 |
|
697 |
|
Lines 410-419
Link Here
|
410 |
UInt d = getUDisp32((Addr)eip); eip += 4; |
705 |
UInt d = getUDisp32((Addr)eip); eip += 4; |
411 |
uInstr2(cb, GET, 4, ArchReg, rm, TempReg, tmq); |
706 |
uInstr2(cb, GET, 4, ArchReg, rm, TempReg, tmq); |
412 |
uInstr2(cb, LEA1, 4, TempReg, tmq, TempReg, tmp); |
707 |
uInstr2(cb, LEA1, 4, TempReg, tmq, TempReg, tmp); |
413 |
LAST_UINSTR(cb).lit32 = d; |
708 |
uLiteral(cb, d); |
414 |
handleSegOverride(cb, sorb, tmp); |
709 |
handleSegOverride(cb, sorb, tmp); |
415 |
if (buf) VG_(sprintf)(buf,"%s0x%x(%s)", sorbTxt(sorb), |
710 |
DIS(buf, "%s0x%x(%s)", sorbTxt(sorb), d, nameIReg(4,rm)); |
416 |
d, nameIReg(4,rm)); |
|
|
417 |
return (5<<24 | tmp); |
711 |
return (5<<24 | tmp); |
418 |
} |
712 |
} |
419 |
|
713 |
|
Lines 430-436
Link Here
|
430 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, tmp); |
724 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, tmp); |
431 |
uLiteral(cb, d); |
725 |
uLiteral(cb, d); |
432 |
handleSegOverride(cb, sorb, tmp); |
726 |
handleSegOverride(cb, sorb, tmp); |
433 |
if (buf) VG_(sprintf)(buf,"%s(0x%x)", sorbTxt(sorb), d); |
727 |
DIS(buf, "%s(0x%x)", sorbTxt(sorb), d); |
434 |
return (5<<24 | tmp); |
728 |
return (5<<24 | tmp); |
435 |
} |
729 |
} |
436 |
|
730 |
|
Lines 466-477
Link Here
|
466 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, base_tmp); |
760 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, base_tmp); |
467 |
uInstr3(cb, LEA2, 4, TempReg, base_tmp, TempReg, index_tmp, |
761 |
uInstr3(cb, LEA2, 4, TempReg, base_tmp, TempReg, index_tmp, |
468 |
TempReg, tmp); |
762 |
TempReg, tmp); |
469 |
LAST_UINSTR(cb).lit32 = 0; |
763 |
uLiteral(cb, 0); |
470 |
LAST_UINSTR(cb).extra4b = 1 << scale; |
764 |
LAST_UINSTR(cb).extra4b = 1 << scale; |
471 |
handleSegOverride(cb, sorb, tmp); |
765 |
handleSegOverride(cb, sorb, tmp); |
472 |
if (buf) VG_(sprintf)(buf,"%s(%s,%s,%d)", sorbTxt(sorb), |
766 |
DIS(buf, "%s(%s,%s,%d)", sorbTxt(sorb), |
473 |
nameIReg(4,base_r), |
767 |
nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale); |
474 |
nameIReg(4,index_r),1<<scale); |
|
|
475 |
return (2<<24 | tmp); |
768 |
return (2<<24 | tmp); |
476 |
} |
769 |
} |
477 |
|
770 |
|
Lines 483-501
Link Here
|
483 |
uLiteral(cb, 0); |
776 |
uLiteral(cb, 0); |
484 |
uInstr3(cb, LEA2, 4, TempReg, tmp, TempReg, index_tmp, |
777 |
uInstr3(cb, LEA2, 4, TempReg, tmp, TempReg, index_tmp, |
485 |
TempReg, tmp); |
778 |
TempReg, tmp); |
486 |
LAST_UINSTR(cb).lit32 = d; |
779 |
uLiteral(cb, d); |
487 |
LAST_UINSTR(cb).extra4b = 1 << scale; |
780 |
LAST_UINSTR(cb).extra4b = 1 << scale; |
488 |
handleSegOverride(cb, sorb, tmp); |
781 |
handleSegOverride(cb, sorb, tmp); |
489 |
if (buf) VG_(sprintf)(buf,"%s0x%x(,%s,%d)", sorbTxt(sorb), d, |
782 |
DIS(buf, "%s0x%x(,%s,%d)", sorbTxt(sorb), d, |
490 |
nameIReg(4,index_r),1<<scale); |
783 |
nameIReg(4,index_r), 1<<scale); |
491 |
return (6<<24 | tmp); |
784 |
return (6<<24 | tmp); |
492 |
} |
785 |
} |
493 |
|
786 |
|
494 |
if (index_r == R_ESP && base_r != R_EBP) { |
787 |
if (index_r == R_ESP && base_r != R_EBP) { |
495 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, tmp); |
788 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, tmp); |
496 |
handleSegOverride(cb, sorb, tmp); |
789 |
handleSegOverride(cb, sorb, tmp); |
497 |
if (buf) VG_(sprintf)(buf,"%s(%s,,)", |
790 |
DIS(buf, "%s(%s,,)", sorbTxt(sorb), nameIReg(4,base_r)); |
498 |
sorbTxt(sorb), nameIReg(4,base_r)); |
|
|
499 |
return (2<<24 | tmp); |
791 |
return (2<<24 | tmp); |
500 |
} |
792 |
} |
501 |
|
793 |
|
Lines 504-510
Link Here
|
504 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, tmp); |
796 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, tmp); |
505 |
uLiteral(cb, d); |
797 |
uLiteral(cb, d); |
506 |
handleSegOverride(cb, sorb, tmp); |
798 |
handleSegOverride(cb, sorb, tmp); |
507 |
if (buf) VG_(sprintf)(buf,"%s0x%x()", sorbTxt(sorb), d); |
799 |
DIS(buf, "%s0x%x()", sorbTxt(sorb), d); |
508 |
return (6<<24 | tmp); |
800 |
return (6<<24 | tmp); |
509 |
} |
801 |
} |
510 |
|
802 |
|
Lines 531-540
Link Here
|
531 |
Int tmq = newTemp(cb); |
823 |
Int tmq = newTemp(cb); |
532 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, tmq); |
824 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, tmq); |
533 |
uInstr2(cb, LEA1, 4, TempReg, tmq, TempReg, tmp); |
825 |
uInstr2(cb, LEA1, 4, TempReg, tmq, TempReg, tmp); |
534 |
LAST_UINSTR(cb).lit32 = d; |
826 |
uLiteral(cb, d); |
535 |
handleSegOverride(cb, sorb, tmp); |
827 |
handleSegOverride(cb, sorb, tmp); |
536 |
if (buf) VG_(sprintf)(buf,"%s%d(%s,,)", sorbTxt(sorb), |
828 |
DIS(buf, "%s%d(%s,,)", sorbTxt(sorb), d, nameIReg(4,base_r)); |
537 |
d, nameIReg(4,base_r)); |
|
|
538 |
return (3<<24 | tmp); |
829 |
return (3<<24 | tmp); |
539 |
} else { |
830 |
} else { |
540 |
Int index_tmp = newTemp(cb); |
831 |
Int index_tmp = newTemp(cb); |
Lines 543-554
Link Here
|
543 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, base_tmp); |
834 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, base_tmp); |
544 |
uInstr3(cb, LEA2, 4, TempReg, base_tmp, TempReg, index_tmp, |
835 |
uInstr3(cb, LEA2, 4, TempReg, base_tmp, TempReg, index_tmp, |
545 |
TempReg, tmp); |
836 |
TempReg, tmp); |
546 |
LAST_UINSTR(cb).lit32 = d; |
837 |
uLiteral(cb, d); |
547 |
LAST_UINSTR(cb).extra4b = 1 << scale; |
838 |
LAST_UINSTR(cb).extra4b = 1 << scale; |
548 |
handleSegOverride(cb, sorb, tmp); |
839 |
handleSegOverride(cb, sorb, tmp); |
549 |
if (buf) VG_(sprintf)(buf,"%s%d(%s,%s,%d)", |
840 |
DIS(buf, "%s%d(%s,%s,%d)", sorbTxt(sorb), d, |
550 |
sorbTxt(sorb), d, nameIReg(4,base_r), |
841 |
nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale); |
551 |
nameIReg(4,index_r), 1<<scale); |
|
|
552 |
return (3<<24 | tmp); |
842 |
return (3<<24 | tmp); |
553 |
} |
843 |
} |
554 |
vg_assert(0); |
844 |
vg_assert(0); |
Lines 574-583
Link Here
|
574 |
Int tmq = newTemp(cb); |
864 |
Int tmq = newTemp(cb); |
575 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, tmq); |
865 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, tmq); |
576 |
uInstr2(cb, LEA1, 4, TempReg, tmq, TempReg, tmp); |
866 |
uInstr2(cb, LEA1, 4, TempReg, tmq, TempReg, tmp); |
577 |
LAST_UINSTR(cb).lit32 = d; |
867 |
uLiteral(cb, d); |
578 |
handleSegOverride(cb, sorb, tmp); |
868 |
handleSegOverride(cb, sorb, tmp); |
579 |
if (buf) VG_(sprintf)(buf,"%s%d(%s,,)", |
869 |
DIS(buf, "%s%d(%s,,)", sorbTxt(sorb), d, nameIReg(4,base_r)); |
580 |
sorbTxt(sorb), d, nameIReg(4,base_r)); |
|
|
581 |
return (6<<24 | tmp); |
870 |
return (6<<24 | tmp); |
582 |
} else { |
871 |
} else { |
583 |
Int index_tmp = newTemp(cb); |
872 |
Int index_tmp = newTemp(cb); |
Lines 586-597
Link Here
|
586 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, base_tmp); |
875 |
uInstr2(cb, GET, 4, ArchReg, base_r, TempReg, base_tmp); |
587 |
uInstr3(cb, LEA2, 4, TempReg, base_tmp, TempReg, index_tmp, |
876 |
uInstr3(cb, LEA2, 4, TempReg, base_tmp, TempReg, index_tmp, |
588 |
TempReg, tmp); |
877 |
TempReg, tmp); |
589 |
LAST_UINSTR(cb).lit32 = d; |
878 |
uLiteral(cb, d); |
590 |
LAST_UINSTR(cb).extra4b = 1 << scale; |
879 |
LAST_UINSTR(cb).extra4b = 1 << scale; |
591 |
handleSegOverride(cb, sorb, tmp); |
880 |
handleSegOverride(cb, sorb, tmp); |
592 |
if (buf) VG_(sprintf)(buf,"%s%d(%s,%s,%d)", |
881 |
DIS(buf, "%s%d(%s,%s,%d)", sorbTxt(sorb), d, |
593 |
sorbTxt(sorb), d, nameIReg(4,base_r), |
882 |
nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale); |
594 |
nameIReg(4,index_r), 1<<scale); |
|
|
595 |
return (6<<24 | tmp); |
883 |
return (6<<24 | tmp); |
596 |
} |
884 |
} |
597 |
vg_assert(0); |
885 |
vg_assert(0); |
Lines 692-700
Link Here
|
692 |
void codegen_XOR_reg_with_itself ( UCodeBlock* cb, Int size, |
980 |
void codegen_XOR_reg_with_itself ( UCodeBlock* cb, Int size, |
693 |
Int ge_reg, Int tmp ) |
981 |
Int ge_reg, Int tmp ) |
694 |
{ |
982 |
{ |
695 |
if (dis) |
983 |
DIP("xor%c %s, %s\n", nameISize(size), |
696 |
VG_(printf)("xor%c %s, %s\n", nameISize(size), |
984 |
nameIReg(size,ge_reg), nameIReg(size,ge_reg) ); |
697 |
nameIReg(size,ge_reg), nameIReg(size,ge_reg) ); |
|
|
698 |
uInstr2(cb, MOV, size, Literal, 0, TempReg, tmp); |
985 |
uInstr2(cb, MOV, size, Literal, 0, TempReg, tmp); |
699 |
uLiteral(cb, 0); |
986 |
uLiteral(cb, 0); |
700 |
uInstr2(cb, XOR, size, TempReg, tmp, TempReg, tmp); |
987 |
uInstr2(cb, XOR, size, TempReg, tmp, TempReg, tmp); |
Lines 766-774
Link Here
|
766 |
} |
1053 |
} |
767 |
if (keep) |
1054 |
if (keep) |
768 |
uInstr2(cb, PUT, size, TempReg, tmp, ArchReg, gregOfRM(rm)); |
1055 |
uInstr2(cb, PUT, size, TempReg, tmp, ArchReg, gregOfRM(rm)); |
769 |
if (dis) VG_(printf)("%s%c %s,%s\n", t_x86opc, nameISize(size), |
1056 |
DIP("%s%c %s,%s\n", t_x86opc, nameISize(size), |
770 |
nameIReg(size,eregOfRM(rm)), |
1057 |
nameIReg(size,eregOfRM(rm)), |
771 |
nameIReg(size,gregOfRM(rm))); |
1058 |
nameIReg(size,gregOfRM(rm))); |
772 |
return 1+eip0; |
1059 |
return 1+eip0; |
773 |
} |
1060 |
} |
774 |
|
1061 |
|
Lines 777-783
Link Here
|
777 |
= (opc == ADD || opc == OR || opc == AND || opc == XOR || opc == ADC) |
1064 |
= (opc == ADD || opc == OR || opc == AND || opc == XOR || opc == ADC) |
778 |
? True : False; |
1065 |
? True : False; |
779 |
if (reversible) { |
1066 |
if (reversible) { |
780 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
1067 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf); |
781 |
Int tmpa = LOW24(pair); |
1068 |
Int tmpa = LOW24(pair); |
782 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmpa); |
1069 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmpa); |
783 |
|
1070 |
|
Lines 792-802
Link Here
|
792 |
} |
1079 |
} |
793 |
if (keep) |
1080 |
if (keep) |
794 |
uInstr2(cb, PUT, size, TempReg, tmpa, ArchReg, gregOfRM(rm)); |
1081 |
uInstr2(cb, PUT, size, TempReg, tmpa, ArchReg, gregOfRM(rm)); |
795 |
if (dis) VG_(printf)("%s%c %s,%s\n", t_x86opc, nameISize(size), |
1082 |
DIP("%s%c %s,%s\n", t_x86opc, nameISize(size), |
796 |
dis_buf,nameIReg(size,gregOfRM(rm))); |
1083 |
dis_buf,nameIReg(size,gregOfRM(rm))); |
797 |
return HI8(pair)+eip0; |
1084 |
return HI8(pair)+eip0; |
798 |
} else { |
1085 |
} else { |
799 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
1086 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf); |
800 |
Int tmpa = LOW24(pair); |
1087 |
Int tmpa = LOW24(pair); |
801 |
Int tmp2 = newTemp(cb); |
1088 |
Int tmp2 = newTemp(cb); |
802 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmpa); |
1089 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmpa); |
Lines 805-812
Link Here
|
805 |
setFlagsFromUOpcode(cb, opc); |
1092 |
setFlagsFromUOpcode(cb, opc); |
806 |
if (keep) |
1093 |
if (keep) |
807 |
uInstr2(cb, PUT, size, TempReg, tmp2, ArchReg, gregOfRM(rm)); |
1094 |
uInstr2(cb, PUT, size, TempReg, tmp2, ArchReg, gregOfRM(rm)); |
808 |
if (dis) VG_(printf)("%s%c %s,%s\n", t_x86opc, nameISize(size), |
1095 |
DIP("%s%c %s,%s\n", t_x86opc, nameISize(size), |
809 |
dis_buf,nameIReg(size,gregOfRM(rm))); |
1096 |
dis_buf,nameIReg(size,gregOfRM(rm))); |
810 |
return HI8(pair)+eip0; |
1097 |
return HI8(pair)+eip0; |
811 |
} |
1098 |
} |
812 |
} |
1099 |
} |
Lines 869-883
Link Here
|
869 |
} |
1156 |
} |
870 |
if (keep) |
1157 |
if (keep) |
871 |
uInstr2(cb, PUT, size, TempReg, tmp, ArchReg, eregOfRM(rm)); |
1158 |
uInstr2(cb, PUT, size, TempReg, tmp, ArchReg, eregOfRM(rm)); |
872 |
if (dis) VG_(printf)("%s%c %s,%s\n", t_x86opc, nameISize(size), |
1159 |
DIP("%s%c %s,%s\n", t_x86opc, nameISize(size), |
873 |
nameIReg(size,gregOfRM(rm)), |
1160 |
nameIReg(size,gregOfRM(rm)), |
874 |
nameIReg(size,eregOfRM(rm))); |
1161 |
nameIReg(size,eregOfRM(rm))); |
875 |
return 1+eip0; |
1162 |
return 1+eip0; |
876 |
} |
1163 |
} |
877 |
|
1164 |
|
878 |
/* E refers to memory */ |
1165 |
/* E refers to memory */ |
879 |
{ |
1166 |
{ |
880 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
1167 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf); |
881 |
Int tmpa = LOW24(pair); |
1168 |
Int tmpa = LOW24(pair); |
882 |
Int tmpv = newTemp(cb); |
1169 |
Int tmpv = newTemp(cb); |
883 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmpv); |
1170 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmpv); |
Lines 894-901
Link Here
|
894 |
if (keep) { |
1181 |
if (keep) { |
895 |
uInstr2(cb, STORE, size, TempReg, tmpv, TempReg, tmpa); |
1182 |
uInstr2(cb, STORE, size, TempReg, tmpv, TempReg, tmpa); |
896 |
} |
1183 |
} |
897 |
if (dis) VG_(printf)("%s%c %s,%s\n", t_x86opc, nameISize(size), |
1184 |
DIP("%s%c %s,%s\n", t_x86opc, nameISize(size), |
898 |
nameIReg(size,gregOfRM(rm)), dis_buf); |
1185 |
nameIReg(size,gregOfRM(rm)), dis_buf); |
899 |
return HI8(pair)+eip0; |
1186 |
return HI8(pair)+eip0; |
900 |
} |
1187 |
} |
901 |
} |
1188 |
} |
Lines 930-936
Link Here
|
930 |
Int tmpv = newTemp(cb); |
1217 |
Int tmpv = newTemp(cb); |
931 |
uInstr2(cb, GET, size, ArchReg, eregOfRM(rm), TempReg, tmpv); |
1218 |
uInstr2(cb, GET, size, ArchReg, eregOfRM(rm), TempReg, tmpv); |
932 |
uInstr2(cb, PUT, size, TempReg, tmpv, ArchReg, gregOfRM(rm)); |
1219 |
uInstr2(cb, PUT, size, TempReg, tmpv, ArchReg, gregOfRM(rm)); |
933 |
if (dis) VG_(printf)("mov%c %s,%s\n", nameISize(size), |
1220 |
DIP("mov%c %s,%s\n", nameISize(size), |
934 |
nameIReg(size,eregOfRM(rm)), |
1221 |
nameIReg(size,eregOfRM(rm)), |
935 |
nameIReg(size,gregOfRM(rm))); |
1222 |
nameIReg(size,gregOfRM(rm))); |
936 |
return 1+eip0; |
1223 |
return 1+eip0; |
Lines 938-949
Link Here
|
938 |
|
1225 |
|
939 |
/* E refers to memory */ |
1226 |
/* E refers to memory */ |
940 |
{ |
1227 |
{ |
941 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
1228 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf); |
942 |
Int tmpa = LOW24(pair); |
1229 |
Int tmpa = LOW24(pair); |
943 |
Int tmpb = newTemp(cb); |
1230 |
Int tmpb = newTemp(cb); |
944 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmpb); |
1231 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmpb); |
945 |
uInstr2(cb, PUT, size, TempReg, tmpb, ArchReg, gregOfRM(rm)); |
1232 |
uInstr2(cb, PUT, size, TempReg, tmpb, ArchReg, gregOfRM(rm)); |
946 |
if (dis) VG_(printf)("mov%c %s,%s\n", nameISize(size), |
1233 |
DIP("mov%c %s,%s\n", nameISize(size), |
947 |
dis_buf,nameIReg(size,gregOfRM(rm))); |
1234 |
dis_buf,nameIReg(size,gregOfRM(rm))); |
948 |
return HI8(pair)+eip0; |
1235 |
return HI8(pair)+eip0; |
949 |
} |
1236 |
} |
Lines 979-985
Link Here
|
979 |
Int tmpv = newTemp(cb); |
1266 |
Int tmpv = newTemp(cb); |
980 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, tmpv); |
1267 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, tmpv); |
981 |
uInstr2(cb, PUT, size, TempReg, tmpv, ArchReg, eregOfRM(rm)); |
1268 |
uInstr2(cb, PUT, size, TempReg, tmpv, ArchReg, eregOfRM(rm)); |
982 |
if (dis) VG_(printf)("mov%c %s,%s\n", nameISize(size), |
1269 |
DIP("mov%c %s,%s\n", nameISize(size), |
983 |
nameIReg(size,gregOfRM(rm)), |
1270 |
nameIReg(size,gregOfRM(rm)), |
984 |
nameIReg(size,eregOfRM(rm))); |
1271 |
nameIReg(size,eregOfRM(rm))); |
985 |
return 1+eip0; |
1272 |
return 1+eip0; |
Lines 987-998
Link Here
|
987 |
|
1274 |
|
988 |
/* E refers to memory */ |
1275 |
/* E refers to memory */ |
989 |
{ |
1276 |
{ |
990 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
1277 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf); |
991 |
Int tmpa = LOW24(pair); |
1278 |
Int tmpa = LOW24(pair); |
992 |
Int tmpv = newTemp(cb); |
1279 |
Int tmpv = newTemp(cb); |
993 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, tmpv); |
1280 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, tmpv); |
994 |
uInstr2(cb, STORE, size, TempReg, tmpv, TempReg, tmpa); |
1281 |
uInstr2(cb, STORE, size, TempReg, tmpv, TempReg, tmpa); |
995 |
if (dis) VG_(printf)("mov%c %s,%s\n", nameISize(size), |
1282 |
DIP("mov%c %s,%s\n", nameISize(size), |
996 |
nameIReg(size,gregOfRM(rm)), dis_buf); |
1283 |
nameIReg(size,gregOfRM(rm)), dis_buf); |
997 |
return HI8(pair)+eip0; |
1284 |
return HI8(pair)+eip0; |
998 |
} |
1285 |
} |
Lines 1024-1031
Link Here
|
1024 |
} |
1311 |
} |
1025 |
if (keep) |
1312 |
if (keep) |
1026 |
uInstr2(cb, PUT, size, TempReg, tmp, ArchReg, R_EAX); |
1313 |
uInstr2(cb, PUT, size, TempReg, tmp, ArchReg, R_EAX); |
1027 |
if (dis) VG_(printf)("%s%c $0x%x, %s\n", t_x86opc, nameISize(size), |
1314 |
DIP("%s%c $0x%x, %s\n", t_x86opc, nameISize(size), |
1028 |
lit, nameIReg(size,R_EAX)); |
1315 |
lit, nameIReg(size,R_EAX)); |
1029 |
return eip+size; |
1316 |
return eip+size; |
1030 |
} |
1317 |
} |
1031 |
|
1318 |
|
Lines 1045-1072
Link Here
|
1045 |
LAST_UINSTR(cb).extra4b = szs; |
1332 |
LAST_UINSTR(cb).extra4b = szs; |
1046 |
LAST_UINSTR(cb).signed_widen = sign_extend; |
1333 |
LAST_UINSTR(cb).signed_widen = sign_extend; |
1047 |
uInstr2(cb, PUT, szd, TempReg, tmpv, ArchReg, gregOfRM(rm)); |
1334 |
uInstr2(cb, PUT, szd, TempReg, tmpv, ArchReg, gregOfRM(rm)); |
1048 |
if (dis) VG_(printf)("mov%c%c%c %s,%s\n", |
1335 |
DIP("mov%c%c%c %s,%s\n", sign_extend ? 's' : 'z', |
1049 |
sign_extend ? 's' : 'z', |
1336 |
nameISize(szs), nameISize(szd), |
1050 |
nameISize(szs), nameISize(szd), |
1337 |
nameIReg(szs,eregOfRM(rm)), |
1051 |
nameIReg(szs,eregOfRM(rm)), |
1338 |
nameIReg(szd,gregOfRM(rm))); |
1052 |
nameIReg(szd,gregOfRM(rm))); |
|
|
1053 |
return 1+eip; |
1339 |
return 1+eip; |
1054 |
} |
1340 |
} |
1055 |
|
1341 |
|
1056 |
/* E refers to memory */ |
1342 |
/* E refers to memory */ |
1057 |
{ |
1343 |
{ |
1058 |
UInt pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL); |
1344 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf); |
1059 |
Int tmpa = LOW24(pair); |
1345 |
Int tmpa = LOW24(pair); |
1060 |
uInstr2(cb, LOAD, szs, TempReg, tmpa, TempReg, tmpa); |
1346 |
uInstr2(cb, LOAD, szs, TempReg, tmpa, TempReg, tmpa); |
1061 |
uInstr1(cb, WIDEN, szd, TempReg, tmpa); |
1347 |
uInstr1(cb, WIDEN, szd, TempReg, tmpa); |
1062 |
LAST_UINSTR(cb).extra4b = szs; |
1348 |
LAST_UINSTR(cb).extra4b = szs; |
1063 |
LAST_UINSTR(cb).signed_widen = sign_extend; |
1349 |
LAST_UINSTR(cb).signed_widen = sign_extend; |
1064 |
uInstr2(cb, PUT, szd, TempReg, tmpa, ArchReg, gregOfRM(rm)); |
1350 |
uInstr2(cb, PUT, szd, TempReg, tmpa, ArchReg, gregOfRM(rm)); |
1065 |
if (dis) VG_(printf)("mov%c%c%c %s,%s\n", |
1351 |
DIP("mov%c%c%c %s,%s\n", sign_extend ? 's' : 'z', |
1066 |
sign_extend ? 's' : 'z', |
1352 |
nameISize(szs), nameISize(szd), |
1067 |
nameISize(szs), nameISize(szd), |
1353 |
dis_buf, nameIReg(szd,gregOfRM(rm))); |
1068 |
dis_buf, |
|
|
1069 |
nameIReg(szd,gregOfRM(rm))); |
1070 |
return HI8(pair)+eip; |
1354 |
return HI8(pair)+eip; |
1071 |
} |
1355 |
} |
1072 |
} |
1356 |
} |
Lines 1160-1171
Link Here
|
1160 |
if (gregOfRM(modrm) < 7) |
1444 |
if (gregOfRM(modrm) < 7) |
1161 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
1445 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
1162 |
eip += (am_sz + d_sz); |
1446 |
eip += (am_sz + d_sz); |
1163 |
if (dis) |
1447 |
DIP("%s%c $0x%x, %s\n", nameGrp1(gregOfRM(modrm)), nameISize(sz), d32, |
1164 |
VG_(printf)("%s%c $0x%x, %s\n", |
1448 |
nameIReg(sz,eregOfRM(modrm))); |
1165 |
nameGrp1(gregOfRM(modrm)), nameISize(sz), d32, |
|
|
1166 |
nameIReg(sz,eregOfRM(modrm))); |
1167 |
} else { |
1449 |
} else { |
1168 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL); |
1450 |
pair = disAMode ( cb, sorb, eip, dis_buf); |
1169 |
t1 = LOW24(pair); |
1451 |
t1 = LOW24(pair); |
1170 |
t2 = newTemp(cb); |
1452 |
t2 = newTemp(cb); |
1171 |
eip += HI8(pair); |
1453 |
eip += HI8(pair); |
Lines 1192-1201
Link Here
|
1192 |
if (gregOfRM(modrm) < 7) { |
1474 |
if (gregOfRM(modrm) < 7) { |
1193 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1); |
1475 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1); |
1194 |
} |
1476 |
} |
1195 |
if (dis) |
1477 |
DIP("%s%c $0x%x, %s\n", nameGrp1(gregOfRM(modrm)), nameISize(sz), |
1196 |
VG_(printf)("%s%c $0x%x, %s\n", |
1478 |
d32, dis_buf); |
1197 |
nameGrp1(gregOfRM(modrm)), nameISize(sz), d32, |
|
|
1198 |
dis_buf); |
1199 |
} |
1479 |
} |
1200 |
return eip; |
1480 |
return eip; |
1201 |
} |
1481 |
} |
Lines 1247-1253
Link Here
|
1247 |
setFlagsFromUOpcode(cb, uopc); |
1527 |
setFlagsFromUOpcode(cb, uopc); |
1248 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
1528 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
1249 |
eip += (am_sz + d_sz); |
1529 |
eip += (am_sz + d_sz); |
1250 |
if (dis) { |
1530 |
if (VG_(print_codegen)) { |
1251 |
if (orig_src_tag == Literal) |
1531 |
if (orig_src_tag == Literal) |
1252 |
VG_(printf)("%s%c $0x%x, %s\n", |
1532 |
VG_(printf)("%s%c $0x%x, %s\n", |
1253 |
nameGrp2(gregOfRM(modrm)), nameISize(sz), |
1533 |
nameGrp2(gregOfRM(modrm)), nameISize(sz), |
Lines 1259-1265
Link Here
|
1259 |
nameIReg(sz,eregOfRM(modrm))); |
1539 |
nameIReg(sz,eregOfRM(modrm))); |
1260 |
} |
1540 |
} |
1261 |
} else { |
1541 |
} else { |
1262 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL); |
1542 |
pair = disAMode ( cb, sorb, eip, dis_buf); |
1263 |
t1 = LOW24(pair); |
1543 |
t1 = LOW24(pair); |
1264 |
t2 = newTemp(cb); |
1544 |
t2 = newTemp(cb); |
1265 |
eip += HI8(pair); |
1545 |
eip += HI8(pair); |
Lines 1280-1286
Link Here
|
1280 |
} |
1560 |
} |
1281 |
setFlagsFromUOpcode(cb, uopc); |
1561 |
setFlagsFromUOpcode(cb, uopc); |
1282 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1); |
1562 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1); |
1283 |
if (dis) { |
1563 |
if (VG_(print_codegen)) { |
1284 |
if (orig_src_tag == Literal) |
1564 |
if (orig_src_tag == Literal) |
1285 |
VG_(printf)("%s%c $0x%x, %s\n", |
1565 |
VG_(printf)("%s%c $0x%x, %s\n", |
1286 |
nameGrp2(gregOfRM(modrm)), nameISize(sz), |
1566 |
nameGrp2(gregOfRM(modrm)), nameISize(sz), |
Lines 1333-1339
Link Here
|
1333 |
And eip on entry points at the modrm byte. */ |
1613 |
And eip on entry points at the modrm byte. */ |
1334 |
Int t1, t2, t_fetched, t_mask; |
1614 |
Int t1, t2, t_fetched, t_mask; |
1335 |
UInt pair; |
1615 |
UInt pair; |
1336 |
UChar dis_buf[50]; |
1616 |
Char dis_buf[50]; |
1337 |
UInt v_mask; |
1617 |
UInt v_mask; |
1338 |
|
1618 |
|
1339 |
/* There is no 1-byte form of this instruction, AFAICS. */ |
1619 |
/* There is no 1-byte form of this instruction, AFAICS. */ |
Lines 1382-1394
Link Here
|
1382 |
uInstr2(cb, PUT, sz, TempReg, t2, ArchReg, eregOfRM(modrm)); |
1662 |
uInstr2(cb, PUT, sz, TempReg, t2, ArchReg, eregOfRM(modrm)); |
1383 |
|
1663 |
|
1384 |
eip += (am_sz + 1); |
1664 |
eip += (am_sz + 1); |
1385 |
if (dis) |
1665 |
DIP("%s%c $0x%x, %s\n", nameGrp8(gregOfRM(modrm)), nameISize(sz), |
1386 |
VG_(printf)("%s%c $0x%x, %s\n", |
1666 |
src_val, nameIReg(sz,eregOfRM(modrm))); |
1387 |
nameGrp8(gregOfRM(modrm)), nameISize(sz), |
|
|
1388 |
src_val, |
1389 |
nameIReg(sz,eregOfRM(modrm))); |
1390 |
} else { |
1667 |
} else { |
1391 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL); |
1668 |
pair = disAMode ( cb, sorb, eip, dis_buf); |
1392 |
t1 = LOW24(pair); |
1669 |
t1 = LOW24(pair); |
1393 |
t2 = newTemp(cb); |
1670 |
t2 = newTemp(cb); |
1394 |
eip += HI8(pair); |
1671 |
eip += HI8(pair); |
Lines 1402-1411
Link Here
|
1402 |
if (gregOfRM(modrm) != 4 /* BT */) { |
1679 |
if (gregOfRM(modrm) != 4 /* BT */) { |
1403 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1); |
1680 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1); |
1404 |
} |
1681 |
} |
1405 |
if (dis) |
1682 |
DIP("%s%c $0x%x, %s\n", nameGrp8(gregOfRM(modrm)), nameISize(sz), |
1406 |
VG_(printf)("%s%c $0x%x, %s\n", |
1683 |
src_val, dis_buf); |
1407 |
nameGrp8(gregOfRM(modrm)), nameISize(sz), src_val, |
|
|
1408 |
dis_buf); |
1409 |
} |
1684 |
} |
1410 |
return eip; |
1685 |
return eip; |
1411 |
|
1686 |
|
Lines 1449-1456
Link Here
|
1449 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
1724 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
1450 |
} |
1725 |
} |
1451 |
uInstr0(cb, CALLM_E, 0); |
1726 |
uInstr0(cb, CALLM_E, 0); |
1452 |
if (dis) VG_(printf)("%s%c %s\n", signed_multiply ? "imul" : "mul", |
1727 |
DIP("%s%c %s\n", signed_multiply ? "imul" : "mul", |
1453 |
nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1728 |
nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1454 |
|
1729 |
|
1455 |
} |
1730 |
} |
1456 |
|
1731 |
|
Lines 1488-1495
Link Here
|
1488 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
1763 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
1489 |
} |
1764 |
} |
1490 |
uInstr0(cb, CALLM_E, 0); |
1765 |
uInstr0(cb, CALLM_E, 0); |
1491 |
if (dis) VG_(printf)("%s%c %s\n", signed_multiply ? "imul" : "mul", |
1766 |
DIP("%s%c %s\n", signed_multiply ? "imul" : "mul", |
1492 |
nameISize(sz), dis_buf); |
1767 |
nameISize(sz), dis_buf); |
1493 |
} |
1768 |
} |
1494 |
|
1769 |
|
1495 |
|
1770 |
|
Lines 1516-1524
Link Here
|
1516 |
uLiteral(cb, d32); |
1791 |
uLiteral(cb, d32); |
1517 |
uInstr2(cb, AND, sz, TempReg, tao, TempReg, t1); |
1792 |
uInstr2(cb, AND, sz, TempReg, tao, TempReg, t1); |
1518 |
setFlagsFromUOpcode(cb, AND); |
1793 |
setFlagsFromUOpcode(cb, AND); |
1519 |
if (dis) |
1794 |
DIP("test%c $0x%x, %s\n", |
1520 |
VG_(printf)("test%c $0x%x, %s\n", |
1795 |
nameISize(sz), d32, nameIReg(sz, eregOfRM(modrm))); |
1521 |
nameISize(sz), d32, nameIReg(sz, eregOfRM(modrm))); |
|
|
1522 |
break; |
1796 |
break; |
1523 |
} |
1797 |
} |
1524 |
case 2: /* NOT */ |
1798 |
case 2: /* NOT */ |
Lines 1527-1535
Link Here
|
1527 |
uInstr1(cb, NOT, sz, TempReg, t1); |
1801 |
uInstr1(cb, NOT, sz, TempReg, t1); |
1528 |
setFlagsFromUOpcode(cb, NOT); |
1802 |
setFlagsFromUOpcode(cb, NOT); |
1529 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
1803 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
1530 |
if (dis) |
1804 |
DIP("not%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1531 |
VG_(printf)("not%c %s\n", |
|
|
1532 |
nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1533 |
break; |
1805 |
break; |
1534 |
case 3: /* NEG */ |
1806 |
case 3: /* NEG */ |
1535 |
eip++; |
1807 |
eip++; |
Lines 1537-1545
Link Here
|
1537 |
uInstr1(cb, NEG, sz, TempReg, t1); |
1809 |
uInstr1(cb, NEG, sz, TempReg, t1); |
1538 |
setFlagsFromUOpcode(cb, NEG); |
1810 |
setFlagsFromUOpcode(cb, NEG); |
1539 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
1811 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
1540 |
if (dis) |
1812 |
DIP("neg%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1541 |
VG_(printf)("neg%c %s\n", |
|
|
1542 |
nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1543 |
break; |
1813 |
break; |
1544 |
case 4: /* MUL */ |
1814 |
case 4: /* MUL */ |
1545 |
eip++; |
1815 |
eip++; |
Lines 1553-1569
Link Here
|
1553 |
eip++; |
1823 |
eip++; |
1554 |
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t1); |
1824 |
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t1); |
1555 |
codegen_div ( cb, sz, t1, False ); |
1825 |
codegen_div ( cb, sz, t1, False ); |
1556 |
if (dis) |
1826 |
DIP("div%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1557 |
VG_(printf)("div%c %s\n", nameISize(sz), |
|
|
1558 |
nameIReg(sz, eregOfRM(modrm))); |
1559 |
break; |
1827 |
break; |
1560 |
case 7: /* IDIV */ |
1828 |
case 7: /* IDIV */ |
1561 |
eip++; |
1829 |
eip++; |
1562 |
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t1); |
1830 |
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t1); |
1563 |
codegen_div ( cb, sz, t1, True ); |
1831 |
codegen_div ( cb, sz, t1, True ); |
1564 |
if (dis) |
1832 |
DIP("idiv%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1565 |
VG_(printf)("idiv%c %s\n", nameISize(sz), |
|
|
1566 |
nameIReg(sz, eregOfRM(modrm))); |
1567 |
break; |
1833 |
break; |
1568 |
default: |
1834 |
default: |
1569 |
VG_(printf)( |
1835 |
VG_(printf)( |
Lines 1571-1577
Link Here
|
1571 |
VG_(core_panic)("Grp3"); |
1837 |
VG_(core_panic)("Grp3"); |
1572 |
} |
1838 |
} |
1573 |
} else { |
1839 |
} else { |
1574 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
1840 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
1575 |
t2 = LOW24(pair); |
1841 |
t2 = LOW24(pair); |
1576 |
t1 = newTemp(cb); |
1842 |
t1 = newTemp(cb); |
1577 |
eip += HI8(pair); |
1843 |
eip += HI8(pair); |
Lines 1584-1624
Link Here
|
1584 |
uLiteral(cb, d32); |
1850 |
uLiteral(cb, d32); |
1585 |
uInstr2(cb, AND, sz, TempReg, tao, TempReg, t1); |
1851 |
uInstr2(cb, AND, sz, TempReg, tao, TempReg, t1); |
1586 |
setFlagsFromUOpcode(cb, AND); |
1852 |
setFlagsFromUOpcode(cb, AND); |
1587 |
if (dis) |
1853 |
DIP("test%c $0x%x, %s\n", nameISize(sz), d32, dis_buf); |
1588 |
VG_(printf)("test%c $0x%x, %s\n", |
|
|
1589 |
nameISize(sz), d32, dis_buf); |
1590 |
break; |
1854 |
break; |
1591 |
} |
1855 |
} |
1592 |
case 2: /* NOT */ |
1856 |
case 2: /* NOT */ |
1593 |
uInstr1(cb, NOT, sz, TempReg, t1); |
1857 |
uInstr1(cb, NOT, sz, TempReg, t1); |
1594 |
setFlagsFromUOpcode(cb, NOT); |
1858 |
setFlagsFromUOpcode(cb, NOT); |
1595 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
1859 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
1596 |
if (dis) |
1860 |
DIP("not%c %s\n", nameISize(sz), dis_buf); |
1597 |
VG_(printf)("not%c %s\n", nameISize(sz), dis_buf); |
|
|
1598 |
break; |
1861 |
break; |
1599 |
case 3: /* NEG */ |
1862 |
case 3: /* NEG */ |
1600 |
uInstr1(cb, NEG, sz, TempReg, t1); |
1863 |
uInstr1(cb, NEG, sz, TempReg, t1); |
1601 |
setFlagsFromUOpcode(cb, NEG); |
1864 |
setFlagsFromUOpcode(cb, NEG); |
1602 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
1865 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
1603 |
if (dis) |
1866 |
DIP("neg%c %s\n", nameISize(sz), dis_buf); |
1604 |
VG_(printf)("neg%c %s\n", nameISize(sz), dis_buf); |
|
|
1605 |
break; |
1867 |
break; |
1606 |
case 4: /* MUL */ |
1868 |
case 4: /* MUL */ |
1607 |
codegen_mul_A_D_Temp ( cb, sz, t1, False, |
1869 |
codegen_mul_A_D_Temp ( cb, sz, t1, False, |
1608 |
dis?dis_buf:NULL ); |
1870 |
dis_buf ); |
1609 |
break; |
1871 |
break; |
1610 |
case 5: /* IMUL */ |
1872 |
case 5: /* IMUL */ |
1611 |
codegen_mul_A_D_Temp ( cb, sz, t1, True, dis?dis_buf:NULL ); |
1873 |
codegen_mul_A_D_Temp ( cb, sz, t1, True, dis_buf ); |
1612 |
break; |
1874 |
break; |
1613 |
case 6: /* DIV */ |
1875 |
case 6: /* DIV */ |
1614 |
codegen_div ( cb, sz, t1, False ); |
1876 |
codegen_div ( cb, sz, t1, False ); |
1615 |
if (dis) |
1877 |
DIP("div%c %s\n", nameISize(sz), dis_buf); |
1616 |
VG_(printf)("div%c %s\n", nameISize(sz), dis_buf); |
|
|
1617 |
break; |
1878 |
break; |
1618 |
case 7: /* IDIV */ |
1879 |
case 7: /* IDIV */ |
1619 |
codegen_div ( cb, sz, t1, True ); |
1880 |
codegen_div ( cb, sz, t1, True ); |
1620 |
if (dis) |
1881 |
DIP("idiv%c %s\n", nameISize(sz), dis_buf); |
1621 |
VG_(printf)("idiv%c %s\n", nameISize(sz), dis_buf); |
|
|
1622 |
break; |
1882 |
break; |
1623 |
default: |
1883 |
default: |
1624 |
VG_(printf)( |
1884 |
VG_(printf)( |
Lines 1663-1673
Link Here
|
1663 |
VG_(core_panic)("Grp4"); |
1923 |
VG_(core_panic)("Grp4"); |
1664 |
} |
1924 |
} |
1665 |
eip++; |
1925 |
eip++; |
1666 |
if (dis) |
1926 |
DIP("%sb %s\n", nameGrp4(gregOfRM(modrm)), |
1667 |
VG_(printf)("%sb %s\n", nameGrp4(gregOfRM(modrm)), |
1927 |
nameIReg(1, eregOfRM(modrm))); |
1668 |
nameIReg(1, eregOfRM(modrm))); |
|
|
1669 |
} else { |
1928 |
} else { |
1670 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
1929 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
1671 |
t2 = LOW24(pair); |
1930 |
t2 = LOW24(pair); |
1672 |
t1 = newTemp(cb); |
1931 |
t1 = newTemp(cb); |
1673 |
uInstr2(cb, LOAD, 1, TempReg, t2, TempReg, t1); |
1932 |
uInstr2(cb, LOAD, 1, TempReg, t2, TempReg, t1); |
Lines 1688-1695
Link Here
|
1688 |
VG_(core_panic)("Grp4"); |
1947 |
VG_(core_panic)("Grp4"); |
1689 |
} |
1948 |
} |
1690 |
eip += HI8(pair); |
1949 |
eip += HI8(pair); |
1691 |
if (dis) |
1950 |
DIP("%sb %s\n", nameGrp4(gregOfRM(modrm)), dis_buf); |
1692 |
VG_(printf)("%sb %s\n", nameGrp4(gregOfRM(modrm)), dis_buf); |
|
|
1693 |
} |
1951 |
} |
1694 |
return eip; |
1952 |
return eip; |
1695 |
} |
1953 |
} |
Lines 1731-1744
Link Here
|
1731 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, t4); |
1989 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, t4); |
1732 |
uLiteral(cb, eip+1); |
1990 |
uLiteral(cb, eip+1); |
1733 |
uInstr2(cb, STORE, 4, TempReg, t4, TempReg, t3); |
1991 |
uInstr2(cb, STORE, 4, TempReg, t4, TempReg, t3); |
1734 |
uInstr1(cb, JMP, 0, TempReg, t1); |
1992 |
jmp_treg(cb, t1); |
1735 |
uCond(cb, CondAlways); |
|
|
1736 |
LAST_UINSTR(cb).jmpkind = JmpCall; |
1993 |
LAST_UINSTR(cb).jmpkind = JmpCall; |
1737 |
*isEnd = True; |
1994 |
*isEnd = True; |
1738 |
break; |
1995 |
break; |
1739 |
case 4: /* jmp Ev */ |
1996 |
case 4: /* jmp Ev */ |
1740 |
uInstr1(cb, JMP, 0, TempReg, t1); |
1997 |
jmp_treg(cb, t1); |
1741 |
uCond(cb, CondAlways); |
|
|
1742 |
*isEnd = True; |
1998 |
*isEnd = True; |
1743 |
break; |
1999 |
break; |
1744 |
default: |
2000 |
default: |
Lines 1747-1757
Link Here
|
1747 |
VG_(core_panic)("Grp5"); |
2003 |
VG_(core_panic)("Grp5"); |
1748 |
} |
2004 |
} |
1749 |
eip++; |
2005 |
eip++; |
1750 |
if (dis) |
2006 |
DIP("%s%c %s\n", nameGrp5(gregOfRM(modrm)), |
1751 |
VG_(printf)("%s%c %s\n", nameGrp5(gregOfRM(modrm)), |
2007 |
nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
1752 |
nameISize(sz), nameIReg(sz, eregOfRM(modrm))); |
|
|
1753 |
} else { |
2008 |
} else { |
1754 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
2009 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
1755 |
t2 = LOW24(pair); |
2010 |
t2 = LOW24(pair); |
1756 |
t1 = newTemp(cb); |
2011 |
t1 = newTemp(cb); |
1757 |
uInstr2(cb, LOAD, sz, TempReg, t2, TempReg, t1); |
2012 |
uInstr2(cb, LOAD, sz, TempReg, t2, TempReg, t1); |
Lines 1775-1788
Link Here
|
1775 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, t4); |
2030 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, t4); |
1776 |
uLiteral(cb, eip+HI8(pair)); |
2031 |
uLiteral(cb, eip+HI8(pair)); |
1777 |
uInstr2(cb, STORE, 4, TempReg, t4, TempReg, t3); |
2032 |
uInstr2(cb, STORE, 4, TempReg, t4, TempReg, t3); |
1778 |
uInstr1(cb, JMP, 0, TempReg, t1); |
2033 |
jmp_treg(cb, t1); |
1779 |
uCond(cb, CondAlways); |
|
|
1780 |
LAST_UINSTR(cb).jmpkind = JmpCall; |
2034 |
LAST_UINSTR(cb).jmpkind = JmpCall; |
1781 |
*isEnd = True; |
2035 |
*isEnd = True; |
1782 |
break; |
2036 |
break; |
1783 |
case 4: /* JMP Ev */ |
2037 |
case 4: /* JMP Ev */ |
1784 |
uInstr1(cb, JMP, 0, TempReg, t1); |
2038 |
jmp_treg(cb, t1); |
1785 |
uCond(cb, CondAlways); |
|
|
1786 |
*isEnd = True; |
2039 |
*isEnd = True; |
1787 |
break; |
2040 |
break; |
1788 |
case 6: /* PUSH Ev */ |
2041 |
case 6: /* PUSH Ev */ |
Lines 1799-1819
Link Here
|
1799 |
VG_(core_panic)("Grp5"); |
2052 |
VG_(core_panic)("Grp5"); |
1800 |
} |
2053 |
} |
1801 |
eip += HI8(pair); |
2054 |
eip += HI8(pair); |
1802 |
if (dis) |
2055 |
DIP("%s%c %s\n", nameGrp5(gregOfRM(modrm)), |
1803 |
VG_(printf)("%s%c %s\n", nameGrp5(gregOfRM(modrm)), |
2056 |
nameISize(sz), dis_buf); |
1804 |
nameISize(sz), dis_buf); |
|
|
1805 |
} |
2057 |
} |
1806 |
return eip; |
2058 |
return eip; |
1807 |
} |
2059 |
} |
1808 |
|
2060 |
|
1809 |
static __inline__ |
|
|
1810 |
void dis_JMP_d32( UCodeBlock* cb, Addr d32 ) |
1811 |
{ |
1812 |
uInstr1(cb, JMP, 0, Literal, 0); |
1813 |
uLiteral(cb, d32); |
1814 |
uCond(cb, CondAlways); |
1815 |
} |
1816 |
|
1817 |
/*------------------------------------------------------------*/ |
2061 |
/*------------------------------------------------------------*/ |
1818 |
/*--- Disassembling string ops (including REP prefixes) ---*/ |
2062 |
/*--- Disassembling string ops (including REP prefixes) ---*/ |
1819 |
/*------------------------------------------------------------*/ |
2063 |
/*------------------------------------------------------------*/ |
Lines 1847-1853
Link Here
|
1847 |
vg_assert(sorb == 0); |
2091 |
vg_assert(sorb == 0); |
1848 |
dis_string_op_increment(cb, sz, t_inc); |
2092 |
dis_string_op_increment(cb, sz, t_inc); |
1849 |
dis_OP( cb, sz, t_inc ); |
2093 |
dis_OP( cb, sz, t_inc ); |
1850 |
if (dis) VG_(printf)("%s%c\n", name, nameISize(sz)); |
2094 |
DIP("%s%c\n", name, nameISize(sz)); |
1851 |
} |
2095 |
} |
1852 |
|
2096 |
|
1853 |
|
2097 |
|
Lines 1964-1979
Link Here
|
1964 |
dis_OP (cb, sz, t_inc); |
2208 |
dis_OP (cb, sz, t_inc); |
1965 |
|
2209 |
|
1966 |
if (cond == CondAlways) { |
2210 |
if (cond == CondAlways) { |
1967 |
dis_JMP_d32 (cb, eip); |
2211 |
jmp_lit(cb, eip); |
1968 |
} else { |
2212 |
} else { |
1969 |
uInstr1 (cb, JMP, 0, Literal, 0); |
2213 |
jcc_lit(cb, eip, cond); |
1970 |
uLiteral (cb, eip); |
2214 |
jmp_lit(cb, eip_next); |
1971 |
uCond (cb, cond); |
|
|
1972 |
uFlagsRWU (cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
1973 |
|
1974 |
dis_JMP_d32 (cb, eip_next); |
1975 |
} |
2215 |
} |
1976 |
if (dis) VG_(printf)("%s%c\n", name, nameISize(sz)); |
2216 |
DIP("%s%c\n", name, nameISize(sz)); |
1977 |
} |
2217 |
} |
1978 |
|
2218 |
|
1979 |
/*------------------------------------------------------------*/ |
2219 |
/*------------------------------------------------------------*/ |
Lines 2001-2016
Link Here
|
2001 |
uInstr2(cb, MUL, size, ArchReg, eregOfRM(rm), TempReg, tg); |
2241 |
uInstr2(cb, MUL, size, ArchReg, eregOfRM(rm), TempReg, tg); |
2002 |
setFlagsFromUOpcode(cb, MUL); |
2242 |
setFlagsFromUOpcode(cb, MUL); |
2003 |
uInstr2(cb, PUT, size, TempReg, tg, ArchReg, gregOfRM(rm)); |
2243 |
uInstr2(cb, PUT, size, TempReg, tg, ArchReg, gregOfRM(rm)); |
2004 |
if (dis) VG_(printf)("%smul%c %s, %s\n", |
2244 |
DIP("%smul%c %s, %s\n", signed_multiply ? "i" : "", |
2005 |
signed_multiply ? "i" : "", |
2245 |
nameISize(size), |
2006 |
nameISize(size), |
2246 |
nameIReg(size,eregOfRM(rm)), |
2007 |
nameIReg(size,eregOfRM(rm)), |
2247 |
nameIReg(size,gregOfRM(rm))); |
2008 |
nameIReg(size,gregOfRM(rm))); |
|
|
2009 |
return 1+eip0; |
2248 |
return 1+eip0; |
2010 |
} else { |
2249 |
} else { |
2011 |
UInt pair; |
2250 |
UInt pair; |
2012 |
vg_assert(signed_multiply); |
2251 |
vg_assert(signed_multiply); |
2013 |
pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
2252 |
pair = disAMode ( cb, sorb, eip0, dis_buf ); |
2014 |
ta = LOW24(pair); |
2253 |
ta = LOW24(pair); |
2015 |
uInstr2(cb, LOAD, size, TempReg, ta, TempReg, te); |
2254 |
uInstr2(cb, LOAD, size, TempReg, ta, TempReg, te); |
2016 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, tg); |
2255 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, tg); |
Lines 2018-2027
Link Here
|
2018 |
setFlagsFromUOpcode(cb, MUL); |
2257 |
setFlagsFromUOpcode(cb, MUL); |
2019 |
uInstr2(cb, PUT, size, TempReg, tg, ArchReg, gregOfRM(rm)); |
2258 |
uInstr2(cb, PUT, size, TempReg, tg, ArchReg, gregOfRM(rm)); |
2020 |
|
2259 |
|
2021 |
if (dis) VG_(printf)("%smul%c %s, %s\n", |
2260 |
DIP("%smul%c %s, %s\n", signed_multiply ? "i" : "", |
2022 |
signed_multiply ? "i" : "", |
2261 |
nameISize(size), |
2023 |
nameISize(size), |
2262 |
dis_buf, nameIReg(size,gregOfRM(rm))); |
2024 |
dis_buf,nameIReg(size,gregOfRM(rm))); |
|
|
2025 |
return HI8(pair)+eip0; |
2263 |
return HI8(pair)+eip0; |
2026 |
} |
2264 |
} |
2027 |
} |
2265 |
} |
Lines 2036-2042
Link Here
|
2036 |
Int litsize ) |
2274 |
Int litsize ) |
2037 |
{ |
2275 |
{ |
2038 |
Int ta, te, tl, d32; |
2276 |
Int ta, te, tl, d32; |
2039 |
UChar dis_buf[50]; |
2277 |
Char dis_buf[50]; |
2040 |
UChar rm = getUChar(eip); |
2278 |
UChar rm = getUChar(eip); |
2041 |
ta = INVALID_TEMPREG; |
2279 |
ta = INVALID_TEMPREG; |
2042 |
te = newTemp(cb); |
2280 |
te = newTemp(cb); |
Lines 2046-2052
Link Here
|
2046 |
uInstr2(cb, GET, size, ArchReg, eregOfRM(rm), TempReg, te); |
2284 |
uInstr2(cb, GET, size, ArchReg, eregOfRM(rm), TempReg, te); |
2047 |
eip++; |
2285 |
eip++; |
2048 |
} else { |
2286 |
} else { |
2049 |
UInt pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL); |
2287 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
2050 |
ta = LOW24(pair); |
2288 |
ta = LOW24(pair); |
2051 |
uInstr2(cb, LOAD, size, TempReg, ta, TempReg, te); |
2289 |
uInstr2(cb, LOAD, size, TempReg, ta, TempReg, te); |
2052 |
eip += HI8(pair); |
2290 |
eip += HI8(pair); |
Lines 2061-2075
Link Here
|
2061 |
setFlagsFromUOpcode(cb, MUL); |
2299 |
setFlagsFromUOpcode(cb, MUL); |
2062 |
uInstr2(cb, PUT, size, TempReg, te, ArchReg, gregOfRM(rm)); |
2300 |
uInstr2(cb, PUT, size, TempReg, te, ArchReg, gregOfRM(rm)); |
2063 |
|
2301 |
|
2064 |
if (dis) { |
2302 |
DIP("imul %d, %s, %s\n", d32, |
2065 |
if (epartIsReg(rm)) { |
2303 |
( epartIsReg(rm) ? nameIReg(size,eregOfRM(rm)) : dis_buf ), |
2066 |
VG_(printf)("imul %d, %s, %s\n", d32, nameIReg(size,eregOfRM(rm)), |
2304 |
nameIReg(size,gregOfRM(rm)) ); |
2067 |
nameIReg(size,gregOfRM(rm))); |
|
|
2068 |
} else { |
2069 |
VG_(printf)("imul %d, %s, %s\n", d32, dis_buf, |
2070 |
nameIReg(size,gregOfRM(rm))); |
2071 |
} |
2072 |
} |
2073 |
|
2305 |
|
2074 |
return eip; |
2306 |
return eip; |
2075 |
} |
2307 |
} |
Lines 2089-2111
Link Here
|
2089 |
UChar second_byte = getUChar(eip); |
2321 |
UChar second_byte = getUChar(eip); |
2090 |
vg_assert(second_byte < 0xC0); |
2322 |
vg_assert(second_byte < 0xC0); |
2091 |
second_byte &= 0x38; |
2323 |
second_byte &= 0x38; |
2092 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
2324 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
2093 |
ta = LOW24(pair); |
2325 |
ta = LOW24(pair); |
2094 |
eip += HI8(pair); |
2326 |
eip += HI8(pair); |
2095 |
uInstr2(cb, is_write ? FPU_W : FPU_R, size, |
2327 |
uInstr2(cb, is_write ? FPU_W : FPU_R, size, |
2096 |
Lit16, |
2328 |
Lit16, |
2097 |
(((UShort)first_byte) << 8) | ((UShort)second_byte), |
2329 |
(((UShort)first_byte) << 8) | ((UShort)second_byte), |
2098 |
TempReg, ta); |
2330 |
TempReg, ta); |
2099 |
if (dis) { |
2331 |
if (is_write) { |
2100 |
if (is_write) |
2332 |
DIP("fpu_w_%d 0x%x:0x%x, %s\n", |
2101 |
VG_(printf)("fpu_w_%d 0x%x:0x%x, %s\n", |
2333 |
size, (UInt)first_byte, (UInt)second_byte, dis_buf ); |
2102 |
size, (UInt)first_byte, |
2334 |
} else { |
2103 |
(UInt)second_byte, dis_buf ); |
2335 |
DIP("fpu_r_%d %s, 0x%x:0x%x\n", |
2104 |
else |
2336 |
size, dis_buf, (UInt)first_byte, (UInt)second_byte ); |
2105 |
VG_(printf)("fpu_r_%d %s, 0x%x:0x%x\n", |
|
|
2106 |
size, dis_buf, |
2107 |
(UInt)first_byte, |
2108 |
(UInt)second_byte ); |
2109 |
} |
2337 |
} |
2110 |
return eip; |
2338 |
return eip; |
2111 |
} |
2339 |
} |
Lines 2174-2183
Link Here
|
2174 |
vg_assert(!uses_ZCP); |
2402 |
vg_assert(!uses_ZCP); |
2175 |
} |
2403 |
} |
2176 |
|
2404 |
|
2177 |
if (dis) VG_(printf)("fpu 0x%x:0x%x%s%s\n", |
2405 |
DIP("fpu 0x%x:0x%x%s%s\n", (UInt)first_byte, (UInt)second_byte, |
2178 |
(UInt)first_byte, (UInt)second_byte, |
2406 |
uses_ZCP ? " -rZCP" : "", |
2179 |
uses_ZCP ? " -rZCP" : "", |
2407 |
sets_ZCP ? " -wZCP" : "" ); |
2180 |
sets_ZCP ? " -wZCP" : "" ); |
|
|
2181 |
return eip; |
2408 |
return eip; |
2182 |
} |
2409 |
} |
2183 |
|
2410 |
|
Lines 2205-2211
Link Here
|
2205 |
uInstr1(cb, POP, 2, TempReg, t1); |
2432 |
uInstr1(cb, POP, 2, TempReg, t1); |
2206 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
2433 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
2207 |
uInstr0(cb, CALLM_E, 0); |
2434 |
uInstr0(cb, CALLM_E, 0); |
2208 |
if (dis) VG_(printf)("fstsw %%ax\n"); |
2435 |
DIP("fstsw %%ax\n"); |
2209 |
eip++; |
2436 |
eip++; |
2210 |
return eip; |
2437 |
return eip; |
2211 |
} |
2438 |
} |
Lines 2407-2419
Link Here
|
2407 |
uFlagsRWU(cb, FlagsEmpty, FlagsOSZACP, FlagsEmpty); |
2634 |
uFlagsRWU(cb, FlagsEmpty, FlagsOSZACP, FlagsEmpty); |
2408 |
uInstr1(cb, POP, sz, TempReg, t); |
2635 |
uInstr1(cb, POP, sz, TempReg, t); |
2409 |
uInstr2(cb, PUT, sz, TempReg, t, ArchReg, eregOfRM(modrm)); |
2636 |
uInstr2(cb, PUT, sz, TempReg, t, ArchReg, eregOfRM(modrm)); |
2410 |
if (dis) |
2637 |
DIP("sh%cd%c %%cl, %s, %s\n", |
2411 |
VG_(printf)("sh%cd%c %%cl, %s, %s\n", |
2638 |
( left_shift ? 'l' : 'r' ), nameISize(sz), |
2412 |
( left_shift ? 'l' : 'r' ), |
2639 |
nameIReg(sz, gregOfRM(modrm)), nameIReg(sz, eregOfRM(modrm))); |
2413 |
nameISize(sz), nameIReg(sz, gregOfRM(modrm)), |
|
|
2414 |
nameIReg(sz, eregOfRM(modrm))); |
2415 |
} else { |
2640 |
} else { |
2416 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
2641 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
2417 |
ta = LOW24(pair); |
2642 |
ta = LOW24(pair); |
2418 |
eip += HI8(pair); |
2643 |
eip += HI8(pair); |
2419 |
uInstr2(cb, LOAD, sz, TempReg, ta, TempReg, t2); |
2644 |
uInstr2(cb, LOAD, sz, TempReg, ta, TempReg, t2); |
Lines 2422-2432
Link Here
|
2422 |
uFlagsRWU(cb, FlagsEmpty, FlagsOSZACP, FlagsEmpty); |
2647 |
uFlagsRWU(cb, FlagsEmpty, FlagsOSZACP, FlagsEmpty); |
2423 |
uInstr1(cb, POP, sz, TempReg, t); |
2648 |
uInstr1(cb, POP, sz, TempReg, t); |
2424 |
uInstr2(cb, STORE, sz, TempReg, t, TempReg, ta); |
2649 |
uInstr2(cb, STORE, sz, TempReg, t, TempReg, ta); |
2425 |
if (dis) |
2650 |
DIP("sh%cd%c %%cl, %s, %s\n", ( left_shift ? 'l' : 'r' ), |
2426 |
VG_(printf)("sh%cd%c %%cl, %s, %s\n", |
2651 |
nameISize(sz), nameIReg(sz, gregOfRM(modrm)), dis_buf); |
2427 |
( left_shift ? 'l' : 'r' ), |
|
|
2428 |
nameISize(sz), nameIReg(sz, gregOfRM(modrm)), |
2429 |
dis_buf); |
2430 |
} |
2652 |
} |
2431 |
|
2653 |
|
2432 |
if (amt_tag == Literal) eip++; |
2654 |
if (amt_tag == Literal) eip++; |
Lines 2460-2474
Link Here
|
2460 |
Int sz, Addr eip, BtOp op ) |
2682 |
Int sz, Addr eip, BtOp op ) |
2461 |
{ |
2683 |
{ |
2462 |
UInt pair; |
2684 |
UInt pair; |
2463 |
UChar dis_buf[50]; |
2685 |
Char dis_buf[50]; |
2464 |
UChar modrm; |
2686 |
UChar modrm; |
2465 |
|
2687 |
|
2466 |
Int t_addr, t_bitno, t_mask, t_fetched, t_esp, temp, lit; |
2688 |
Int t_addr, t_bitno, t_mask, t_fetched, t_esp, temp, lit; |
2467 |
|
2689 |
|
2468 |
/* 2 and 4 are actually possible. */ |
|
|
2469 |
vg_assert(sz == 2 || sz == 4); |
2690 |
vg_assert(sz == 2 || sz == 4); |
2470 |
/* We only handle 4. */ |
|
|
2471 |
vg_assert(sz == 4); |
2472 |
|
2691 |
|
2473 |
t_addr = t_bitno = t_mask |
2692 |
t_addr = t_bitno = t_mask |
2474 |
= t_fetched = t_esp = temp = INVALID_TEMPREG; |
2693 |
= t_fetched = t_esp = temp = INVALID_TEMPREG; |
Lines 2482-2499
Link Here
|
2482 |
|
2701 |
|
2483 |
uInstr2(cb, GET, sz, ArchReg, gregOfRM(modrm), TempReg, t_bitno); |
2702 |
uInstr2(cb, GET, sz, ArchReg, gregOfRM(modrm), TempReg, t_bitno); |
2484 |
|
2703 |
|
|
|
2704 |
if (sz == 2) { |
2705 |
uInstr1(cb, WIDEN, 4, TempReg, t_bitno); |
2706 |
LAST_UINSTR(cb).extra4b = 2; |
2707 |
LAST_UINSTR(cb).signed_widen = False; |
2708 |
} |
2709 |
|
2485 |
if (epartIsReg(modrm)) { |
2710 |
if (epartIsReg(modrm)) { |
2486 |
eip++; |
2711 |
eip++; |
2487 |
/* Get it onto the client's stack. */ |
2712 |
/* Get it onto the client's stack. */ |
2488 |
t_esp = newTemp(cb); |
2713 |
t_esp = newTemp(cb); |
2489 |
t_addr = newTemp(cb); |
2714 |
t_addr = newTemp(cb); |
2490 |
uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t_esp); |
2715 |
uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t_esp); |
2491 |
uInstr2(cb, SUB, sz, Literal, 0, TempReg, t_esp); |
2716 |
uInstr2(cb, SUB, 4, Literal, 0, TempReg, t_esp); |
2492 |
uLiteral(cb, sz); |
2717 |
uLiteral(cb, sz); |
2493 |
uInstr2(cb, PUT, 4, TempReg, t_esp, ArchReg, R_ESP); |
2718 |
uInstr2(cb, PUT, 4, TempReg, t_esp, ArchReg, R_ESP); |
2494 |
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, temp); |
2719 |
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, temp); |
2495 |
uInstr2(cb, STORE, sz, TempReg, temp, TempReg, t_esp); |
2720 |
uInstr2(cb, STORE, sz, TempReg, temp, TempReg, t_esp); |
2496 |
/* Make ta point at it. */ |
2721 |
/* Make t_addr point at it. */ |
2497 |
uInstr2(cb, MOV, 4, TempReg, t_esp, TempReg, t_addr); |
2722 |
uInstr2(cb, MOV, 4, TempReg, t_esp, TempReg, t_addr); |
2498 |
/* Mask out upper bits of the shift amount, since we're doing a |
2723 |
/* Mask out upper bits of the shift amount, since we're doing a |
2499 |
reg. */ |
2724 |
reg. */ |
Lines 2501-2512
Link Here
|
2501 |
uLiteral(cb, sz == 4 ? 31 : 15); |
2726 |
uLiteral(cb, sz == 4 ? 31 : 15); |
2502 |
uInstr2(cb, AND, 4, TempReg, lit, TempReg, t_bitno); |
2727 |
uInstr2(cb, AND, 4, TempReg, lit, TempReg, t_bitno); |
2503 |
} else { |
2728 |
} else { |
2504 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
2729 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
2505 |
t_addr = LOW24(pair); |
2730 |
t_addr = LOW24(pair); |
2506 |
eip += HI8(pair); |
2731 |
eip += HI8(pair); |
2507 |
} |
2732 |
} |
2508 |
|
2733 |
|
2509 |
/* At this point: ta points to the address being operated on. If |
2734 |
/* At this point: t_addr points to the address being operated on. If |
2510 |
it was a reg, we will have pushed it onto the client's stack. |
2735 |
it was a reg, we will have pushed it onto the client's stack. |
2511 |
t_bitno is the bit number, suitable masked in the case of a reg. */ |
2736 |
t_bitno is the bit number, suitable masked in the case of a reg. */ |
2512 |
|
2737 |
|
Lines 2516-2527
Link Here
|
2516 |
uInstr2(cb, SAR, 4, Literal, 0, TempReg, temp); |
2741 |
uInstr2(cb, SAR, 4, Literal, 0, TempReg, temp); |
2517 |
uLiteral(cb, 3); |
2742 |
uLiteral(cb, 3); |
2518 |
uInstr2(cb, ADD, 4, TempReg, temp, TempReg, t_addr); |
2743 |
uInstr2(cb, ADD, 4, TempReg, temp, TempReg, t_addr); |
2519 |
/* ta now holds effective address */ |
2744 |
/* t_addr now holds effective address */ |
2520 |
|
2745 |
|
2521 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, lit); |
2746 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, lit); |
2522 |
uLiteral(cb, 7); |
2747 |
uLiteral(cb, 7); |
2523 |
uInstr2(cb, AND, 4, TempReg, lit, TempReg, t_bitno); |
2748 |
uInstr2(cb, AND, 4, TempReg, lit, TempReg, t_bitno); |
2524 |
/* bitno contains offset of bit within byte */ |
2749 |
/* t_bitno contains offset of bit within byte */ |
2525 |
|
2750 |
|
2526 |
if (op != BtOpNone) { |
2751 |
if (op != BtOpNone) { |
2527 |
t_mask = newTemp(cb); |
2752 |
t_mask = newTemp(cb); |
Lines 2529-2535
Link Here
|
2529 |
uLiteral(cb, 1); |
2754 |
uLiteral(cb, 1); |
2530 |
uInstr2(cb, SHL, 4, TempReg, t_bitno, TempReg, t_mask); |
2755 |
uInstr2(cb, SHL, 4, TempReg, t_bitno, TempReg, t_mask); |
2531 |
} |
2756 |
} |
2532 |
/* mask is now a suitable byte mask */ |
2757 |
/* t_mask is now a suitable byte mask */ |
2533 |
|
2758 |
|
2534 |
uInstr2(cb, LOAD, 1, TempReg, t_addr, TempReg, t_fetched); |
2759 |
uInstr2(cb, LOAD, 1, TempReg, t_addr, TempReg, t_fetched); |
2535 |
if (op != BtOpNone) { |
2760 |
if (op != BtOpNone) { |
Lines 2559-2602
Link Here
|
2559 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, lit); |
2784 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, lit); |
2560 |
uLiteral(cb, 1); |
2785 |
uLiteral(cb, 1); |
2561 |
uInstr2(cb, AND, 4, TempReg, lit, TempReg, t_fetched); |
2786 |
uInstr2(cb, AND, 4, TempReg, lit, TempReg, t_fetched); |
2562 |
/* fetched is now 1 or 0 */ |
2787 |
/* t_fetched is now 1 or 0 */ |
2563 |
|
2788 |
|
2564 |
/* NEG is a handy way to convert zero/nonzero into the carry |
2789 |
/* NEG is a handy way to convert zero/nonzero into the carry |
2565 |
flag. */ |
2790 |
flag. */ |
2566 |
uInstr1(cb, NEG, 4, TempReg, t_fetched); |
2791 |
uInstr1(cb, NEG, 4, TempReg, t_fetched); |
2567 |
setFlagsFromUOpcode(cb, NEG); |
2792 |
setFlagsFromUOpcode(cb, NEG); |
2568 |
/* fetched is now in carry flag */ |
2793 |
/* t_fetched is now in carry flag */ |
2569 |
|
2794 |
|
2570 |
/* Move reg operand from stack back to reg */ |
2795 |
/* Move reg operand from stack back to reg */ |
2571 |
if (epartIsReg(modrm)) { |
2796 |
if (epartIsReg(modrm)) { |
2572 |
/* t_esp still points at it. */ |
2797 |
/* t_esp still points at it. */ |
2573 |
uInstr2(cb, LOAD, sz, TempReg, t_esp, TempReg, temp); |
2798 |
uInstr2(cb, LOAD, sz, TempReg, t_esp, TempReg, temp); |
2574 |
uInstr2(cb, PUT, sz, TempReg, temp, ArchReg, eregOfRM(modrm)); |
2799 |
uInstr2(cb, PUT, sz, TempReg, temp, ArchReg, eregOfRM(modrm)); |
2575 |
uInstr2(cb, ADD, sz, Literal, 0, TempReg, t_esp); |
2800 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t_esp); |
2576 |
uLiteral(cb, sz); |
2801 |
uLiteral(cb, sz); |
2577 |
uInstr2(cb, PUT, 4, TempReg, t_esp, ArchReg, R_ESP); |
2802 |
uInstr2(cb, PUT, 4, TempReg, t_esp, ArchReg, R_ESP); |
2578 |
} |
2803 |
} |
2579 |
|
2804 |
|
2580 |
if (epartIsReg(modrm)) { |
2805 |
DIP("bt%s%c %s, %s\n", |
2581 |
if (dis) |
2806 |
nameBtOp(op), nameISize(sz), nameIReg(sz, gregOfRM(modrm)), |
2582 |
VG_(printf)("bt%s%c %s, %s\n", |
2807 |
( epartIsReg(modrm) ? nameIReg(sz, eregOfRM(modrm)) : dis_buf ) ); |
2583 |
nameBtOp(op), |
|
|
2584 |
nameISize(sz), nameIReg(sz, gregOfRM(modrm)), |
2585 |
nameIReg(sz, eregOfRM(modrm))); |
2586 |
} else { |
2587 |
if (dis) |
2588 |
VG_(printf)("bt%s%c %s, %s\n", |
2589 |
nameBtOp(op), |
2590 |
nameISize(sz), nameIReg(sz, gregOfRM(modrm)), |
2591 |
dis_buf); |
2592 |
} |
2593 |
|
2808 |
|
2594 |
return eip; |
2809 |
return eip; |
2595 |
} |
2810 |
} |
2596 |
|
2811 |
|
2597 |
|
2812 |
|
2598 |
|
2813 |
|
2599 |
|
|
|
2600 |
/* Handle BSF/BSR. Only v-size seems necessary. */ |
2814 |
/* Handle BSF/BSR. Only v-size seems necessary. */ |
2601 |
static |
2815 |
static |
2602 |
Addr dis_bs_E_G ( UCodeBlock* cb, |
2816 |
Addr dis_bs_E_G ( UCodeBlock* cb, |
Lines 2605-2617
Link Here
|
2605 |
{ |
2819 |
{ |
2606 |
Int t, t1, ta, helper; |
2820 |
Int t, t1, ta, helper; |
2607 |
UInt pair; |
2821 |
UInt pair; |
2608 |
UChar dis_buf[50]; |
2822 |
Char dis_buf[50]; |
2609 |
UChar modrm; |
2823 |
UChar modrm; |
|
|
2824 |
Bool isReg; |
2610 |
|
2825 |
|
2611 |
vg_assert(sz == 2 || sz == 4); |
2826 |
vg_assert(sz == 2 || sz == 4); |
2612 |
vg_assert(sz==4); |
|
|
2613 |
|
2827 |
|
2614 |
helper = fwds ? VGOFF_(helper_bsf) : VGOFF_(helper_bsr); |
2828 |
if (fwds) |
|
|
2829 |
helper = sz == 2 ? VGOFF_(helper_bsfw) : VGOFF_(helper_bsfl); |
2830 |
else |
2831 |
helper = sz == 2 ? VGOFF_(helper_bsrw) : VGOFF_(helper_bsrl); |
2832 |
|
2615 |
modrm = getUChar(eip); |
2833 |
modrm = getUChar(eip); |
2616 |
t1 = newTemp(cb); |
2834 |
t1 = newTemp(cb); |
2617 |
t = newTemp(cb); |
2835 |
t = newTemp(cb); |
Lines 2620-2644
Link Here
|
2620 |
uInstr2(cb, GET, sz, ArchReg, gregOfRM(modrm), TempReg, t1); |
2838 |
uInstr2(cb, GET, sz, ArchReg, gregOfRM(modrm), TempReg, t1); |
2621 |
uInstr1(cb, PUSH, sz, TempReg, t1); |
2839 |
uInstr1(cb, PUSH, sz, TempReg, t1); |
2622 |
|
2840 |
|
2623 |
if (epartIsReg(modrm)) { |
2841 |
isReg = epartIsReg(modrm); |
|
|
2842 |
if (isReg) { |
2624 |
eip++; |
2843 |
eip++; |
2625 |
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t); |
2844 |
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t); |
2626 |
if (dis) |
|
|
2627 |
VG_(printf)("bs%c%c %s, %s\n", |
2628 |
fwds ? 'f' : 'r', |
2629 |
nameISize(sz), nameIReg(sz, eregOfRM(modrm)), |
2630 |
nameIReg(sz, gregOfRM(modrm))); |
2631 |
} else { |
2845 |
} else { |
2632 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
2846 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
2633 |
ta = LOW24(pair); |
2847 |
ta = LOW24(pair); |
2634 |
eip += HI8(pair); |
2848 |
eip += HI8(pair); |
2635 |
uInstr2(cb, LOAD, sz, TempReg, ta, TempReg, t); |
2849 |
uInstr2(cb, LOAD, sz, TempReg, ta, TempReg, t); |
2636 |
if (dis) |
|
|
2637 |
VG_(printf)("bs%c%c %s, %s\n", |
2638 |
fwds ? 'f' : 'r', |
2639 |
nameISize(sz), dis_buf, |
2640 |
nameIReg(sz, gregOfRM(modrm))); |
2641 |
} |
2850 |
} |
|
|
2851 |
DIP("bs%c%c %s, %s\n", |
2852 |
fwds ? 'f' : 'r', nameISize(sz), |
2853 |
( isReg ? nameIReg(sz, eregOfRM(modrm)) : dis_buf ), |
2854 |
nameIReg(sz, gregOfRM(modrm))); |
2642 |
|
2855 |
|
2643 |
uInstr1(cb, PUSH, sz, TempReg, t); |
2856 |
uInstr1(cb, PUSH, sz, TempReg, t); |
2644 |
uInstr1(cb, CALLM, 0, Lit16, helper); |
2857 |
uInstr1(cb, CALLM, 0, Lit16, helper); |
Lines 2663-2671
Link Here
|
2663 |
uInstr2(cb, GET, sz, ArchReg, reg, TempReg, t2); |
2876 |
uInstr2(cb, GET, sz, ArchReg, reg, TempReg, t2); |
2664 |
uInstr2(cb, PUT, sz, TempReg, t2, ArchReg, R_EAX); |
2877 |
uInstr2(cb, PUT, sz, TempReg, t2, ArchReg, R_EAX); |
2665 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, reg); |
2878 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, reg); |
2666 |
if (dis) |
2879 |
DIP("xchg%c %s, %s\n", |
2667 |
VG_(printf)("xchg%c %s, %s\n", nameISize(sz), |
2880 |
nameISize(sz), nameIReg(sz, R_EAX), nameIReg(sz, reg)); |
2668 |
nameIReg(sz, R_EAX), nameIReg(sz, reg)); |
|
|
2669 |
} |
2881 |
} |
2670 |
|
2882 |
|
2671 |
|
2883 |
|
Lines 2739-2760
Link Here
|
2739 |
if (epartIsReg(rm)) { |
2951 |
if (epartIsReg(rm)) { |
2740 |
uInstr2(cb, GET, size, ArchReg, eregOfRM(rm), TempReg, dest); |
2952 |
uInstr2(cb, GET, size, ArchReg, eregOfRM(rm), TempReg, dest); |
2741 |
eip0++; |
2953 |
eip0++; |
2742 |
if (dis) VG_(printf)("cmpxchg%c %s,%s\n", |
2954 |
DIP("cmpxchg%c %s,%s\n", nameISize(size), |
2743 |
nameISize(size), |
2955 |
nameIReg(size,gregOfRM(rm)), |
2744 |
nameIReg(size,gregOfRM(rm)), |
2956 |
nameIReg(size,eregOfRM(rm)) ); |
2745 |
nameIReg(size,eregOfRM(rm)) ); |
|
|
2746 |
} else { |
2957 |
} else { |
2747 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL ); |
2958 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf ); |
2748 |
ta = LOW24(pair); |
2959 |
ta = LOW24(pair); |
2749 |
uInstr2(cb, LOAD, size, TempReg, ta, TempReg, dest); |
2960 |
uInstr2(cb, LOAD, size, TempReg, ta, TempReg, dest); |
2750 |
eip0 += HI8(pair); |
2961 |
eip0 += HI8(pair); |
2751 |
if (dis) VG_(printf)("cmpxchg%c %s,%s\n", nameISize(size), |
2962 |
DIP("cmpxchg%c %s,%s\n", nameISize(size), |
2752 |
nameIReg(size,gregOfRM(rm)), dis_buf); |
2963 |
nameIReg(size,gregOfRM(rm)), dis_buf); |
2753 |
} |
2964 |
} |
2754 |
|
2965 |
|
2755 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, src); |
2966 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, src); |
2756 |
uInstr2(cb, GET, size, ArchReg, R_EAX, TempReg, acc); |
2967 |
uInstr2(cb, GET, size, ArchReg, R_EAX, TempReg, acc); |
2757 |
uInstr2(cb, MOV, size, TempReg, acc, TempReg, junk); |
2968 |
uInstr2(cb, MOV, 4, TempReg, acc, TempReg, junk); |
2758 |
uInstr2(cb, SUB, size, TempReg, dest, TempReg, junk); |
2969 |
uInstr2(cb, SUB, size, TempReg, dest, TempReg, junk); |
2759 |
setFlagsFromUOpcode(cb, SUB); |
2970 |
setFlagsFromUOpcode(cb, SUB); |
2760 |
|
2971 |
|
Lines 2776-2781
Link Here
|
2776 |
} |
2987 |
} |
2777 |
|
2988 |
|
2778 |
|
2989 |
|
|
|
2990 |
static |
2991 |
Addr dis_cmpxchg8b ( UCodeBlock* cb, |
2992 |
UChar sorb, |
2993 |
Addr eip0 ) |
2994 |
{ |
2995 |
Int tal, tah, junkl, junkh, destl, desth, srcl, srch, accl, acch; |
2996 |
UChar dis_buf[50]; |
2997 |
UChar rm; |
2998 |
UInt pair; |
2999 |
|
3000 |
rm = getUChar(eip0); |
3001 |
accl = newTemp(cb); |
3002 |
acch = newTemp(cb); |
3003 |
srcl = newTemp(cb); |
3004 |
srch = newTemp(cb); |
3005 |
destl = newTemp(cb); |
3006 |
desth = newTemp(cb); |
3007 |
junkl = newTemp(cb); |
3008 |
junkh = newTemp(cb); |
3009 |
|
3010 |
vg_assert(!epartIsReg(rm)); |
3011 |
|
3012 |
pair = disAMode ( cb, sorb, eip0, dis_buf ); |
3013 |
tal = LOW24(pair); |
3014 |
tah = newTemp(cb); |
3015 |
uInstr2(cb, MOV, 4, TempReg, tal, TempReg, tah); |
3016 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, tah); |
3017 |
uLiteral(cb, 4); |
3018 |
eip0 += HI8(pair); |
3019 |
DIP("cmpxchg8b %s\n", dis_buf); |
3020 |
|
3021 |
uInstr0(cb, CALLM_S, 0); |
3022 |
|
3023 |
uInstr2(cb, LOAD, 4, TempReg, tah, TempReg, desth); |
3024 |
uInstr1(cb, PUSH, 4, TempReg, desth); |
3025 |
uInstr2(cb, LOAD, 4, TempReg, tal, TempReg, destl); |
3026 |
uInstr1(cb, PUSH, 4, TempReg, destl); |
3027 |
uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, srch); |
3028 |
uInstr1(cb, PUSH, 4, TempReg, srch); |
3029 |
uInstr2(cb, GET, 4, ArchReg, R_EBX, TempReg, srcl); |
3030 |
uInstr1(cb, PUSH, 4, TempReg, srcl); |
3031 |
uInstr2(cb, GET, 4, ArchReg, R_EDX, TempReg, acch); |
3032 |
uInstr1(cb, PUSH, 4, TempReg, acch); |
3033 |
uInstr2(cb, GET, 4, ArchReg, R_EAX, TempReg, accl); |
3034 |
uInstr1(cb, PUSH, 4, TempReg, accl); |
3035 |
|
3036 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_cmpxchg8b)); |
3037 |
uFlagsRWU(cb, FlagsEmpty, FlagZ, FlagsEmpty); |
3038 |
|
3039 |
uInstr1(cb, POP, 4, TempReg, accl); |
3040 |
uInstr2(cb, PUT, 4, TempReg, accl, ArchReg, R_EAX); |
3041 |
uInstr1(cb, POP, 4, TempReg, acch); |
3042 |
uInstr2(cb, PUT, 4, TempReg, acch, ArchReg, R_EDX); |
3043 |
uInstr1(cb, POP, 4, TempReg, srcl); |
3044 |
uInstr2(cb, PUT, 4, TempReg, srcl, ArchReg, R_EBX); |
3045 |
uInstr1(cb, POP, 4, TempReg, srch); |
3046 |
uInstr2(cb, PUT, 4, TempReg, srch, ArchReg, R_ECX); |
3047 |
uInstr1(cb, POP, 4, TempReg, destl); |
3048 |
uInstr2(cb, STORE, 4, TempReg, destl, TempReg, tal); |
3049 |
uInstr1(cb, POP, 4, TempReg, desth); |
3050 |
uInstr2(cb, STORE, 4, TempReg, desth, TempReg, tah); |
3051 |
|
3052 |
uInstr0(cb, CALLM_E, 0); |
3053 |
|
3054 |
return eip0; |
3055 |
} |
3056 |
|
3057 |
|
2779 |
/* Handle conditional move instructions of the form |
3058 |
/* Handle conditional move instructions of the form |
2780 |
cmovcc E(reg-or-mem), G(reg) |
3059 |
cmovcc E(reg-or-mem), G(reg) |
2781 |
|
3060 |
|
Lines 2813-2829
Link Here
|
2813 |
uCond(cb, cond); |
3092 |
uCond(cb, cond); |
2814 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
3093 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
2815 |
uInstr2(cb, PUT, size, TempReg, tmpd, ArchReg, gregOfRM(rm)); |
3094 |
uInstr2(cb, PUT, size, TempReg, tmpd, ArchReg, gregOfRM(rm)); |
2816 |
if (dis) VG_(printf)("cmov%c%s %s,%s\n", |
3095 |
DIP("cmov%c%s %s,%s\n", nameISize(size), |
2817 |
nameISize(size), |
3096 |
VG_(name_UCondcode)(cond), |
2818 |
VG_(name_UCondcode)(cond), |
3097 |
nameIReg(size,eregOfRM(rm)), |
2819 |
nameIReg(size,eregOfRM(rm)), |
3098 |
nameIReg(size,gregOfRM(rm))); |
2820 |
nameIReg(size,gregOfRM(rm))); |
|
|
2821 |
return 1+eip0; |
3099 |
return 1+eip0; |
2822 |
} |
3100 |
} |
2823 |
|
3101 |
|
2824 |
/* E refers to memory */ |
3102 |
/* E refers to memory */ |
2825 |
{ |
3103 |
{ |
2826 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
3104 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf ); |
2827 |
Int tmpa = LOW24(pair); |
3105 |
Int tmpa = LOW24(pair); |
2828 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmps); |
3106 |
uInstr2(cb, LOAD, size, TempReg, tmpa, TempReg, tmps); |
2829 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, tmpd); |
3107 |
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, tmpd); |
Lines 2831-2841
Link Here
|
2831 |
uCond(cb, cond); |
3109 |
uCond(cb, cond); |
2832 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
3110 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
2833 |
uInstr2(cb, PUT, size, TempReg, tmpd, ArchReg, gregOfRM(rm)); |
3111 |
uInstr2(cb, PUT, size, TempReg, tmpd, ArchReg, gregOfRM(rm)); |
2834 |
if (dis) VG_(printf)("cmov%c%s %s,%s\n", |
3112 |
DIP("cmov%c%s %s,%s\n", nameISize(size), |
2835 |
nameISize(size), |
3113 |
VG_(name_UCondcode)(cond), |
2836 |
VG_(name_UCondcode)(cond), |
3114 |
dis_buf, |
2837 |
dis_buf, |
3115 |
nameIReg(size,gregOfRM(rm))); |
2838 |
nameIReg(size,gregOfRM(rm))); |
|
|
2839 |
return HI8(pair)+eip0; |
3116 |
return HI8(pair)+eip0; |
2840 |
} |
3117 |
} |
2841 |
} |
3118 |
} |
Lines 2860-2872
Link Here
|
2860 |
setFlagsFromUOpcode(cb, ADD); |
3137 |
setFlagsFromUOpcode(cb, ADD); |
2861 |
uInstr2(cb, PUT, sz, TempReg, tmpt, ArchReg, eregOfRM(rm)); |
3138 |
uInstr2(cb, PUT, sz, TempReg, tmpt, ArchReg, eregOfRM(rm)); |
2862 |
uInstr2(cb, PUT, sz, TempReg, tmpd, ArchReg, gregOfRM(rm)); |
3139 |
uInstr2(cb, PUT, sz, TempReg, tmpd, ArchReg, gregOfRM(rm)); |
2863 |
if (dis) |
3140 |
DIP("xadd%c %s, %s\n", |
2864 |
VG_(printf)("xadd%c %s, %s\n", nameISize(sz), |
3141 |
nameISize(sz), nameIReg(sz,gregOfRM(rm)), nameIReg(sz,eregOfRM(rm))); |
2865 |
nameIReg(sz,gregOfRM(rm)), |
|
|
2866 |
nameIReg(sz,eregOfRM(rm))); |
2867 |
return 1+eip0; |
3142 |
return 1+eip0; |
2868 |
} else { |
3143 |
} else { |
2869 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
3144 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf ); |
2870 |
Int tmpa = LOW24(pair); |
3145 |
Int tmpa = LOW24(pair); |
2871 |
uInstr2(cb, LOAD, sz, TempReg, tmpa, TempReg, tmpd); |
3146 |
uInstr2(cb, LOAD, sz, TempReg, tmpa, TempReg, tmpd); |
2872 |
uInstr2(cb, GET, sz, ArchReg, gregOfRM(rm), TempReg, tmpt); |
3147 |
uInstr2(cb, GET, sz, ArchReg, gregOfRM(rm), TempReg, tmpt); |
Lines 2874-2883
Link Here
|
2874 |
setFlagsFromUOpcode(cb, ADD); |
3149 |
setFlagsFromUOpcode(cb, ADD); |
2875 |
uInstr2(cb, STORE, sz, TempReg, tmpt, TempReg, tmpa); |
3150 |
uInstr2(cb, STORE, sz, TempReg, tmpt, TempReg, tmpa); |
2876 |
uInstr2(cb, PUT, sz, TempReg, tmpd, ArchReg, gregOfRM(rm)); |
3151 |
uInstr2(cb, PUT, sz, TempReg, tmpd, ArchReg, gregOfRM(rm)); |
2877 |
if (dis) |
3152 |
DIP("xadd%c %s, %s\n", |
2878 |
VG_(printf)("xadd%c %s, %s\n", nameISize(sz), |
3153 |
nameISize(sz), nameIReg(sz,gregOfRM(rm)), dis_buf); |
2879 |
nameIReg(sz,gregOfRM(rm)), |
|
|
2880 |
dis_buf); |
2881 |
return HI8(pair)+eip0; |
3154 |
return HI8(pair)+eip0; |
2882 |
} |
3155 |
} |
2883 |
} |
3156 |
} |
Lines 2911-2931
Link Here
|
2911 |
Int tmpv = newTemp(cb); |
3184 |
Int tmpv = newTemp(cb); |
2912 |
uInstr2(cb, GET, 2, ArchReg, eregOfRM(rm), TempReg, tmpv); |
3185 |
uInstr2(cb, GET, 2, ArchReg, eregOfRM(rm), TempReg, tmpv); |
2913 |
uInstr2(cb, PUTSEG, 2, TempReg, tmpv, ArchRegS, gregOfRM(rm)); |
3186 |
uInstr2(cb, PUTSEG, 2, TempReg, tmpv, ArchRegS, gregOfRM(rm)); |
2914 |
if (dis) VG_(printf)("movw %s,%s\n", |
3187 |
DIP("movw %s,%s\n", nameIReg(2,eregOfRM(rm)), nameSReg(gregOfRM(rm))); |
2915 |
nameIReg(2,eregOfRM(rm)), |
|
|
2916 |
nameSReg(gregOfRM(rm))); |
2917 |
return 1+eip0; |
3188 |
return 1+eip0; |
2918 |
} |
3189 |
} |
2919 |
|
3190 |
|
2920 |
/* E refers to memory */ |
3191 |
/* E refers to memory */ |
2921 |
{ |
3192 |
{ |
2922 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
3193 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf ); |
2923 |
Int tmpa = LOW24(pair); |
3194 |
Int tmpa = LOW24(pair); |
2924 |
Int tmpb = newTemp(cb); |
3195 |
Int tmpb = newTemp(cb); |
2925 |
uInstr2(cb, LOAD, 2, TempReg, tmpa, TempReg, tmpb); |
3196 |
uInstr2(cb, LOAD, 2, TempReg, tmpa, TempReg, tmpb); |
2926 |
uInstr2(cb, PUTSEG, 2, TempReg, tmpb, ArchRegS, gregOfRM(rm)); |
3197 |
uInstr2(cb, PUTSEG, 2, TempReg, tmpb, ArchRegS, gregOfRM(rm)); |
2927 |
if (dis) VG_(printf)("movw %s,%s\n", |
3198 |
DIP("movw %s,%s\n", dis_buf,nameSReg(gregOfRM(rm))); |
2928 |
dis_buf,nameSReg(gregOfRM(rm))); |
|
|
2929 |
return HI8(pair)+eip0; |
3199 |
return HI8(pair)+eip0; |
2930 |
} |
3200 |
} |
2931 |
} |
3201 |
} |
Lines 2959-2979
Link Here
|
2959 |
Int tmpv = newTemp(cb); |
3229 |
Int tmpv = newTemp(cb); |
2960 |
uInstr2(cb, GETSEG, 2, ArchRegS, gregOfRM(rm), TempReg, tmpv); |
3230 |
uInstr2(cb, GETSEG, 2, ArchRegS, gregOfRM(rm), TempReg, tmpv); |
2961 |
uInstr2(cb, PUT, 2, TempReg, tmpv, ArchReg, eregOfRM(rm)); |
3231 |
uInstr2(cb, PUT, 2, TempReg, tmpv, ArchReg, eregOfRM(rm)); |
2962 |
if (dis) VG_(printf)("movw %s,%s\n", |
3232 |
DIP("movw %s,%s\n", nameSReg(gregOfRM(rm)), nameIReg(2,eregOfRM(rm))); |
2963 |
nameSReg(gregOfRM(rm)), |
|
|
2964 |
nameIReg(2,eregOfRM(rm))); |
2965 |
return 1+eip0; |
3233 |
return 1+eip0; |
2966 |
} |
3234 |
} |
2967 |
|
3235 |
|
2968 |
/* E refers to memory */ |
3236 |
/* E refers to memory */ |
2969 |
{ |
3237 |
{ |
2970 |
UInt pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL); |
3238 |
UInt pair = disAMode ( cb, sorb, eip0, dis_buf ); |
2971 |
Int tmpa = LOW24(pair); |
3239 |
Int tmpa = LOW24(pair); |
2972 |
Int tmpv = newTemp(cb); |
3240 |
Int tmpv = newTemp(cb); |
2973 |
uInstr2(cb, GETSEG, 2, ArchRegS, gregOfRM(rm), TempReg, tmpv); |
3241 |
uInstr2(cb, GETSEG, 2, ArchRegS, gregOfRM(rm), TempReg, tmpv); |
2974 |
uInstr2(cb, STORE, 2, TempReg, tmpv, TempReg, tmpa); |
3242 |
uInstr2(cb, STORE, 2, TempReg, tmpv, TempReg, tmpa); |
2975 |
if (dis) VG_(printf)("mov %s,%s\n", |
3243 |
DIP("mov %s,%s\n", nameSReg(gregOfRM(rm)), dis_buf); |
2976 |
nameSReg(gregOfRM(rm)), dis_buf); |
|
|
2977 |
return HI8(pair)+eip0; |
3244 |
return HI8(pair)+eip0; |
2978 |
} |
3245 |
} |
2979 |
} |
3246 |
} |
Lines 2994-3028
Link Here
|
2994 |
Char* name, |
3261 |
Char* name, |
2995 |
Bool show_granularity ) |
3262 |
Bool show_granularity ) |
2996 |
{ |
3263 |
{ |
2997 |
UChar dis_buf[50]; |
3264 |
Char dis_buf[50]; |
2998 |
UChar modrm; |
3265 |
UChar modrm = getUChar(eip); |
2999 |
modrm = getUChar(eip); |
3266 |
Bool isReg = epartIsReg(modrm); |
3000 |
if (epartIsReg(modrm)) { |
3267 |
|
|
|
3268 |
if (isReg) { |
3001 |
eip++; |
3269 |
eip++; |
3002 |
uInstr1(cb, MMX2, 0, |
3270 |
uInstr1(cb, MMX2, 0, |
3003 |
Lit16, |
3271 |
Lit16, |
3004 |
(((UShort)(opc)) << 8) | ((UShort)modrm) ); |
3272 |
(((UShort)(opc)) << 8) | ((UShort)modrm) ); |
3005 |
if (dis) |
|
|
3006 |
VG_(printf)("%s%s %s, %s\n", |
3007 |
name, |
3008 |
show_granularity ? nameMMXGran(opc & 3) : (Char*)"", |
3009 |
nameMMXReg(eregOfRM(modrm)), |
3010 |
nameMMXReg(gregOfRM(modrm))); |
3011 |
} else { |
3273 |
} else { |
3012 |
UInt pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
3274 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3013 |
Int tmpa = LOW24(pair); |
3275 |
Int tmpa = LOW24(pair); |
3014 |
eip += HI8(pair); |
3276 |
eip += HI8(pair); |
3015 |
uInstr2(cb, MMX2_MemRd, 8, |
3277 |
uInstr2(cb, MMX2_MemRd, 8, |
3016 |
Lit16, |
3278 |
Lit16, |
3017 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
3279 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
3018 |
TempReg, tmpa); |
3280 |
TempReg, tmpa); |
3019 |
if (dis) |
|
|
3020 |
VG_(printf)("%s%s %s, %s\n", |
3021 |
name, |
3022 |
show_granularity ? nameMMXGran(opc & 3) : (Char*)"", |
3023 |
dis_buf, |
3024 |
nameMMXReg(gregOfRM(modrm))); |
3025 |
} |
3281 |
} |
|
|
3282 |
|
3283 |
DIP("%s%s %s, %s\n", |
3284 |
name, show_granularity ? nameMMXGran(opc & 3) : (Char*)"", |
3285 |
( isReg ? nameMMXReg(eregOfRM(modrm)) : dis_buf ), |
3286 |
nameMMXReg(gregOfRM(modrm)) ); |
3287 |
|
3026 |
return eip; |
3288 |
return eip; |
3027 |
} |
3289 |
} |
3028 |
|
3290 |
|
Lines 3045-3076
Link Here
|
3045 |
UChar opc2, |
3307 |
UChar opc2, |
3046 |
UChar opc3 ) |
3308 |
UChar opc3 ) |
3047 |
{ |
3309 |
{ |
3048 |
UChar dis_buf[50]; |
3310 |
Char dis_buf[50]; |
3049 |
UChar modrm = getUChar(eip); |
3311 |
UChar modrm = getUChar(eip); |
3050 |
if (epartIsReg(modrm)) { |
3312 |
Bool isReg = epartIsReg(modrm); |
|
|
3313 |
|
3314 |
if (isReg) { |
3051 |
/* Completely internal SSE insn. */ |
3315 |
/* Completely internal SSE insn. */ |
3052 |
uInstr2(cb, SSE4, 0, /* ignore sz for internal ops */ |
3316 |
uInstr2(cb, SSE4, 0, /* ignore sz for internal ops */ |
3053 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3317 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3054 |
Lit16, (((UShort)opc3) << 8) | (UShort)modrm ); |
3318 |
Lit16, (((UShort)opc3) << 8) | (UShort)modrm ); |
3055 |
if (dis) |
|
|
3056 |
VG_(printf)("%s %s, %s\n", name, |
3057 |
nameXMMReg(eregOfRM(modrm)), |
3058 |
nameXMMReg(gregOfRM(modrm)) ); |
3059 |
eip++; |
3319 |
eip++; |
3060 |
} else { |
3320 |
} else { |
3061 |
UInt pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
3321 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3062 |
Int tmpa = LOW24(pair); |
3322 |
Int tmpa = LOW24(pair); |
3063 |
eip += HI8(pair); |
3323 |
eip += HI8(pair); |
3064 |
uInstr3(cb, SSE3a_MemRd, sz, |
3324 |
uInstr3(cb, SSE3a_MemRd, sz, |
3065 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3325 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3066 |
Lit16, (((UShort)(opc3)) << 8) | ((UShort)modrm), |
3326 |
Lit16, (((UShort)(opc3)) << 8) | ((UShort)modrm), |
3067 |
TempReg, tmpa); |
3327 |
TempReg, tmpa); |
3068 |
if (dis) |
|
|
3069 |
VG_(printf)("%s %s, %s\n", |
3070 |
name, |
3071 |
dis_buf, |
3072 |
nameXMMReg(gregOfRM(modrm))); |
3073 |
} |
3328 |
} |
|
|
3329 |
|
3330 |
DIP("%s %s, %s\n", |
3331 |
name, |
3332 |
( isReg ? nameXMMReg(eregOfRM(modrm)) : dis_buf ), |
3333 |
nameXMMReg(gregOfRM(modrm)) ); |
3334 |
|
3074 |
return eip; |
3335 |
return eip; |
3075 |
} |
3336 |
} |
3076 |
|
3337 |
|
Lines 3091-3122
Link Here
|
3091 |
UChar opc1, |
3352 |
UChar opc1, |
3092 |
UChar opc2 ) |
3353 |
UChar opc2 ) |
3093 |
{ |
3354 |
{ |
3094 |
UChar dis_buf[50]; |
3355 |
Char dis_buf[50]; |
3095 |
UChar modrm = getUChar(eip); |
3356 |
UChar modrm = getUChar(eip); |
3096 |
if (epartIsReg(modrm)) { |
3357 |
Bool isReg = epartIsReg(modrm); |
|
|
3358 |
|
3359 |
if (isReg) { |
3097 |
/* Completely internal SSE insn. */ |
3360 |
/* Completely internal SSE insn. */ |
3098 |
uInstr2(cb, SSE3, 0, /* ignore sz for internal ops */ |
3361 |
uInstr2(cb, SSE3, 0, /* ignore sz for internal ops */ |
3099 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3362 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3100 |
Lit16, (UShort)modrm ); |
3363 |
Lit16, (UShort)modrm ); |
3101 |
if (dis) |
|
|
3102 |
VG_(printf)("%s %s, %s\n", name, |
3103 |
nameXMMReg(eregOfRM(modrm)), |
3104 |
nameXMMReg(gregOfRM(modrm)) ); |
3105 |
eip++; |
3364 |
eip++; |
3106 |
} else { |
3365 |
} else { |
3107 |
UInt pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
3366 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3108 |
Int tmpa = LOW24(pair); |
3367 |
Int tmpa = LOW24(pair); |
3109 |
eip += HI8(pair); |
3368 |
eip += HI8(pair); |
3110 |
uInstr3(cb, SSE2a_MemRd, sz, |
3369 |
uInstr3(cb, SSE2a_MemRd, sz, |
3111 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3370 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3112 |
Lit16, (UShort)modrm, |
3371 |
Lit16, (UShort)modrm, |
3113 |
TempReg, tmpa); |
3372 |
TempReg, tmpa); |
3114 |
if (dis) |
|
|
3115 |
VG_(printf)("%s %s, %s\n", |
3116 |
name, |
3117 |
dis_buf, |
3118 |
nameXMMReg(gregOfRM(modrm))); |
3119 |
} |
3373 |
} |
|
|
3374 |
DIP("%s %s, %s\n", |
3375 |
name, |
3376 |
( isReg ? nameXMMReg(eregOfRM(modrm)) : dis_buf ), |
3377 |
nameXMMReg(gregOfRM(modrm)) ); |
3378 |
|
3120 |
return eip; |
3379 |
return eip; |
3121 |
} |
3380 |
} |
3122 |
|
3381 |
|
Lines 3137-3159
Link Here
|
3137 |
UChar opc1, |
3396 |
UChar opc1, |
3138 |
UChar opc2 ) |
3397 |
UChar opc2 ) |
3139 |
{ |
3398 |
{ |
3140 |
UChar dis_buf[50]; |
3399 |
Char dis_buf[50]; |
3141 |
UChar modrm = getUChar(eip); |
3400 |
UChar modrm = getUChar(eip); |
3142 |
UChar imm8; |
3401 |
UChar imm8; |
3143 |
if (epartIsReg(modrm)) { |
3402 |
Bool isReg = epartIsReg(modrm); |
|
|
3403 |
|
3404 |
if (isReg) { |
3144 |
/* Completely internal SSE insn. */ |
3405 |
/* Completely internal SSE insn. */ |
3145 |
eip++; |
3406 |
eip++; |
3146 |
imm8 = getUChar(eip); |
3407 |
imm8 = getUChar(eip); |
3147 |
uInstr2(cb, SSE4, 0, /* ignore sz for internal ops */ |
3408 |
uInstr2(cb, SSE4, 0, /* ignore sz for internal ops */ |
3148 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3409 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3149 |
Lit16, (((UShort)modrm) << 8) | (UShort)imm8 ); |
3410 |
Lit16, (((UShort)modrm) << 8) | (UShort)imm8 ); |
3150 |
if (dis) |
|
|
3151 |
VG_(printf)("%s %s, %s, $%d\n", name, |
3152 |
nameXMMReg(eregOfRM(modrm)), |
3153 |
nameXMMReg(gregOfRM(modrm)), (Int)imm8 ); |
3154 |
eip++; |
3411 |
eip++; |
3155 |
} else { |
3412 |
} else { |
3156 |
UInt pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
3413 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3157 |
Int tmpa = LOW24(pair); |
3414 |
Int tmpa = LOW24(pair); |
3158 |
eip += HI8(pair); |
3415 |
eip += HI8(pair); |
3159 |
imm8 = getUChar(eip); |
3416 |
imm8 = getUChar(eip); |
Lines 3162-3173
Link Here
|
3162 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3419 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3163 |
Lit16, (((UShort)(modrm)) << 8) | ((UShort)imm8), |
3420 |
Lit16, (((UShort)(modrm)) << 8) | ((UShort)imm8), |
3164 |
TempReg, tmpa); |
3421 |
TempReg, tmpa); |
3165 |
if (dis) |
|
|
3166 |
VG_(printf)("%s %s, %s, $%d\n", |
3167 |
name, |
3168 |
dis_buf, |
3169 |
nameXMMReg(gregOfRM(modrm)), (Int)imm8 ); |
3170 |
} |
3422 |
} |
|
|
3423 |
DIP("%s %s, %s, $%d\n", |
3424 |
name, ( isReg ? nameXMMReg(eregOfRM(modrm)) : dis_buf ), |
3425 |
nameXMMReg(gregOfRM(modrm)), (Int)imm8 ); |
3171 |
return eip; |
3426 |
return eip; |
3172 |
} |
3427 |
} |
3173 |
|
3428 |
|
Lines 3189-3198
Link Here
|
3189 |
UChar opc2, |
3444 |
UChar opc2, |
3190 |
UChar opc3 ) |
3445 |
UChar opc3 ) |
3191 |
{ |
3446 |
{ |
3192 |
UChar dis_buf[50]; |
3447 |
Char dis_buf[50]; |
3193 |
UChar modrm = getUChar(eip); |
3448 |
UChar modrm = getUChar(eip); |
3194 |
UChar imm8; |
3449 |
UChar imm8; |
3195 |
if (epartIsReg(modrm)) { |
3450 |
Bool isReg = epartIsReg(modrm); |
|
|
3451 |
|
3452 |
if (isReg) { |
3196 |
/* Completely internal SSE insn. */ |
3453 |
/* Completely internal SSE insn. */ |
3197 |
eip++; |
3454 |
eip++; |
3198 |
imm8 = getUChar(eip); |
3455 |
imm8 = getUChar(eip); |
Lines 3200-3212
Link Here
|
3200 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3457 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3201 |
Lit16, (((UShort)opc3) << 8) | (UShort)modrm, |
3458 |
Lit16, (((UShort)opc3) << 8) | (UShort)modrm, |
3202 |
Lit16, (UShort)imm8 ); |
3459 |
Lit16, (UShort)imm8 ); |
3203 |
if (dis) |
|
|
3204 |
VG_(printf)("%s %s, %s, $%d\n", name, |
3205 |
nameXMMReg(eregOfRM(modrm)), |
3206 |
nameXMMReg(gregOfRM(modrm)), (Int)imm8 ); |
3207 |
eip++; |
3460 |
eip++; |
3208 |
} else { |
3461 |
} else { |
3209 |
UInt pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
3462 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3210 |
Int tmpa = LOW24(pair); |
3463 |
Int tmpa = LOW24(pair); |
3211 |
eip += HI8(pair); |
3464 |
eip += HI8(pair); |
3212 |
imm8 = getUChar(eip); |
3465 |
imm8 = getUChar(eip); |
Lines 3216-3227
Link Here
|
3216 |
Lit16, (((UShort)(opc3)) << 8) | ((UShort)modrm), |
3469 |
Lit16, (((UShort)(opc3)) << 8) | ((UShort)modrm), |
3217 |
TempReg, tmpa); |
3470 |
TempReg, tmpa); |
3218 |
uLiteral(cb, imm8); |
3471 |
uLiteral(cb, imm8); |
3219 |
if (dis) |
|
|
3220 |
VG_(printf)("%s %s, %s, $%d\n", |
3221 |
name, |
3222 |
dis_buf, |
3223 |
nameXMMReg(gregOfRM(modrm)), (Int)imm8 ); |
3224 |
} |
3472 |
} |
|
|
3473 |
DIP("%s %s, %s, $%d\n", |
3474 |
name, ( isReg ? nameXMMReg(eregOfRM(modrm)) : dis_buf ), |
3475 |
nameXMMReg(gregOfRM(modrm)), (Int)imm8 ); |
3225 |
return eip; |
3476 |
return eip; |
3226 |
} |
3477 |
} |
3227 |
|
3478 |
|
Lines 3241-3279
Link Here
|
3241 |
UChar insn1, |
3492 |
UChar insn1, |
3242 |
UChar insn2 ) |
3493 |
UChar insn2 ) |
3243 |
{ |
3494 |
{ |
3244 |
UChar dis_buf[50]; |
3495 |
Char dis_buf[50]; |
3245 |
UChar modrm; |
3496 |
UChar modrm = getUChar(eip); |
|
|
3497 |
Bool isReg = epartIsReg(modrm); |
3246 |
UInt pair; |
3498 |
UInt pair; |
3247 |
Int t1; |
3499 |
Int t1; |
3248 |
modrm = getUChar(eip); |
3500 |
|
3249 |
if (epartIsReg(modrm)) { |
3501 |
if (isReg) { |
3250 |
/* Completely internal; we can issue SSE4. */ |
3502 |
/* Completely internal; we can issue SSE4. */ |
3251 |
eip++; |
3503 |
eip++; |
3252 |
uInstr2(cb, SSE4, 0, /* ignore sz for internal ops */ |
3504 |
uInstr2(cb, SSE4, 0, /* ignore sz for internal ops */ |
3253 |
Lit16, (((UShort)insn0) << 8) | (UShort)insn1, |
3505 |
Lit16, (((UShort)insn0) << 8) | (UShort)insn1, |
3254 |
Lit16, (((UShort)insn2) << 8) | (UShort)modrm ); |
3506 |
Lit16, (((UShort)insn2) << 8) | (UShort)modrm ); |
3255 |
if (dis && is_store) |
|
|
3256 |
VG_(printf)("%s %s, %s\n", name, |
3257 |
nameXMMReg(gregOfRM(modrm)), |
3258 |
nameXMMReg(eregOfRM(modrm)) ); |
3259 |
if (dis && !is_store) |
3260 |
VG_(printf)("%s %s, %s\n", name, |
3261 |
nameXMMReg(eregOfRM(modrm)), |
3262 |
nameXMMReg(gregOfRM(modrm)) ); |
3263 |
} else { |
3507 |
} else { |
3264 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
3508 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
3265 |
t1 = LOW24(pair); |
3509 |
t1 = LOW24(pair); |
3266 |
eip += HI8(pair); |
3510 |
eip += HI8(pair); |
3267 |
uInstr3(cb, is_store ? SSE3a_MemWr : SSE3a_MemRd, sz, |
3511 |
uInstr3(cb, is_store ? SSE3a_MemWr : SSE3a_MemRd, sz, |
3268 |
Lit16, (((UShort)insn0) << 8) | (UShort)insn1, |
3512 |
Lit16, (((UShort)insn0) << 8) | (UShort)insn1, |
3269 |
Lit16, (((UShort)insn2) << 8) | (UShort)modrm, |
3513 |
Lit16, (((UShort)insn2) << 8) | (UShort)modrm, |
3270 |
TempReg, t1 ); |
3514 |
TempReg, t1 ); |
3271 |
if (dis && is_store) |
3515 |
} |
3272 |
VG_(printf)("%s %s, %s\n", name, |
3516 |
|
3273 |
nameXMMReg(gregOfRM(modrm)), dis_buf ); |
3517 |
if (is_store) { |
3274 |
if (dis && !is_store) |
3518 |
DIP("%s %s, %s\n", |
3275 |
VG_(printf)("%s %s, %s\n", name, |
3519 |
name, |
3276 |
dis_buf, nameXMMReg(gregOfRM(modrm)) ); |
3520 |
nameXMMReg(gregOfRM(modrm)), |
|
|
3521 |
( isReg ? nameXMMReg(eregOfRM(modrm)) : dis_buf ) ); |
3522 |
} else { |
3523 |
DIP("%s %s, %s\n", |
3524 |
name, |
3525 |
( isReg ? nameXMMReg(eregOfRM(modrm)) : dis_buf ), |
3526 |
nameXMMReg(gregOfRM(modrm)) ); |
3277 |
} |
3527 |
} |
3278 |
return eip; |
3528 |
return eip; |
3279 |
} |
3529 |
} |
Lines 3292-3373
Link Here
|
3292 |
UChar insn0, |
3542 |
UChar insn0, |
3293 |
UChar insn1 ) |
3543 |
UChar insn1 ) |
3294 |
{ |
3544 |
{ |
3295 |
UChar dis_buf[50]; |
3545 |
Char dis_buf[50]; |
3296 |
UChar modrm; |
3546 |
UChar modrm = getUChar(eip); |
|
|
3547 |
Bool isReg = epartIsReg(modrm); |
3297 |
UInt pair; |
3548 |
UInt pair; |
3298 |
Int t1; |
3549 |
Int t1; |
3299 |
modrm = getUChar(eip); |
3550 |
|
3300 |
if (epartIsReg(modrm)) { |
3551 |
if (isReg) { |
3301 |
/* Completely internal; we can issue SSE3. */ |
3552 |
/* Completely internal; we can issue SSE3. */ |
3302 |
eip++; |
3553 |
eip++; |
3303 |
uInstr2(cb, SSE3, 0, /* ignore sz for internal ops */ |
3554 |
uInstr2(cb, SSE3, 0, /* ignore sz for internal ops */ |
3304 |
Lit16, (((UShort)insn0) << 8) | (UShort)insn1, |
3555 |
Lit16, (((UShort)insn0) << 8) | (UShort)insn1, |
3305 |
Lit16, (UShort)modrm ); |
3556 |
Lit16, (UShort)modrm ); |
3306 |
if (dis && is_store) |
|
|
3307 |
VG_(printf)("%s %s, %s\n", name, |
3308 |
nameXMMReg(gregOfRM(modrm)), |
3309 |
nameXMMReg(eregOfRM(modrm)) ); |
3310 |
if (dis && !is_store) |
3311 |
VG_(printf)("%s %s, %s\n", name, |
3312 |
nameXMMReg(eregOfRM(modrm)), |
3313 |
nameXMMReg(gregOfRM(modrm)) ); |
3314 |
} else { |
3557 |
} else { |
3315 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
3558 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
3316 |
t1 = LOW24(pair); |
3559 |
t1 = LOW24(pair); |
3317 |
eip += HI8(pair); |
3560 |
eip += HI8(pair); |
3318 |
uInstr3(cb, is_store ? SSE2a_MemWr : SSE2a_MemRd, sz, |
3561 |
uInstr3(cb, is_store ? SSE2a_MemWr : SSE2a_MemRd, sz, |
3319 |
Lit16, (((UShort)insn0) << 8) | (UShort)insn1, |
3562 |
Lit16, (((UShort)insn0) << 8) | (UShort)insn1, |
3320 |
Lit16, (UShort)modrm, |
3563 |
Lit16, (UShort)modrm, |
3321 |
TempReg, t1 ); |
3564 |
TempReg, t1 ); |
3322 |
if (dis && is_store) |
3565 |
} |
3323 |
VG_(printf)("%s %s, %s\n", name, |
3566 |
|
3324 |
nameXMMReg(gregOfRM(modrm)), dis_buf ); |
3567 |
if (is_store) { |
3325 |
if (dis && !is_store) |
3568 |
DIP("%s %s, %s\n", |
3326 |
VG_(printf)("%s %s, %s\n", name, |
3569 |
name, |
3327 |
dis_buf, nameXMMReg(gregOfRM(modrm)) ); |
3570 |
nameXMMReg(gregOfRM(modrm)), |
|
|
3571 |
( isReg ? nameXMMReg(eregOfRM(modrm)) : dis_buf ) ); |
3572 |
} else { |
3573 |
DIP("%s %s, %s\n", |
3574 |
name, |
3575 |
( isReg ? nameXMMReg(eregOfRM(modrm)) : dis_buf ), |
3576 |
nameXMMReg(gregOfRM(modrm)) ); |
3328 |
} |
3577 |
} |
3329 |
return eip; |
3578 |
return eip; |
3330 |
} |
3579 |
} |
3331 |
|
3580 |
|
3332 |
static |
|
|
3333 |
void dis_push_segreg ( UCodeBlock* cb, UInt sreg, Int sz ) |
3334 |
{ |
3335 |
Int t1 = newTemp(cb), t2 = newTemp(cb); |
3336 |
vg_assert(sz == 4); |
3337 |
uInstr2(cb, GETSEG, 2, ArchRegS, sreg, TempReg, t1); |
3338 |
uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t2); |
3339 |
uInstr2(cb, SUB, 4, Literal, 0, TempReg, t2); |
3340 |
uLiteral(cb, 4); |
3341 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
3342 |
uInstr2(cb, STORE, 2, TempReg, t1, TempReg, t2); |
3343 |
if (dis) |
3344 |
VG_(printf)("push %s\n", VG_(name_of_seg_reg)(sreg)); |
3345 |
} |
3346 |
|
3581 |
|
|
|
3582 |
/* Simple SSE operations, either |
3583 |
op (src)xmmreg, (dst)mmxreg |
3584 |
or |
3585 |
op (src)address, (dst)mmxreg |
3586 |
2 opcode bytes. |
3587 |
Supplied eip points to the first address mode byte. |
3588 |
*/ |
3347 |
static |
3589 |
static |
3348 |
void dis_pop_segreg ( UCodeBlock* cb, UInt sreg, Int sz ) |
3590 |
Addr dis_SSE2_to_MMX ( UCodeBlock *cb, |
|
|
3591 |
UChar sorb, |
3592 |
Addr eip, |
3593 |
Int sz, |
3594 |
Char* name, |
3595 |
UChar opc1, |
3596 |
UChar opc2 ) |
3349 |
{ |
3597 |
{ |
3350 |
Int t1 = newTemp(cb), t2 = newTemp(cb); |
3598 |
UChar dis_buf[50]; |
3351 |
vg_assert(sz == 4); |
3599 |
UChar modrm = getUChar(eip); |
3352 |
uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t2); |
3600 |
if (epartIsReg(modrm)) { |
3353 |
uInstr2(cb, LOAD, 2, TempReg, t2, TempReg, t1); |
3601 |
/* Completely internal SSE insn. */ |
3354 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t2); |
3602 |
uInstr2(cb, SSE3, 0, /* ignore sz for internal ops */ |
3355 |
uLiteral(cb, sz); |
3603 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3356 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
3604 |
Lit16, (UShort)modrm ); |
3357 |
uInstr2(cb, PUTSEG, 2, TempReg, t1, ArchRegS, sreg); |
3605 |
DIP("%s %s, %s\n", |
3358 |
if (dis) |
3606 |
name, nameXMMReg(eregOfRM(modrm)), nameMMXReg(gregOfRM(modrm)) ); |
3359 |
VG_(printf)("pop %s\n", VG_(name_of_seg_reg)(sreg)); |
3607 |
eip++; |
|
|
3608 |
} else { |
3609 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3610 |
Int tmpa = LOW24(pair); |
3611 |
eip += HI8(pair); |
3612 |
uInstr3(cb, SSE2a_MemRd, sz, |
3613 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3614 |
Lit16, ((UShort)modrm), |
3615 |
TempReg, tmpa); |
3616 |
DIP("%s %s, %s\n", name, dis_buf, nameMMXReg(gregOfRM(modrm))); |
3617 |
} |
3618 |
return eip; |
3360 |
} |
3619 |
} |
3361 |
|
3620 |
|
3362 |
/*------------------------------------------------------------*/ |
|
|
3363 |
/*--- Disassembling entire basic blocks ---*/ |
3364 |
/*------------------------------------------------------------*/ |
3365 |
|
3366 |
/* Disassemble a single instruction into ucode, returning the updated |
3367 |
eip, and setting *isEnd to True if this is the last insn in a basic |
3368 |
block. Also do debug printing if (dis). */ |
3369 |
|
3621 |
|
3370 |
static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd ) |
3622 |
/* Simple SSE operations, either |
|
|
3623 |
op (src)mmxreg, (dst)xmmreg |
3624 |
or |
3625 |
op (src)address, (dst)xmmreg |
3626 |
2 opcode bytes. |
3627 |
Supplied eip points to the first address mode byte. |
3628 |
*/ |
3629 |
static |
3630 |
Addr dis_SSE2_from_MMX ( UCodeBlock *cb, |
3631 |
UChar sorb, |
3632 |
Addr eip, |
3633 |
Int sz, |
3634 |
Char* name, |
3635 |
UChar opc1, |
3636 |
UChar opc2 ) |
3637 |
{ |
3638 |
UChar dis_buf[50]; |
3639 |
UChar modrm = getUChar(eip); |
3640 |
if (epartIsReg(modrm)) { |
3641 |
/* Completely internal SSE insn. */ |
3642 |
uInstr2(cb, SSE3, 0, /* ignore sz for internal ops */ |
3643 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3644 |
Lit16, (UShort)modrm ); |
3645 |
DIP("%s %s, %s\n", |
3646 |
name, nameMMXReg(eregOfRM(modrm)), nameXMMReg(gregOfRM(modrm)) ); |
3647 |
eip++; |
3648 |
} else { |
3649 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3650 |
Int tmpa = LOW24(pair); |
3651 |
eip += HI8(pair); |
3652 |
uInstr3(cb, SSE2a_MemRd, sz, |
3653 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3654 |
Lit16, ((UShort)modrm), |
3655 |
TempReg, tmpa); |
3656 |
DIP("%s %s, %s\n", name, dis_buf, nameXMMReg(gregOfRM(modrm))); |
3657 |
} |
3658 |
return eip; |
3659 |
} |
3660 |
|
3661 |
|
3662 |
/* Simple SSE operations, either |
3663 |
op (src)xmmreg, (dst)mmxreg |
3664 |
or |
3665 |
op (src)address, (dst)mmxreg |
3666 |
3 opcode bytes. |
3667 |
Supplied eip points to the first address mode byte. |
3668 |
*/ |
3669 |
static |
3670 |
Addr dis_SSE3_to_MMX ( UCodeBlock *cb, |
3671 |
UChar sorb, |
3672 |
Addr eip, |
3673 |
Int sz, |
3674 |
Char* name, |
3675 |
UChar opc1, |
3676 |
UChar opc2, |
3677 |
UChar opc3 ) |
3678 |
{ |
3679 |
UChar dis_buf[50]; |
3680 |
UChar modrm = getUChar(eip); |
3681 |
if (epartIsReg(modrm)) { |
3682 |
/* Completely internal SSE insn. */ |
3683 |
uInstr2(cb, SSE4, 0, /* ignore sz for internal ops */ |
3684 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3685 |
Lit16, (((UShort)opc3) << 8) | (UShort)modrm ); |
3686 |
DIP("%s %s, %s\n", |
3687 |
name, nameXMMReg(eregOfRM(modrm)), nameMMXReg(gregOfRM(modrm)) ); |
3688 |
eip++; |
3689 |
} else { |
3690 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3691 |
Int tmpa = LOW24(pair); |
3692 |
eip += HI8(pair); |
3693 |
uInstr3(cb, SSE3a_MemRd, sz, |
3694 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3695 |
Lit16, (((UShort)(opc3)) << 8) | ((UShort)modrm), |
3696 |
TempReg, tmpa); |
3697 |
DIP("%s %s, %s\n", name, dis_buf, nameMMXReg(gregOfRM(modrm))); |
3698 |
} |
3699 |
return eip; |
3700 |
} |
3701 |
|
3702 |
|
3703 |
/* Simple SSE operations, either |
3704 |
op (src)mmxreg, (dst)xmmreg |
3705 |
or |
3706 |
op (src)address, (dst)xmmreg |
3707 |
3 opcode bytes. |
3708 |
Supplied eip points to the first address mode byte. |
3709 |
*/ |
3710 |
static |
3711 |
Addr dis_SSE3_from_MMX ( UCodeBlock *cb, |
3712 |
UChar sorb, |
3713 |
Addr eip, |
3714 |
Int sz, |
3715 |
Char* name, |
3716 |
UChar opc1, |
3717 |
UChar opc2, |
3718 |
UChar opc3 ) |
3719 |
{ |
3720 |
UChar dis_buf[50]; |
3721 |
UChar modrm = getUChar(eip); |
3722 |
if (epartIsReg(modrm)) { |
3723 |
/* Completely internal SSE insn. */ |
3724 |
uInstr2(cb, SSE4, 0, /* ignore sz for internal ops */ |
3725 |
Lit16, (((UShort)opc1) << 8) | (UShort)opc2, |
3726 |
Lit16, (((UShort)opc3) << 8) | (UShort)modrm ); |
3727 |
DIP("%s %s, %s\n", |
3728 |
name, nameMMXReg(eregOfRM(modrm)), nameXMMReg(gregOfRM(modrm)) ); |
3729 |
eip++; |
3730 |
} else { |
3731 |
UInt pair = disAMode ( cb, sorb, eip, dis_buf ); |
3732 |
Int tmpa = LOW24(pair); |
3733 |
eip += HI8(pair); |
3734 |
uInstr3(cb, SSE3a_MemRd, sz, |
3735 |
Lit16, (((UShort)(opc1)) << 8) | ((UShort)opc2), |
3736 |
Lit16, (((UShort)(opc3)) << 8) | ((UShort)modrm), |
3737 |
TempReg, tmpa); |
3738 |
DIP("%s %s, %s\n", name, dis_buf, nameXMMReg(gregOfRM(modrm))); |
3739 |
} |
3740 |
return eip; |
3741 |
} |
3742 |
|
3743 |
|
3744 |
static |
3745 |
void dis_push_segreg ( UCodeBlock* cb, UInt sreg, Int sz ) |
3746 |
{ |
3747 |
Int t1 = newTemp(cb), t2 = newTemp(cb); |
3748 |
vg_assert(sz == 4); |
3749 |
uInstr2(cb, GETSEG, 2, ArchRegS, sreg, TempReg, t1); |
3750 |
uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t2); |
3751 |
uInstr2(cb, SUB, 4, Literal, 0, TempReg, t2); |
3752 |
uLiteral(cb, 4); |
3753 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
3754 |
uInstr2(cb, STORE, 2, TempReg, t1, TempReg, t2); |
3755 |
DIP("push %s\n", VG_(name_of_seg_reg)(sreg)); |
3756 |
} |
3757 |
|
3758 |
static |
3759 |
void dis_pop_segreg ( UCodeBlock* cb, UInt sreg, Int sz ) |
3760 |
{ |
3761 |
Int t1 = newTemp(cb), t2 = newTemp(cb); |
3762 |
vg_assert(sz == 4); |
3763 |
uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t2); |
3764 |
uInstr2(cb, LOAD, 2, TempReg, t2, TempReg, t1); |
3765 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t2); |
3766 |
uLiteral(cb, sz); |
3767 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
3768 |
uInstr2(cb, PUTSEG, 2, TempReg, t1, ArchRegS, sreg); |
3769 |
DIP("pop %s\n", VG_(name_of_seg_reg)(sreg)); |
3770 |
} |
3771 |
|
3772 |
/*------------------------------------------------------------*/ |
3773 |
/*--- Disassembling entire basic blocks ---*/ |
3774 |
/*------------------------------------------------------------*/ |
3775 |
|
3776 |
/* Disassemble a single instruction into ucode, returning the updated |
3777 |
eip, and setting *isEnd to True if this is the last insn in a basic |
3778 |
block. Also do debug printing if necessary. */ |
3779 |
|
3780 |
static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd ) |
3371 |
{ |
3781 |
{ |
3372 |
UChar opc, modrm, abyte; |
3782 |
UChar opc, modrm, abyte; |
3373 |
UInt d32, pair; |
3783 |
UInt d32, pair; |
Lines 3393-3399
Link Here
|
3393 |
*isEnd = False; |
3803 |
*isEnd = False; |
3394 |
t1 = t2 = t3 = t4 = INVALID_TEMPREG; |
3804 |
t1 = t2 = t3 = t4 = INVALID_TEMPREG; |
3395 |
|
3805 |
|
3396 |
if (dis) VG_(printf)("\t0x%x: ", eip); |
3806 |
DIP("\t0x%x: ", eip); |
3397 |
|
3807 |
|
3398 |
/* Spot the client-request magic sequence. */ |
3808 |
/* Spot the client-request magic sequence. */ |
3399 |
{ |
3809 |
{ |
Lines 3414-3426
Link Here
|
3414 |
myeip[15] == 0xC1 && myeip[16] == 0xC0 && myeip[17] == 0x13 |
3824 |
myeip[15] == 0xC1 && myeip[16] == 0xC0 && myeip[17] == 0x13 |
3415 |
) { |
3825 |
) { |
3416 |
eip += 18; |
3826 |
eip += 18; |
3417 |
uInstr1(cb, JMP, 0, Literal, 0); |
3827 |
jmp_lit(cb, eip); |
3418 |
uLiteral(cb, eip); |
|
|
3419 |
uCond(cb, CondAlways); |
3420 |
LAST_UINSTR(cb).jmpkind = JmpClientReq; |
3828 |
LAST_UINSTR(cb).jmpkind = JmpClientReq; |
3421 |
*isEnd = True; |
3829 |
*isEnd = True; |
3422 |
if (dis) |
3830 |
DIP("%%edx = client_request ( %%eax )\n"); |
3423 |
VG_(printf)("%%edx = client_request ( %%eax )\n"); |
|
|
3424 |
return eip; |
3831 |
return eip; |
3425 |
} |
3832 |
} |
3426 |
} |
3833 |
} |
Lines 3477-3496
Link Here
|
3477 |
if (VG_(have_ssestate)) { |
3884 |
if (VG_(have_ssestate)) { |
3478 |
UChar* insn = (UChar*)eip; |
3885 |
UChar* insn = (UChar*)eip; |
3479 |
|
3886 |
|
|
|
3887 |
/* FXSAVE/FXRSTOR m32 -- load/store the FPU/MMX/SSE state. */ |
3888 |
if (insn[0] == 0x0F && insn[1] == 0xAE |
3889 |
&& (!epartIsReg(insn[2])) |
3890 |
&& (gregOfRM(insn[2]) == 1 || gregOfRM(insn[2]) == 0) ) { |
3891 |
Bool store = gregOfRM(insn[2]) == 0; |
3892 |
vg_assert(sz == 4); |
3893 |
pair = disAMode ( cb, sorb, eip+2, dis_buf ); |
3894 |
t1 = LOW24(pair); |
3895 |
eip += 2+HI8(pair); |
3896 |
uInstr3(cb, store ? SSE2a_MemWr : SSE2a_MemRd, 512, |
3897 |
Lit16, (((UShort)insn[0]) << 8) | (UShort)insn[1], |
3898 |
Lit16, (UShort)insn[2], |
3899 |
TempReg, t1 ); |
3900 |
DIP("fx%s %s\n", store ? "save" : "rstor", dis_buf ); |
3901 |
goto decode_success; |
3902 |
} |
3903 |
|
3480 |
/* STMXCSR/LDMXCSR m32 -- load/store the MXCSR register. */ |
3904 |
/* STMXCSR/LDMXCSR m32 -- load/store the MXCSR register. */ |
3481 |
if (insn[0] == 0x0F && insn[1] == 0xAE |
3905 |
if (insn[0] == 0x0F && insn[1] == 0xAE |
|
|
3906 |
&& (!epartIsReg(insn[2])) |
3482 |
&& (gregOfRM(insn[2]) == 3 || gregOfRM(insn[2]) == 2) ) { |
3907 |
&& (gregOfRM(insn[2]) == 3 || gregOfRM(insn[2]) == 2) ) { |
3483 |
Bool store = gregOfRM(insn[2]) == 3; |
3908 |
Bool store = gregOfRM(insn[2]) == 3; |
3484 |
vg_assert(sz == 4); |
3909 |
vg_assert(sz == 4); |
3485 |
pair = disAMode ( cb, sorb, eip+2, dis?dis_buf:NULL ); |
3910 |
pair = disAMode ( cb, sorb, eip+2, dis_buf ); |
3486 |
t1 = LOW24(pair); |
3911 |
t1 = LOW24(pair); |
3487 |
eip += 2+HI8(pair); |
3912 |
eip += 2+HI8(pair); |
3488 |
uInstr3(cb, store ? SSE2a_MemWr : SSE2a_MemRd, 4, |
3913 |
uInstr3(cb, store ? SSE2a_MemWr : SSE2a_MemRd, 4, |
3489 |
Lit16, (((UShort)insn[0]) << 8) | (UShort)insn[1], |
3914 |
Lit16, (((UShort)insn[0]) << 8) | (UShort)insn[1], |
3490 |
Lit16, (UShort)insn[2], |
3915 |
Lit16, (UShort)insn[2], |
3491 |
TempReg, t1 ); |
3916 |
TempReg, t1 ); |
3492 |
if (dis) |
3917 |
DIP("%smxcsr %s\n", store ? "st" : "ld", dis_buf ); |
3493 |
VG_(printf)("%smxcsr %s\n", store ? "st" : "ld", dis_buf ); |
|
|
3494 |
goto decode_success; |
3918 |
goto decode_success; |
3495 |
} |
3919 |
} |
3496 |
|
3920 |
|
Lines 3504-3511
Link Here
|
3504 |
uInstr2(cb, SSE3, 0, /* ignore sz for internal ops */ |
3928 |
uInstr2(cb, SSE3, 0, /* ignore sz for internal ops */ |
3505 |
Lit16, (((UShort)0x0F) << 8) | (UShort)0xAE, |
3929 |
Lit16, (((UShort)0x0F) << 8) | (UShort)0xAE, |
3506 |
Lit16, (UShort)insn[2] ); |
3930 |
Lit16, (UShort)insn[2] ); |
3507 |
if (dis) |
3931 |
DIP("sfence\n"); |
3508 |
VG_(printf)("sfence\n"); |
3932 |
goto decode_success; |
|
|
3933 |
} |
3934 |
|
3935 |
/* CLFLUSH -- flush cache line */ |
3936 |
if (insn[0] == 0x0F && insn[1] == 0xAE |
3937 |
&& (!epartIsReg(insn[2])) |
3938 |
&& (gregOfRM(insn[2]) == 7)) |
3939 |
{ |
3940 |
vg_assert(sz == 4); |
3941 |
pair = disAMode ( cb, sorb, eip+2, dis_buf ); |
3942 |
t1 = LOW24(pair); |
3943 |
eip += 2+HI8(pair); |
3944 |
uInstr3(cb, SSE2a_MemRd, 0, /* ignore sz for internal ops */ |
3945 |
Lit16, (((UShort)0x0F) << 8) | (UShort)0xAE, |
3946 |
Lit16, (UShort)insn[2], |
3947 |
TempReg, t1 ); |
3948 |
DIP("clflush %s\n", dis_buf); |
3949 |
goto decode_success; |
3950 |
} |
3951 |
|
3952 |
/* CVTPI2PS (0x0F,0x2A) -- mm/m64, xmm */ |
3953 |
/* CVTPI2PD (0x66,0x0F,0x2A) -- mm/m64, xmm */ |
3954 |
if (insn[0] == 0x0F && insn[1] == 0x2A) { |
3955 |
if (sz == 4) { |
3956 |
eip = dis_SSE2_from_MMX |
3957 |
( cb, sorb, eip+2, 8, "cvtpi2ps", |
3958 |
insn[0], insn[1] ); |
3959 |
} else { |
3960 |
eip = dis_SSE3_from_MMX |
3961 |
( cb, sorb, eip+2, 8, "cvtpi2pd", |
3962 |
0x66, insn[0], insn[1] ); |
3963 |
} |
3964 |
goto decode_success; |
3965 |
} |
3966 |
|
3967 |
/* CVTTPS2PI (0x0F,0x2C) -- xmm/m64, mm */ |
3968 |
/* CVTPS2PI (0x0F,0x2D) -- xmm/m64, mm */ |
3969 |
/* CVTTPD2PI (0x66,0x0F,0x2C) -- xmm/m128, mm */ |
3970 |
/* CVTPD2PI (0x66,0x0F,0x2D) -- xmm/m128, mm */ |
3971 |
if (insn[0] == 0x0F |
3972 |
&& (insn[1] == 0x2C || insn[1] == 0x2D)) { |
3973 |
if (sz == 4) { |
3974 |
eip = dis_SSE2_to_MMX |
3975 |
( cb, sorb, eip+2, 8, "cvt{t}ps2pi", |
3976 |
insn[0], insn[1] ); |
3977 |
} else { |
3978 |
eip = dis_SSE3_to_MMX |
3979 |
( cb, sorb, eip+2, 16, "cvt{t}pd2pi", |
3980 |
0x66, insn[0], insn[1] ); |
3981 |
} |
3509 |
goto decode_success; |
3982 |
goto decode_success; |
3510 |
} |
3983 |
} |
3511 |
|
3984 |
|
Lines 3537-3546
Link Here
|
3537 |
Lit16, (((UShort)insn[2]) << 8) | (UShort)modrm, |
4010 |
Lit16, (((UShort)insn[2]) << 8) | (UShort)modrm, |
3538 |
TempReg, t1 ); |
4011 |
TempReg, t1 ); |
3539 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
4012 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
3540 |
if (dis) |
4013 |
DIP("cvt{t}s{s,d}2si %s, %s\n", |
3541 |
VG_(printf)("cvt{t}s{s,d}2si %s, %s\n", |
4014 |
nameXMMReg(eregOfRM(modrm)), nameIReg(4,gregOfRM(modrm)) ); |
3542 |
nameXMMReg(eregOfRM(modrm)), |
|
|
3543 |
nameIReg(4,gregOfRM(modrm)) ); |
3544 |
} else { |
4015 |
} else { |
3545 |
/* So, we're reading memory and writing an ireg. This calls |
4016 |
/* So, we're reading memory and writing an ireg. This calls |
3546 |
for the ultra-horrible SSE3ag_MemRd_RegWr uinstr. We |
4017 |
for the ultra-horrible SSE3ag_MemRd_RegWr uinstr. We |
Lines 3551-3557
Link Here
|
3551 |
/* Destination ireg is GREG. Address goes as EREG as |
4022 |
/* Destination ireg is GREG. Address goes as EREG as |
3552 |
usual. */ |
4023 |
usual. */ |
3553 |
t1 = newTemp(cb); /* t1 holds value on its way to ireg */ |
4024 |
t1 = newTemp(cb); /* t1 holds value on its way to ireg */ |
3554 |
pair = disAMode ( cb, sorb, eip+3, dis?dis_buf:NULL ); |
4025 |
pair = disAMode ( cb, sorb, eip+3, dis_buf ); |
3555 |
t2 = LOW24(pair); /* t2 holds addr */ |
4026 |
t2 = LOW24(pair); /* t2 holds addr */ |
3556 |
eip += 3+HI8(pair); |
4027 |
eip += 3+HI8(pair); |
3557 |
uInstr2(cb, SSE3ag_MemRd_RegWr, insn[0]==0xF2 ? 8 : 4, |
4028 |
uInstr2(cb, SSE3ag_MemRd_RegWr, insn[0]==0xF2 ? 8 : 4, |
Lines 3562-3571
Link Here
|
3562 |
| (((UInt)insn[2]) << 8) |
4033 |
| (((UInt)insn[2]) << 8) |
3563 |
| ((UInt)modrm) ); |
4034 |
| ((UInt)modrm) ); |
3564 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
4035 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
3565 |
if (dis) |
4036 |
DIP("cvt{t}s{s,d}2si %s, %s\n", |
3566 |
VG_(printf)("cvt{t}s{s,d}2si %s, %s\n", |
4037 |
dis_buf, nameIReg(4,gregOfRM(modrm)) ); |
3567 |
dis_buf, |
|
|
3568 |
nameIReg(4,gregOfRM(modrm)) ); |
3569 |
} |
4038 |
} |
3570 |
goto decode_success; |
4039 |
goto decode_success; |
3571 |
} |
4040 |
} |
Lines 3588-3609
Link Here
|
3588 |
Lit16, (((UShort)insn[2]) << 8) | (UShort)modrm, |
4057 |
Lit16, (((UShort)insn[2]) << 8) | (UShort)modrm, |
3589 |
TempReg, t1 ); |
4058 |
TempReg, t1 ); |
3590 |
eip += 4; |
4059 |
eip += 4; |
3591 |
if (dis) |
4060 |
DIP("cvtsi2s%s %s, %s\n", s_or_d, |
3592 |
VG_(printf)("cvtsi2s%s %s, %s\n", s_or_d, |
4061 |
nameIReg(4,eregOfRM(modrm)), nameXMMReg(gregOfRM(modrm))); |
3593 |
nameIReg(4,eregOfRM(modrm)), |
|
|
3594 |
nameXMMReg(gregOfRM(modrm))); |
3595 |
} else { |
4062 |
} else { |
3596 |
pair = disAMode ( cb, sorb, eip+3, dis?dis_buf:NULL ); |
4063 |
pair = disAMode ( cb, sorb, eip+3, dis_buf ); |
3597 |
t2 = LOW24(pair); |
4064 |
t2 = LOW24(pair); |
3598 |
eip += 3+HI8(pair); |
4065 |
eip += 3+HI8(pair); |
3599 |
uInstr3(cb, SSE3a_MemRd, 4, |
4066 |
uInstr3(cb, SSE3a_MemRd, 4, |
3600 |
Lit16, (((UShort)insn[0]) << 8) | (UShort)insn[1], |
4067 |
Lit16, (((UShort)insn[0]) << 8) | (UShort)insn[1], |
3601 |
Lit16, (((UShort)insn[2]) << 8) | (UShort)modrm, |
4068 |
Lit16, (((UShort)insn[2]) << 8) | (UShort)modrm, |
3602 |
TempReg, t2 ); |
4069 |
TempReg, t2 ); |
3603 |
if (dis) |
4070 |
DIP("cvtsi2s%s %s, %s\n", |
3604 |
VG_(printf)("cvtsi2s%s %s, %s\n", s_or_d, |
4071 |
s_or_d, dis_buf, nameXMMReg(gregOfRM(modrm))); |
3605 |
dis_buf, |
4072 |
} |
3606 |
nameXMMReg(gregOfRM(modrm))); |
4073 |
goto decode_success; |
|
|
4074 |
} |
4075 |
|
4076 |
/* CVTPS2PD -- convert two packed floats to two packed doubles. */ |
4077 |
/* 0x66: CVTPD2PS -- convert two packed doubles to two packed floats. */ |
4078 |
if (insn[0] == 0x0F && insn[1] == 0x5A) { |
4079 |
vg_assert(sz == 2 || sz == 4); |
4080 |
if (sz == 4) { |
4081 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 8, "cvtps2pd", |
4082 |
insn[0], insn[1] ); |
4083 |
} else { |
4084 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "cvtpd2ps", |
4085 |
0x66, insn[0], insn[1] ); |
3607 |
} |
4086 |
} |
3608 |
goto decode_success; |
4087 |
goto decode_success; |
3609 |
} |
4088 |
} |
Lines 3624-3629
Link Here
|
3624 |
goto decode_success; |
4103 |
goto decode_success; |
3625 |
} |
4104 |
} |
3626 |
|
4105 |
|
|
|
4106 |
/* CVTDQ2PS -- convert four ints to four packed floats. */ |
4107 |
/* 0x66: CVTPS2DQ -- convert four packed floats to four ints. */ |
4108 |
if (insn[0] == 0x0F && insn[1] == 0x5B) { |
4109 |
vg_assert(sz == 2 || sz == 4); |
4110 |
if (sz == 4) { |
4111 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "cvtdq2ps", |
4112 |
insn[0], insn[1] ); |
4113 |
} else { |
4114 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "cvtps2dq", |
4115 |
0x66, insn[0], insn[1] ); |
4116 |
} |
4117 |
goto decode_success; |
4118 |
} |
4119 |
|
4120 |
/* CVTPD2DQ -- convert two packed doubles to two ints. */ |
4121 |
if (sz == 2 |
4122 |
&& insn[0] == 0x0F && insn[1] == 0xE6) { |
4123 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 8, "cvtpd2dq", |
4124 |
0x66, insn[0], insn[1] ); |
4125 |
goto decode_success; |
4126 |
} |
4127 |
|
4128 |
/* CVTTPD2DQ -- convert two packed doubles to two ints with truncation. */ |
4129 |
if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0xE6) { |
4130 |
vg_assert(sz == 4); |
4131 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+3, 8, "cvttpd2dq", |
4132 |
insn[0], insn[1], insn[2] ); |
4133 |
goto decode_success; |
4134 |
} |
4135 |
|
4136 |
/* CVTDQ2PD -- convert two ints to two packed doubles. */ |
4137 |
if (insn[0] == 0xF3 && insn[1] == 0x0F && insn[2] == 0xE6) { |
4138 |
vg_assert(sz == 4); |
4139 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+3, 8, "cvtdq2pd", |
4140 |
insn[0], insn[1], insn[2] ); |
4141 |
goto decode_success; |
4142 |
} |
4143 |
|
4144 |
/* CVTTPS2DQ -- convert four packed floats to four ints with truncation. */ |
4145 |
if (insn[0] == 0xF3 && insn[1] == 0x0F && insn[2] == 0x5B) { |
4146 |
vg_assert(sz == 4); |
4147 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+3, 16, "cvttps2dq", |
4148 |
insn[0], insn[1], insn[2] ); |
4149 |
goto decode_success; |
4150 |
} |
4151 |
|
4152 |
/* CMPSS -- compare scalar floats. */ |
4153 |
if (insn[0] == 0xF3 && insn[1] == 0x0F && insn[2] == 0xC2) { |
4154 |
vg_assert(sz == 4); |
4155 |
eip = dis_SSE3_reg_or_mem_Imm8 ( cb, sorb, eip+3, 8, "cmpss", |
4156 |
insn[0], insn[1], insn[2] ); |
4157 |
goto decode_success; |
4158 |
} |
4159 |
|
3627 |
/* CMPSD -- compare scalar doubles. */ |
4160 |
/* CMPSD -- compare scalar doubles. */ |
3628 |
if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0xC2) { |
4161 |
if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0xC2) { |
3629 |
vg_assert(sz == 4); |
4162 |
vg_assert(sz == 4); |
Lines 3655-3664
Link Here
|
3655 |
goto decode_success; |
4188 |
goto decode_success; |
3656 |
} |
4189 |
} |
3657 |
|
4190 |
|
|
|
4191 |
/* PSHUFLW */ |
4192 |
if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0x70) { |
4193 |
eip = dis_SSE3_reg_or_mem_Imm8 ( cb, sorb, eip+3, 16, |
4194 |
"pshuflw", |
4195 |
insn[0], insn[1], insn[2] ); |
4196 |
goto decode_success; |
4197 |
} |
4198 |
|
4199 |
/* PSHUFHW */ |
4200 |
if (insn[0] == 0xF3 && insn[1] == 0x0F && insn[2] == 0x70) { |
4201 |
eip = dis_SSE3_reg_or_mem_Imm8 ( cb, sorb, eip+3, 16, |
4202 |
"pshufhw", |
4203 |
insn[0], insn[1], insn[2] ); |
4204 |
goto decode_success; |
4205 |
} |
4206 |
|
3658 |
/* PSHUFW */ |
4207 |
/* PSHUFW */ |
3659 |
if (sz == 4 |
4208 |
if (sz == 4 |
3660 |
&& insn[0] == 0x0F && insn[1] == 0x70) { |
4209 |
&& insn[0] == 0x0F && insn[1] == 0x70) { |
3661 |
eip = dis_SSE2_reg_or_mem_Imm8 ( cb, sorb, eip+2, 16, |
4210 |
eip = dis_SSE2_reg_or_mem_Imm8 ( cb, sorb, eip+2, 8, |
3662 |
"pshufw", |
4211 |
"pshufw", |
3663 |
insn[0], insn[1] ); |
4212 |
insn[0], insn[1] ); |
3664 |
goto decode_success; |
4213 |
goto decode_success; |
Lines 3795-3800
Link Here
|
3795 |
goto decode_success; |
4344 |
goto decode_success; |
3796 |
} |
4345 |
} |
3797 |
|
4346 |
|
|
|
4347 |
/* MINPS */ |
4348 |
/* 0x66: MINPD */ |
4349 |
if (insn[0] == 0x0F && insn[1] == 0x5D) { |
4350 |
vg_assert(sz == 4 || sz == 2); |
4351 |
if (sz == 4) { |
4352 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "minps", |
4353 |
insn[0], insn[1] ); |
4354 |
} else { |
4355 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "minpd", |
4356 |
0x66, insn[0], insn[1] ); |
4357 |
} |
4358 |
goto decode_success; |
4359 |
} |
4360 |
|
3798 |
/* 0xF3: MAXSD */ |
4361 |
/* 0xF3: MAXSD */ |
3799 |
/* 0xF3: MAXSS */ |
4362 |
/* 0xF3: MAXSS */ |
3800 |
if ((insn[0] == 0xF2 || insn[0] == 0xF3) |
4363 |
if ((insn[0] == 0xF2 || insn[0] == 0xF3) |
Lines 3857-3867
Link Here
|
3857 |
goto decode_success; |
4420 |
goto decode_success; |
3858 |
} |
4421 |
} |
3859 |
|
4422 |
|
3860 |
/* ORPD (src)xmmreg-or-mem, (dst)xmmreg */ |
4423 |
/* ORPS */ |
3861 |
if (sz == 2 |
4424 |
/* 0x66: ORPD (src)xmmreg-or-mem, (dst)xmmreg */ |
3862 |
&& insn[0] == 0x0F && insn[1] == 0x56) { |
4425 |
if (insn[0] == 0x0F && insn[1] == 0x56) { |
|
|
4426 |
vg_assert(sz == 4 || sz == 2); |
4427 |
if (sz == 4) { |
4428 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "orps", |
4429 |
insn[0], insn[1] ); |
4430 |
} else { |
3863 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "orpd", |
4431 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "orpd", |
3864 |
0x66, insn[0], insn[1] ); |
4432 |
0x66, insn[0], insn[1] ); |
|
|
4433 |
} |
3865 |
goto decode_success; |
4434 |
goto decode_success; |
3866 |
} |
4435 |
} |
3867 |
|
4436 |
|
Lines 3926-3948
Link Here
|
3926 |
0x66, insn[0], insn[1] ); |
4495 |
0x66, insn[0], insn[1] ); |
3927 |
goto decode_success; |
4496 |
goto decode_success; |
3928 |
} |
4497 |
} |
3929 |
/* 0xE0: PAVGB(src)xmmreg-or-mem, (dst)xmmreg, size 4 */ |
4498 |
|
3930 |
if (sz == 4 |
4499 |
/* 0xF6: PSADBW(src)xmmreg-or-mem, (dst)xmmreg */ |
3931 |
&& insn[0] == 0x0F |
4500 |
if (sz == 2 |
3932 |
&& insn[1] == 0xE0 ) { |
4501 |
&& insn[0] == 0x0F && insn[1] == 0xF6) { |
3933 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "pavg{b,w}", |
4502 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "psadbw", |
3934 |
insn[0], insn[1] ); |
4503 |
0x66, insn[0], insn[1] ); |
3935 |
goto decode_success; |
4504 |
goto decode_success; |
3936 |
} |
4505 |
} |
3937 |
|
4506 |
|
3938 |
/* 0x60: PUNPCKLBW (src)xmmreg-or-mem, (dst)xmmreg */ |
4507 |
/* 0x60: PUNPCKLBW (src)xmmreg-or-mem, (dst)xmmreg */ |
3939 |
/* 0x61: PUNPCKLWD (src)xmmreg-or-mem, (dst)xmmreg */ |
4508 |
/* 0x61: PUNPCKLWD (src)xmmreg-or-mem, (dst)xmmreg */ |
3940 |
/* 0x62: PUNPCKLDQ (src)xmmreg-or-mem, (dst)xmmreg */ |
4509 |
/* 0x62: PUNPCKLDQ (src)xmmreg-or-mem, (dst)xmmreg */ |
|
|
4510 |
/* 0x6C: PUNPCKQLQDQ (src)xmmreg-or-mem, (dst)xmmreg */ |
3941 |
if (sz == 2 |
4511 |
if (sz == 2 |
3942 |
&& insn[0] == 0x0F |
4512 |
&& insn[0] == 0x0F |
3943 |
&& (insn[1] == 0x60 || insn[1] == 0x61 || insn[1] == 0x62)) { |
4513 |
&& (insn[1] == 0x60 || insn[1] == 0x61 |
|
|
4514 |
|| insn[1] == 0x62 || insn[1] == 0x6C)) { |
3944 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, |
4515 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, |
3945 |
"punpckl{bw,wd,dq}", |
4516 |
"punpckl{bw,wd,dq,qdq}", |
3946 |
0x66, insn[0], insn[1] ); |
4517 |
0x66, insn[0], insn[1] ); |
3947 |
goto decode_success; |
4518 |
goto decode_success; |
3948 |
} |
4519 |
} |
Lines 3950-3960
Link Here
|
3950 |
/* 0x68: PUNPCKHBW (src)xmmreg-or-mem, (dst)xmmreg */ |
4521 |
/* 0x68: PUNPCKHBW (src)xmmreg-or-mem, (dst)xmmreg */ |
3951 |
/* 0x69: PUNPCKHWD (src)xmmreg-or-mem, (dst)xmmreg */ |
4522 |
/* 0x69: PUNPCKHWD (src)xmmreg-or-mem, (dst)xmmreg */ |
3952 |
/* 0x6A: PUNPCKHDQ (src)xmmreg-or-mem, (dst)xmmreg */ |
4523 |
/* 0x6A: PUNPCKHDQ (src)xmmreg-or-mem, (dst)xmmreg */ |
|
|
4524 |
/* 0x6D: PUNPCKHQDQ (src)xmmreg-or-mem, (dst)xmmreg */ |
3953 |
if (sz == 2 |
4525 |
if (sz == 2 |
3954 |
&& insn[0] == 0x0F |
4526 |
&& insn[0] == 0x0F |
3955 |
&& (insn[1] == 0x68 || insn[1] == 0x69 || insn[1] == 0x6A)) { |
4527 |
&& (insn[1] == 0x68 || insn[1] == 0x69 |
|
|
4528 |
|| insn[1] == 0x6A || insn[1] == 0x6D)) { |
3956 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, |
4529 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, |
3957 |
"punpckh{bw,wd,dq}", |
4530 |
"punpckh{bw,wd,dq,qdq}", |
3958 |
0x66, insn[0], insn[1] ); |
4531 |
0x66, insn[0], insn[1] ); |
3959 |
goto decode_success; |
4532 |
goto decode_success; |
3960 |
} |
4533 |
} |
Lines 4055-4066
Link Here
|
4055 |
goto decode_success; |
4628 |
goto decode_success; |
4056 |
} |
4629 |
} |
4057 |
|
4630 |
|
|
|
4631 |
/* 0xE4: PMULHUW(src)xmmreg-or-mem, (dst)xmmreg */ |
4058 |
/* 0xE5: PMULHW(src)xmmreg-or-mem, (dst)xmmreg */ |
4632 |
/* 0xE5: PMULHW(src)xmmreg-or-mem, (dst)xmmreg */ |
4059 |
/* 0xD5: PMULLW(src)xmmreg-or-mem, (dst)xmmreg */ |
4633 |
/* 0xD5: PMULLW(src)xmmreg-or-mem, (dst)xmmreg */ |
4060 |
if (sz == 2 |
4634 |
if (sz == 2 |
4061 |
&& insn[0] == 0x0F |
4635 |
&& insn[0] == 0x0F |
4062 |
&& (insn[1] == 0xE5 || insn[1] == 0xD5)) { |
4636 |
&& (insn[1] == 0xE4 || insn[1] == 0xE5 || insn[1] == 0xD5)) { |
4063 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "pmul{h,l}w", |
4637 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "pmul{hu,h,l}w", |
|
|
4638 |
0x66, insn[0], insn[1] ); |
4639 |
goto decode_success; |
4640 |
} |
4641 |
|
4642 |
/* 0xD5: PMULUDQ(src)xmmreg-or-mem, (dst)xmmreg */ |
4643 |
if (sz == 2 |
4644 |
&& insn[0] == 0x0F && insn[1] == 0xF4) { |
4645 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "pmuludq", |
4064 |
0x66, insn[0], insn[1] ); |
4646 |
0x66, insn[0], insn[1] ); |
4065 |
goto decode_success; |
4647 |
goto decode_success; |
4066 |
} |
4648 |
} |
Lines 4204-4209
Link Here
|
4204 |
goto decode_success; |
4786 |
goto decode_success; |
4205 |
} |
4787 |
} |
4206 |
|
4788 |
|
|
|
4789 |
/* MOVDQ2Q -- move low 4 bytes of XMM reg to MMX reg. */ |
4790 |
if (insn[0] == 0xF2 |
4791 |
&& insn[1] == 0x0F |
4792 |
&& insn[2] == 0xD6) { |
4793 |
eip = dis_SSE3_to_MMX |
4794 |
( cb, sorb, eip+3, 8, "movdq2q", |
4795 |
insn[0], insn[1], insn[2] ); |
4796 |
goto decode_success; |
4797 |
} |
4798 |
|
4799 |
/* MOVQ2DQ -- move MMX reg to low 4 bytes of XMM reg. */ |
4800 |
if (insn[0] == 0xF3 |
4801 |
&& insn[1] == 0x0F |
4802 |
&& insn[2] == 0xD6) { |
4803 |
eip = dis_SSE3_from_MMX |
4804 |
( cb, sorb, eip+3, 8, "movq2dq", |
4805 |
insn[0], insn[1], insn[2] ); |
4806 |
goto decode_success; |
4807 |
} |
4808 |
|
4207 |
/* MOVSS -- move 4 bytes of XMM reg to/from XMM reg or mem. */ |
4809 |
/* MOVSS -- move 4 bytes of XMM reg to/from XMM reg or mem. */ |
4208 |
if (insn[0] == 0xF3 |
4810 |
if (insn[0] == 0xF3 |
4209 |
&& insn[1] == 0x0F |
4811 |
&& insn[1] == 0x0F |
Lines 4269-4287
Link Here
|
4269 |
goto decode_success; |
4871 |
goto decode_success; |
4270 |
} |
4872 |
} |
4271 |
|
4873 |
|
4272 |
/* MOVLPD -- 8-byte load/store. */ |
|
|
4273 |
if (sz == 2 |
4274 |
&& insn[0] == 0x0F |
4275 |
&& (insn[1] == 0x12 || insn[1] == 0x13)) { |
4276 |
Bool is_store = insn[1]==0x13; |
4277 |
/* Cannot be used for reg-reg moves, according to Intel docs. */ |
4278 |
vg_assert(!epartIsReg(insn[2])); |
4279 |
eip = dis_SSE3_load_store_or_mov |
4280 |
(cb, sorb, eip+2, 8, is_store, "movlpd", |
4281 |
0x66, insn[0], insn[1] ); |
4282 |
goto decode_success; |
4283 |
} |
4284 |
|
4285 |
/* MOVDQU -- unaligned 16-byte load/store. */ |
4874 |
/* MOVDQU -- unaligned 16-byte load/store. */ |
4286 |
if (insn[0] == 0xF3 |
4875 |
if (insn[0] == 0xF3 |
4287 |
&& insn[1] == 0x0F |
4876 |
&& insn[1] == 0x0F |
Lines 4304-4309
Link Here
|
4304 |
goto decode_success; |
4893 |
goto decode_success; |
4305 |
} |
4894 |
} |
4306 |
|
4895 |
|
|
|
4896 |
/* MOVNTPS -- 16-byte store with temporal hint (which we |
4897 |
ignore). */ |
4898 |
if (insn[0] == 0x0F |
4899 |
&& insn[1] == 0x2B) { |
4900 |
eip = dis_SSE2_load_store_or_mov |
4901 |
(cb, sorb, eip+2, 16, True /* is_store */, "movntps", |
4902 |
insn[0], insn[1] ); |
4903 |
goto decode_success; |
4904 |
} |
4905 |
|
4906 |
/* MOVNTPD -- 16-byte store with temporal hint (which we |
4907 |
ignore). */ |
4908 |
if (sz == 2 |
4909 |
&& insn[0] == 0x0F |
4910 |
&& insn[1] == 0x2B) { |
4911 |
eip = dis_SSE3_load_store_or_mov |
4912 |
(cb, sorb, eip+2, 16, True /* is_store */, "movntpd", |
4913 |
0x66, insn[0], insn[1] ); |
4914 |
goto decode_success; |
4915 |
} |
4916 |
|
4307 |
/* MOVD -- 4-byte move between xmmregs and (ireg or memory). */ |
4917 |
/* MOVD -- 4-byte move between xmmregs and (ireg or memory). */ |
4308 |
if (sz == 2 |
4918 |
if (sz == 2 |
4309 |
&& insn[0] == 0x0F |
4919 |
&& insn[0] == 0x0F |
Lines 4317-4326
Link Here
|
4317 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
4927 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
4318 |
TempReg, t1 ); |
4928 |
TempReg, t1 ); |
4319 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, eregOfRM(modrm)); |
4929 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, eregOfRM(modrm)); |
4320 |
if (dis) |
4930 |
DIP("movd %s, %s\n", |
4321 |
VG_(printf)("movd %s, %s\n", |
4931 |
nameXMMReg(gregOfRM(modrm)), nameIReg(4,eregOfRM(modrm))); |
4322 |
nameXMMReg(gregOfRM(modrm)), |
|
|
4323 |
nameIReg(4,eregOfRM(modrm))); |
4324 |
eip += 3; |
4932 |
eip += 3; |
4325 |
} else |
4933 |
} else |
4326 |
if (epartIsReg(modrm) && !is_store) { |
4934 |
if (epartIsReg(modrm) && !is_store) { |
Lines 4330-4339
Link Here
|
4330 |
Lit16, (((UShort)0x66) << 8) | (UShort)insn[0], |
4938 |
Lit16, (((UShort)0x66) << 8) | (UShort)insn[0], |
4331 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
4939 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
4332 |
TempReg, t1 ); |
4940 |
TempReg, t1 ); |
4333 |
if (dis) |
4941 |
DIP("movd %s, %s\n", |
4334 |
VG_(printf)("movd %s, %s\n", |
4942 |
nameIReg(4,eregOfRM(modrm)), nameXMMReg(gregOfRM(modrm))); |
4335 |
nameIReg(4,eregOfRM(modrm)), |
|
|
4336 |
nameXMMReg(gregOfRM(modrm))); |
4337 |
eip += 3; |
4943 |
eip += 3; |
4338 |
} else { |
4944 |
} else { |
4339 |
eip = dis_SSE3_load_store_or_mov |
4945 |
eip = dis_SSE3_load_store_or_mov |
Lines 4355-4364
Link Here
|
4355 |
TempReg, t1 ); |
4961 |
TempReg, t1 ); |
4356 |
uLiteral(cb, insn[3]); |
4962 |
uLiteral(cb, insn[3]); |
4357 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
4963 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
4358 |
if (dis) |
4964 |
DIP("pextrw %s, %d, %s\n", |
4359 |
VG_(printf)("pextrw %s, %d, %s\n", |
4965 |
nameXMMReg(eregOfRM(modrm)), (Int)insn[3], |
4360 |
nameXMMReg(eregOfRM(modrm)), (Int)insn[3], |
4966 |
nameIReg(4, gregOfRM(modrm))); |
4361 |
nameIReg(4, gregOfRM(modrm))); |
|
|
4362 |
eip += 4; |
4967 |
eip += 4; |
4363 |
goto decode_success; |
4968 |
goto decode_success; |
4364 |
} |
4969 |
} |
Lines 4375-4385
Link Here
|
4375 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
4980 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
4376 |
TempReg, t1 ); |
4981 |
TempReg, t1 ); |
4377 |
uLiteral(cb, insn[3]); |
4982 |
uLiteral(cb, insn[3]); |
4378 |
if (dis) |
4983 |
DIP("pinsrw %s, %d, %s\n", |
4379 |
VG_(printf)("pinsrw %s, %d, %s\n", |
4984 |
nameIReg(2, eregOfRM(modrm)), (Int)insn[3], |
4380 |
nameIReg(2, eregOfRM(modrm)), |
4985 |
nameXMMReg(gregOfRM(modrm))); |
4381 |
(Int)insn[3], |
|
|
4382 |
nameXMMReg(gregOfRM(modrm))); |
4383 |
eip += 4; |
4986 |
eip += 4; |
4384 |
} else { |
4987 |
} else { |
4385 |
VG_(core_panic)("PINSRW mem"); |
4988 |
VG_(core_panic)("PINSRW mem"); |
Lines 4405-4421
Link Here
|
4405 |
goto decode_success; |
5008 |
goto decode_success; |
4406 |
} |
5009 |
} |
4407 |
|
5010 |
|
4408 |
/* MOVLPS -- 8-byte load/store. How is this different from MOVLPS |
5011 |
/* RSQRTSS: square root reciprocal of scalar float. */ |
4409 |
? */ |
5012 |
if (insn[0] == 0xF3 && insn[1] == 0x0F && insn[2] == 0x52) { |
4410 |
if (insn[0] == 0x0F |
|
|
4411 |
&& (insn[1] == 0x12 || insn[1] == 0x13)) { |
4412 |
Bool is_store = insn[1]==0x13; |
4413 |
vg_assert(sz == 4); |
5013 |
vg_assert(sz == 4); |
4414 |
/* Cannot be used for reg-reg moves, according to Intel docs. */ |
5014 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+3, 4, |
4415 |
// vg_assert(!epartIsReg(insn[2])); |
5015 |
"sqrtss", |
4416 |
eip = dis_SSE2_load_store_or_mov |
5016 |
insn[0], insn[1], insn[2] ); |
4417 |
(cb, sorb, eip+2, 8, is_store, "movlps", |
|
|
4418 |
insn[0], insn[1] ); |
4419 |
goto decode_success; |
5017 |
goto decode_success; |
4420 |
} |
5018 |
} |
4421 |
|
5019 |
|
Lines 4430-4450
Link Here
|
4430 |
|
5028 |
|
4431 |
/* MOVMSKPD -- extract 2 sign bits from a xmm reg and copy them to |
5029 |
/* MOVMSKPD -- extract 2 sign bits from a xmm reg and copy them to |
4432 |
an ireg. Top 30 bits of ireg are set to zero. */ |
5030 |
an ireg. Top 30 bits of ireg are set to zero. */ |
4433 |
if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x50) { |
5031 |
/* MOVMSKPS -- extract 4 sign bits from a xmm reg and copy them to |
|
|
5032 |
an ireg. Top 28 bits of ireg are set to zero. */ |
5033 |
if (insn[0] == 0x0F && insn[1] == 0x50) { |
5034 |
vg_assert(sz == 4 || sz == 2); |
4434 |
modrm = insn[2]; |
5035 |
modrm = insn[2]; |
4435 |
/* Intel docs don't say anything about a memory source being |
5036 |
/* Intel docs don't say anything about a memory source being |
4436 |
allowed here. */ |
5037 |
allowed here. */ |
4437 |
vg_assert(epartIsReg(modrm)); |
5038 |
vg_assert(epartIsReg(modrm)); |
4438 |
t1 = newTemp(cb); |
5039 |
t1 = newTemp(cb); |
4439 |
uInstr3(cb, SSE3g_RegWr, 4, |
5040 |
if (sz == 4) { |
4440 |
Lit16, (((UShort)0x66) << 8) | (UShort)insn[0], |
5041 |
uInstr3(cb, SSE2g_RegWr, 4, |
4441 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
5042 |
Lit16, (((UShort)insn[0]) << 8) | (UShort)insn[1], |
4442 |
TempReg, t1 ); |
5043 |
Lit16, (UShort)modrm, |
4443 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
5044 |
TempReg, t1 ); |
4444 |
if (dis) |
5045 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
4445 |
VG_(printf)("movmskpd %s, %s\n", |
5046 |
} else { |
4446 |
nameXMMReg(eregOfRM(modrm)), |
5047 |
uInstr3(cb, SSE3g_RegWr, 4, |
4447 |
nameIReg(4,gregOfRM(modrm))); |
5048 |
Lit16, (((UShort)0x66) << 8) | (UShort)insn[0], |
|
|
5049 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
5050 |
TempReg, t1 ); |
5051 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
5052 |
} |
5053 |
DIP("movmskp%c %s, %s\n", sz == 4 ? 's' : 'd', |
5054 |
nameXMMReg(eregOfRM(modrm)), nameIReg(4,gregOfRM(modrm))); |
4448 |
eip += 3; |
5055 |
eip += 3; |
4449 |
goto decode_success; |
5056 |
goto decode_success; |
4450 |
} |
5057 |
} |
Lines 4463-4478
Link Here
|
4463 |
goto decode_success; |
5070 |
goto decode_success; |
4464 |
} |
5071 |
} |
4465 |
|
5072 |
|
4466 |
/* MOVHPD -- 8-byte load/store. */ |
5073 |
/* MOVHLPS -- move two packed floats from high quadword to low quadword */ |
4467 |
if (sz == 2 |
5074 |
/* MOVLPS -- load/store two packed floats to/from low quadword. */ |
4468 |
&& insn[0] == 0x0F |
5075 |
/* MOVLPD -- load/store packed double to/from low quadword. */ |
|
|
5076 |
if (insn[0] == 0x0F |
5077 |
&& (insn[1] == 0x12 || insn[1] == 0x13)) { |
5078 |
Bool is_store = insn[1]==0x13; |
5079 |
vg_assert(sz == 4 || sz == 2); |
5080 |
if (sz == 4) { |
5081 |
if (epartIsReg(insn[2])) { |
5082 |
vg_assert(insn[1]==0x12); |
5083 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "movhlps", |
5084 |
insn[0], insn[1] ); |
5085 |
} else { |
5086 |
eip = dis_SSE2_load_store_or_mov |
5087 |
(cb, sorb, eip+2, 8, is_store, "movlps", |
5088 |
insn[0], insn[1] ); |
5089 |
} |
5090 |
} else { |
5091 |
vg_assert(!epartIsReg(insn[2])); |
5092 |
eip = dis_SSE3_load_store_or_mov |
5093 |
(cb, sorb, eip+2, 8, is_store, "movlpd", |
5094 |
0x66, insn[0], insn[1] ); |
5095 |
} |
5096 |
goto decode_success; |
5097 |
} |
5098 |
|
5099 |
/* MOVLHPS -- move two packed floats from low quadword to high quadword */ |
5100 |
/* MOVHPS -- load/store two packed floats to/from high quadword. */ |
5101 |
/* MOVHPD -- load/store packed double to/from high quadword. */ |
5102 |
if (insn[0] == 0x0F |
4469 |
&& (insn[1] == 0x16 || insn[1] == 0x17)) { |
5103 |
&& (insn[1] == 0x16 || insn[1] == 0x17)) { |
4470 |
Bool is_store = insn[1]==0x17; |
5104 |
Bool is_store = insn[1]==0x17; |
4471 |
/* Cannot be used for reg-reg moves, according to Intel docs. */ |
5105 |
vg_assert(sz == 4 || sz == 2); |
|
|
5106 |
if (sz == 4) { |
5107 |
if (epartIsReg(insn[2])) { |
5108 |
vg_assert(insn[1]==0x16); |
5109 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "movlhps", |
5110 |
insn[0], insn[1] ); |
5111 |
} else { |
5112 |
eip = dis_SSE2_load_store_or_mov |
5113 |
(cb, sorb, eip+2, 8, is_store, "movhps", |
5114 |
insn[0], insn[1] ); |
5115 |
} |
5116 |
} else { |
4472 |
vg_assert(!epartIsReg(insn[2])); |
5117 |
vg_assert(!epartIsReg(insn[2])); |
4473 |
eip = dis_SSE3_load_store_or_mov |
5118 |
eip = dis_SSE3_load_store_or_mov |
4474 |
(cb, sorb, eip+2, 8, is_store, "movhpd", |
5119 |
(cb, sorb, eip+2, 8, is_store, "movhpd", |
4475 |
0x66, insn[0], insn[1] ); |
5120 |
0x66, insn[0], insn[1] ); |
|
|
5121 |
} |
4476 |
goto decode_success; |
5122 |
goto decode_success; |
4477 |
} |
5123 |
} |
4478 |
|
5124 |
|
Lines 4489-4524
Link Here
|
4489 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
5135 |
Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, |
4490 |
TempReg, t1 ); |
5136 |
TempReg, t1 ); |
4491 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
5137 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
4492 |
if (dis) |
5138 |
DIP("pmovmskb %s, %s\n", |
4493 |
VG_(printf)("pmovmskb %s, %s\n", |
5139 |
nameXMMReg(eregOfRM(modrm)), nameIReg(4,gregOfRM(modrm))); |
4494 |
nameXMMReg(eregOfRM(modrm)), |
|
|
4495 |
nameIReg(4,gregOfRM(modrm))); |
4496 |
eip += 3; |
5140 |
eip += 3; |
4497 |
goto decode_success; |
5141 |
goto decode_success; |
4498 |
} |
5142 |
} |
4499 |
|
5143 |
|
4500 |
/* CVTDQ2PD -- convert one single double. to float. */ |
5144 |
/* sz==4: SQRTPS: square root of packed float. */ |
4501 |
if (insn[0] == 0xF3 && insn[1] == 0x0F && insn[2] == 0xE6) { |
5145 |
/* sz==2: SQRTPD: square root of packed double. */ |
4502 |
vg_assert(sz == 4); |
5146 |
if (insn[0] == 0x0F && insn[1] == 0x51) { |
4503 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+3, 8, "cvtdq2pd", |
5147 |
vg_assert(sz == 2 || sz == 4); |
4504 |
insn[0], insn[1], insn[2] ); |
5148 |
if (sz == 4) { |
4505 |
goto decode_success; |
5149 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, |
4506 |
} |
5150 |
"sqrtps", |
4507 |
|
5151 |
insn[0], insn[1] ); |
4508 |
/* CVTPD2PS -- convert two doubles to two floats. */ |
5152 |
} else { |
4509 |
if (sz == 2 && |
5153 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, |
4510 |
insn[0] == 0x0F && insn[1] == 0x5A) { |
5154 |
"sqrtpd", |
4511 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "cvtpd2ps", |
|
|
4512 |
0x66, insn[0], insn[1] ); |
5155 |
0x66, insn[0], insn[1] ); |
|
|
5156 |
} |
4513 |
goto decode_success; |
5157 |
goto decode_success; |
4514 |
} |
5158 |
} |
4515 |
|
5159 |
|
4516 |
/* SQRTPD: square root of packed double. */ |
5160 |
/* RSQRTPS: square root reciprocal of packed float. */ |
4517 |
if (sz == 2 |
5161 |
if (insn[0] == 0x0F && insn[1] == 0x52) { |
4518 |
&& insn[0] == 0x0F && insn[1] == 0x51) { |
5162 |
vg_assert(sz == 4); |
4519 |
eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, |
5163 |
eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, |
4520 |
"sqrtpd", |
5164 |
"rsqrtps", |
4521 |
0x66, insn[0], insn[1] ); |
5165 |
insn[0], insn[1] ); |
4522 |
goto decode_success; |
5166 |
goto decode_success; |
4523 |
} |
5167 |
} |
4524 |
|
5168 |
|
Lines 4554-4568
Link Here
|
4554 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t1); |
5198 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t1); |
4555 |
uLiteral(cb, 4+d32); |
5199 |
uLiteral(cb, 4+d32); |
4556 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP); |
5200 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP); |
4557 |
uInstr1(cb, JMP, 0, TempReg, t2); |
5201 |
jmp_treg(cb, t2); |
4558 |
uCond(cb, CondAlways); |
|
|
4559 |
LAST_UINSTR(cb).jmpkind = JmpRet; |
5202 |
LAST_UINSTR(cb).jmpkind = JmpRet; |
4560 |
|
5203 |
|
4561 |
*isEnd = True; |
5204 |
*isEnd = True; |
4562 |
if (dis) { |
5205 |
if (d32 == 0) { DIP("ret\n"); } |
4563 |
if (d32 == 0) VG_(printf)("ret\n"); |
5206 |
else { DIP("ret %d\n", d32); } |
4564 |
else VG_(printf)("ret %d\n", d32); |
5207 |
|
4565 |
} |
|
|
4566 |
break; |
5208 |
break; |
4567 |
|
5209 |
|
4568 |
case 0xE8: /* CALL J4 */ |
5210 |
case 0xE8: /* CALL J4 */ |
Lines 4583-4590
Link Here
|
4583 |
uLiteral(cb, eip); |
5225 |
uLiteral(cb, eip); |
4584 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, archReg); |
5226 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, archReg); |
4585 |
eip++; /* Step over the POP */ |
5227 |
eip++; /* Step over the POP */ |
4586 |
if (dis) |
5228 |
DIP("call 0x%x ; popl %s\n",d32,nameIReg(4,archReg)); |
4587 |
VG_(printf)("call 0x%x ; popl %s\n",d32,nameIReg(4,archReg)); |
|
|
4588 |
} else { |
5229 |
} else { |
4589 |
/* The normal sequence for a call. */ |
5230 |
/* The normal sequence for a call. */ |
4590 |
t1 = newTemp(cb); t2 = newTemp(cb); t3 = newTemp(cb); |
5231 |
t1 = newTemp(cb); t2 = newTemp(cb); t3 = newTemp(cb); |
Lines 4596-4607
Link Here
|
4596 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, t2); |
5237 |
uInstr2(cb, MOV, 4, Literal, 0, TempReg, t2); |
4597 |
uLiteral(cb, eip); |
5238 |
uLiteral(cb, eip); |
4598 |
uInstr2(cb, STORE, 4, TempReg, t2, TempReg, t1); |
5239 |
uInstr2(cb, STORE, 4, TempReg, t2, TempReg, t1); |
4599 |
uInstr1(cb, JMP, 0, Literal, 0); |
5240 |
jmp_lit(cb, d32); |
4600 |
uLiteral(cb, d32); |
|
|
4601 |
uCond(cb, CondAlways); |
4602 |
LAST_UINSTR(cb).jmpkind = JmpCall; |
5241 |
LAST_UINSTR(cb).jmpkind = JmpCall; |
4603 |
*isEnd = True; |
5242 |
*isEnd = True; |
4604 |
if (dis) VG_(printf)("call 0x%x\n",d32); |
5243 |
DIP("call 0x%x\n",d32); |
4605 |
} |
5244 |
} |
4606 |
break; |
5245 |
break; |
4607 |
|
5246 |
|
Lines 4625-4631
Link Here
|
4625 |
uLiteral(cb, d32); |
5264 |
uLiteral(cb, d32); |
4626 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
5265 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
4627 |
} |
5266 |
} |
4628 |
if (dis) VG_(printf)("enter 0x%x, 0x%x", d32, abyte); |
5267 |
DIP("enter 0x%x, 0x%x", d32, abyte); |
4629 |
break; |
5268 |
break; |
4630 |
|
5269 |
|
4631 |
case 0xC9: /* LEAVE */ |
5270 |
case 0xC9: /* LEAVE */ |
Lines 4639-4645
Link Here
|
4639 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t1); |
5278 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t1); |
4640 |
uLiteral(cb, 4); |
5279 |
uLiteral(cb, 4); |
4641 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP); |
5280 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP); |
4642 |
if (dis) VG_(printf)("leave"); |
5281 |
DIP("leave"); |
4643 |
break; |
5282 |
break; |
4644 |
|
5283 |
|
4645 |
/* ---------------- Misc weird-ass insns --------------- */ |
5284 |
/* ---------------- Misc weird-ass insns --------------- */ |
Lines 4656-4666
Link Here
|
4656 |
uInstr1(cb, PUSH, 4, TempReg, t1); |
5295 |
uInstr1(cb, PUSH, 4, TempReg, t1); |
4657 |
uInstr1(cb, CALLM, 0, Lit16, |
5296 |
uInstr1(cb, CALLM, 0, Lit16, |
4658 |
opc == 0x27 ? VGOFF_(helper_DAA) : VGOFF_(helper_DAS) ); |
5297 |
opc == 0x27 ? VGOFF_(helper_DAA) : VGOFF_(helper_DAS) ); |
4659 |
uFlagsRWU(cb, FlagsAC, FlagsOSZACP, FlagsEmpty); |
5298 |
uFlagsRWU(cb, FlagsAC, FlagsSZACP, FlagO); |
4660 |
uInstr1(cb, POP, 4, TempReg, t1); |
5299 |
uInstr1(cb, POP, 4, TempReg, t1); |
4661 |
uInstr0(cb, CALLM_E, 0); |
5300 |
uInstr0(cb, CALLM_E, 0); |
4662 |
uInstr2(cb, PUT, 1, TempReg, t1, ArchReg, R_AL); |
5301 |
uInstr2(cb, PUT, 1, TempReg, t1, ArchReg, R_AL); |
4663 |
if (dis) VG_(printf)(opc == 0x27 ? "daa\n" : "das\n"); |
5302 |
DIP(opc == 0x27 ? "daa\n" : "das\n"); |
|
|
5303 |
break; |
5304 |
|
5305 |
case 0x37: /* AAA */ |
5306 |
case 0x3F: /* AAS */ |
5307 |
t1 = newTemp(cb); |
5308 |
uInstr2(cb, GET, 2, ArchReg, R_EAX, TempReg, t1); |
5309 |
/* Widen %AL to 32 bits, so it's all defined when we push it. */ |
5310 |
uInstr1(cb, WIDEN, 4, TempReg, t1); |
5311 |
LAST_UINSTR(cb).extra4b = 2; |
5312 |
LAST_UINSTR(cb).signed_widen = False; |
5313 |
uInstr0(cb, CALLM_S, 0); |
5314 |
uInstr1(cb, PUSH, 4, TempReg, t1); |
5315 |
uInstr1(cb, CALLM, 0, Lit16, |
5316 |
opc == 0x37 ? VGOFF_(helper_AAA) : VGOFF_(helper_AAS) ); |
5317 |
uFlagsRWU(cb, FlagA, FlagsAC, FlagsEmpty); |
5318 |
uInstr1(cb, POP, 4, TempReg, t1); |
5319 |
uInstr0(cb, CALLM_E, 0); |
5320 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
5321 |
DIP(opc == 0x37 ? "aaa\n" : "aas\n"); |
5322 |
break; |
5323 |
|
5324 |
case 0xD4: /* AAM */ |
5325 |
case 0xD5: /* AAD */ |
5326 |
d32 = getUChar(eip); eip++; |
5327 |
if (d32 != 10) VG_(core_panic)("disInstr: AAM/AAD but base not 10 !"); |
5328 |
t1 = newTemp(cb); |
5329 |
uInstr2(cb, GET, 2, ArchReg, R_EAX, TempReg, t1); |
5330 |
/* Widen %AX to 32 bits, so it's all defined when we push it. */ |
5331 |
uInstr1(cb, WIDEN, 4, TempReg, t1); |
5332 |
LAST_UINSTR(cb).extra4b = 2; |
5333 |
LAST_UINSTR(cb).signed_widen = False; |
5334 |
uInstr0(cb, CALLM_S, 0); |
5335 |
uInstr1(cb, PUSH, 4, TempReg, t1); |
5336 |
uInstr1(cb, CALLM, 0, Lit16, |
5337 |
opc == 0xD4 ? VGOFF_(helper_AAM) : VGOFF_(helper_AAD) ); |
5338 |
uFlagsRWU(cb, FlagsEmpty, FlagsSZP, FlagsEmpty); |
5339 |
uInstr1(cb, POP, 4, TempReg, t1); |
5340 |
uInstr0(cb, CALLM_E, 0); |
5341 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
5342 |
DIP(opc == 0xD4 ? "aam\n" : "aad\n"); |
4664 |
break; |
5343 |
break; |
4665 |
|
5344 |
|
4666 |
/* ------------------------ CWD/CDQ -------------------- */ |
5345 |
/* ------------------------ CWD/CDQ -------------------- */ |
Lines 4673-4679
Link Here
|
4673 |
LAST_UINSTR(cb).extra4b = 2; /* the source size */ |
5352 |
LAST_UINSTR(cb).extra4b = 2; /* the source size */ |
4674 |
LAST_UINSTR(cb).signed_widen = True; |
5353 |
LAST_UINSTR(cb).signed_widen = True; |
4675 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_EAX); |
5354 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_EAX); |
4676 |
if (dis) VG_(printf)("cwd\n"); |
5355 |
DIP("cwd\n"); |
4677 |
} else { |
5356 |
} else { |
4678 |
vg_assert(sz == 2); |
5357 |
vg_assert(sz == 2); |
4679 |
uInstr2(cb, GET, 1, ArchReg, R_EAX, TempReg, t1); |
5358 |
uInstr2(cb, GET, 1, ArchReg, R_EAX, TempReg, t1); |
Lines 4681-4687
Link Here
|
4681 |
LAST_UINSTR(cb).extra4b = 1; /* the source size */ |
5360 |
LAST_UINSTR(cb).extra4b = 1; /* the source size */ |
4682 |
LAST_UINSTR(cb).signed_widen = True; |
5361 |
LAST_UINSTR(cb).signed_widen = True; |
4683 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
5362 |
uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); |
4684 |
if (dis) VG_(printf)("cbw\n"); |
5363 |
DIP("cbw\n"); |
4685 |
} |
5364 |
} |
4686 |
break; |
5365 |
break; |
4687 |
|
5366 |
|
Lines 4691-4714
Link Here
|
4691 |
uInstr2(cb, SAR, sz, Literal, 0, TempReg, t1); |
5370 |
uInstr2(cb, SAR, sz, Literal, 0, TempReg, t1); |
4692 |
uLiteral(cb, sz == 2 ? 15 : 31); |
5371 |
uLiteral(cb, sz == 2 ? 15 : 31); |
4693 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, R_EDX); |
5372 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, R_EDX); |
4694 |
if (dis) VG_(printf)(sz == 2 ? "cwdq\n" : "cdqq\n"); |
5373 |
DIP(sz == 2 ? "cwdq\n" : "cdqq\n"); |
4695 |
break; |
5374 |
break; |
4696 |
|
5375 |
|
4697 |
/* ------------------------ FPU ops -------------------- */ |
5376 |
/* ------------------------ FPU ops -------------------- */ |
4698 |
|
5377 |
|
4699 |
case 0x9E: /* SAHF */ |
5378 |
case 0x9E: /* SAHF */ |
4700 |
codegen_SAHF ( cb ); |
5379 |
codegen_SAHF ( cb ); |
4701 |
if (dis) VG_(printf)("sahf\n"); |
5380 |
DIP("sahf\n"); |
4702 |
break; |
5381 |
break; |
4703 |
|
5382 |
|
4704 |
case 0x9F: /* LAHF */ |
5383 |
case 0x9F: /* LAHF */ |
4705 |
codegen_LAHF ( cb ); |
5384 |
codegen_LAHF ( cb ); |
4706 |
if (dis) VG_(printf)("lahf\n"); |
5385 |
DIP("lahf\n"); |
4707 |
break; |
5386 |
break; |
4708 |
|
5387 |
|
4709 |
case 0x9B: /* FWAIT */ |
5388 |
case 0x9B: /* FWAIT */ |
4710 |
/* ignore? */ |
5389 |
/* ignore? */ |
4711 |
if (dis) VG_(printf)("fwait\n"); |
5390 |
DIP("fwait\n"); |
4712 |
break; |
5391 |
break; |
4713 |
|
5392 |
|
4714 |
case 0xD8: |
5393 |
case 0xD8: |
Lines 4739-4746
Link Here
|
4739 |
setFlagsFromUOpcode(cb, INC); |
5418 |
setFlagsFromUOpcode(cb, INC); |
4740 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, |
5419 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, |
4741 |
(UInt)(opc - 0x40)); |
5420 |
(UInt)(opc - 0x40)); |
4742 |
if (dis) |
5421 |
DIP("inc%c %s\n", nameISize(sz), nameIReg(sz,opc-0x40)); |
4743 |
VG_(printf)("inc%c %s\n", nameISize(sz), nameIReg(sz,opc-0x40)); |
|
|
4744 |
break; |
5422 |
break; |
4745 |
|
5423 |
|
4746 |
case 0x48: /* DEC eAX */ |
5424 |
case 0x48: /* DEC eAX */ |
Lines 4758-4765
Link Here
|
4758 |
setFlagsFromUOpcode(cb, DEC); |
5436 |
setFlagsFromUOpcode(cb, DEC); |
4759 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, |
5437 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, |
4760 |
(UInt)(opc - 0x48)); |
5438 |
(UInt)(opc - 0x48)); |
4761 |
if (dis) |
5439 |
DIP("dec%c %s\n", nameISize(sz), nameIReg(sz,opc-0x48)); |
4762 |
VG_(printf)("dec%c %s\n", nameISize(sz), nameIReg(sz,opc-0x48)); |
|
|
4763 |
break; |
5440 |
break; |
4764 |
|
5441 |
|
4765 |
/* ------------------------ INT ------------------------ */ |
5442 |
/* ------------------------ INT ------------------------ */ |
Lines 4770-4803
Link Here
|
4770 |
/* It's important that all ArchRegs carry their up-to-date value |
5447 |
/* It's important that all ArchRegs carry their up-to-date value |
4771 |
at this point. So we declare an end-of-block here, which |
5448 |
at this point. So we declare an end-of-block here, which |
4772 |
forces any TempRegs caching ArchRegs to be flushed. */ |
5449 |
forces any TempRegs caching ArchRegs to be flushed. */ |
4773 |
uInstr1(cb, JMP, 0, Literal, 0); |
5450 |
jmp_lit(cb, eip); |
4774 |
uLiteral(cb, eip); |
|
|
4775 |
uCond(cb, CondAlways); |
4776 |
LAST_UINSTR(cb).jmpkind = JmpSyscall; |
5451 |
LAST_UINSTR(cb).jmpkind = JmpSyscall; |
4777 |
*isEnd = True; |
5452 |
*isEnd = True; |
4778 |
if (dis) VG_(printf)("int $0x80\n"); |
5453 |
DIP("int $0x80\n"); |
4779 |
break; |
5454 |
break; |
4780 |
|
5455 |
|
4781 |
/* ------------------------ Jcond, byte offset --------- */ |
5456 |
/* ------------------------ Jcond, byte offset --------- */ |
4782 |
|
5457 |
|
4783 |
case 0xEB: /* Jb (jump, byte offset) */ |
5458 |
case 0xEB: /* Jb (jump, byte offset) */ |
4784 |
d32 = (eip+1) + getSDisp8(eip); eip++; |
5459 |
d32 = (eip+1) + getSDisp8(eip); eip++; |
4785 |
uInstr1(cb, JMP, 0, Literal, 0); |
5460 |
jmp_lit(cb, d32); |
4786 |
uLiteral(cb, d32); |
|
|
4787 |
uCond(cb, CondAlways); |
4788 |
*isEnd = True; |
5461 |
*isEnd = True; |
4789 |
if (dis) |
5462 |
DIP("jmp-8 0x%x\n", d32); |
4790 |
VG_(printf)("jmp-8 0x%x\n", d32); |
|
|
4791 |
break; |
5463 |
break; |
4792 |
|
5464 |
|
4793 |
case 0xE9: /* Jv (jump, 16/32 offset) */ |
5465 |
case 0xE9: /* Jv (jump, 16/32 offset) */ |
4794 |
d32 = (eip+sz) + getSDisp(sz,eip); eip += sz; |
5466 |
d32 = (eip+sz) + getSDisp(sz,eip); eip += sz; |
4795 |
uInstr1(cb, JMP, 0, Literal, 0); |
5467 |
jmp_lit(cb, d32); |
4796 |
uLiteral(cb, d32); |
|
|
4797 |
uCond(cb, CondAlways); |
4798 |
*isEnd = True; |
5468 |
*isEnd = True; |
4799 |
if (dis) |
5469 |
DIP("jmp 0x%x\n", d32); |
4800 |
VG_(printf)("jmp 0x%x\n", d32); |
|
|
4801 |
break; |
5470 |
break; |
4802 |
|
5471 |
|
4803 |
case 0x70: |
5472 |
case 0x70: |
Lines 4817-4839
Link Here
|
4817 |
case 0x7E: /* JLEb/JNGb (jump less or equal) */ |
5486 |
case 0x7E: /* JLEb/JNGb (jump less or equal) */ |
4818 |
case 0x7F: /* JGb/JNLEb (jump greater) */ |
5487 |
case 0x7F: /* JGb/JNLEb (jump greater) */ |
4819 |
d32 = (eip+1) + getSDisp8(eip); eip++; |
5488 |
d32 = (eip+1) + getSDisp8(eip); eip++; |
4820 |
uInstr1(cb, JMP, 0, Literal, 0); |
5489 |
jcc_lit(cb, d32, (Condcode)(opc - 0x70)); |
4821 |
uLiteral(cb, d32); |
|
|
4822 |
uCond(cb, (Condcode)(opc - 0x70)); |
4823 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
4824 |
/* It's actually acceptable not to end this basic block at a |
5490 |
/* It's actually acceptable not to end this basic block at a |
4825 |
control transfer, reducing the number of jumps through |
5491 |
control transfer, reducing the number of jumps through |
4826 |
vg_dispatch, at the expense of possibly translating the insns |
5492 |
vg_dispatch, at the expense of possibly translating the insns |
4827 |
following this jump twice. This does give faster code, but |
5493 |
following this jump twice. This does give faster code, but |
4828 |
on the whole I don't think the effort is worth it. */ |
5494 |
on the whole I don't think the effort is worth it. */ |
4829 |
uInstr1(cb, JMP, 0, Literal, 0); |
5495 |
jmp_lit(cb, eip); |
4830 |
uLiteral(cb, eip); |
|
|
4831 |
uCond(cb, CondAlways); |
4832 |
*isEnd = True; |
5496 |
*isEnd = True; |
4833 |
/* The above 3 lines would be removed if the bb was not to end |
5497 |
/* The above 3 lines would be removed if the bb was not to end |
4834 |
here. */ |
5498 |
here. */ |
4835 |
if (dis) |
5499 |
DIP("j%s-8 0x%x\n", VG_(name_UCondcode)(opc - 0x70), d32); |
4836 |
VG_(printf)("j%s-8 0x%x\n", VG_(name_UCondcode)(opc - 0x70), d32); |
|
|
4837 |
break; |
5500 |
break; |
4838 |
|
5501 |
|
4839 |
case 0xE3: /* JECXZ or perhaps JCXZ, depending on OSO ? Intel |
5502 |
case 0xE3: /* JECXZ or perhaps JCXZ, depending on OSO ? Intel |
Lines 4844-4851
Link Here
|
4844 |
uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, t1); |
5507 |
uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, t1); |
4845 |
uInstr2(cb, JIFZ, 4, TempReg, t1, Literal, 0); |
5508 |
uInstr2(cb, JIFZ, 4, TempReg, t1, Literal, 0); |
4846 |
uLiteral(cb, d32); |
5509 |
uLiteral(cb, d32); |
4847 |
if (dis) |
5510 |
DIP("j%sz 0x%x\n", nameIReg(sz, R_ECX), d32); |
4848 |
VG_(printf)("j%sz 0x%x\n", nameIReg(sz, R_ECX), d32); |
|
|
4849 |
break; |
5511 |
break; |
4850 |
|
5512 |
|
4851 |
case 0xE0: /* LOOPNE disp8 */ |
5513 |
case 0xE0: /* LOOPNE disp8 */ |
Lines 4863-4879
Link Here
|
4863 |
uInstr2(cb, JIFZ, 4, TempReg, t1, Literal, 0); |
5525 |
uInstr2(cb, JIFZ, 4, TempReg, t1, Literal, 0); |
4864 |
uLiteral(cb, eip); |
5526 |
uLiteral(cb, eip); |
4865 |
if (opc == 0xE0 || opc == 0xE1) { /* LOOPE/LOOPNE */ |
5527 |
if (opc == 0xE0 || opc == 0xE1) { /* LOOPE/LOOPNE */ |
4866 |
uInstr1(cb, JMP, 0, Literal, 0); |
5528 |
jcc_lit(cb, eip, (opc == 0xE1 ? CondNZ : CondZ)); |
4867 |
uLiteral(cb, eip); |
|
|
4868 |
uCond(cb, (opc == 0xE1 ? CondNZ : CondZ)); |
4869 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
4870 |
} |
5529 |
} |
4871 |
uInstr1(cb, JMP, 0, Literal, 0); |
5530 |
jmp_lit(cb, d32); |
4872 |
uLiteral(cb, d32); |
|
|
4873 |
uCond(cb, CondAlways); |
4874 |
*isEnd = True; |
5531 |
*isEnd = True; |
4875 |
if (dis) |
5532 |
DIP("loop 0x%x\n", d32); |
4876 |
VG_(printf)("loop 0x%x\n", d32); |
|
|
4877 |
break; |
5533 |
break; |
4878 |
|
5534 |
|
4879 |
/* ------------------------ IMUL ----------------------- */ |
5535 |
/* ------------------------ IMUL ----------------------- */ |
Lines 4910-4922
Link Here
|
4910 |
/* NOTE! this is the one place where a segment override prefix |
5566 |
/* NOTE! this is the one place where a segment override prefix |
4911 |
has no effect on the address calculation. Therefore we pass |
5567 |
has no effect on the address calculation. Therefore we pass |
4912 |
zero instead of sorb here. */ |
5568 |
zero instead of sorb here. */ |
4913 |
pair = disAMode ( cb, /*sorb*/ 0, eip, dis?dis_buf:NULL ); |
5569 |
pair = disAMode ( cb, /*sorb*/ 0, eip, dis_buf ); |
4914 |
eip += HI8(pair); |
5570 |
eip += HI8(pair); |
4915 |
t1 = LOW24(pair); |
5571 |
t1 = LOW24(pair); |
4916 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, gregOfRM(modrm)); |
5572 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, gregOfRM(modrm)); |
4917 |
if (dis) |
5573 |
DIP("lea%c %s, %s\n", nameISize(sz), dis_buf, |
4918 |
VG_(printf)("lea%c %s, %s\n", nameISize(sz), dis_buf, |
5574 |
nameIReg(sz,gregOfRM(modrm))); |
4919 |
nameIReg(sz,gregOfRM(modrm))); |
|
|
4920 |
break; |
5575 |
break; |
4921 |
|
5576 |
|
4922 |
case 0x8C: /* MOV Sw,Ew -- MOV from a SEGMENT REGISTER */ |
5577 |
case 0x8C: /* MOV Sw,Ew -- MOV from a SEGMENT REGISTER */ |
Lines 4938-4946
Link Here
|
4938 |
handleSegOverride(cb, sorb, t2); |
5593 |
handleSegOverride(cb, sorb, t2); |
4939 |
uInstr2(cb, LOAD, sz, TempReg, t2, TempReg, t1); |
5594 |
uInstr2(cb, LOAD, sz, TempReg, t2, TempReg, t1); |
4940 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, R_EAX); |
5595 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, R_EAX); |
4941 |
if (dis) VG_(printf)("mov%c %s0x%x, %s\n", nameISize(sz), |
5596 |
DIP("mov%c %s0x%x, %s\n", nameISize(sz), sorbTxt(sorb), |
4942 |
sorbTxt(sorb), |
5597 |
d32, nameIReg(sz,R_EAX)); |
4943 |
d32, nameIReg(sz,R_EAX)); |
|
|
4944 |
break; |
5598 |
break; |
4945 |
|
5599 |
|
4946 |
case 0xA2: /* MOV AL,Ob */ |
5600 |
case 0xA2: /* MOV AL,Ob */ |
Lines 4954-4962
Link Here
|
4954 |
uLiteral(cb, d32); |
5608 |
uLiteral(cb, d32); |
4955 |
handleSegOverride(cb, sorb, t2); |
5609 |
handleSegOverride(cb, sorb, t2); |
4956 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
5610 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
4957 |
if (dis) VG_(printf)("mov%c %s, %s0x%x\n", nameISize(sz), |
5611 |
DIP("mov%c %s, %s0x%x\n", nameISize(sz), nameIReg(sz,R_EAX), |
4958 |
nameIReg(sz,R_EAX), |
5612 |
sorbTxt(sorb), d32); |
4959 |
sorbTxt(sorb), d32); |
|
|
4960 |
break; |
5613 |
break; |
4961 |
|
5614 |
|
4962 |
case 0xB0: /* MOV imm,AL */ |
5615 |
case 0xB0: /* MOV imm,AL */ |
Lines 4972-4979
Link Here
|
4972 |
uInstr2(cb, MOV, 1, Literal, 0, TempReg, t1); |
5625 |
uInstr2(cb, MOV, 1, Literal, 0, TempReg, t1); |
4973 |
uLiteral(cb, d32); |
5626 |
uLiteral(cb, d32); |
4974 |
uInstr2(cb, PUT, 1, TempReg, t1, ArchReg, opc-0xB0); |
5627 |
uInstr2(cb, PUT, 1, TempReg, t1, ArchReg, opc-0xB0); |
4975 |
if (dis) VG_(printf)("movb $0x%x,%s\n", d32, |
5628 |
DIP("movb $0x%x,%s\n", d32, nameIReg(1,opc-0xB0)); |
4976 |
nameIReg(1,opc-0xB0)); |
|
|
4977 |
break; |
5629 |
break; |
4978 |
|
5630 |
|
4979 |
case 0xB8: /* MOV imm,eAX */ |
5631 |
case 0xB8: /* MOV imm,eAX */ |
Lines 4989-4996
Link Here
|
4989 |
uInstr2(cb, MOV, sz, Literal, 0, TempReg, t1); |
5641 |
uInstr2(cb, MOV, sz, Literal, 0, TempReg, t1); |
4990 |
uLiteral(cb, d32); |
5642 |
uLiteral(cb, d32); |
4991 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, opc-0xB8); |
5643 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, opc-0xB8); |
4992 |
if (dis) VG_(printf)("mov%c $0x%x,%s\n", nameISize(sz), d32, |
5644 |
DIP("mov%c $0x%x,%s\n", nameISize(sz), d32, nameIReg(sz,opc-0xB8)); |
4993 |
nameIReg(sz,opc-0xB8)); |
|
|
4994 |
break; |
5645 |
break; |
4995 |
|
5646 |
|
4996 |
case 0xC6: /* MOV Ib,Eb */ |
5647 |
case 0xC6: /* MOV Ib,Eb */ |
Lines 5008-5017
Link Here
|
5008 |
uInstr2(cb, MOV, sz, Literal, 0, TempReg, t1); |
5659 |
uInstr2(cb, MOV, sz, Literal, 0, TempReg, t1); |
5009 |
uLiteral(cb, d32); |
5660 |
uLiteral(cb, d32); |
5010 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
5661 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm)); |
5011 |
if (dis) VG_(printf)("mov%c $0x%x, %s\n", nameISize(sz), d32, |
5662 |
DIP("mov%c $0x%x, %s\n", nameISize(sz), d32, |
5012 |
nameIReg(sz,eregOfRM(modrm))); |
5663 |
nameIReg(sz,eregOfRM(modrm))); |
5013 |
} else { |
5664 |
} else { |
5014 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
5665 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
5015 |
eip += HI8(pair); |
5666 |
eip += HI8(pair); |
5016 |
d32 = getUDisp(sz,eip); eip += sz; |
5667 |
d32 = getUDisp(sz,eip); eip += sz; |
5017 |
t1 = newTemp(cb); |
5668 |
t1 = newTemp(cb); |
Lines 5019-5025
Link Here
|
5019 |
uInstr2(cb, MOV, sz, Literal, 0, TempReg, t1); |
5670 |
uInstr2(cb, MOV, sz, Literal, 0, TempReg, t1); |
5020 |
uLiteral(cb, d32); |
5671 |
uLiteral(cb, d32); |
5021 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
5672 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
5022 |
if (dis) VG_(printf)("mov%c $0x%x, %s\n", nameISize(sz), d32, dis_buf); |
5673 |
DIP("mov%c $0x%x, %s\n", nameISize(sz), d32, dis_buf); |
5023 |
} |
5674 |
} |
5024 |
break; |
5675 |
break; |
5025 |
|
5676 |
|
Lines 5049-5054
Link Here
|
5049 |
case 0x1C: /* SBB Ib, AL */ |
5700 |
case 0x1C: /* SBB Ib, AL */ |
5050 |
eip = dis_op_imm_A(cb, 1, SBB, True, eip, "sbb" ); |
5701 |
eip = dis_op_imm_A(cb, 1, SBB, True, eip, "sbb" ); |
5051 |
break; |
5702 |
break; |
|
|
5703 |
case 0x1D: /* SBB Iv, eAX */ |
5704 |
eip = dis_op_imm_A(cb, sz, SBB, True, eip, "sbb" ); |
5705 |
break; |
5052 |
|
5706 |
|
5053 |
case 0x24: /* AND Ib, AL */ |
5707 |
case 0x24: /* AND Ib, AL */ |
5054 |
eip = dis_op_imm_A(cb, 1, AND, True, eip, "and" ); |
5708 |
eip = dis_op_imm_A(cb, 1, AND, True, eip, "and" ); |
Lines 5173-5178
Link Here
|
5173 |
eip = dis_op2_G_E ( cb, sorb, ADC, True, sz, eip, "adc" ); |
5827 |
eip = dis_op2_G_E ( cb, sorb, ADC, True, sz, eip, "adc" ); |
5174 |
break; |
5828 |
break; |
5175 |
|
5829 |
|
|
|
5830 |
case 0x18: /* SBB Gb,Eb */ |
5831 |
eip = dis_op2_G_E ( cb, sorb, SBB, True, 1, eip, "sbb" ); |
5832 |
break; |
5176 |
case 0x19: /* SBB Gv,Ev */ |
5833 |
case 0x19: /* SBB Gv,Ev */ |
5177 |
eip = dis_op2_G_E ( cb, sorb, SBB, True, sz, eip, "sbb" ); |
5834 |
eip = dis_op2_G_E ( cb, sorb, SBB, True, sz, eip, "sbb" ); |
5178 |
break; |
5835 |
break; |
Lines 5222-5229
Link Here
|
5222 |
uLiteral(cb, sz); |
5879 |
uLiteral(cb, sz); |
5223 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
5880 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
5224 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, opc-0x58); |
5881 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, opc-0x58); |
5225 |
if (dis) |
5882 |
DIP("pop%c %s\n", nameISize(sz), nameIReg(sz,opc-0x58)); |
5226 |
VG_(printf)("pop%c %s\n", nameISize(sz), nameIReg(sz,opc-0x58)); |
|
|
5227 |
break; |
5883 |
break; |
5228 |
|
5884 |
|
5229 |
case 0x9D: /* POPF */ |
5885 |
case 0x9D: /* POPF */ |
Lines 5237-5244
Link Here
|
5237 |
uInstr1(cb, PUTF, sz, TempReg, t1); |
5893 |
uInstr1(cb, PUTF, sz, TempReg, t1); |
5238 |
/* PUTF writes all the flags we are interested in */ |
5894 |
/* PUTF writes all the flags we are interested in */ |
5239 |
uFlagsRWU(cb, FlagsEmpty, FlagsALL, FlagsEmpty); |
5895 |
uFlagsRWU(cb, FlagsEmpty, FlagsALL, FlagsEmpty); |
5240 |
if (dis) |
5896 |
DIP("popf%c\n", nameISize(sz)); |
5241 |
VG_(printf)("popf%c\n", nameISize(sz)); |
|
|
5242 |
break; |
5897 |
break; |
5243 |
|
5898 |
|
5244 |
case 0x61: /* POPA */ |
5899 |
case 0x61: /* POPA */ |
Lines 5277-5284
Link Here
|
5277 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t3); |
5932 |
uInstr2(cb, ADD, 4, Literal, 0, TempReg, t3); |
5278 |
uLiteral(cb, sz * 8); /* One 'sz' per register */ |
5933 |
uLiteral(cb, sz * 8); /* One 'sz' per register */ |
5279 |
uInstr2(cb, PUT, 4, TempReg, t3, ArchReg, R_ESP); |
5934 |
uInstr2(cb, PUT, 4, TempReg, t3, ArchReg, R_ESP); |
5280 |
if (dis) |
5935 |
DIP("popa%c\n", nameISize(sz)); |
5281 |
VG_(printf)("popa%c\n", nameISize(sz)); |
|
|
5282 |
break; |
5936 |
break; |
5283 |
} |
5937 |
} |
5284 |
|
5938 |
|
Lines 5309-5323
Link Here
|
5309 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP); |
5963 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP); |
5310 |
|
5964 |
|
5311 |
/* resolve MODR/M */ |
5965 |
/* resolve MODR/M */ |
5312 |
pair1 = disAMode ( cb, sorb, eip, dis?dis_buf:NULL); |
5966 |
pair1 = disAMode ( cb, sorb, eip, dis_buf ); |
5313 |
|
5967 |
|
5314 |
tmpa = LOW24(pair1); |
5968 |
tmpa = LOW24(pair1); |
5315 |
/* uInstr2(cb, LOAD, sz, TempReg, tmpa, TempReg, tmpa); */ |
5969 |
/* uInstr2(cb, LOAD, sz, TempReg, tmpa, TempReg, tmpa); */ |
5316 |
/* store value from stack in memory, M[m32] = t3 */ |
5970 |
/* store value from stack in memory, M[m32] = t3 */ |
5317 |
uInstr2(cb, STORE, 4, TempReg, t3, TempReg, tmpa); |
5971 |
uInstr2(cb, STORE, 4, TempReg, t3, TempReg, tmpa); |
5318 |
|
5972 |
|
5319 |
if (dis) |
5973 |
DIP("popl %s\n", dis_buf); |
5320 |
VG_(printf)("popl %s\n", dis_buf); |
|
|
5321 |
|
5974 |
|
5322 |
eip += HI8(pair1); |
5975 |
eip += HI8(pair1); |
5323 |
break; |
5976 |
break; |
Lines 5351-5358
Link Here
|
5351 |
uLiteral(cb, sz); |
6004 |
uLiteral(cb, sz); |
5352 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
6005 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
5353 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
6006 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
5354 |
if (dis) |
6007 |
DIP("push%c %s\n", nameISize(sz), nameIReg(sz,opc-0x50)); |
5355 |
VG_(printf)("push%c %s\n", nameISize(sz), nameIReg(sz,opc-0x50)); |
|
|
5356 |
break; |
6008 |
break; |
5357 |
|
6009 |
|
5358 |
case 0x68: /* PUSH Iv */ |
6010 |
case 0x68: /* PUSH Iv */ |
Lines 5370-5377
Link Here
|
5370 |
uInstr2(cb, MOV, sz, Literal, 0, TempReg, t2); |
6022 |
uInstr2(cb, MOV, sz, Literal, 0, TempReg, t2); |
5371 |
uLiteral(cb, d32); |
6023 |
uLiteral(cb, d32); |
5372 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1); |
6024 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1); |
5373 |
if (dis) |
6025 |
DIP("push%c $0x%x\n", nameISize(sz), d32); |
5374 |
VG_(printf)("push%c $0x%x\n", nameISize(sz), d32); |
|
|
5375 |
break; |
6026 |
break; |
5376 |
|
6027 |
|
5377 |
case 0x9C: /* PUSHF */ |
6028 |
case 0x9C: /* PUSHF */ |
Lines 5386-5393
Link Here
|
5386 |
uLiteral(cb, sz); |
6037 |
uLiteral(cb, sz); |
5387 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
6038 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP); |
5388 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
6039 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
5389 |
if (dis) |
6040 |
DIP("pushf%c\n", nameISize(sz)); |
5390 |
VG_(printf)("pushf%c\n", nameISize(sz)); |
|
|
5391 |
break; |
6041 |
break; |
5392 |
|
6042 |
|
5393 |
case 0x60: /* PUSHA */ |
6043 |
case 0x60: /* PUSHA */ |
Lines 5429-5436
Link Here
|
5429 |
uLiteral(cb, sz); |
6079 |
uLiteral(cb, sz); |
5430 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
6080 |
uInstr2(cb, STORE, sz, TempReg, t1, TempReg, t2); |
5431 |
} |
6081 |
} |
5432 |
if (dis) |
6082 |
DIP("pusha%c\n", nameISize(sz)); |
5433 |
VG_(printf)("pusha%c\n", nameISize(sz)); |
|
|
5434 |
break; |
6083 |
break; |
5435 |
} |
6084 |
} |
5436 |
|
6085 |
|
Lines 5476-5482
Link Here
|
5476 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CLD)); |
6125 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CLD)); |
5477 |
uFlagsRWU(cb, FlagsEmpty, FlagD, FlagsEmpty); |
6126 |
uFlagsRWU(cb, FlagsEmpty, FlagD, FlagsEmpty); |
5478 |
uInstr0(cb, CALLM_E, 0); |
6127 |
uInstr0(cb, CALLM_E, 0); |
5479 |
if (dis) VG_(printf)("cld\n"); |
6128 |
DIP("cld\n"); |
5480 |
break; |
6129 |
break; |
5481 |
|
6130 |
|
5482 |
case 0xFD: /* STD */ |
6131 |
case 0xFD: /* STD */ |
Lines 5484-5490
Link Here
|
5484 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_STD)); |
6133 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_STD)); |
5485 |
uFlagsRWU(cb, FlagsEmpty, FlagD, FlagsEmpty); |
6134 |
uFlagsRWU(cb, FlagsEmpty, FlagD, FlagsEmpty); |
5486 |
uInstr0(cb, CALLM_E, 0); |
6135 |
uInstr0(cb, CALLM_E, 0); |
5487 |
if (dis) VG_(printf)("std\n"); |
6136 |
DIP("std\n"); |
5488 |
break; |
6137 |
break; |
5489 |
|
6138 |
|
5490 |
case 0xF8: /* CLC */ |
6139 |
case 0xF8: /* CLC */ |
Lines 5492-5506
Link Here
|
5492 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CLC)); |
6141 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CLC)); |
5493 |
uFlagsRWU(cb, FlagsEmpty, FlagC, FlagsOSZAP); |
6142 |
uFlagsRWU(cb, FlagsEmpty, FlagC, FlagsOSZAP); |
5494 |
uInstr0(cb, CALLM_E, 0); |
6143 |
uInstr0(cb, CALLM_E, 0); |
5495 |
if (dis) VG_(printf)("clc\n"); |
6144 |
DIP("clc\n"); |
5496 |
break; |
6145 |
break; |
5497 |
|
6146 |
|
5498 |
case 0xF9: /* STC */ |
6147 |
case 0xF9: /* STC */ |
5499 |
uInstr0(cb, CALLM_S, 0); |
6148 |
uInstr0(cb, CALLM_S, 0); |
5500 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_STC)); |
6149 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_STC)); |
5501 |
uFlagsRWU(cb, FlagsEmpty, FlagC, FlagsOSZCP); |
6150 |
uFlagsRWU(cb, FlagsEmpty, FlagC, FlagsOSZAP); |
|
|
6151 |
uInstr0(cb, CALLM_E, 0); |
6152 |
DIP("stc\n"); |
6153 |
break; |
6154 |
|
6155 |
case 0xF5: /* CMC */ |
6156 |
uInstr0(cb, CALLM_S, 0); |
6157 |
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CMC)); |
6158 |
uFlagsRWU(cb, FlagC, FlagC, FlagsOSZAP); |
5502 |
uInstr0(cb, CALLM_E, 0); |
6159 |
uInstr0(cb, CALLM_E, 0); |
5503 |
if (dis) VG_(printf)("stc\n"); |
6160 |
DIP("cmc\n"); |
5504 |
break; |
6161 |
break; |
5505 |
|
6162 |
|
5506 |
case 0xF2: { /* REPNE prefix insn */ |
6163 |
case 0xF2: { /* REPNE prefix insn */ |
Lines 5554-5561
Link Here
|
5554 |
} |
6211 |
} |
5555 |
else |
6212 |
else |
5556 |
if (abyte == 0x90) { /* REP NOP (PAUSE) */ |
6213 |
if (abyte == 0x90) { /* REP NOP (PAUSE) */ |
5557 |
if (dis) VG_(printf)("rep nop (P4 pause)\n"); |
6214 |
/* a hint to the P4 re spin-wait loop */ |
5558 |
/* do nothing; apparently a hint to the P4 re spin-wait loop */ |
6215 |
DIP("rep nop (P4 pause)\n"); |
|
|
6216 |
jmp_lit(cb, eip); |
6217 |
LAST_UINSTR(cb).jmpkind = JmpYield; |
6218 |
*isEnd = True; |
5559 |
} |
6219 |
} |
5560 |
else { |
6220 |
else { |
5561 |
goto decode_failure; |
6221 |
goto decode_failure; |
Lines 5577-5603
Link Here
|
5577 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, gregOfRM(modrm)); |
6237 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, gregOfRM(modrm)); |
5578 |
uInstr2(cb, PUT, sz, TempReg, t2, ArchReg, eregOfRM(modrm)); |
6238 |
uInstr2(cb, PUT, sz, TempReg, t2, ArchReg, eregOfRM(modrm)); |
5579 |
eip++; |
6239 |
eip++; |
5580 |
if (dis) |
6240 |
DIP("xchg%c %s, %s\n", |
5581 |
VG_(printf)("xchg%c %s, %s\n", nameISize(sz), |
6241 |
nameISize(sz), nameIReg(sz,gregOfRM(modrm)), |
5582 |
nameIReg(sz,gregOfRM(modrm)), |
6242 |
nameIReg(sz,eregOfRM(modrm))); |
5583 |
nameIReg(sz,eregOfRM(modrm))); |
|
|
5584 |
} else { |
6243 |
} else { |
5585 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL); |
6244 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
5586 |
t3 = LOW24(pair); |
6245 |
t3 = LOW24(pair); |
5587 |
uInstr2(cb, LOAD, sz, TempReg, t3, TempReg, t1); |
6246 |
uInstr2(cb, LOAD, sz, TempReg, t3, TempReg, t1); |
5588 |
uInstr2(cb, GET, sz, ArchReg, gregOfRM(modrm), TempReg, t2); |
6247 |
uInstr2(cb, GET, sz, ArchReg, gregOfRM(modrm), TempReg, t2); |
5589 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t3); |
6248 |
uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t3); |
5590 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, gregOfRM(modrm)); |
6249 |
uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, gregOfRM(modrm)); |
5591 |
eip += HI8(pair); |
6250 |
eip += HI8(pair); |
5592 |
if (dis) |
6251 |
DIP("xchg%c %s, %s\n", nameISize(sz), |
5593 |
VG_(printf)("xchg%c %s, %s\n", nameISize(sz), |
6252 |
nameIReg(sz,gregOfRM(modrm)), dis_buf); |
5594 |
nameIReg(sz,gregOfRM(modrm)), |
|
|
5595 |
dis_buf); |
5596 |
} |
6253 |
} |
5597 |
break; |
6254 |
break; |
5598 |
|
6255 |
|
5599 |
case 0x90: /* XCHG eAX,eAX */ |
6256 |
case 0x90: /* XCHG eAX,eAX */ |
5600 |
if (dis) VG_(printf)("nop\n"); |
6257 |
DIP("nop\n"); |
5601 |
break; |
6258 |
break; |
5602 |
case 0x91: /* XCHG eAX,eCX */ |
6259 |
case 0x91: /* XCHG eAX,eCX */ |
5603 |
case 0x92: /* XCHG eAX,eDX */ |
6260 |
case 0x92: /* XCHG eAX,eDX */ |
Lines 5624-5631
Link Here
|
5624 |
uInstr2(cb, LOAD, 1, TempReg, t1, TempReg, t2); /* get byte at t1 into t2 */ |
6281 |
uInstr2(cb, LOAD, 1, TempReg, t1, TempReg, t2); /* get byte at t1 into t2 */ |
5625 |
uInstr2(cb, PUT, 1, TempReg, t2, ArchReg, R_AL); /* put byte into AL */ |
6282 |
uInstr2(cb, PUT, 1, TempReg, t2, ArchReg, R_AL); /* put byte into AL */ |
5626 |
|
6283 |
|
5627 |
if (dis) |
6284 |
DIP("xlat%c [ebx]\n", nameISize(sz)); |
5628 |
VG_(printf)("xlat%c [ebx]\n", nameISize(sz)); |
|
|
5629 |
break; |
6285 |
break; |
5630 |
|
6286 |
|
5631 |
/* ------------------------ IN / OUT ----------------------- */ |
6287 |
/* ------------------------ IN / OUT ----------------------- */ |
Lines 5659-5669
Link Here
|
5659 |
uInstr1(cb, CLEAR, 0, Lit16, 4); |
6315 |
uInstr1(cb, CLEAR, 0, Lit16, 4); |
5660 |
uInstr0(cb, CALLM_E, 0); |
6316 |
uInstr0(cb, CALLM_E, 0); |
5661 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_EAX); |
6317 |
uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_EAX); |
5662 |
if (dis) { |
6318 |
if ( opc == 0xE4 || opc == 0xE5 ) { |
5663 |
if ( opc == 0xE4 || opc == 0xE5 ) |
6319 |
DIP("in 0x%x, %%eax/%%ax/%%al\n", getUChar(eip-1) ); |
5664 |
VG_(printf)("in 0x%x, %%eax/%%ax/%%al\n", getUChar(eip-1) ); |
6320 |
} else { |
5665 |
else |
6321 |
DIP("in (%%dx), %%eax/%%ax/%%al\n"); |
5666 |
VG_(printf)("in (%%dx), %%eax/%%ax/%%al\n"); |
|
|
5667 |
} |
6322 |
} |
5668 |
break; |
6323 |
break; |
5669 |
case 0xE6: /* OUT %al,ib */ |
6324 |
case 0xE6: /* OUT %al,ib */ |
Lines 5694-5704
Link Here
|
5694 |
uFlagsRWU(cb, FlagsEmpty, FlagsEmpty, FlagsEmpty); |
6349 |
uFlagsRWU(cb, FlagsEmpty, FlagsEmpty, FlagsEmpty); |
5695 |
uInstr1(cb, CLEAR, 0, Lit16, 12); |
6350 |
uInstr1(cb, CLEAR, 0, Lit16, 12); |
5696 |
uInstr0(cb, CALLM_E, 0); |
6351 |
uInstr0(cb, CALLM_E, 0); |
5697 |
if (dis) { |
6352 |
if ( opc == 0xE4 || opc == 0xE5 ) { |
5698 |
if ( opc == 0xE4 || opc == 0xE5 ) |
6353 |
DIP("out %%eax/%%ax/%%al, 0x%x\n", getUChar(eip-1) ); |
5699 |
VG_(printf)("out %%eax/%%ax/%%al, 0x%x\n", getUChar(eip-1) ); |
6354 |
} else { |
5700 |
else |
6355 |
DIP("out %%eax/%%ax/%%al, (%%dx)\n"); |
5701 |
VG_(printf)("out %%eax/%%ax/%%al, (%%dx)\n"); |
|
|
5702 |
} |
6356 |
} |
5703 |
break; |
6357 |
break; |
5704 |
|
6358 |
|
Lines 5841-5847
Link Here
|
5841 |
uInstr2(cb, GET, 4, ArchReg, opc-0xC8, TempReg, t1); |
6495 |
uInstr2(cb, GET, 4, ArchReg, opc-0xC8, TempReg, t1); |
5842 |
uInstr1(cb, BSWAP, 4, TempReg, t1); |
6496 |
uInstr1(cb, BSWAP, 4, TempReg, t1); |
5843 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, opc-0xC8); |
6497 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, opc-0xC8); |
5844 |
if (dis) VG_(printf)("bswapl %s\n", nameIReg(4, opc-0xC8)); |
6498 |
DIP("bswapl %s\n", nameIReg(4, opc-0xC8)); |
5845 |
break; |
6499 |
break; |
5846 |
|
6500 |
|
5847 |
/* =-=-=-=-=-=-=-=-=- BT/BTS/BTR/BTC =-=-=-=-=-=-= */ |
6501 |
/* =-=-=-=-=-=-=-=-=- BT/BTS/BTR/BTC =-=-=-=-=-=-= */ |
Lines 5882-5894
Link Here
|
5882 |
|
6536 |
|
5883 |
/* =-=-=-=-=-=-=-=-=- CMPXCHG -=-=-=-=-=-=-=-=-=-= */ |
6537 |
/* =-=-=-=-=-=-=-=-=- CMPXCHG -=-=-=-=-=-=-=-=-=-= */ |
5884 |
|
6538 |
|
|
|
6539 |
case 0xB0: /* CMPXCHG Gv,Ev */ |
6540 |
eip = dis_cmpxchg_G_E ( cb, sorb, 1, eip ); |
6541 |
break; |
5885 |
case 0xB1: /* CMPXCHG Gv,Ev */ |
6542 |
case 0xB1: /* CMPXCHG Gv,Ev */ |
5886 |
eip = dis_cmpxchg_G_E ( cb, sorb, sz, eip ); |
6543 |
eip = dis_cmpxchg_G_E ( cb, sorb, sz, eip ); |
5887 |
break; |
6544 |
break; |
|
|
6545 |
case 0xC7: /* CMPXCHG8B Gv */ |
6546 |
eip = dis_cmpxchg8b ( cb, sorb, eip ); |
6547 |
break; |
5888 |
|
6548 |
|
5889 |
/* =-=-=-=-=-=-=-=-=- CPUID -=-=-=-=-=-=-=-=-=-=-= */ |
6549 |
/* =-=-=-=-=-=-=-=-=- CPUID -=-=-=-=-=-=-=-=-=-=-= */ |
5890 |
|
6550 |
|
5891 |
case 0xA2: /* CPUID */ |
6551 |
case 0xA2: /* CPUID */ |
|
|
6552 |
if (!VG_(cpu_has_feature)(VG_X86_FEAT_CPUID)) |
6553 |
goto decode_failure; |
6554 |
|
5892 |
t1 = newTemp(cb); |
6555 |
t1 = newTemp(cb); |
5893 |
t2 = newTemp(cb); |
6556 |
t2 = newTemp(cb); |
5894 |
t3 = newTemp(cb); |
6557 |
t3 = newTemp(cb); |
Lines 5926-5932
Link Here
|
5926 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_EAX); |
6589 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_EAX); |
5927 |
|
6590 |
|
5928 |
uInstr0(cb, CALLM_E, 0); |
6591 |
uInstr0(cb, CALLM_E, 0); |
5929 |
if (dis) VG_(printf)("cpuid\n"); |
6592 |
DIP("cpuid\n"); |
5930 |
break; |
6593 |
break; |
5931 |
|
6594 |
|
5932 |
/* =-=-=-=-=-=-=-=-=- MOVZX, MOVSX =-=-=-=-=-=-=-= */ |
6595 |
/* =-=-=-=-=-=-=-=-=- MOVZX, MOVSX =-=-=-=-=-=-=-= */ |
Lines 5945-5950
Link Here
|
5945 |
eip = dis_movx_E_G ( cb, sorb, eip, 2, 4, True ); |
6608 |
eip = dis_movx_E_G ( cb, sorb, eip, 2, 4, True ); |
5946 |
break; |
6609 |
break; |
5947 |
|
6610 |
|
|
|
6611 |
/* =-=-=-=-=-=-=-=-=-=-= MOVNTI -=-=-=-=-=-=-=-=-= */ |
6612 |
|
6613 |
case 0xC3: /* MOVNTI Gv,Ev */ |
6614 |
vg_assert(sz == 4); |
6615 |
modrm = getUChar(eip); |
6616 |
vg_assert(!epartIsReg(modrm)); |
6617 |
t1 = newTemp(cb); |
6618 |
uInstr2(cb, GET, 4, ArchReg, gregOfRM(modrm), TempReg, t1); |
6619 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
6620 |
t2 = LOW24(pair); |
6621 |
eip += HI8(pair); |
6622 |
uInstr2(cb, STORE, 4, TempReg, t1, TempReg, t2); |
6623 |
DIP("movnti %s,%s\n", nameIReg(4,gregOfRM(modrm)), dis_buf); |
6624 |
break; |
6625 |
|
5948 |
/* =-=-=-=-=-=-=-=-=- MUL/IMUL =-=-=-=-=-=-=-=-=-= */ |
6626 |
/* =-=-=-=-=-=-=-=-=- MUL/IMUL =-=-=-=-=-=-=-=-=-= */ |
5949 |
|
6627 |
|
5950 |
case 0xAF: /* IMUL Ev, Gv */ |
6628 |
case 0xAF: /* IMUL Ev, Gv */ |
Lines 5969-5985
Link Here
|
5969 |
case 0x8E: /* JLEb/JNGb (jump less or equal) */ |
6647 |
case 0x8E: /* JLEb/JNGb (jump less or equal) */ |
5970 |
case 0x8F: /* JGb/JNLEb (jump greater) */ |
6648 |
case 0x8F: /* JGb/JNLEb (jump greater) */ |
5971 |
d32 = (eip+4) + getUDisp32(eip); eip += 4; |
6649 |
d32 = (eip+4) + getUDisp32(eip); eip += 4; |
5972 |
uInstr1(cb, JMP, 0, Literal, 0); |
6650 |
jcc_lit(cb, d32, (Condcode)(opc - 0x80)); |
5973 |
uLiteral(cb, d32); |
6651 |
jmp_lit(cb, eip); |
5974 |
uCond(cb, (Condcode)(opc - 0x80)); |
|
|
5975 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
5976 |
uInstr1(cb, JMP, 0, Literal, 0); |
5977 |
uLiteral(cb, eip); |
5978 |
uCond(cb, CondAlways); |
5979 |
*isEnd = True; |
6652 |
*isEnd = True; |
5980 |
if (dis) |
6653 |
DIP("j%s-32 0x%x\n", VG_(name_UCondcode)(opc - 0x80), d32); |
5981 |
VG_(printf)("j%s-32 0x%x\n", |
|
|
5982 |
VG_(name_UCondcode)(opc - 0x80), d32); |
5983 |
break; |
6654 |
break; |
5984 |
|
6655 |
|
5985 |
/* =-=-=-=-=-=-=-=-=- RDTSC -=-=-=-=-=-=-=-=-=-=-= */ |
6656 |
/* =-=-=-=-=-=-=-=-=- RDTSC -=-=-=-=-=-=-=-=-=-=-= */ |
Lines 6002-6008
Link Here
|
6002 |
uInstr1(cb, POP, 4, TempReg, t3); |
6673 |
uInstr1(cb, POP, 4, TempReg, t3); |
6003 |
uInstr2(cb, PUT, 4, TempReg, t3, ArchReg, R_EAX); |
6674 |
uInstr2(cb, PUT, 4, TempReg, t3, ArchReg, R_EAX); |
6004 |
uInstr0(cb, CALLM_E, 0); |
6675 |
uInstr0(cb, CALLM_E, 0); |
6005 |
if (dis) VG_(printf)("rdtsc\n"); |
6676 |
DIP("rdtsc\n"); |
6006 |
break; |
6677 |
break; |
6007 |
|
6678 |
|
6008 |
/* =-=-=-=-=-=-=-=-=- SETcc Eb =-=-=-=-=-=-=-=-=-= */ |
6679 |
/* =-=-=-=-=-=-=-=-=- SETcc Eb =-=-=-=-=-=-=-=-=-= */ |
Lines 6030-6049
Link Here
|
6030 |
uCond(cb, (Condcode)(opc-0x90)); |
6701 |
uCond(cb, (Condcode)(opc-0x90)); |
6031 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
6702 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
6032 |
uInstr2(cb, PUT, 1, TempReg, t1, ArchReg, eregOfRM(modrm)); |
6703 |
uInstr2(cb, PUT, 1, TempReg, t1, ArchReg, eregOfRM(modrm)); |
6033 |
if (dis) VG_(printf)("set%s %s\n", |
6704 |
DIP("set%s %s\n", VG_(name_UCondcode)(opc-0x90), |
6034 |
VG_(name_UCondcode)(opc-0x90), |
6705 |
nameIReg(1,eregOfRM(modrm))); |
6035 |
nameIReg(1,eregOfRM(modrm))); |
|
|
6036 |
} else { |
6706 |
} else { |
6037 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
6707 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
6038 |
t2 = LOW24(pair); |
6708 |
t2 = LOW24(pair); |
6039 |
eip += HI8(pair); |
6709 |
eip += HI8(pair); |
6040 |
uInstr1(cb, CC2VAL, 1, TempReg, t1); |
6710 |
uInstr1(cb, CC2VAL, 1, TempReg, t1); |
6041 |
uCond(cb, (Condcode)(opc-0x90)); |
6711 |
uCond(cb, (Condcode)(opc-0x90)); |
6042 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
6712 |
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty); |
6043 |
uInstr2(cb, STORE, 1, TempReg, t1, TempReg, t2); |
6713 |
uInstr2(cb, STORE, 1, TempReg, t1, TempReg, t2); |
6044 |
if (dis) VG_(printf)("set%s %s\n", |
6714 |
DIP("set%s %s\n", VG_(name_UCondcode)(opc-0x90), dis_buf); |
6045 |
VG_(name_UCondcode)(opc-0x90), |
|
|
6046 |
dis_buf); |
6047 |
} |
6715 |
} |
6048 |
break; |
6716 |
break; |
6049 |
|
6717 |
|
Lines 6077-6082
Link Here
|
6077 |
|
6745 |
|
6078 |
/* =-=-=-=-=-=-=-=-=- CMPXCHG -=-=-=-=-=-=-=-=-=-= */ |
6746 |
/* =-=-=-=-=-=-=-=-=- CMPXCHG -=-=-=-=-=-=-=-=-=-= */ |
6079 |
|
6747 |
|
|
|
6748 |
case 0xC0: /* XADD Gb,Eb */ |
6749 |
eip = dis_xadd_G_E ( cb, sorb, 1, eip ); |
6750 |
break; |
6080 |
case 0xC1: /* XADD Gv,Ev */ |
6751 |
case 0xC1: /* XADD Gv,Ev */ |
6081 |
eip = dis_xadd_G_E ( cb, sorb, sz, eip ); |
6752 |
eip = dis_xadd_G_E ( cb, sorb, sz, eip ); |
6082 |
break; |
6753 |
break; |
Lines 6095-6103
Link Here
|
6095 |
goto decode_failure; |
6766 |
goto decode_failure; |
6096 |
} |
6767 |
} |
6097 |
eip += lengthAMode(eip); |
6768 |
eip += lengthAMode(eip); |
6098 |
if (dis) { |
6769 |
if (VG_(print_codegen)) { |
6099 |
UChar* hintstr; |
6770 |
UChar* hintstr; |
6100 |
if(opc == 0x0D) { |
6771 |
if (opc == 0x0D) { |
6101 |
switch (gregOfRM(modrm)) { |
6772 |
switch (gregOfRM(modrm)) { |
6102 |
case 0: hintstr = ""; break; |
6773 |
case 0: hintstr = ""; break; |
6103 |
case 1: hintstr = "w"; break; |
6774 |
case 1: hintstr = "w"; break; |
Lines 6117-6126
Link Here
|
6117 |
} |
6788 |
} |
6118 |
break; |
6789 |
break; |
6119 |
|
6790 |
|
6120 |
case 0x71: case 0x72: case 0x73: |
6791 |
case 0x71: case 0x72: case 0x73: { |
6121 |
/* (sz==4): PSLL/PSRA/PSRL mmxreg by imm8 */ |
6792 |
/* (sz==4): PSLL/PSRA/PSRL mmxreg by imm8 */ |
6122 |
/* (sz==2): PSLL/PSRA/PSRL xmmreg by imm8 */ |
6793 |
/* (sz==2): PSLL/PSRA/PSRL xmmreg by imm8 */ |
6123 |
{ |
|
|
6124 |
UChar byte1, byte2, byte3, subopc, mmreg; |
6794 |
UChar byte1, byte2, byte3, subopc, mmreg; |
6125 |
vg_assert(sz == 4 || sz == 2); |
6795 |
vg_assert(sz == 4 || sz == 2); |
6126 |
byte1 = opc; /* 0x71/72/73 */ |
6796 |
byte1 = opc; /* 0x71/72/73 */ |
Lines 6146-6186
Link Here
|
6146 |
uInstr2(cb, MMX3, 0, |
6816 |
uInstr2(cb, MMX3, 0, |
6147 |
Lit16, (((UShort)byte1) << 8) | ((UShort)byte2), |
6817 |
Lit16, (((UShort)byte1) << 8) | ((UShort)byte2), |
6148 |
Lit16, ((UShort)byte3) ); |
6818 |
Lit16, ((UShort)byte3) ); |
6149 |
if (dis) |
6819 |
DIP("ps%s%s $%d, %s\n", |
6150 |
VG_(printf)("ps%s%s $%d, %s\n", |
6820 |
( subopc == 2 ? "rl" |
6151 |
(subopc == 2 ? "rl" |
6821 |
: subopc == 6 ? "ll" |
6152 |
: subopc == 6 ? "ll" |
6822 |
: subopc == 4 ? "ra" |
6153 |
: subopc == 4 ? "ra" |
6823 |
: "??"), |
6154 |
: "??"), |
6824 |
nameMMXGran(opc & 3), (Int)byte3, nameMMXReg(mmreg) ); |
6155 |
nameMMXGran(opc & 3), |
|
|
6156 |
(Int)byte3, |
6157 |
nameMMXReg(mmreg) ); |
6158 |
} else { |
6825 |
} else { |
6159 |
/* Whereas we have to include it for SSE. */ |
6826 |
/* Whereas we have to include it for SSE. */ |
6160 |
uInstr3(cb, SSE5, 0, |
6827 |
uInstr3(cb, SSE5, 0, |
6161 |
Lit16, (((UShort)0x66) << 8) | ((UShort)0x0F), |
6828 |
Lit16, (((UShort)0x66) << 8) | ((UShort)0x0F), |
6162 |
Lit16, (((UShort)byte1) << 8) | ((UShort)byte2), |
6829 |
Lit16, (((UShort)byte1) << 8) | ((UShort)byte2), |
6163 |
Lit16, ((UShort)byte3) ); |
6830 |
Lit16, ((UShort)byte3) ); |
6164 |
if (dis) |
6831 |
DIP("ps%s%s $%d, %s\n", |
6165 |
VG_(printf)("ps%s%s $%d, %s\n", |
6832 |
( subopc == 2 ? "rl" |
6166 |
(subopc == 2 ? "rl" |
6833 |
: subopc == 6 ? "ll" |
6167 |
: subopc == 6 ? "ll" |
6834 |
: subopc == 4 ? "ra" |
6168 |
: subopc == 4 ? "ra" |
6835 |
: subopc == 3 ? "(PSRLDQ)" |
6169 |
: subopc == 3 ? "(PSRLDQ)" |
6836 |
: subopc == 7 ? "(PSLLDQ)" |
6170 |
: subopc == 7 ? "(PSLLDQ)" |
6837 |
: "??"), |
6171 |
: "??"), |
6838 |
nameMMXGran(opc & 3), (Int)byte3, nameXMMReg(mmreg) ); |
6172 |
nameMMXGran(opc & 3), |
|
|
6173 |
(Int)byte3, |
6174 |
nameXMMReg(mmreg) ); |
6175 |
} |
6176 |
} |
6839 |
} |
6177 |
break; |
6840 |
break; |
|
|
6841 |
} |
6178 |
|
6842 |
|
6179 |
case 0x77: /* EMMS */ |
6843 |
case 0x77: /* EMMS */ |
6180 |
vg_assert(sz == 4); |
6844 |
vg_assert(sz == 4); |
6181 |
uInstr1(cb, MMX1, 0, Lit16, ((UShort)(opc)) ); |
6845 |
uInstr1(cb, MMX1, 0, Lit16, ((UShort)(opc)) ); |
6182 |
if (dis) |
6846 |
DIP("emms\n"); |
6183 |
VG_(printf)("emms\n"); |
|
|
6184 |
break; |
6847 |
break; |
6185 |
|
6848 |
|
6186 |
case 0x7E: /* MOVD (src)mmxreg, (dst)ireg-or-mem */ |
6849 |
case 0x7E: /* MOVD (src)mmxreg, (dst)ireg-or-mem */ |
Lines 6194-6216
Link Here
|
6194 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6857 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6195 |
TempReg, t1 ); |
6858 |
TempReg, t1 ); |
6196 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, eregOfRM(modrm)); |
6859 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, eregOfRM(modrm)); |
6197 |
if (dis) |
6860 |
DIP("movd %s, %s\n", |
6198 |
VG_(printf)("movd %s, %s\n", |
6861 |
nameMMXReg(gregOfRM(modrm)), nameIReg(4,eregOfRM(modrm))); |
6199 |
nameMMXReg(gregOfRM(modrm)), |
|
|
6200 |
nameIReg(4,eregOfRM(modrm))); |
6201 |
} else { |
6862 |
} else { |
6202 |
Int tmpa; |
6863 |
Int tmpa; |
6203 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
6864 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
6204 |
tmpa = LOW24(pair); |
6865 |
tmpa = LOW24(pair); |
6205 |
eip += HI8(pair); |
6866 |
eip += HI8(pair); |
6206 |
uInstr2(cb, MMX2_MemWr, 4, |
6867 |
uInstr2(cb, MMX2_MemWr, 4, |
6207 |
Lit16, |
6868 |
Lit16, |
6208 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6869 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6209 |
TempReg, tmpa); |
6870 |
TempReg, tmpa); |
6210 |
if (dis) |
6871 |
DIP("movd %s, %s\n", nameMMXReg(gregOfRM(modrm)), dis_buf); |
6211 |
VG_(printf)("movd %s, %s\n", |
|
|
6212 |
nameMMXReg(gregOfRM(modrm)), |
6213 |
dis_buf); |
6214 |
} |
6872 |
} |
6215 |
break; |
6873 |
break; |
6216 |
|
6874 |
|
Lines 6225-6247
Link Here
|
6225 |
Lit16, |
6883 |
Lit16, |
6226 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6884 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6227 |
TempReg, t1 ); |
6885 |
TempReg, t1 ); |
6228 |
if (dis) |
6886 |
DIP("movd %s, %s\n", |
6229 |
VG_(printf)("movd %s, %s\n", |
6887 |
nameIReg(4,eregOfRM(modrm)), nameMMXReg(gregOfRM(modrm))); |
6230 |
nameIReg(4,eregOfRM(modrm)), |
|
|
6231 |
nameMMXReg(gregOfRM(modrm))); |
6232 |
} else { |
6888 |
} else { |
6233 |
Int tmpa; |
6889 |
Int tmpa; |
6234 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
6890 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
6235 |
tmpa = LOW24(pair); |
6891 |
tmpa = LOW24(pair); |
6236 |
eip += HI8(pair); |
6892 |
eip += HI8(pair); |
6237 |
uInstr2(cb, MMX2_MemRd, 4, |
6893 |
uInstr2(cb, MMX2_MemRd, 4, |
6238 |
Lit16, |
6894 |
Lit16, |
6239 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6895 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6240 |
TempReg, tmpa); |
6896 |
TempReg, tmpa); |
6241 |
if (dis) |
6897 |
DIP("movd %s, %s\n", dis_buf, nameMMXReg(gregOfRM(modrm))); |
6242 |
VG_(printf)("movd %s, %s\n", |
|
|
6243 |
dis_buf, |
6244 |
nameMMXReg(gregOfRM(modrm))); |
6245 |
} |
6898 |
} |
6246 |
break; |
6899 |
break; |
6247 |
|
6900 |
|
Lines 6253-6275
Link Here
|
6253 |
uInstr1(cb, MMX2, 0, |
6906 |
uInstr1(cb, MMX2, 0, |
6254 |
Lit16, |
6907 |
Lit16, |
6255 |
(((UShort)(opc)) << 8) | ((UShort)modrm) ); |
6908 |
(((UShort)(opc)) << 8) | ((UShort)modrm) ); |
6256 |
if (dis) |
6909 |
DIP("movq %s, %s\n", |
6257 |
VG_(printf)("movq %s, %s\n", |
6910 |
nameMMXReg(eregOfRM(modrm)), nameMMXReg(gregOfRM(modrm))); |
6258 |
nameMMXReg(eregOfRM(modrm)), |
|
|
6259 |
nameMMXReg(gregOfRM(modrm))); |
6260 |
} else { |
6911 |
} else { |
6261 |
Int tmpa; |
6912 |
Int tmpa; |
6262 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
6913 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
6263 |
tmpa = LOW24(pair); |
6914 |
tmpa = LOW24(pair); |
6264 |
eip += HI8(pair); |
6915 |
eip += HI8(pair); |
6265 |
uInstr2(cb, MMX2_MemRd, 8, |
6916 |
uInstr2(cb, MMX2_MemRd, 8, |
6266 |
Lit16, |
6917 |
Lit16, |
6267 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6918 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6268 |
TempReg, tmpa); |
6919 |
TempReg, tmpa); |
6269 |
if (dis) |
6920 |
DIP("movq %s, %s\n", |
6270 |
VG_(printf)("movq %s, %s\n", |
6921 |
dis_buf, nameMMXReg(gregOfRM(modrm))); |
6271 |
dis_buf, |
|
|
6272 |
nameMMXReg(gregOfRM(modrm))); |
6273 |
} |
6922 |
} |
6274 |
break; |
6923 |
break; |
6275 |
|
6924 |
|
Lines 6278-6297
Link Here
|
6278 |
vg_assert(sz == 4); |
6927 |
vg_assert(sz == 4); |
6279 |
modrm = getUChar(eip); |
6928 |
modrm = getUChar(eip); |
6280 |
if (epartIsReg(modrm)) { |
6929 |
if (epartIsReg(modrm)) { |
6281 |
goto decode_failure; |
6930 |
eip++; |
|
|
6931 |
uInstr1(cb, MMX2, 0, |
6932 |
Lit16, |
6933 |
(((UShort)(opc)) << 8) | ((UShort)modrm) ); |
6934 |
DIP("movq %s, %s\n", |
6935 |
nameMMXReg(gregOfRM(modrm)), nameMMXReg(eregOfRM(modrm))); |
6282 |
} else { |
6936 |
} else { |
6283 |
Int tmpa; |
6937 |
Int tmpa; |
6284 |
pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL ); |
6938 |
pair = disAMode ( cb, sorb, eip, dis_buf ); |
6285 |
tmpa = LOW24(pair); |
6939 |
tmpa = LOW24(pair); |
6286 |
eip += HI8(pair); |
6940 |
eip += HI8(pair); |
6287 |
uInstr2(cb, MMX2_MemWr, 8, |
6941 |
uInstr2(cb, MMX2_MemWr, 8, |
6288 |
Lit16, |
6942 |
Lit16, |
6289 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6943 |
(((UShort)(opc)) << 8) | ((UShort)modrm), |
6290 |
TempReg, tmpa); |
6944 |
TempReg, tmpa); |
6291 |
if (dis) |
6945 |
DIP("mov(nt)q %s, %s\n", |
6292 |
VG_(printf)("mov(nt)q %s, %s\n", |
6946 |
nameMMXReg(gregOfRM(modrm)), dis_buf); |
6293 |
nameMMXReg(gregOfRM(modrm)), |
|
|
6294 |
dis_buf); |
6295 |
} |
6947 |
} |
6296 |
break; |
6948 |
break; |
6297 |
|
6949 |
|
Lines 6301-6306
Link Here
|
6301 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "padd", True ); |
6953 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "padd", True ); |
6302 |
break; |
6954 |
break; |
6303 |
|
6955 |
|
|
|
6956 |
case 0xD4: |
6957 |
/* PADDQ (src)mmxreg-or-mem, (dst)mmxreg */ |
6958 |
vg_assert(sz == 4); |
6959 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "paddq", False ); |
6960 |
break; |
6961 |
|
6304 |
case 0xEC: case 0xED: |
6962 |
case 0xEC: case 0xED: |
6305 |
/* PADDSgg (src)mmxreg-or-mem, (dst)mmxreg */ |
6963 |
/* PADDSgg (src)mmxreg-or-mem, (dst)mmxreg */ |
6306 |
vg_assert(sz == 4); |
6964 |
vg_assert(sz == 4); |
Lines 6313-6319
Link Here
|
6313 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "paddus", True ); |
6971 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "paddus", True ); |
6314 |
break; |
6972 |
break; |
6315 |
|
6973 |
|
6316 |
case 0xF8: case 0xF9: case 0xFA: |
6974 |
case 0xF8: case 0xF9: case 0xFA: case 0xFB: |
6317 |
/* PSUBgg (src)mmxreg-or-mem, (dst)mmxreg */ |
6975 |
/* PSUBgg (src)mmxreg-or-mem, (dst)mmxreg */ |
6318 |
vg_assert(sz == 4); |
6976 |
vg_assert(sz == 4); |
6319 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "psub", True ); |
6977 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "psub", True ); |
Lines 6331-6336
Link Here
|
6331 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "psubus", True ); |
6989 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "psubus", True ); |
6332 |
break; |
6990 |
break; |
6333 |
|
6991 |
|
|
|
6992 |
case 0xE4: /* PMULHUW (src)mmxreg-or-mem, (dst)mmxreg */ |
6993 |
vg_assert(sz == 4); |
6994 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmulhuw", False ); |
6995 |
break; |
6996 |
|
6334 |
case 0xE5: /* PMULHW (src)mmxreg-or-mem, (dst)mmxreg */ |
6997 |
case 0xE5: /* PMULHW (src)mmxreg-or-mem, (dst)mmxreg */ |
6335 |
vg_assert(sz == 4); |
6998 |
vg_assert(sz == 4); |
6336 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmulhw", False ); |
6999 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmulhw", False ); |
Lines 6341-6346
Link Here
|
6341 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmullw", False ); |
7004 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmullw", False ); |
6342 |
break; |
7005 |
break; |
6343 |
|
7006 |
|
|
|
7007 |
case 0xF4: /* PMULUDQ (src)mmxreg-or-mem, (dst)mmxreg */ |
7008 |
vg_assert(sz == 4); |
7009 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmuludq", False ); |
7010 |
break; |
7011 |
|
6344 |
case 0xF5: /* PMADDWD (src)mmxreg-or-mem, (dst)mmxreg */ |
7012 |
case 0xF5: /* PMADDWD (src)mmxreg-or-mem, (dst)mmxreg */ |
6345 |
vg_assert(sz == 4); |
7013 |
vg_assert(sz == 4); |
6346 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmaddwd", False ); |
7014 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmaddwd", False ); |
Lines 6423-6428
Link Here
|
6423 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "psra", True ); |
7091 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "psra", True ); |
6424 |
break; |
7092 |
break; |
6425 |
|
7093 |
|
|
|
7094 |
case 0xDA: |
7095 |
/* PMINUB (src)mmxreg-or-mem, (dst)mmxreg */ |
7096 |
vg_assert(sz == 4); |
7097 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pminub", False ); |
7098 |
break; |
7099 |
|
7100 |
case 0xDE: |
7101 |
/* PMAXUB (src)mmxreg-or-mem, (dst)mmxreg */ |
7102 |
vg_assert(sz == 4); |
7103 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmaxub", False ); |
7104 |
break; |
7105 |
|
7106 |
case 0xEA: |
7107 |
/* PMINSW (src)mmxreg-or-mem, (dst)mmxreg */ |
7108 |
vg_assert(sz == 4); |
7109 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pminsw", False ); |
7110 |
break; |
7111 |
|
7112 |
case 0xEE: |
7113 |
/* PMAXSW (src)mmxreg-or-mem, (dst)mmxreg */ |
7114 |
vg_assert(sz == 4); |
7115 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pmaxsw", False ); |
7116 |
break; |
7117 |
|
7118 |
case 0xE0: |
7119 |
/* PAVGB (src)mmxreg-or-mem, (dst)mmxreg */ |
7120 |
vg_assert(sz == 4); |
7121 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pavgb", False ); |
7122 |
break; |
7123 |
|
7124 |
case 0xE3: |
7125 |
/* PAVGW (src)mmxreg-or-mem, (dst)mmxreg */ |
7126 |
vg_assert(sz == 4); |
7127 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "pavgw", False ); |
7128 |
break; |
7129 |
|
7130 |
case 0xF6: |
7131 |
/* PSADBW (src)mmxreg-or-mem, (dst)mmxreg */ |
7132 |
vg_assert(sz == 4); |
7133 |
eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "psadbw", False ); |
7134 |
break; |
7135 |
|
7136 |
case 0xD7: |
7137 |
/* PMOVMSKB (src)mmxreg, (dst)ireg */ |
7138 |
vg_assert(sz == 4); |
7139 |
modrm = getUChar(eip); |
7140 |
vg_assert(epartIsReg(modrm)); |
7141 |
t1 = newTemp(cb); |
7142 |
uInstr3(cb, SSE2g_RegWr, 4, |
7143 |
Lit16, (((UShort)(0x0F)) << 8) | (UShort)(opc), |
7144 |
Lit16, (UShort)modrm, |
7145 |
TempReg, t1 ); |
7146 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
7147 |
DIP("pmovmskb %s, %s\n", |
7148 |
nameMMXReg(eregOfRM(modrm)), nameIReg(4,gregOfRM(modrm))); |
7149 |
eip++; |
7150 |
break; |
7151 |
|
7152 |
case 0xC5: |
7153 |
/* PEXTRW (src)mmxreg, (dst)ireg */ |
7154 |
vg_assert(sz == 4); |
7155 |
t1 = newTemp(cb); |
7156 |
modrm = getUChar(eip); eip++; |
7157 |
abyte = getUChar(eip); eip++; |
7158 |
vg_assert(epartIsReg(modrm)); |
7159 |
uInstr3(cb, SSE2g1_RegWr, 4, |
7160 |
Lit16, (((UShort)(0x0F)) << 8) | (UShort)(opc), |
7161 |
Lit16, (UShort)modrm, |
7162 |
TempReg, t1 ); |
7163 |
uLiteral(cb, abyte); |
7164 |
uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); |
7165 |
DIP("pextrw %s, %d, %s\n", |
7166 |
nameMMXReg(eregOfRM(modrm)), (Int)abyte, |
7167 |
nameIReg(4, gregOfRM(modrm))); |
7168 |
break; |
7169 |
|
7170 |
case 0xC4: |
7171 |
/* PINSRW (src)ireg, (dst)mmxreg */ |
7172 |
vg_assert(sz == 4); |
7173 |
t1 = newTemp(cb); |
7174 |
modrm = getUChar(eip); eip++; |
7175 |
abyte = getUChar(eip); eip++; |
7176 |
vg_assert(epartIsReg(modrm)); |
7177 |
uInstr2(cb, GET, 2, ArchReg, eregOfRM(modrm), TempReg, t1); |
7178 |
uInstr3(cb, SSE2e1_RegRd, 2, |
7179 |
Lit16, (((UShort)(0x0F)) << 8) | (UShort)(opc), |
7180 |
Lit16, (UShort)modrm, |
7181 |
TempReg, t1 ); |
7182 |
uLiteral(cb, abyte); |
7183 |
DIP("pinsrw %s, %d, %s\n", nameIReg(2, eregOfRM(modrm)), |
7184 |
(Int)abyte, nameMMXReg(gregOfRM(modrm))); |
7185 |
break; |
7186 |
|
6426 |
case 0xA1: /* POP %FS */ |
7187 |
case 0xA1: /* POP %FS */ |
6427 |
dis_pop_segreg( cb, R_FS, sz ); break; |
7188 |
dis_pop_segreg( cb, R_FS, sz ); break; |
6428 |
case 0xA9: /* POP %GS */ |
7189 |
case 0xA9: /* POP %GS */ |
Lines 6464-6472
Link Here
|
6464 |
|
7225 |
|
6465 |
/* just because everything else insists the last instruction of |
7226 |
/* just because everything else insists the last instruction of |
6466 |
a BB is a jmp */ |
7227 |
a BB is a jmp */ |
6467 |
uInstr1(cb, JMP, 0, Literal, 0); |
7228 |
jmp_lit(cb, eip); |
6468 |
uCond(cb, CondAlways); |
|
|
6469 |
uLiteral(cb, eip); |
6470 |
*isEnd = True; |
7229 |
*isEnd = True; |
6471 |
break; |
7230 |
break; |
6472 |
return eip; |
7231 |
return eip; |
Lines 6475-6485
Link Here
|
6475 |
|
7234 |
|
6476 |
decode_success: |
7235 |
decode_success: |
6477 |
/* All decode successes end up here. */ |
7236 |
/* All decode successes end up here. */ |
6478 |
if (dis) |
7237 |
DIP("\n"); |
6479 |
VG_(printf)("\n"); |
|
|
6480 |
for (; first_uinstr < cb->used; first_uinstr++) { |
7238 |
for (; first_uinstr < cb->used; first_uinstr++) { |
6481 |
Bool sane = VG_(saneUInstr)(True, True, &cb->instrs[first_uinstr]); |
7239 |
Bool sane = VG_(saneUInstr)(True, True, &cb->instrs[first_uinstr]); |
6482 |
if (dis) |
7240 |
if (VG_(print_codegen)) |
6483 |
VG_(pp_UInstr)(first_uinstr, &cb->instrs[first_uinstr]); |
7241 |
VG_(pp_UInstr)(first_uinstr, &cb->instrs[first_uinstr]); |
6484 |
else if (!sane) |
7242 |
else if (!sane) |
6485 |
VG_(up_UInstr)(-1, &cb->instrs[first_uinstr]); |
7243 |
VG_(up_UInstr)(-1, &cb->instrs[first_uinstr]); |
Lines 6500-6513
Link Here
|
6500 |
Bool block_sane; |
7258 |
Bool block_sane; |
6501 |
Int delta = 0; |
7259 |
Int delta = 0; |
6502 |
|
7260 |
|
6503 |
if (dis) VG_(printf)("Original x86 code to UCode:\n\n"); |
7261 |
DIP("Original x86 code to UCode:\n\n"); |
6504 |
|
7262 |
|
6505 |
/* After every x86 instruction do an INCEIP, except for the final one |
7263 |
/* After every x86 instruction do an INCEIP, except for the final one |
6506 |
* in the basic block. For them we patch in the x86 instruction size |
7264 |
* in the basic block. For them we patch in the x86 instruction size |
6507 |
* into the `extra4b' field of the basic-block-ending JMP. |
7265 |
* into the `extra4b' field of the basic-block-ending JMP. |
6508 |
* |
7266 |
* |
6509 |
* The INCEIPs and JMP.extra4b fields allows a skin to track x86 |
7267 |
* The INCEIPs and JMP.extra4b fields allows a tool to track x86 |
6510 |
* instruction sizes, important for some skins (eg. cache simulation). |
7268 |
* instruction sizes, important for some tools (eg. Cachegrind). |
6511 |
*/ |
7269 |
*/ |
6512 |
if (VG_(clo_single_step)) { |
7270 |
if (VG_(clo_single_step)) { |
6513 |
eip = disInstr ( cb, eip, &isEnd ); |
7271 |
eip = disInstr ( cb, eip, &isEnd ); |
Lines 6516-6528
Link Here
|
6516 |
* already end with a JMP instr. We also need to check for no UCode, |
7274 |
* already end with a JMP instr. We also need to check for no UCode, |
6517 |
* which occurs if the x86 instr was a nop */ |
7275 |
* which occurs if the x86 instr was a nop */ |
6518 |
if (cb->used == 0 || LAST_UINSTR(cb).opcode != JMP) { |
7276 |
if (cb->used == 0 || LAST_UINSTR(cb).opcode != JMP) { |
6519 |
uInstr1(cb, JMP, 0, Literal, 0); |
7277 |
jmp_lit(cb, eip); |
6520 |
uLiteral(cb, eip); |
|
|
6521 |
uCond(cb, CondAlways); |
6522 |
/* Print added JMP */ |
7278 |
/* Print added JMP */ |
6523 |
if (dis) VG_(pp_UInstr)(cb->used-1, &cb->instrs[cb->used-1]); |
7279 |
if (VG_(print_codegen)) |
|
|
7280 |
VG_(pp_UInstr)(cb->used-1, &cb->instrs[cb->used-1]); |
6524 |
} |
7281 |
} |
6525 |
if (dis) VG_(printf)("\n"); |
7282 |
DIP("\n"); |
6526 |
delta = eip - eip0; |
7283 |
delta = eip - eip0; |
6527 |
|
7284 |
|
6528 |
} else { |
7285 |
} else { |
Lines 6536-6555
Link Here
|
6536 |
if (eip - eip0 > 2000 && !isEnd) { |
7293 |
if (eip - eip0 > 2000 && !isEnd) { |
6537 |
if (VG_(clo_verbosity) > 2) |
7294 |
if (VG_(clo_verbosity) > 2) |
6538 |
VG_(message)(Vg_DebugMsg, |
7295 |
VG_(message)(Vg_DebugMsg, |
6539 |
"Warning: splitting giant basic block into pieces"); |
7296 |
"Warning: splitting giant basic block into pieces at %p %(y", |
6540 |
uInstr1(cb, JMP, 0, Literal, 0); |
7297 |
eip, eip); |
6541 |
uLiteral(cb, eip); |
7298 |
jmp_lit(cb, eip); |
6542 |
uCond(cb, CondAlways); |
|
|
6543 |
/* Print added JMP */ |
7299 |
/* Print added JMP */ |
6544 |
if (dis) VG_(pp_UInstr)(cb->used-1, &cb->instrs[cb->used-1]); |
7300 |
if (VG_(print_codegen)) |
|
|
7301 |
VG_(pp_UInstr)(cb->used-1, &cb->instrs[cb->used-1]); |
6545 |
isEnd = True; |
7302 |
isEnd = True; |
6546 |
|
7303 |
|
6547 |
} else if (!isEnd) { |
7304 |
} else if (!isEnd) { |
6548 |
uInstr1(cb, INCEIP, 0, Lit16, delta); |
7305 |
uInstr1(cb, INCEIP, 0, Lit16, delta); |
6549 |
/* Print added INCEIP */ |
7306 |
/* Print added INCEIP */ |
6550 |
if (dis) VG_(pp_UInstr)(cb->used-1, &cb->instrs[cb->used-1]); |
7307 |
if (VG_(print_codegen)) |
|
|
7308 |
VG_(pp_UInstr)(cb->used-1, &cb->instrs[cb->used-1]); |
6551 |
} |
7309 |
} |
6552 |
if (dis) VG_(printf)("\n"); |
7310 |
DIP("\n"); |
6553 |
} |
7311 |
} |
6554 |
} |
7312 |
} |
6555 |
|
7313 |
|
Lines 6565-6571
Link Here
|
6565 |
return eip - eip0; |
7323 |
return eip - eip0; |
6566 |
} |
7324 |
} |
6567 |
|
7325 |
|
6568 |
#undef dis |
7326 |
#undef DIP |
|
|
7327 |
#undef DIS |
6569 |
|
7328 |
|
6570 |
/*--------------------------------------------------------------------*/ |
7329 |
/*--------------------------------------------------------------------*/ |
6571 |
/*--- end vg_to_ucode.c ---*/ |
7330 |
/*--- end vg_to_ucode.c ---*/ |