mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-13 22:46:59 +00:00
Bug 415757 - vex x86->IR: unhandled instruction bytes: 0x66 0xF 0xCE (bswapw).
Implement bswapw, even though the instruction does not officially exist. Patch from Alex Henrie (alexhenrie24@gmail.com).
This commit is contained in:
@@ -14676,15 +14676,21 @@ DisResult disInstr_X86_WRK (
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF: /* BSWAP %edi */
|
||||
/* AFAICS from the Intel docs, this only exists at size 4. */
|
||||
if (sz != 4) goto decode_failure;
|
||||
|
||||
t1 = newTemp(Ity_I32);
|
||||
assign( t1, getIReg(4, opc-0xC8) );
|
||||
t2 = math_BSWAP(t1, Ity_I32);
|
||||
|
||||
putIReg(4, opc-0xC8, mkexpr(t2));
|
||||
DIP("bswapl %s\n", nameIReg(4, opc-0xC8));
|
||||
/* According to the Intel and AMD docs, 16-bit BSWAP is undefined.
|
||||
* However, the result of a 16-bit BSWAP is always zero in every Intel
|
||||
* and AMD CPU, and some software depends on this behavior. */
|
||||
if (sz == 2) {
|
||||
putIReg(2, opc-0xC8, mkU16(0));
|
||||
DIP("bswapw %s\n", nameIReg(2, opc-0xC8));
|
||||
} else if (sz == 4) {
|
||||
t1 = newTemp(Ity_I32);
|
||||
assign( t1, getIReg(4, opc-0xC8) );
|
||||
t2 = math_BSWAP(t1, Ity_I32);
|
||||
putIReg(4, opc-0xC8, mkexpr(t2));
|
||||
DIP("bswapl %s\n", nameIReg(4, opc-0xC8));
|
||||
} else {
|
||||
goto decode_failure;
|
||||
}
|
||||
break;
|
||||
|
||||
/* =-=-=-=-=-=-=-=-=- BT/BTS/BTR/BTC =-=-=-=-=-=-= */
|
||||
|
||||
@@ -35,6 +35,7 @@ EXTRA_DIST = \
|
||||
aad_aam.stdout.exp aad_aam.stderr.exp aad_aam.vgtest \
|
||||
badseg.stderr.exp badseg.stdout.exp badseg.stdout.exp-solaris \
|
||||
badseg.vgtest \
|
||||
bswapw.stderr.exp bswapw.stdout.exp bswapw.vgtest \
|
||||
bt_everything.stderr.exp bt_everything.stdout.exp bt_everything.vgtest \
|
||||
bt_literal.stderr.exp bt_literal.stdout.exp bt_literal.vgtest \
|
||||
bug125959-x86.stderr.exp bug125959-x86.stdout.exp bug125959-x86.vgtest \
|
||||
@@ -85,6 +86,7 @@ check_PROGRAMS = \
|
||||
aad_aam \
|
||||
allexec \
|
||||
badseg \
|
||||
bswapw \
|
||||
bt_everything \
|
||||
bt_literal \
|
||||
bug125959-x86 \
|
||||
|
||||
31
none/tests/x86/bswapw.c
Normal file
31
none/tests/x86/bswapw.c
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned int UInt;
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
|
||||
#define GO16(REG,VALUE) \
|
||||
value = VALUE; \
|
||||
__asm__ __volatile__( \
|
||||
"pushl %%" REG " \n\t" \
|
||||
"movl 0(" "%0" "), %%" REG " \n\t" \
|
||||
".byte 0x66 \n\t" "bswapl %%" REG "\n\t" \
|
||||
"movl %%" REG ", 0(" "%0" ") \n\t" \
|
||||
"popl %%" REG "\n" \
|
||||
: : "r" (&value) : REG, "memory", "cc" \
|
||||
); \
|
||||
printf("0x%08x\n", value)
|
||||
|
||||
UInt value;
|
||||
GO16("eax", 0x12345678);
|
||||
GO16("ebx", 0x23456789);
|
||||
GO16("ecx", 0x3456789a);
|
||||
GO16("edx", 0x456789ab);
|
||||
GO16("esi", 0x56789abc);
|
||||
GO16("edi", 0x6789abcd);
|
||||
//GO16("ebp", 0x789abcde); // The compiler complains
|
||||
|
||||
return 0;
|
||||
}
|
||||
0
none/tests/x86/bswapw.stderr.exp
Normal file
0
none/tests/x86/bswapw.stderr.exp
Normal file
6
none/tests/x86/bswapw.stdout.exp
Normal file
6
none/tests/x86/bswapw.stdout.exp
Normal file
@@ -0,0 +1,6 @@
|
||||
0x12340000
|
||||
0x23450000
|
||||
0x34560000
|
||||
0x45670000
|
||||
0x56780000
|
||||
0x67890000
|
||||
2
none/tests/x86/bswapw.vgtest
Normal file
2
none/tests/x86/bswapw.vgtest
Normal file
@@ -0,0 +1,2 @@
|
||||
prog: bswapw
|
||||
vgopts: -q
|
||||
Reference in New Issue
Block a user