goto fail;
printf("okay\n");
+ printf("%-40s", "Testing imull -4(%ecx)...");
+ instr[0] = 0xf7; instr[1] = 0x69; instr[2] = 0xfc;
+ regs.eflags = EFLAGS_ALWAYS_SET;
+ regs.eip = (unsigned long)&instr[0];
+ regs.eax = 0x89abcdef;
+ res[0] = 0x12345678;
+ regs.ecx = (unsigned long)(res + 1);
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (regs.eax != 0x89abcdef * 0x12345678) ||
+ (regs.edx != (uint64_t)((int64_t)(int32_t)0x89abcdef *
+ 0x12345678) >> 32) ||
+ ((regs.eflags & (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF |
+ X86_EFLAGS_OF)) !=
+ (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF | X86_EFLAGS_OF)) ||
+ (regs.eip != (unsigned long)&instr[3]) )
+ goto fail;
+ printf("okay\n");
+
+ printf("%-40s", "Testing imul $3,-4(%edx),%ecx...");
+ instr[0] = 0x6b; instr[1] = 0x4a; instr[2] = 0xfc; instr[3] = 0x03;
+ regs.eflags = EFLAGS_ALWAYS_SET;
+ regs.eip = (unsigned long)&instr[0];
+ regs.ecx = 0x12345678;
+ res[0] = 0x89abcdef;
+ regs.edx = (unsigned long)(res + 1);
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (regs.ecx != 0x89abcdef * 3) ||
+ ((regs.eflags & (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF |
+ X86_EFLAGS_OF)) !=
+ (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF | X86_EFLAGS_OF)) ||
+ (regs.eip != (unsigned long)&instr[4]) )
+ goto fail;
+ printf("okay\n");
+
#ifndef __x86_64__
printf("%-40s", "Testing daa/das (all inputs)...");
/* Bits 0-7: AL; Bit 8: EFLAGS.AF; Bit 9: EFLAGS.CF; Bit 10: DAA vs. DAS. */
}
break;
case 5: /* imul */
+ dst.val = _regs.r(ax);
imul:
_regs.eflags &= ~(X86_EFLAGS_OF | X86_EFLAGS_CF);
switch ( dst.bytes )
{
case 1:
- dst.val = (int8_t)src.val * (int8_t)_regs.al;
+ dst.val = (int8_t)src.val * (int8_t)dst.val;
if ( (int8_t)dst.val != (int16_t)dst.val )
_regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF;
ASSERT(b > 0x6b);
break;
case 2:
dst.val = ((uint32_t)(int16_t)src.val *
- (uint32_t)(int16_t)_regs.ax);
+ (uint32_t)(int16_t)dst.val);
if ( (int16_t)dst.val != (int32_t)dst.val )
_regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF;
if ( b > 0x6b )
#ifdef __x86_64__
case 4:
dst.val = ((uint64_t)(int32_t)src.val *
- (uint64_t)(int32_t)_regs.eax);
+ (uint64_t)(int32_t)dst.val);
if ( (int32_t)dst.val != dst.val )
_regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF;
if ( b > 0x6b )
#endif
default:
u[0] = src.val;
- u[1] = _regs.r(ax);
+ u[1] = dst.val;
if ( imul_dbl(u) )
_regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF;
if ( b > 0x6b )