Moved the recompiler timings to cpu/ because they are common to both recompilers and fixed a bug in the common timings header file.
This commit is contained in:
@@ -1,421 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
#define CYCLES(c) (int *)c
|
||||
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
|
||||
static int *opcode_timings[256] =
|
||||
{
|
||||
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
|
||||
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
|
||||
/*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
|
||||
/*30*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2),
|
||||
|
||||
/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
|
||||
/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17),
|
||||
/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
|
||||
|
||||
/*80*/ &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm, &timing_rm, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6),
|
||||
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
|
||||
/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6),
|
||||
/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0),
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_mod3[256] =
|
||||
{
|
||||
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
|
||||
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
|
||||
/*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
|
||||
/*30*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2),
|
||||
|
||||
/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
|
||||
/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17),
|
||||
/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
|
||||
|
||||
/*80*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1),
|
||||
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
|
||||
/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6),
|
||||
/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0),
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_0f[256] =
|
||||
{
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, &timing_rm,
|
||||
/*70*/ NULL, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rm, &timing_rm,
|
||||
|
||||
/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
|
||||
/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3),
|
||||
/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30),
|
||||
/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
|
||||
};
|
||||
static int *opcode_timings_0f_mod3[256] =
|
||||
{
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, &timing_rr,
|
||||
/*70*/ NULL, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rr, &timing_rr,
|
||||
|
||||
/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
|
||||
/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3),
|
||||
/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30),
|
||||
/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL,
|
||||
};
|
||||
|
||||
static int *opcode_timings_shift[8] =
|
||||
{
|
||||
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
|
||||
};
|
||||
static int *opcode_timings_shift_mod3[8] =
|
||||
{
|
||||
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
|
||||
};
|
||||
|
||||
static int *opcode_timings_f6[8] =
|
||||
{
|
||||
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
};
|
||||
static int *opcode_timings_f6_mod3[8] =
|
||||
{
|
||||
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
};
|
||||
static int *opcode_timings_f7[8] =
|
||||
{
|
||||
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
};
|
||||
static int *opcode_timings_f7_mod3[8] =
|
||||
{
|
||||
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
};
|
||||
static int *opcode_timings_ff[8] =
|
||||
{
|
||||
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
|
||||
};
|
||||
static int *opcode_timings_ff_mod3[8] =
|
||||
{
|
||||
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_d8[8] =
|
||||
{
|
||||
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
};
|
||||
static int *opcode_timings_d8_mod3[8] =
|
||||
{
|
||||
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
|
||||
CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
};
|
||||
|
||||
static int *opcode_timings_d9[8] =
|
||||
{
|
||||
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
|
||||
CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
|
||||
};
|
||||
static int *opcode_timings_d9_mod3[64] =
|
||||
{
|
||||
/*FLD*/
|
||||
CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4),
|
||||
/*FXCH*/
|
||||
CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4),
|
||||
/*FNOP*/
|
||||
CYCLES(3), NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*FSTP*/
|
||||
CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3),
|
||||
/* opFCHS opFABS opFTST opFXAM*/
|
||||
CYCLES(6), CYCLES(3), NULL, NULL, CYCLES(4), CYCLES(8), NULL, NULL,
|
||||
/* opFLD1 opFLDL2T opFLDL2E opFLDPI opFLDEG2 opFLDLN2 opFLDZ*/
|
||||
CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(4), NULL,
|
||||
/* opF2XM1 opFYL2X opFPTAN opFPATAN opFDECSTP opFINCSTP,*/
|
||||
CYCLES(140), CYCLES(196), CYCLES(200), CYCLES(218), NULL, NULL, CYCLES(3), CYCLES(3),
|
||||
/* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
CYCLES(70), NULL, CYCLES(83), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(257), CYCLES(257)
|
||||
};
|
||||
|
||||
static int *opcode_timings_da[8] =
|
||||
{
|
||||
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
};
|
||||
static int *opcode_timings_da_mod3[8] =
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
|
||||
};
|
||||
|
||||
|
||||
static int *opcode_timings_db[8] =
|
||||
{
|
||||
/* FLDil FSTil FSTPil FLDe FSTPe*/
|
||||
CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6)
|
||||
};
|
||||
static int *opcode_timings_db_mod3[64] =
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* opFNOP opFCLEX opFINIT opFNOP opFNOP*/
|
||||
NULL, CYCLES(3), CYCLES(7), CYCLES(17), CYCLES(3), CYCLES(3), NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
static int *opcode_timings_dc[8] =
|
||||
{
|
||||
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
|
||||
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
};
|
||||
static int *opcode_timings_dc_mod3[8] =
|
||||
{
|
||||
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
};
|
||||
|
||||
static int *opcode_timings_dd[8] =
|
||||
{
|
||||
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
|
||||
CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3)
|
||||
};
|
||||
static int *opcode_timings_dd_mod3[8] =
|
||||
{
|
||||
/* FFFREE FST FSTP FUCOM FUCOMP*/
|
||||
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_de[8] =
|
||||
{
|
||||
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
};
|
||||
static int *opcode_timings_de_mod3[8] =
|
||||
{
|
||||
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
|
||||
CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
};
|
||||
|
||||
static int *opcode_timings_df[8] =
|
||||
{
|
||||
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
|
||||
CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28)
|
||||
};
|
||||
static int *opcode_timings_df_mod3[8] =
|
||||
{
|
||||
/* FFREE FST FSTP FUCOM FUCOMP*/
|
||||
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_8x[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static inline int COUNT(int *c, int op_32)
|
||||
{
|
||||
if ((uintptr_t)c <= 10000)
|
||||
return (int)(uintptr_t)c;
|
||||
if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff))
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
return ((uintptr_t)c >> 8) & 0xff;
|
||||
return (uintptr_t)c & 0xff;
|
||||
}
|
||||
return *c;
|
||||
}
|
||||
|
||||
void codegen_timing_486_block_start()
|
||||
{
|
||||
regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_486_start()
|
||||
{
|
||||
timing_count = 0;
|
||||
last_prefix = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
{
|
||||
timing_count += COUNT(opcode_timings[prefix], 0);
|
||||
last_prefix = prefix;
|
||||
}
|
||||
|
||||
void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
|
||||
{
|
||||
int **timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
|
||||
void codegen_timing_486_block_end()
|
||||
{
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_486 =
|
||||
{
|
||||
codegen_timing_486_start,
|
||||
codegen_timing_486_prefix,
|
||||
codegen_timing_486_opcode,
|
||||
codegen_timing_486_block_start,
|
||||
codegen_timing_486_block_end,
|
||||
NULL
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,850 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
uint64_t opcode_deps[256] =
|
||||
{
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
/* OR OR OR OR*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* OR OR PUSH CS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0,
|
||||
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
/* SBB SBB SBB SBB*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* AND AND DAA*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
/* SUB SUB SUB SUB*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* SUB SUB DAS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* XOR XOR AAA*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
/* CMP CMP CMP CMP*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM,
|
||||
/* CMP CMP AAS*/
|
||||
SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* INC ESP INC EBP INC ESI INC EDI*/
|
||||
SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* DEC EAX DEC ECX DEC EDX DEC EBX*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* DEC ESP DEC EBP DEC ESI DEC EDI*/
|
||||
SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI,
|
||||
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP,
|
||||
/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
|
||||
SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP,
|
||||
/* POP EAX POP ECX POP EDX POP EBX*/
|
||||
DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP,
|
||||
/* POP ESP POP EBP POP ESI POP EDI*/
|
||||
DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP,
|
||||
|
||||
/* PUSHA POPA BOUND ARPL*/
|
||||
/*60*/ IMPL_ESP, IMPL_ESP, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
/* PUSH imm IMUL PUSH imm IMUL*/
|
||||
IMPL_ESP, DSTDEP_REG | MODRM, IMPL_ESP, DSTDEP_REG | MODRM,
|
||||
/* INSB INSW OUTSB OUTSW*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* Jxx*/
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
/* TEST TEST XCHG XCHG*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* MOV MOV MOV MOV*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_REG | MODRM,
|
||||
/* MOV from seg LEA MOV to seg POP*/
|
||||
MODRM, DSTDEP_REG | MODRM, MODRM, IMPL_ESP | MODRM,
|
||||
|
||||
/* NOP XCHG XCHG XCHG*/
|
||||
/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* XCHG XCHG XCHG XCHG*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* CBW CWD CALL far WAIT*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0,
|
||||
/* PUSHF POPF SAHF LAHF*/
|
||||
IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX,
|
||||
|
||||
/* MOV MOV MOV MOV*/
|
||||
/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX,
|
||||
/* MOVSB MOVSW CMPSB CMPSW*/
|
||||
0, 0, 0, 0,
|
||||
/* TEST TEST STOSB STOSW*/
|
||||
SRCDEP_EAX, SRCDEP_EAX, 0, 0,
|
||||
/* LODSB LODSW SCASB SCASW*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* MOV*/
|
||||
/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI,
|
||||
|
||||
/* RET imm RET*/
|
||||
/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP,
|
||||
/* LES LDS MOV MOV*/
|
||||
DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM, MODRM,
|
||||
/* ENTER LEAVE RETF RETF*/
|
||||
IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP,
|
||||
/* INT3 INT INTO IRET*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
|
||||
/*d0*/ 0, 0, 0, 0,
|
||||
/* AAM AAD SETALC XLAT*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* LOOPNE LOOPE LOOP JCXZ*/
|
||||
/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX,
|
||||
/* CALL JMP JMP JMP*/
|
||||
IMPL_ESP, 0, 0, 0,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX,
|
||||
|
||||
/* REPNE REPE*/
|
||||
/*f0*/ 0, 0, 0, 0,
|
||||
/* HLT CMC*/
|
||||
0, 0, 0, 0,
|
||||
/* CLC STC CLI STI*/
|
||||
0, 0, 0, 0,
|
||||
/* CLD STD INCDEC*/
|
||||
0, 0, MODRM, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_mod3[256] =
|
||||
{
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
/* OR OR OR OR*/
|
||||
SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* OR OR PUSH CS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0,
|
||||
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
/* SBB SBB SBB SBB*/
|
||||
SRCDEP_REG |SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* AND AND DAA*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
/* SUB SUB SUB SUB*/
|
||||
SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* SUB SUB DAS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* XOR XOR AAA*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
/* CMP CMP CMP CMP*/
|
||||
SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* CMP CMP AAS*/
|
||||
SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* INC ESP INC EBP INC ESI INC EDI*/
|
||||
SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* DEC EAX DEC ECX DEC EDX DEC EBX*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* DEC ESP DEC EBP DEC ESI DEC EDI*/
|
||||
SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI,
|
||||
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP,
|
||||
/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
|
||||
SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP,
|
||||
/* POP EAX POP ECX POP EDX POP EBX*/
|
||||
DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP,
|
||||
/* POP ESP POP EBP POP ESI POP EDI*/
|
||||
DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP,
|
||||
|
||||
/* PUSHA POPA BOUND ARPL*/
|
||||
/*60*/ IMPL_ESP, IMPL_ESP, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
/* PUSH imm IMUL PUSH imm IMUL*/
|
||||
IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* INSB INSW OUTSB OUTSW*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* Jxx*/
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
/* TEST TEST XCHG XCHG*/
|
||||
SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
/* MOV MOV MOV MOV*/
|
||||
SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM,
|
||||
/* MOV from seg LEA MOV to seg POP*/
|
||||
DSTDEP_RM | MODRM, DSTDEP_REG | MODRM, SRCDEP_RM | MODRM, IMPL_ESP | DSTDEP_RM | MODRM,
|
||||
|
||||
/* NOP XCHG XCHG XCHG*/
|
||||
/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* XCHG XCHG XCHG XCHG*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* CBW CWD CALL far WAIT*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0,
|
||||
/* PUSHF POPF SAHF LAHF*/
|
||||
IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX,
|
||||
|
||||
/* MOV MOV MOV MOV*/
|
||||
/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX,
|
||||
/* MOVSB MOVSW CMPSB CMPSW*/
|
||||
0, 0, 0, 0,
|
||||
/* TEST TEST STOSB STOSW*/
|
||||
SRCDEP_EAX, SRCDEP_EAX, 0, 0,
|
||||
/* LODSB LODSW SCASB SCASW*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* MOV*/
|
||||
/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI,
|
||||
|
||||
/* RET imm RET*/
|
||||
/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP,
|
||||
/* LES LDS MOV MOV*/
|
||||
DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_RM | MODRM, DSTDEP_RM | MODRM,
|
||||
/* ENTER LEAVE RETF RETF*/
|
||||
IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP,
|
||||
/* INT3 INT INTO IRET*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
|
||||
/*d0*/ 0, 0, 0, 0,
|
||||
/* AAM AAD SETALC XLAT*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* LOOPNE LOOPE LOOP JCXZ*/
|
||||
/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX,
|
||||
/* CALL JMP JMP JMP*/
|
||||
IMPL_ESP, 0, 0, 0,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX,
|
||||
|
||||
/* REPNE REPE*/
|
||||
/*f0*/ 0, 0, 0, 0,
|
||||
/* HLT CMC*/
|
||||
0, 0, 0, 0,
|
||||
/* CLC STC CLI STI*/
|
||||
0, 0, 0, 0,
|
||||
/* CLD STD INCDEC*/
|
||||
0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_0f[256] =
|
||||
{
|
||||
/*00*/ MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, MODRM, 0, MODRM,
|
||||
|
||||
/*10*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*20*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*30*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*50*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*60*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, 0, MODRM, MODRM,
|
||||
|
||||
/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, MODRM, MODRM,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*90*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
|
||||
/*a0*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*b0*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
|
||||
/*c0*/ MODRM, MODRM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
};
|
||||
uint64_t opcode_deps_0f_mod3[256] =
|
||||
{
|
||||
/*00*/ MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, MODRM, 0, MODRM,
|
||||
|
||||
/*10*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*20*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*30*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*50*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*60*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, 0, MODRM, MODRM,
|
||||
|
||||
/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, MODRM, MODRM,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*90*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
|
||||
/*a0*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*b0*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
|
||||
/*c0*/ MODRM, MODRM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_0f0f[256] =
|
||||
{
|
||||
/*00*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, MODRM, 0, 0,
|
||||
|
||||
/*10*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, MODRM, 0, 0,
|
||||
|
||||
/*20*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*30*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*50*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*60*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*70*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*90*/ MODRM, 0, 0, 0,
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
0, 0, MODRM, 0,
|
||||
0, 0, MODRM, 0,
|
||||
|
||||
/*a0*/ MODRM, 0, 0, 0,
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*b0*/ MODRM, 0, 0, 0,
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, MODRM,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*d0*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*e0*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*f0*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
};
|
||||
uint64_t opcode_deps_0f0f_mod3[256] =
|
||||
{
|
||||
/*00*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, MODRM, 0, 0,
|
||||
|
||||
/*10*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, MODRM, 0, 0,
|
||||
|
||||
/*20*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*30*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*50*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*60*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*70*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*90*/ MODRM, 0, 0, 0,
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
0, 0, MODRM, 0,
|
||||
0, 0, MODRM, 0,
|
||||
|
||||
/*a0*/ MODRM, 0, 0, 0,
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*b0*/ MODRM, 0, 0, 0,
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, MODRM,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*d0*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*e0*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*f0*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_shift[8] =
|
||||
{
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
};
|
||||
uint64_t opcode_deps_shift_mod3[8] =
|
||||
{
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_shift_cl[8] =
|
||||
{
|
||||
MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX,
|
||||
MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX,
|
||||
};
|
||||
uint64_t opcode_deps_shift_cl_mod3[8] =
|
||||
{
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_f6[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_f6_mod3[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_f7[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_f7_mod3[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_ff[8] =
|
||||
{
|
||||
/* INC DEC CALL CALL far*/
|
||||
MODRM, MODRM, MODRM | IMPL_ESP, MODRM,
|
||||
/* JMP JMP far PUSH*/
|
||||
MODRM, MODRM, MODRM | IMPL_ESP, 0
|
||||
};
|
||||
uint64_t opcode_deps_ff_mod3[8] =
|
||||
{
|
||||
/* INC DEC CALL CALL far*/
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM | IMPL_ESP, MODRM,
|
||||
/* JMP JMP far PUSH*/
|
||||
SRCDEP_RM | MODRM, MODRM, SRCDEP_RM | MODRM | IMPL_ESP, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_d8[8] =
|
||||
{
|
||||
/* FADDs FMULs FCOMs FCOMPs*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_POP | FPU_READ_ST0 | MODRM,
|
||||
/* FSUBs FSUBRs FDIVs FDIVRs*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_d8_mod3[8] =
|
||||
{
|
||||
/* FADD FMUL FCOM FCOMP*/
|
||||
FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG, FPU_POP | FPU_READ_ST0 | FPU_READ_STREG,
|
||||
/* FSUB FSUBR FDIV FDIVR*/
|
||||
FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_d9[8] =
|
||||
{
|
||||
/* FLDs FSTs FSTPs*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM,
|
||||
/* FLDENV FLDCW FSTENV FSTCW*/
|
||||
MODRM, MODRM, MODRM, MODRM
|
||||
};
|
||||
uint64_t opcode_deps_d9_mod3[64] =
|
||||
{
|
||||
/*FLD*/
|
||||
FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG,
|
||||
FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG,
|
||||
/*FXCH*/
|
||||
FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH,
|
||||
FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH,
|
||||
/*FNOP*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*FSTP*/
|
||||
FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP,
|
||||
FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP,
|
||||
/* opFCHS opFABS*/
|
||||
0, 0, 0, 0,
|
||||
/* opFTST opFXAM*/
|
||||
0, 0, 0, 0,
|
||||
/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/
|
||||
FPU_PUSH, FPU_PUSH, FPU_PUSH, FPU_PUSH,
|
||||
/* opFLDEG2 opFLDLN2 opFLDZ*/
|
||||
FPU_PUSH, FPU_PUSH, FPU_PUSH, 0,
|
||||
/* opF2XM1 opFYL2X opFPTAN opFPATAN*/
|
||||
0, 0, 0, 0,
|
||||
/* opFDECSTP opFINCSTP,*/
|
||||
0, 0, 0, 0,
|
||||
/* opFPREM opFSQRT opFSINCOS*/
|
||||
0, 0, 0, 0,
|
||||
/* opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_da[8] =
|
||||
{
|
||||
/* FIADDl FIMULl FICOMl FICOMPl*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FISUBl FISUBRl FIDIVl FIDIVRl*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_da_mod3[8] =
|
||||
{
|
||||
0, 0, 0, 0,
|
||||
/* FCOMPP*/
|
||||
0, FPU_POP2, 0, 0
|
||||
};
|
||||
|
||||
|
||||
uint64_t opcode_deps_db[8] =
|
||||
{
|
||||
/* FLDil FSTil FSTPil*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FLDe FSTPe*/
|
||||
0, FPU_PUSH | MODRM, 0, FPU_READ_ST0 | FPU_POP | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_db_mod3[64] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/* opFNOP opFCLEX opFINIT*/
|
||||
0, 0, 0, 0,
|
||||
/* opFNOP opFNOP*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_dc[8] =
|
||||
{
|
||||
/* FADDd FMULd FCOMd FCOMPd*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FSUBd FSUBRd FDIVd FDIVRd*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_dc_mod3[8] =
|
||||
{
|
||||
/* opFADDr opFMULr*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, 0, 0,
|
||||
/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_dd[8] =
|
||||
{
|
||||
/* FLDd FSTd FSTPd*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FRSTOR FSAVE FSTSW*/
|
||||
MODRM, 0, MODRM, MODRM
|
||||
};
|
||||
uint64_t opcode_deps_dd_mod3[8] =
|
||||
{
|
||||
/* FFFREE FST FSTP*/
|
||||
0, 0, FPU_READ_ST0 | FPU_WRITE_STREG, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP,
|
||||
/* FUCOM FUCOMP*/
|
||||
FPU_READ_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG | FPU_POP, 0, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_de[8] =
|
||||
{
|
||||
/* FIADDw FIMULw FICOMw FICOMPw*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_de_mod3[8] =
|
||||
{
|
||||
/* FADDP FMULP FCOMPP*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, 0, FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2,
|
||||
/* FSUBP FSUBRP FDIVP FDIVRP*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_df[8] =
|
||||
{
|
||||
/* FILDiw FISTiw FISTPiw*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FILDiq FBSTP FISTPiq*/
|
||||
0, FPU_PUSH | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, FPU_READ_ST0 | FPU_POP | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_df_mod3[8] =
|
||||
{
|
||||
0, 0, 0, 0,
|
||||
/* FSTSW AX*/
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_81[8] =
|
||||
{
|
||||
MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632,
|
||||
MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632
|
||||
};
|
||||
uint64_t opcode_deps_81_mod3[8] =
|
||||
{
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632
|
||||
};
|
||||
uint64_t opcode_deps_8x[8] =
|
||||
{
|
||||
MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8,
|
||||
MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8
|
||||
};
|
||||
uint64_t opcode_deps_8x_mod3[8] =
|
||||
{
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8
|
||||
};
|
||||
@@ -1,232 +0,0 @@
|
||||
#include "codegen_ops.h"
|
||||
|
||||
/*Instruction has input dependency on register in REG field*/
|
||||
#define SRCDEP_REG (1ull << 0)
|
||||
/*Instruction has input dependency on register in R/M field*/
|
||||
#define SRCDEP_RM (1ull << 1)
|
||||
/*Instruction modifies register in REG field*/
|
||||
#define DSTDEP_REG (1ull << 2)
|
||||
/*Instruction modifies register in R/M field*/
|
||||
#define DSTDEP_RM (1ull << 3)
|
||||
|
||||
#define SRCDEP_SHIFT 4
|
||||
#define DSTDEP_SHIFT 12
|
||||
|
||||
/*Instruction has input dependency on given register*/
|
||||
#define SRCDEP_EAX (1ull << 4)
|
||||
#define SRCDEP_ECX (1ull << 5)
|
||||
#define SRCDEP_EDX (1ull << 6)
|
||||
#define SRCDEP_EBX (1ull << 7)
|
||||
#define SRCDEP_ESP (1ull << 8)
|
||||
#define SRCDEP_EBP (1ull << 9)
|
||||
#define SRCDEP_ESI (1ull << 10)
|
||||
#define SRCDEP_EDI (1ull << 11)
|
||||
|
||||
/*Instruction modifies given register*/
|
||||
#define DSTDEP_EAX (1ull << 12)
|
||||
#define DSTDEP_ECX (1ull << 13)
|
||||
#define DSTDEP_EDX (1ull << 14)
|
||||
#define DSTDEP_EBX (1ull << 15)
|
||||
#define DSTDEP_ESP (1ull << 16)
|
||||
#define DSTDEP_EBP (1ull << 17)
|
||||
#define DSTDEP_ESI (1ull << 18)
|
||||
#define DSTDEP_EDI (1ull << 19)
|
||||
|
||||
/*Instruction has ModR/M byte*/
|
||||
#define MODRM (1ull << 20)
|
||||
/*Instruction implicitly uses ESP*/
|
||||
#define IMPL_ESP (1ull << 21)
|
||||
|
||||
/*Instruction is MMX shift or pack/unpack instruction*/
|
||||
#define MMX_SHIFTPACK (1ull << 22)
|
||||
/*Instruction is MMX multiply instruction*/
|
||||
#define MMX_MULTIPLY (1ull << 23)
|
||||
|
||||
/*Instruction pops the FPU stack*/
|
||||
#define FPU_POP (1ull << 24)
|
||||
/*Instruction pops the FPU stack twice*/
|
||||
#define FPU_POP2 (1ull << 25)
|
||||
/*Instruction pushes onto the FPU stack*/
|
||||
#define FPU_PUSH (1ull << 26)
|
||||
|
||||
/*Instruction writes to ST(0)*/
|
||||
#define FPU_WRITE_ST0 (1ull << 27)
|
||||
/*Instruction reads from ST(0)*/
|
||||
#define FPU_READ_ST0 (1ull << 28)
|
||||
/*Instruction reads from and writes to ST(0)*/
|
||||
#define FPU_RW_ST0 (3ull << 27)
|
||||
|
||||
/*Instruction reads from ST(1)*/
|
||||
#define FPU_READ_ST1 (1ull << 29)
|
||||
/*Instruction writes to ST(1)*/
|
||||
#define FPU_WRITE_ST1 (1ull << 30)
|
||||
/*Instruction reads from and writes to ST(1)*/
|
||||
#define FPU_RW_ST1 (3ull << 29)
|
||||
|
||||
/*Instruction reads from ST(reg)*/
|
||||
#define FPU_READ_STREG (1ull << 31)
|
||||
/*Instruction writes to ST(reg)*/
|
||||
#define FPU_WRITE_STREG (1ull << 32)
|
||||
/*Instruction reads from and writes to ST(reg)*/
|
||||
#define FPU_RW_STREG (3ull << 30)
|
||||
|
||||
#define FPU_FXCH (1ull << 33)
|
||||
|
||||
|
||||
#define HAS_IMM8 (1ull << 34)
|
||||
#define HAS_IMM1632 (1ull << 35)
|
||||
|
||||
|
||||
#define REGMASK_IMPL_ESP (1 << 8)
|
||||
#define REGMASK_SHIFTPACK (1 << 9)
|
||||
#define REGMASK_MULTIPLY (1 << 9)
|
||||
|
||||
|
||||
extern uint64_t opcode_deps[256];
|
||||
extern uint64_t opcode_deps_mod3[256];
|
||||
extern uint64_t opcode_deps_0f[256];
|
||||
extern uint64_t opcode_deps_0f_mod3[256];
|
||||
extern uint64_t opcode_deps_0f0f[256];
|
||||
extern uint64_t opcode_deps_0f0f_mod3[256];
|
||||
extern uint64_t opcode_deps_shift[8];
|
||||
extern uint64_t opcode_deps_shift_mod3[8];
|
||||
extern uint64_t opcode_deps_shift_cl[8];
|
||||
extern uint64_t opcode_deps_shift_cl_mod3[8];
|
||||
extern uint64_t opcode_deps_f6[8];
|
||||
extern uint64_t opcode_deps_f6_mod3[8];
|
||||
extern uint64_t opcode_deps_f7[8];
|
||||
extern uint64_t opcode_deps_f7_mod3[8];
|
||||
extern uint64_t opcode_deps_ff[8];
|
||||
extern uint64_t opcode_deps_ff_mod3[8];
|
||||
extern uint64_t opcode_deps_d8[8];
|
||||
extern uint64_t opcode_deps_d8_mod3[8];
|
||||
extern uint64_t opcode_deps_d9[8];
|
||||
extern uint64_t opcode_deps_d9_mod3[64];
|
||||
extern uint64_t opcode_deps_da[8];
|
||||
extern uint64_t opcode_deps_da_mod3[8];
|
||||
extern uint64_t opcode_deps_db[8];
|
||||
extern uint64_t opcode_deps_db_mod3[64];
|
||||
extern uint64_t opcode_deps_dc[8];
|
||||
extern uint64_t opcode_deps_dc_mod3[8];
|
||||
extern uint64_t opcode_deps_dd[8];
|
||||
extern uint64_t opcode_deps_dd_mod3[8];
|
||||
extern uint64_t opcode_deps_de[8];
|
||||
extern uint64_t opcode_deps_de_mod3[8];
|
||||
extern uint64_t opcode_deps_df[8];
|
||||
extern uint64_t opcode_deps_df_mod3[8];
|
||||
extern uint64_t opcode_deps_81[8];
|
||||
extern uint64_t opcode_deps_81_mod3[8];
|
||||
extern uint64_t opcode_deps_8x[8];
|
||||
extern uint64_t opcode_deps_8x_mod3[8];
|
||||
|
||||
|
||||
|
||||
static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
uint32_t addr_regmask = 0;
|
||||
|
||||
if (data & MODRM)
|
||||
{
|
||||
uint8_t modrm = fetchdat & 0xff;
|
||||
|
||||
if ((modrm & 0xc0) != 0xc0)
|
||||
{
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
if ((modrm & 0x7) == 4)
|
||||
{
|
||||
uint8_t sib = (fetchdat >> 8) & 0xff;
|
||||
|
||||
if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5)
|
||||
{
|
||||
addr_regmask = 1 << (sib & 7);
|
||||
if ((sib & 0x38) != 0x20)
|
||||
addr_regmask |= 1 << ((sib >> 3) & 7);
|
||||
}
|
||||
}
|
||||
else if ((modrm & 0xc7) != 5)
|
||||
{
|
||||
addr_regmask = 1 << (modrm & 7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) != 0x06)
|
||||
{
|
||||
switch (modrm & 7)
|
||||
{
|
||||
case 0: addr_regmask = REG_BX | REG_SI; break;
|
||||
case 1: addr_regmask = REG_BX | REG_DI; break;
|
||||
case 2: addr_regmask = REG_BP | REG_SI; break;
|
||||
case 3: addr_regmask = REG_BP | REG_DI; break;
|
||||
case 4: addr_regmask = REG_SI; break;
|
||||
case 5: addr_regmask = REG_DI; break;
|
||||
case 6: addr_regmask = REG_BP; break;
|
||||
case 7: addr_regmask = REG_BX; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data & IMPL_ESP)
|
||||
addr_regmask |= REGMASK_IMPL_ESP;
|
||||
|
||||
return addr_regmask;
|
||||
}
|
||||
|
||||
static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
if (data & SRCDEP_REG)
|
||||
{
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & SRCDEP_RM)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> SRCDEP_SHIFT) & 0xff);
|
||||
if (data & MMX_SHIFTPACK)
|
||||
mask |= REGMASK_SHIFTPACK;
|
||||
if (data & MMX_MULTIPLY)
|
||||
mask |= REGMASK_MULTIPLY;
|
||||
|
||||
mask |= get_addr_regmask(data, fetchdat, op_32);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
if (data & DSTDEP_REG)
|
||||
{
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & DSTDEP_RM)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> DSTDEP_SHIFT) & 0xff);
|
||||
if (data & MMX_SHIFTPACK)
|
||||
mask |= REGMASK_SHIFTPACK;
|
||||
if (data & MMX_MULTIPLY)
|
||||
mask |= REGMASK_MULTIPLY;
|
||||
if (data & IMPL_ESP)
|
||||
mask |= REGMASK_IMPL_ESP | (1 << REG_ESP);
|
||||
|
||||
return mask;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,421 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include <86box/mem.h>
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
#define CYCLES(c) (int *)c
|
||||
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
|
||||
static int *opcode_timings[256] =
|
||||
{
|
||||
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
|
||||
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
|
||||
/*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
|
||||
/*30*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2),
|
||||
|
||||
/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
|
||||
/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17),
|
||||
/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
|
||||
|
||||
/*80*/ &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm, &timing_rm, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6),
|
||||
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
|
||||
/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6),
|
||||
/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0),
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_mod3[256] =
|
||||
{
|
||||
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
|
||||
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
|
||||
/*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
|
||||
/*30*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2),
|
||||
|
||||
/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
|
||||
/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17),
|
||||
/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
|
||||
|
||||
/*80*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1),
|
||||
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
|
||||
/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6),
|
||||
/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0),
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_0f[256] =
|
||||
{
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, &timing_rm,
|
||||
/*70*/ NULL, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rm, &timing_rm,
|
||||
|
||||
/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
|
||||
/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3),
|
||||
/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30),
|
||||
/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
|
||||
};
|
||||
static int *opcode_timings_0f_mod3[256] =
|
||||
{
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, &timing_rr,
|
||||
/*70*/ NULL, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rr, &timing_rr,
|
||||
|
||||
/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
|
||||
/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3),
|
||||
/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30),
|
||||
/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL,
|
||||
};
|
||||
|
||||
static int *opcode_timings_shift[8] =
|
||||
{
|
||||
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
|
||||
};
|
||||
static int *opcode_timings_shift_mod3[8] =
|
||||
{
|
||||
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
|
||||
};
|
||||
|
||||
static int *opcode_timings_f6[8] =
|
||||
{
|
||||
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
};
|
||||
static int *opcode_timings_f6_mod3[8] =
|
||||
{
|
||||
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
};
|
||||
static int *opcode_timings_f7[8] =
|
||||
{
|
||||
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
};
|
||||
static int *opcode_timings_f7_mod3[8] =
|
||||
{
|
||||
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
};
|
||||
static int *opcode_timings_ff[8] =
|
||||
{
|
||||
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
|
||||
};
|
||||
static int *opcode_timings_ff_mod3[8] =
|
||||
{
|
||||
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_d8[8] =
|
||||
{
|
||||
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
|
||||
};
|
||||
static int *opcode_timings_d8_mod3[8] =
|
||||
{
|
||||
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
|
||||
CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
|
||||
};
|
||||
|
||||
static int *opcode_timings_d9[8] =
|
||||
{
|
||||
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
|
||||
CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
|
||||
};
|
||||
static int *opcode_timings_d9_mod3[64] =
|
||||
{
|
||||
/*FLD*/
|
||||
CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*FXCH*/
|
||||
CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4),
|
||||
/*FNOP*/
|
||||
CYCLES(7), NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*FSTP*/
|
||||
CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/* opFCHS opFABS opFTST opFXAM*/
|
||||
CYCLES(2), CYCLES(2), NULL, NULL, CYCLES(5), CYCLES(7), NULL, NULL,
|
||||
/* opFLD1 opFLDL2T opFLDL2E opFLDPI opFLDEG2 opFLDLN2 opFLDZ*/
|
||||
CYCLES(5), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(5), NULL,
|
||||
/* opF2XM1 opFYL2X opFPTAN opFPATAN opFDECSTP opFINCSTP,*/
|
||||
CYCLES(300), CYCLES(58), CYCLES(676), CYCLES(355), NULL, NULL, CYCLES(3), CYCLES(3),
|
||||
/* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
CYCLES(70), NULL, CYCLES(72), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(474), CYCLES(474)
|
||||
};
|
||||
|
||||
static int *opcode_timings_da[8] =
|
||||
{
|
||||
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
|
||||
};
|
||||
static int *opcode_timings_da_mod3[8] =
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
|
||||
};
|
||||
|
||||
|
||||
static int *opcode_timings_db[8] =
|
||||
{
|
||||
/* FLDil FSTil FSTPil FLDe FSTPe*/
|
||||
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8)
|
||||
};
|
||||
static int *opcode_timings_db_mod3[64] =
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/* opFNOP opFCLEX opFINIT opFNOP opFNOP*/
|
||||
NULL, CYCLES(7), CYCLES(18), CYCLES(27), CYCLES(7), CYCLES(7), NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
static int *opcode_timings_dc[8] =
|
||||
{
|
||||
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
|
||||
CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74)
|
||||
};
|
||||
static int *opcode_timings_dc_mod3[8] =
|
||||
{
|
||||
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
|
||||
};
|
||||
|
||||
static int *opcode_timings_dd[8] =
|
||||
{
|
||||
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
|
||||
CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5)
|
||||
};
|
||||
static int *opcode_timings_dd_mod3[8] =
|
||||
{
|
||||
/* FFFREE FST FSTP FUCOM FUCOMP*/
|
||||
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_de[8] =
|
||||
{
|
||||
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
|
||||
};
|
||||
static int *opcode_timings_de_mod3[8] =
|
||||
{
|
||||
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
|
||||
CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
|
||||
};
|
||||
|
||||
static int *opcode_timings_df[8] =
|
||||
{
|
||||
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
|
||||
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8)
|
||||
};
|
||||
static int *opcode_timings_df_mod3[8] =
|
||||
{
|
||||
/* FFREE FST FSTP FUCOM FUCOMP*/
|
||||
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
|
||||
};
|
||||
|
||||
static int *opcode_timings_8x[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static inline int COUNT(int *c, int op_32)
|
||||
{
|
||||
if ((uintptr_t)c <= 10000)
|
||||
return (int)(uintptr_t)c;
|
||||
if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff))
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
return ((uintptr_t)c >> 8) & 0xff;
|
||||
return (uintptr_t)c & 0xff;
|
||||
}
|
||||
return *c;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_block_start()
|
||||
{
|
||||
regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_start()
|
||||
{
|
||||
timing_count = 0;
|
||||
last_prefix = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
{
|
||||
timing_count += COUNT(opcode_timings[prefix], 0);
|
||||
last_prefix = prefix;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
|
||||
{
|
||||
int **timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_block_end()
|
||||
{
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_winchip =
|
||||
{
|
||||
codegen_timing_winchip_start,
|
||||
codegen_timing_winchip_prefix,
|
||||
codegen_timing_winchip_opcode,
|
||||
codegen_timing_winchip_block_start,
|
||||
codegen_timing_winchip_block_end,
|
||||
NULL
|
||||
};
|
||||
@@ -1,743 +0,0 @@
|
||||
/*Since IDT/Centaur didn't document cycle timings in the WinChip datasheets, and
|
||||
I don't currently own a WinChip 2 to test against, most of the timing here is
|
||||
a guess. This code makes the current (probably wrong) assumptions :
|
||||
- FPU uses same timings as a Pentium, except for FXCH (which doesn't pair)
|
||||
- 3DNow! instructions perfectly pair
|
||||
- MMX follows mostly Pentium rules - one pipeline has shift/pack, one has
|
||||
multiply, and other instructions can execute in either pipeline
|
||||
- Instructions with prefixes can pair if both instructions are fully decoded
|
||||
when the first instruction starts execution.*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
/*Instruction has different execution time for 16 and 32 bit data. Does not pair */
|
||||
#define CYCLES_HAS_MULTI (1 << 31)
|
||||
|
||||
#define CYCLES_FPU (1 << 30)
|
||||
|
||||
#define CYCLES_IS_MMX_MUL (1 << 29)
|
||||
#define CYCLES_IS_MMX_SHIFT (1 << 28)
|
||||
#define CYCLES_IS_MMX_ANY (1 << 27)
|
||||
#define CYCLES_IS_3DNOW (1 << 26)
|
||||
|
||||
#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c)
|
||||
#define CYCLES_MMX_SHIFT(c) (CYCLES_IS_MMX_SHIFT | c)
|
||||
#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c)
|
||||
#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c)
|
||||
|
||||
#define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW)
|
||||
|
||||
#define GET_CYCLES(c) (c & ~(CYCLES_HAS_MULTI | CYCLES_FPU | CYCLES_IS_MMX))
|
||||
|
||||
#define CYCLES(c) c
|
||||
#define CYCLES2(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8))
|
||||
|
||||
/*comp_time = cycles until instruction complete
|
||||
i_overlap = cycles that overlap with integer
|
||||
f_overlap = cycles that overlap with subsequent FPU*/
|
||||
#define FPU_CYCLES(comp_time, i_overlap, f_overlap) (comp_time) | (i_overlap << 8) | (f_overlap << 16) | CYCLES_FPU
|
||||
|
||||
#define FPU_COMP_TIME(timing) (timing & 0xff)
|
||||
#define FPU_I_OVERLAP(timing) ((timing >> 8) & 0xff)
|
||||
#define FPU_F_OVERLAP(timing) ((timing >> 16) & 0xff)
|
||||
|
||||
#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing))
|
||||
|
||||
#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing))
|
||||
|
||||
#define FPU_RESULT_LATENCY(timing) ((timing >> 8) & 0xff)
|
||||
|
||||
#define INVALID 0
|
||||
|
||||
static uint32_t opcode_timings[256] =
|
||||
{
|
||||
/*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID,
|
||||
/*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3),
|
||||
/*20*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3),
|
||||
/*30*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2),
|
||||
|
||||
/*40*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17),
|
||||
/*70*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
|
||||
/*80*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6),
|
||||
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
|
||||
/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6),
|
||||
/*b0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0),
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_mod3[256] =
|
||||
{
|
||||
/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID,
|
||||
/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3),
|
||||
/*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3),
|
||||
/*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2),
|
||||
|
||||
/*40*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17),
|
||||
/*70*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
|
||||
/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1),
|
||||
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
|
||||
/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6),
|
||||
/*b0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0),
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID,
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_0f[256] =
|
||||
{
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1),
|
||||
/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
/*40*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*50*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*60*/ CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2),
|
||||
/*70*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2),
|
||||
|
||||
/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3),
|
||||
/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18,30),
|
||||
/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*d0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2),
|
||||
/*e0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2),
|
||||
/*f0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID,
|
||||
};
|
||||
static uint32_t opcode_timings_0f_mod3[256] =
|
||||
{
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1),
|
||||
/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
/*40*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*50*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
|
||||
/*60*/ CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1),
|
||||
/*70*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1),
|
||||
|
||||
/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3),
|
||||
/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18,30),
|
||||
/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1),
|
||||
/*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1),
|
||||
/*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID,
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_shift[8] =
|
||||
{
|
||||
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
|
||||
};
|
||||
static uint32_t opcode_timings_shift_mod3[8] =
|
||||
{
|
||||
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_f6[8] =
|
||||
{
|
||||
CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
};
|
||||
static uint32_t opcode_timings_f6_mod3[8] =
|
||||
{
|
||||
CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
};
|
||||
static uint32_t opcode_timings_f7[8] =
|
||||
{
|
||||
CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
};
|
||||
static uint32_t opcode_timings_f7_mod3[8] =
|
||||
{
|
||||
CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
};
|
||||
static uint32_t opcode_timings_ff[8] =
|
||||
{
|
||||
CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID
|
||||
};
|
||||
static uint32_t opcode_timings_ff_mod3[8] =
|
||||
{
|
||||
CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_d8[8] =
|
||||
{
|
||||
/* FADDs FMULs FCOMs FCOMPs*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
/* FSUBs FSUBRs FDIVs FDIVRs*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
|
||||
};
|
||||
static uint32_t opcode_timings_d8_mod3[8] =
|
||||
{
|
||||
/* FADD FMUL FCOM FCOMP*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
/* FSUB FSUBR FDIV FDIVR*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_d9[8] =
|
||||
{
|
||||
/* FLDs FSTs FSTPs*/
|
||||
FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0),
|
||||
/* FLDENV FLDCW FSTENV FSTCW*/
|
||||
FPU_CYCLES(32,0,0), FPU_CYCLES(8,0,0), FPU_CYCLES(48,0,0), FPU_CYCLES(2,0,0)
|
||||
};
|
||||
static uint32_t opcode_timings_d9_mod3[64] =
|
||||
{
|
||||
/*FLD*/
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
/*FXCH*/
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
/*FNOP*/
|
||||
FPU_CYCLES(3,0,0), INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/*FSTP*/
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
/* opFCHS opFABS*/
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), INVALID, INVALID,
|
||||
/* opFTST opFXAM*/
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(21,4,0), INVALID, INVALID,
|
||||
/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/
|
||||
FPU_CYCLES(2,0,0), FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2),
|
||||
/* opFLDEG2 opFLDLN2 opFLDZ*/
|
||||
FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), FPU_CYCLES(2,0,0), INVALID,
|
||||
/* opF2XM1 opFYL2X opFPTAN opFPATAN*/
|
||||
FPU_CYCLES(53,2,2), FPU_CYCLES(103,2,2),FPU_CYCLES(120,36,0),FPU_CYCLES(112,2,2),
|
||||
/* opFDECSTP opFINCSTP,*/
|
||||
INVALID, INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0),
|
||||
/* opFPREM opFSQRT opFSINCOS*/
|
||||
FPU_CYCLES(64,2,2), INVALID, FPU_CYCLES(70,69,2),FPU_CYCLES(89,2,2),
|
||||
/* opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
FPU_CYCLES(9,0,0), FPU_CYCLES(20,5,0), FPU_CYCLES(65,2,2), FPU_CYCLES(65,2,2)
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_da[8] =
|
||||
{
|
||||
/* FIADDl FIMULl FICOMl FICOMPl*/
|
||||
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0),
|
||||
/* FISUBl FISUBRl FIDIVl FIDIVRl*/
|
||||
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2)
|
||||
};
|
||||
static uint32_t opcode_timings_da_mod3[8] =
|
||||
{
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/* FCOMPP*/
|
||||
INVALID, FPU_CYCLES(1,0,0), INVALID, INVALID
|
||||
};
|
||||
|
||||
|
||||
static uint32_t opcode_timings_db[8] =
|
||||
{
|
||||
/* FLDil FSTil FSTPil*/
|
||||
FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0),
|
||||
/* FLDe FSTPe*/
|
||||
INVALID, FPU_CYCLES(3,0,0), INVALID, FPU_CYCLES(3,0,0)
|
||||
};
|
||||
static uint32_t opcode_timings_db_mod3[64] =
|
||||
{
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
/* opFNOP opFCLEX opFINIT*/
|
||||
INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(7,0,0), FPU_CYCLES(17,0,0),
|
||||
/* opFNOP opFNOP*/
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), INVALID, INVALID,
|
||||
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_dc[8] =
|
||||
{
|
||||
/* FADDd FMULd FCOMd FCOMPd*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
/* FSUBd FSUBRd FDIVd FDIVRd*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
|
||||
};
|
||||
static uint32_t opcode_timings_dc_mod3[8] =
|
||||
{
|
||||
/* opFADDr opFMULr*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),INVALID, INVALID,
|
||||
/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_dd[8] =
|
||||
{
|
||||
/* FLDd FSTd FSTPd*/
|
||||
FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0),
|
||||
/* FRSTOR FSAVE FSTSW*/
|
||||
FPU_CYCLES(70,0,0), INVALID, FPU_CYCLES(127,0,0), FPU_CYCLES(6,0,0)
|
||||
};
|
||||
static uint32_t opcode_timings_dd_mod3[8] =
|
||||
{
|
||||
/* FFFREE FST FSTP*/
|
||||
FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
|
||||
/* FUCOM FUCOMP*/
|
||||
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),INVALID, INVALID
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_de[8] =
|
||||
{
|
||||
/* FIADDw FIMULw FICOMw FICOMPw*/
|
||||
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0),
|
||||
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
|
||||
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2)
|
||||
};
|
||||
static uint32_t opcode_timings_de_mod3[8] =
|
||||
{
|
||||
/* FADDP FMULP FCOMPP*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(1,0,0),
|
||||
/* FSUBP FSUBRP FDIVP FDIVRP*/
|
||||
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_df[8] =
|
||||
{
|
||||
/* FILDiw FISTiw FISTPiw*/
|
||||
FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0),
|
||||
/* FILDiq FBSTP FISTPiq*/
|
||||
INVALID, FPU_CYCLES(3,2,2), FPU_CYCLES(148,0,0), FPU_CYCLES(6,0,0)
|
||||
};
|
||||
static uint32_t opcode_timings_df_mod3[8] =
|
||||
{
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/* FSTSW AX*/
|
||||
FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_8x[8] =
|
||||
{
|
||||
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
|
||||
};
|
||||
static uint32_t opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
|
||||
};
|
||||
static uint32_t opcode_timings_81[8] =
|
||||
{
|
||||
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
|
||||
};
|
||||
static uint32_t opcode_timings_81_mod3[8] =
|
||||
{
|
||||
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
|
||||
};
|
||||
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static uint32_t regmask_modified;
|
||||
static int decode_delay, decode_delay_offset;
|
||||
static int fpu_latency;
|
||||
static int fpu_st_latency[8];
|
||||
|
||||
static int u_pipe_full;
|
||||
static uint32_t u_pipe_opcode;
|
||||
static uint32_t *u_pipe_timings;
|
||||
static uint32_t u_pipe_op_32;
|
||||
static uint32_t u_pipe_regmask;
|
||||
static uint32_t u_pipe_fetchdat;
|
||||
static int u_pipe_decode_delay_offset;
|
||||
static uint64_t *u_pipe_deps;
|
||||
|
||||
int can_pair(uint32_t timing_a, uint32_t timing_b, uint8_t regmask_b)
|
||||
{
|
||||
/*Only MMX/3DNow instructions can pair*/
|
||||
if (!(timing_b & CYCLES_IS_MMX))
|
||||
return 0;
|
||||
/*Only one MMX multiply per cycle*/
|
||||
if ((timing_a & CYCLES_IS_MMX_MUL) && (timing_b & CYCLES_IS_MMX_MUL))
|
||||
return 0;
|
||||
/*Only one MMX shift/pack per cycle*/
|
||||
if ((timing_a & CYCLES_IS_MMX_SHIFT) && (timing_b & CYCLES_IS_MMX_SHIFT))
|
||||
return 0;
|
||||
/*Second instruction can not access registers written by first*/
|
||||
if (u_pipe_regmask & regmask_b)
|
||||
return 0;
|
||||
/*Must have had enough time to decode prefixes*/
|
||||
if ((decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) > 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int COUNT(uint32_t c, int op_32)
|
||||
{
|
||||
if (c & CYCLES_FPU)
|
||||
return FPU_I_LATENCY(c);
|
||||
if (c & CYCLES_HAS_MULTI)
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
return (c >> 8) & 0xff;
|
||||
return c & 0xff;
|
||||
}
|
||||
return GET_CYCLES(c);
|
||||
}
|
||||
|
||||
static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32);
|
||||
|
||||
/*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not
|
||||
cause AGIs with each other, but do with instructions that use it explicitly*/
|
||||
if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP))
|
||||
addr_regmask |= (1 << REG_ESP);
|
||||
|
||||
return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP;
|
||||
}
|
||||
|
||||
static int codegen_fpu_latencies(uint64_t deps, int reg)
|
||||
{
|
||||
int latency = fpu_latency;
|
||||
|
||||
if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency)
|
||||
latency = fpu_st_latency[0];
|
||||
if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency)
|
||||
latency = fpu_st_latency[1];
|
||||
if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency)
|
||||
latency = fpu_st_latency[reg];
|
||||
|
||||
return latency;
|
||||
}
|
||||
|
||||
#define SUB_AND_CLAMP(latency, count) \
|
||||
latency -= count; \
|
||||
if (latency < 0) \
|
||||
latency = 0
|
||||
|
||||
static void codegen_fpu_latency_clock(int count)
|
||||
{
|
||||
SUB_AND_CLAMP(fpu_latency, count);
|
||||
SUB_AND_CLAMP(fpu_st_latency[0], count);
|
||||
SUB_AND_CLAMP(fpu_st_latency[1], count);
|
||||
SUB_AND_CLAMP(fpu_st_latency[2], count);
|
||||
SUB_AND_CLAMP(fpu_st_latency[3], count);
|
||||
SUB_AND_CLAMP(fpu_st_latency[4], count);
|
||||
SUB_AND_CLAMP(fpu_st_latency[5], count);
|
||||
SUB_AND_CLAMP(fpu_st_latency[6], count);
|
||||
SUB_AND_CLAMP(fpu_st_latency[7], count);
|
||||
}
|
||||
|
||||
static void codegen_instruction(uint32_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay)
|
||||
{
|
||||
int instr_cycles, latency = 0;
|
||||
|
||||
if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH))
|
||||
instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7);
|
||||
else
|
||||
instr_cycles = 0;
|
||||
|
||||
if ((decode_delay + decode_delay_offset) > 0)
|
||||
codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles);
|
||||
else
|
||||
codegen_fpu_latency_clock(instr_cycles);
|
||||
instr_cycles += COUNT(timings[opcode], op_32);
|
||||
instr_cycles += exec_delay;
|
||||
if ((decode_delay + decode_delay_offset) > 0)
|
||||
codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset;
|
||||
else
|
||||
codegen_block_cycles += instr_cycles;
|
||||
decode_delay = (-instr_cycles) + 1;
|
||||
|
||||
if (deps[opcode] & FPU_POP)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 7; c++)
|
||||
fpu_st_latency[c] = fpu_st_latency[c+1];
|
||||
fpu_st_latency[7] = 0;
|
||||
}
|
||||
if (deps[opcode] & FPU_POP2)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 6; c++)
|
||||
fpu_st_latency[c] = fpu_st_latency[c+2];
|
||||
fpu_st_latency[6] = fpu_st_latency[7] = 0;
|
||||
}
|
||||
if (timings[opcode] & CYCLES_FPU)
|
||||
{
|
||||
/* if (fpu_latency)
|
||||
fatal("Bad latency FPU\n");*/
|
||||
fpu_latency = FPU_F_LATENCY(timings[opcode]);
|
||||
}
|
||||
|
||||
if (deps[opcode] & FPU_PUSH)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 7; c++)
|
||||
fpu_st_latency[c+1] = fpu_st_latency[c];
|
||||
fpu_st_latency[0] = 0;
|
||||
}
|
||||
if (deps[opcode] & FPU_WRITE_ST0)
|
||||
{
|
||||
/* if (fpu_st_latency[0])
|
||||
fatal("Bad latency ST0\n");*/
|
||||
fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]);
|
||||
}
|
||||
if (deps[opcode] & FPU_WRITE_ST1)
|
||||
{
|
||||
/* if (fpu_st_latency[1])
|
||||
fatal("Bad latency ST1\n");*/
|
||||
fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]);
|
||||
}
|
||||
if (deps[opcode] & FPU_WRITE_STREG)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (deps[opcode] & FPU_POP)
|
||||
reg--;
|
||||
if (reg >= 0 &&
|
||||
!(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) &&
|
||||
!(reg == 1 && (deps[opcode] & FPU_WRITE_ST1)))
|
||||
{
|
||||
/* if (fpu_st_latency[reg])
|
||||
fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/
|
||||
fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void codegen_timing_winchip2_block_start()
|
||||
{
|
||||
regmask_modified = 0;
|
||||
decode_delay = decode_delay_offset = 0;
|
||||
u_pipe_full = 0;
|
||||
}
|
||||
|
||||
static void codegen_timing_winchip2_start()
|
||||
{
|
||||
timing_count = 0;
|
||||
last_prefix = 0;
|
||||
}
|
||||
|
||||
static void codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
{
|
||||
if (prefix == 0x0f)
|
||||
{
|
||||
/*0fh prefix is 'free'*/
|
||||
last_prefix = prefix;
|
||||
return;
|
||||
}
|
||||
/*On WinChip all prefixes take 1 cycle to decode. Decode may be shadowed
|
||||
by execution of previous instructions*/
|
||||
decode_delay_offset++;
|
||||
last_prefix = prefix;
|
||||
}
|
||||
|
||||
static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
|
||||
{
|
||||
uint32_t *timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
int agi_stall = 0;
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (u_pipe_full)
|
||||
{
|
||||
uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32);
|
||||
|
||||
if (can_pair(u_pipe_timings[u_pipe_opcode], timings[opcode], regmask))
|
||||
{
|
||||
int cycles_a = u_pipe_timings[u_pipe_opcode] & 0xff;
|
||||
int cycles_b = timings[opcode] & 0xff;
|
||||
uint32_t timing = (cycles_a > cycles_b) ? u_pipe_timings[u_pipe_opcode] : timings[opcode];
|
||||
uint64_t temp_deps = 0;
|
||||
|
||||
if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32))
|
||||
agi_stall = 1;
|
||||
|
||||
codegen_instruction(&timing, &temp_deps, 0, 0, 0, 0, agi_stall);
|
||||
u_pipe_full = 0;
|
||||
decode_delay_offset = 0;
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*No pairing, run first instruction now*/
|
||||
if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32))
|
||||
agi_stall = 1;
|
||||
codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall);
|
||||
u_pipe_full = 0;
|
||||
regmask_modified = u_pipe_regmask;
|
||||
}
|
||||
}
|
||||
if (timings[opcode] & CYCLES_IS_MMX)
|
||||
{
|
||||
/*Might pair with next instruction*/
|
||||
u_pipe_full = 1;
|
||||
u_pipe_opcode = opcode;
|
||||
u_pipe_timings = timings;
|
||||
u_pipe_op_32 = op_32;
|
||||
u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
u_pipe_fetchdat = fetchdat;
|
||||
u_pipe_decode_delay_offset = decode_delay_offset;
|
||||
u_pipe_deps = deps;
|
||||
decode_delay_offset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (check_agi(deps, opcode, fetchdat, op_32))
|
||||
agi_stall = 1;
|
||||
codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall);
|
||||
decode_delay_offset = 0;
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
|
||||
static void codegen_timing_winchip2_block_end()
|
||||
{
|
||||
if (u_pipe_full)
|
||||
{
|
||||
int agi_stall = 0;
|
||||
|
||||
if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32))
|
||||
agi_stall = 1;
|
||||
codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall);
|
||||
u_pipe_full = 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_winchip2 =
|
||||
{
|
||||
codegen_timing_winchip2_start,
|
||||
codegen_timing_winchip2_prefix,
|
||||
codegen_timing_winchip2_opcode,
|
||||
codegen_timing_winchip2_block_start,
|
||||
codegen_timing_winchip2_block_end,
|
||||
NULL
|
||||
};
|
||||
Reference in New Issue
Block a user