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 =-=-=-=-=-=-= */
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 \
aad_aam \
allexec \
badseg \
+ bswapw \
bt_everything \
bt_literal \
bug125959-x86 \
--- /dev/null
+
+#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;
+}