[no ci] Format Changes

This commit is contained in:
Michael J. Manley
2022-06-23 11:26:13 -07:00
parent fa9c5ef6c0
commit bed5fced7b
725 changed files with 219949 additions and 199821 deletions

148
.clang-format Normal file
View File

@@ -0,0 +1,148 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveBitFields: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 130
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentWidth: 8
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 8
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
---

File diff suppressed because it is too large Load Diff

View File

@@ -6,40 +6,37 @@
extern char pcem_path[512];
LPT_DEVICE l_epsonlx810 = { "Epson LX-810 Printer", "lpt_epsonlx810", &lpt_epsonprinter_device };
LPT_DEVICE l_epsonlx810 = {"Epson LX-810 Printer", "lpt_epsonlx810", &lpt_epsonprinter_device};
#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0)
#define safe_strncpy(a, b, n) \
do { \
strncpy((a), (b), (n)-1); \
(a)[(n)-1] = 0; \
} while (0)
char printer_path[512];
void set_printer_path(char *s)
{
void set_printer_path(char *s) {
safe_strncpy(printer_path, s, 512);
append_slash(printer_path, 512);
}
void load_config()
{
char* cfg_printer_path = config_get_string(CFG_GLOBAL, "Paths", "printer_path", 0);
void load_config() {
char *cfg_printer_path = config_get_string(CFG_GLOBAL, "Paths", "printer_path", 0);
if (cfg_printer_path)
set_printer_path(cfg_printer_path);
}
void save_config()
{
config_set_string(CFG_GLOBAL, "Paths", "printer_path", printer_path);
}
void save_config() { config_set_string(CFG_GLOBAL, "Paths", "printer_path", printer_path); }
void init_config()
{
void init_config() {
char s[512];
append_filename(s, pcem_path, "printer/", 512);
set_printer_path(s);
}
PLUGIN_INIT(printer_epsonlx810)
{
PLUGIN_INIT(printer_epsonlx810) {
add_config_callback(load_config, save_config, init_config);
pcem_add_lpt(&l_epsonlx810);
}

View File

@@ -4,33 +4,28 @@
#include <wx/wfstream.h>
#include <wx/log.h>
int wx_image_save_fullpath(const char* fullpath, const char* format, unsigned char* rgba, int width, int height, int alpha)
{
int wx_image_save_fullpath(const char *fullpath, const char *format, unsigned char *rgba, int width, int height, int alpha) {
int x, y;
wxLogNull logNull;
wxImage image(width, height);
if (alpha)
{
if (alpha) {
// these will be automatically freed
unsigned char* rgb = (unsigned char*)malloc(width*height*3);
unsigned char* a = (unsigned char*)malloc(width*height);
for (x = 0; x < width; ++x)
{
for (y = 0; y < height; ++y)
{
rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0];
rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1];
rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2];
a[y*width+x] = rgba[(y*width+x)*4+3];
unsigned char *rgb = (unsigned char *)malloc(width * height * 3);
unsigned char *a = (unsigned char *)malloc(width * height);
for (x = 0; x < width; ++x) {
for (y = 0; y < height; ++y) {
rgb[(y * width + x) * 3 + 0] = rgba[(y * width + x) * 4 + 0];
rgb[(y * width + x) * 3 + 1] = rgba[(y * width + x) * 4 + 1];
rgb[(y * width + x) * 3 + 2] = rgba[(y * width + x) * 4 + 2];
a[y * width + x] = rgba[(y * width + x) * 4 + 3];
}
}
image.SetData(rgb);
image.SetAlpha(a);
}
else
} else
image.SetData(rgba, true);
wxImageHandler* h;
wxImageHandler *h;
if (!strcmp(format, IMAGE_TIFF))
h = new wxTIFFHandler();
@@ -42,8 +37,7 @@ int wx_image_save_fullpath(const char* fullpath, const char* format, unsigned ch
h = new wxPNGHandler();
int res = 0;
if (h)
{
if (h) {
wxString p(fullpath);
wxFileOutputStream stream(p);

View File

@@ -8,112 +8,72 @@
#include <byteswap.h>
#else
#define bswap_16(x) \
({ \
uint16_t __x = (x); \
((uint16_t)( \
(((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
(((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
})
#define bswap_16(x) \
({ \
uint16_t __x = (x); \
((uint16_t)((((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8))); \
})
#define bswap_32(x) \
({ \
uint32_t __x = (x); \
((uint32_t)( \
(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
})
#define bswap_32(x) \
({ \
uint32_t __x = (x); \
((uint32_t)((((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24))); \
})
#define bswap_64(x) \
({ \
uint64_t __x = (x); \
((uint64_t)( \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
})
#define bswap_64(x) \
({ \
uint64_t __x = (x); \
((uint64_t)((uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
(uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56))); \
})
#endif /* !HAVE_BYTESWAP_H */
static inline uint16_t bswap16(uint16_t x)
{
return bswap_16(x);
}
static inline uint16_t bswap16(uint16_t x) { return bswap_16(x); }
static inline uint32_t bswap32(uint32_t x)
{
return bswap_32(x);
}
static inline uint32_t bswap32(uint32_t x) { return bswap_32(x); }
static inline uint64_t bswap64(uint64_t x)
{
return bswap_64(x);
}
static inline uint64_t bswap64(uint64_t x) { return bswap_64(x); }
static inline void bswap16s(uint16_t *s)
{
*s = bswap16(*s);
}
static inline void bswap16s(uint16_t *s) { *s = bswap16(*s); }
static inline void bswap32s(uint32_t *s)
{
*s = bswap32(*s);
}
static inline void bswap32s(uint32_t *s) { *s = bswap32(*s); }
static inline void bswap64s(uint64_t *s)
{
*s = bswap64(*s);
}
static inline void bswap64s(uint64_t *s) { *s = bswap64(*s); }
#if defined(WORDS_BIGENDIAN)
#define be_bswap(v, size) (v)
#define le_bswap(v, size) bswap ## size(v)
#define le_bswap(v, size) bswap##size(v)
#define be_bswaps(v, size)
#define le_bswaps(p, size) *p = bswap ## size(*p);
#define le_bswaps(p, size) *p = bswap##size(*p);
#else
#define le_bswap(v, size) (v)
#define be_bswap(v, size) bswap ## size(v)
#define be_bswap(v, size) bswap##size(v)
#define le_bswaps(v, size)
#define be_bswaps(p, size) *p = bswap ## size(*p);
#define be_bswaps(p, size) *p = bswap##size(*p);
#endif
#define CPU_CONVERT(endian, size, type)\
static inline type endian ## size ## _to_cpu(type v)\
{\
return endian ## _bswap(v, size);\
}\
\
static inline type cpu_to_ ## endian ## size(type v)\
{\
return endian ## _bswap(v, size);\
}\
\
static inline void endian ## size ## _to_cpus(type *p)\
{\
endian ## _bswaps(p, size)\
}\
\
static inline void cpu_to_ ## endian ## size ## s(type *p)\
{\
endian ## _bswaps(p, size)\
}\
\
static inline type endian ## size ## _to_cpup(const type *p)\
{\
return endian ## size ## _to_cpu(*p);\
}\
\
static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
{\
*p = cpu_to_ ## endian ## size(v);\
}
#define CPU_CONVERT(endian, size, type) \
static inline type endian##size##_to_cpu(type v) { return endian##_bswap(v, size); } \
\
static inline type cpu_to_##endian##size(type v) { return endian##_bswap(v, size); } \
\
static inline void endian##size##_to_cpus(type *p) { endian##_bswaps(p, size) } \
\
static inline void cpu_to_##endian##size##s(type *p) { endian##_bswaps(p, size) } \
\
static inline type endian##size##_to_cpup(const type *p) { return endian##size##_to_cpu(*p); } \
\
static inline void cpu_to_##endian##size##w(type *p, type v) { *p = cpu_to_##endian##size(v); }
CPU_CONVERT(be, 16, uint16_t)
CPU_CONVERT(be, 32, uint32_t)
@@ -137,52 +97,46 @@ CPU_CONVERT(le, 64, uint64_t)
#else
static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
{
uint8_t *p1 = (uint8_t *)p;
static inline void cpu_to_le16wu(uint16_t *p, uint16_t v) {
uint8_t *p1 = (uint8_t *)p;
p1[0] = v;
p1[1] = v >> 8;
p1[0] = v;
p1[1] = v >> 8;
}
static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
{
uint8_t *p1 = (uint8_t *)p;
static inline void cpu_to_le32wu(uint32_t *p, uint32_t v) {
uint8_t *p1 = (uint8_t *)p;
p1[0] = v;
p1[1] = v >> 8;
p1[2] = v >> 16;
p1[3] = v >> 24;
p1[0] = v;
p1[1] = v >> 8;
p1[2] = v >> 16;
p1[3] = v >> 24;
}
static inline uint16_t le16_to_cpupu(const uint16_t *p)
{
const uint8_t *p1 = (const uint8_t *)p;
return p1[0] | (p1[1] << 8);
static inline uint16_t le16_to_cpupu(const uint16_t *p) {
const uint8_t *p1 = (const uint8_t *)p;
return p1[0] | (p1[1] << 8);
}
static inline uint32_t le32_to_cpupu(const uint32_t *p)
{
const uint8_t *p1 = (const uint8_t *)p;
return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
static inline uint32_t le32_to_cpupu(const uint32_t *p) {
const uint8_t *p1 = (const uint8_t *)p;
return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
}
static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
{
uint8_t *p1 = (uint8_t *)p;
static inline void cpu_to_be16wu(uint16_t *p, uint16_t v) {
uint8_t *p1 = (uint8_t *)p;
p1[0] = v >> 8;
p1[1] = v;
p1[0] = v >> 8;
p1[1] = v;
}
static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
{
uint8_t *p1 = (uint8_t *)p;
static inline void cpu_to_be32wu(uint32_t *p, uint32_t v) {
uint8_t *p1 = (uint8_t *)p;
p1[0] = v >> 24;
p1[1] = v >> 16;
p1[2] = v >> 8;
p1[3] = v;
p1[0] = v >> 24;
p1[1] = v >> 16;
p1[2] = v >> 8;
p1[3] = v;
}
#endif

View File

@@ -1,7 +1,8 @@
#ifndef _MCA_H_
#define _MCA_H_
void mca_init(int nr_cards);
void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(void *priv), void *priv);
void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(void *priv),
void *priv);
void mca_set_index(int index);
uint8_t mca_read(uint16_t port);
void mca_write(uint16_t port, uint8_t val);

View File

@@ -2,8 +2,10 @@
#define _PCI_H_
void pci_init(int type);
void pci_slot(int card);
void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv),
void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv),
void *priv);
void pci_set_irq_routing(int card, int irq);
void pci_set_card_routing(int card, int pci_int);
void pci_set_irq(int card, int pci_int);
@@ -11,7 +13,7 @@ void pci_clear_irq(int card, int pci_int);
#define PCI_REG_COMMAND 0x04
#define PCI_COMMAND_IO 0x01
#define PCI_COMMAND_IO 0x01
#define PCI_COMMAND_MEM 0x02
#define PCI_CONFIG_TYPE_1 1

View File

@@ -12,25 +12,24 @@
added to the page_lookup for this purpose. When in the page_lookup, each write
will go through the mem_write_ram*_page() functions and set the dirty mask
appropriately.
Each codeblock also contains a code mask (actually two masks, one for each
page the block is/may be in), again with each bit representing 64 bytes.
Each page has a list of codeblocks present in it. As each codeblock can span
up to two pages, two lists are present.
When a codeblock is about to be executed, the code masks are compared with the
dirty masks for the relevant pages. If either intersect, then
codegen_check_flush() is called on the affected page(s), and all affected
blocks are evicted.
The 64 byte granularity appears to work reasonably well for most cases,
avoiding most unnecessary evictions (eg when code & data are stored in the
same page).
*/
typedef struct codeblock_t
{
typedef struct codeblock_t {
uint32_t pc;
uint32_t _cs;
uint32_t phys, phys_2;
@@ -44,7 +43,7 @@ typedef struct codeblock_t
uint16_t parent, left, right;
uint8_t *data;
uint64_t page_mask, page_mask2;
uint64_t *dirty_mask, *dirty_mask2;
@@ -86,27 +85,21 @@ extern uint8_t *block_write_data;
#define BLOCK_INVALID 0
static inline int get_block_nr(codeblock_t *block)
{
return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t);
}
static inline int get_block_nr(codeblock_t *block) { return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); }
static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
{
static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) {
codeblock_t *block;
uint64_t a = _cs | ((uint64_t)phys << 32);
if (!pages[phys >> 12].head)
return NULL;
block = &codeblock[pages[phys >> 12].head];
while (block)
{
while (block) {
uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32);
if (a == block_cmp)
{
if (a == block_cmp) {
if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
break;
}
if (a < block_cmp)
@@ -114,48 +107,42 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
else
block = block->right ? &codeblock[block->right] : NULL;
}
return block;
}
static inline void codeblock_tree_add(codeblock_t *new_block)
{
static inline void codeblock_tree_add(codeblock_t *new_block) {
codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head];
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
if (!pages[new_block->phys >> 12].head)
{
if (!pages[new_block->phys >> 12].head) {
pages[new_block->phys >> 12].head = get_block_nr(new_block);
new_block->parent = new_block->left = new_block->right = BLOCK_INVALID;
}
else
{
} else {
codeblock_t *old_block = NULL;
uint64_t old_block_cmp = 0;
while (block)
{
while (block) {
old_block = block;
old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32);
if (a < old_block_cmp)
block = block->left ? &codeblock[block->left] : NULL;
else
block = block->right ? &codeblock[block->right] : NULL;
}
if (a < old_block_cmp)
old_block->left = get_block_nr(new_block);
else
old_block->right = get_block_nr(new_block);
new_block->parent = get_block_nr(old_block);
new_block->left = new_block->right = BLOCK_INVALID;
}
}
static inline void codeblock_tree_delete(codeblock_t *block)
{
static inline void codeblock_tree_delete(codeblock_t *block) {
uint16_t parent_nr = block->parent;
codeblock_t *parent;
@@ -164,90 +151,71 @@ static inline void codeblock_tree_delete(codeblock_t *block)
else
parent = NULL;
if (!block->left && !block->right)
{
if (!block->left && !block->right) {
/*Easy case - remove from parent*/
if (!parent)
pages[block->phys >> 12].head = BLOCK_INVALID;
else
{
else {
uint16_t block_nr = get_block_nr(block);
if (parent->left == block_nr)
parent->left = BLOCK_INVALID;
if (parent->right == block_nr)
parent->right = BLOCK_INVALID;
}
return;
}
else if (!block->left)
{
} else if (!block->left) {
/*Only right node*/
if (!parent_nr)
{
if (!parent_nr) {
pages[block->phys >> 12].head = block->right;
codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID;
}
else
{
} else {
uint16_t block_nr = get_block_nr(block);
if (parent->left == block_nr)
{
if (parent->left == block_nr) {
parent->left = block->right;
codeblock[parent->left].parent = parent_nr;
}
if (parent->right == block_nr)
{
if (parent->right == block_nr) {
parent->right = block->right;
codeblock[parent->right].parent = parent_nr;
}
}
return;
}
else if (!block->right)
{
} else if (!block->right) {
/*Only left node*/
if (!parent_nr)
{
if (!parent_nr) {
pages[block->phys >> 12].head = block->left;
codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID;
}
else
{
} else {
uint16_t block_nr = get_block_nr(block);
if (parent->left == block_nr)
{
if (parent->left == block_nr) {
parent->left = block->left;
codeblock[parent->left].parent = parent_nr;
}
if (parent->right == block_nr)
{
if (parent->right == block_nr) {
parent->right = block->left;
codeblock[parent->right].parent = parent_nr;
}
}
return;
}
else
{
} else {
/*Difficult case - node has two children. Walk right child to find lowest node*/
codeblock_t *lowest = &codeblock[block->right], *highest;
codeblock_t *old_parent;
uint16_t lowest_nr;
while (lowest->left)
lowest = &codeblock[lowest->left];
lowest_nr = get_block_nr(lowest);
old_parent = &codeblock[lowest->parent];
/*Replace deleted node with lowest node*/
if (!parent_nr)
pages[block->phys >> 12].head = lowest_nr;
else
{
else {
uint16_t block_nr = get_block_nr(block);
if (parent->left == block_nr)
@@ -262,12 +230,10 @@ static inline void codeblock_tree_delete(codeblock_t *block)
codeblock[lowest->left].parent = lowest_nr;
old_parent->left = BLOCK_INVALID;
highest = &codeblock[lowest->right];
if (!lowest->right)
{
if (lowest_nr != block->right)
{
if (!lowest->right) {
if (lowest_nr != block->right) {
lowest->right = block->right;
codeblock[block->right].parent = lowest_nr;
}
@@ -277,8 +243,7 @@ static inline void codeblock_tree_delete(codeblock_t *block)
while (highest->right)
highest = &codeblock[highest->right];
if (block->right && block->right != lowest_nr)
{
if (block->right && block->right != lowest_nr) {
highest->right = block->right;
codeblock[block->right].parent = get_block_nr(highest);
}
@@ -290,26 +255,20 @@ static inline void codeblock_tree_delete(codeblock_t *block)
void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len);
static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len)
{
if (len == 1)
{
if (block->flags & CODEBLOCK_BYTE_MASK)
{
static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) {
if (len == 1) {
if (block->flags & CODEBLOCK_BYTE_MASK) {
if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/
block->page_mask |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK));
else
block->page_mask2 |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK));
}
else
{
} else {
if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/
block->page_mask |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK));
else
block->page_mask2 |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK));
}
}
else
} else
codegen_mark_code_present_multibyte(block, start_pc, len);
}
@@ -328,7 +287,8 @@ void codegen_set_op32();
void codegen_flush();
void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr);
struct ir_data_t;
x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset);
x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc,
uint32_t op_32, int stack_offset);
void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
@@ -359,8 +319,7 @@ extern void (*codegen_timing_block_start)();
extern void (*codegen_timing_block_end)();
extern int (*codegen_timing_jump_cycles)();
typedef struct codegen_timing_t
{
typedef struct codegen_timing_t {
void (*start)();
void (*prefix)(uint8_t prefix, uint32_t fetchdat);
void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
@@ -410,7 +369,7 @@ int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_inst
void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction);
#ifdef DEBUG_EXTRA
extern uint32_t instr_counts[256*256];
extern uint32_t instr_counts[256 * 256];
#endif
#endif

View File

@@ -1,11 +1,10 @@
#ifndef _CODEGEN_ACCUMULATE_H_
#define _CODEGEN_ACCUMULATE_H_
enum
{
ACCREG_ins = 0,
enum {
ACCREG_ins = 0,
ACCREG_cycles = 1,
ACCREG_COUNT
};
@@ -15,5 +14,4 @@ void codegen_accumulate(int acc_reg, int delta);
void codegen_accumulate_flush(struct ir_data_t *ir);
void codegen_accumulate_reset();
#endif /* _CODEGEN_ACCUMULATE_H_ */

View File

@@ -4,12 +4,12 @@
/*The allocator handles all allocation of executable memory. Since the two-pass
recompiler design makes applying hard limits to codeblock size difficult, the
allocator allows memory to be provided as and when required.
The allocator provides a block size of a little under 1 kB (slightly lower to
limit cache aliasing). Each generated codeblock is allocated one block by default,
and will allocate additional block(s) once the existing memory is sorted. Blocks
are chained together by jump instructions.
Due to the chaining, the total memory size is limited by the range of a jump
instruction. ARMv7 is restricted to +/- 32 MB, ARMv8 to +/- 128 MB, x86 to
+/- 2GB. As a result, total memory size is limited to 32 MB on ARMv7*/
@@ -19,7 +19,7 @@
#define MEM_BLOCK_NR 131072
#endif
#define MEM_BLOCK_MASK (MEM_BLOCK_NR-1)
#define MEM_BLOCK_MASK (MEM_BLOCK_NR - 1)
#define MEM_BLOCK_SIZE 0x3c0
void codegen_allocator_init();

View File

@@ -31,8 +31,7 @@ extern const uOpFn uop_handlers[];
/*Register will not be preserved across function calls*/
#define HOST_REG_FLAG_VOLATILE (1 << 0)
typedef struct host_reg_def_t
{
typedef struct host_reg_def_t {
int reg;
int flags;
} host_reg_def_t;

View File

@@ -10,7 +10,7 @@
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
#define HASH(l) ((l)&0x1ffff)
#define BLOCK_MAX 0x3c0
@@ -26,5 +26,4 @@ void host_arm_nop(codeblock_t *block);
void codegen_alloc(codeblock_t *block, int size);
#endif /* _CODEGEN_BACKEND_ARM_H_ */

View File

@@ -10,11 +10,10 @@
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
#define HASH(l) ((l)&0x1ffff)
#define BLOCK_MAX 0x3c0
void host_arm64_BLR(codeblock_t *block, int addr_reg);
void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest);
void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data);
@@ -33,5 +32,4 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data);
uint32_t host_arm64_find_imm(uint32_t data);
#endif /* _CODEGEN_BACKEND_ARM64_H_ */

View File

@@ -1,16 +1,16 @@
#ifndef _CODEGEN_BACKEND_ARM64_DEFS_H_
#define _CODEGEN_BACKEND_ARM64_DEFS_H_
#define REG_W0 0
#define REG_W1 1
#define REG_W2 2
#define REG_W3 3
#define REG_W4 4
#define REG_W5 5
#define REG_W6 6
#define REG_W7 7
#define REG_W8 8
#define REG_W9 9
#define REG_W0 0
#define REG_W1 1
#define REG_W2 2
#define REG_W3 3
#define REG_W4 4
#define REG_W5 5
#define REG_W6 6
#define REG_W7 7
#define REG_W8 8
#define REG_W9 9
#define REG_W10 10
#define REG_W11 11
#define REG_W12 12
@@ -34,16 +34,16 @@
#define REG_W30 30
#define REG_WZR 31
#define REG_X0 0
#define REG_X1 1
#define REG_X2 2
#define REG_X3 3
#define REG_X4 4
#define REG_X5 5
#define REG_X6 6
#define REG_X7 7
#define REG_X8 8
#define REG_X9 9
#define REG_X0 0
#define REG_X1 1
#define REG_X2 2
#define REG_X3 3
#define REG_X4 4
#define REG_X5 5
#define REG_X6 6
#define REG_X7 7
#define REG_X8 8
#define REG_X9 9
#define REG_X10 10
#define REG_X11 11
#define REG_X12 12
@@ -67,16 +67,16 @@
#define REG_X30 30
#define REG_XZR 31
#define REG_V0 0
#define REG_V1 1
#define REG_V2 2
#define REG_V3 3
#define REG_V4 4
#define REG_V5 5
#define REG_V6 6
#define REG_V7 7
#define REG_V8 8
#define REG_V9 9
#define REG_V0 0
#define REG_V1 1
#define REG_V2 2
#define REG_V3 3
#define REG_V4 4
#define REG_V5 5
#define REG_V6 6
#define REG_V7 7
#define REG_V8 8
#define REG_V9 9
#define REG_V10 10
#define REG_V11 11
#define REG_V12 12
@@ -109,7 +109,7 @@
#define REG_CPUSTATE REG_X29
#define REG_TEMP REG_X7
#define REG_TEMP REG_X7
#define REG_TEMP2 REG_X6
#define REG_V_TEMP REG_V0
@@ -137,5 +137,4 @@ extern void *codegen_fp_round_quad;
extern void *codegen_gpf_rout;
extern void *codegen_exit_rout;
#endif /* _CODEGEN_BACKEND_ARM64_DEFS_H_ */

View File

@@ -254,17 +254,14 @@ void host_arm64_call(codeblock_t *block, void *dst_addr);
void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr);
void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data);
#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7))
#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset)&7))
#define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000))
#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset) & 1))
#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3))
#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7))
#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset)&1))
#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset)&3))
#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset)&7))
void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p);
void codegen_alloc(codeblock_t *block, int size);
#endif /* _CODEGEN_BACKEND_ARM64_OPS_H_ */

View File

@@ -1,22 +1,22 @@
#ifndef _CODEGEN_BACKEND_ARM_DEFS_H_
#define _CODEGEN_BACKEND_ARM_DEFS_H_
#define REG_R0 0
#define REG_R1 1
#define REG_R2 2
#define REG_R3 3
#define REG_R4 4
#define REG_R5 5
#define REG_R6 6
#define REG_R7 7
#define REG_R8 8
#define REG_R9 9
#define REG_R0 0
#define REG_R1 1
#define REG_R2 2
#define REG_R3 3
#define REG_R4 4
#define REG_R5 5
#define REG_R6 6
#define REG_R7 7
#define REG_R8 8
#define REG_R9 9
#define REG_R10 10
#define REG_R11 11
#define REG_R12 12
#define REG_HOST_SP 13
#define REG_LR 14
#define REG_PC 15
#define REG_HOST_SP 13
#define REG_LR 14
#define REG_PC 15
#define REG_ARG0 REG_R0
#define REG_ARG1 REG_R1
@@ -25,19 +25,19 @@
#define REG_CPUSTATE REG_R10
#define REG_TEMP REG_R3
#define REG_TEMP REG_R3
#define REG_TEMP2 REG_R2
#define REG_D0 0
#define REG_D1 1
#define REG_D2 2
#define REG_D3 3
#define REG_D4 4
#define REG_D5 5
#define REG_D6 6
#define REG_D7 7
#define REG_D8 8
#define REG_D9 9
#define REG_D0 0
#define REG_D1 1
#define REG_D2 2
#define REG_D3 3
#define REG_D4 4
#define REG_D5 5
#define REG_D6 6
#define REG_D7 7
#define REG_D8 8
#define REG_D9 9
#define REG_D10 10
#define REG_D11 11
#define REG_D12 12
@@ -46,28 +46,28 @@
#define REG_D15 15
#define REG_D_TEMP REG_D0
#define REG_Q_TEMP REG_D0
#define REG_Q_TEMP REG_D0
#define REG_Q_TEMP_2 REG_D2
#define REG_MASK_R0 (1 << REG_R0)
#define REG_MASK_R1 (1 << REG_R1)
#define REG_MASK_R2 (1 << REG_R2)
#define REG_MASK_R3 (1 << REG_R3)
#define REG_MASK_R4 (1 << REG_R4)
#define REG_MASK_R5 (1 << REG_R5)
#define REG_MASK_R6 (1 << REG_R6)
#define REG_MASK_R7 (1 << REG_R7)
#define REG_MASK_R8 (1 << REG_R8)
#define REG_MASK_R9 (1 << REG_R9)
#define REG_MASK_R0 (1 << REG_R0)
#define REG_MASK_R1 (1 << REG_R1)
#define REG_MASK_R2 (1 << REG_R2)
#define REG_MASK_R3 (1 << REG_R3)
#define REG_MASK_R4 (1 << REG_R4)
#define REG_MASK_R5 (1 << REG_R5)
#define REG_MASK_R6 (1 << REG_R6)
#define REG_MASK_R7 (1 << REG_R7)
#define REG_MASK_R8 (1 << REG_R8)
#define REG_MASK_R9 (1 << REG_R9)
#define REG_MASK_R10 (1 << REG_R10)
#define REG_MASK_R11 (1 << REG_R11)
#define REG_MASK_R12 (1 << REG_R12)
#define REG_MASK_SP (1 << REG_HOST_SP)
#define REG_MASK_LR (1 << REG_LR)
#define REG_MASK_PC (1 << REG_PC)
#define REG_MASK_SP (1 << REG_HOST_SP)
#define REG_MASK_LR (1 << REG_LR)
#define REG_MASK_PC (1 << REG_PC)
#define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \
REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11)
#define REG_MASK_LOCAL \
(REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11)
#define CODEGEN_HOST_REGS 7
#define CODEGEN_HOST_FP_REGS 8
@@ -91,5 +91,4 @@ extern void *codegen_fp_round;
extern void *codegen_gpf_rout;
extern void *codegen_exit_rout;
#endif /* _CODEGEN_BACKEND_ARM_DEFS_H_ */

View File

@@ -105,7 +105,8 @@ void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int s
void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift);
#define host_arm_ORR_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_AL, dst_reg, src_reg, imm)
#define host_arm_ORR_REG_LSL(block, dst_reg, src_reg_a, src_reg_b, shift) host_arm_ORR_REG_LSL_cond(block, COND_AL, dst_reg, src_reg_a, src_reg_b, shift)
#define host_arm_ORR_REG_LSL(block, dst_reg, src_reg_a, src_reg_b, shift) \
host_arm_ORR_REG_LSL_cond(block, COND_AL, dst_reg, src_reg_a, src_reg_b, shift)
#define host_arm_ORRCC_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_CC, dst_reg, src_reg, imm)
#define host_arm_ORREQ_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_EQ, dst_reg, src_reg, imm)
@@ -254,5 +255,4 @@ void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg);
void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg);
void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg);
#endif /* _CODEGEN_BACKEND_ARM_OPS_H_ */

View File

@@ -10,11 +10,10 @@
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
#define HASH(l) ((l)&0x1ffff)
#define BLOCK_MAX 0x3c0
#define CODEGEN_BACKEND_HAS_MOV_IMM
#endif /* _CODEGEN_BACKEND_X86_64_H_ */

View File

@@ -30,8 +30,8 @@
#define REG_RBP 5
#define REG_RSI 6
#define REG_RDI 7
#define REG_R8 8
#define REG_R9 9
#define REG_R8 8
#define REG_R9 9
#define REG_R10 10
#define REG_R11 11
#define REG_R12 12
@@ -70,5 +70,4 @@ extern void *codegen_mem_store_double;
extern void *codegen_gpf_rout;
extern void *codegen_exit_rout;
#endif /* _CODEGEN_BACKEND_X86_64_DEFS_H_ */

View File

@@ -198,5 +198,4 @@ void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
#endif /* _CODEGEN_BACKEND_X86_64_OPS_H_ */

View File

@@ -3,29 +3,23 @@
#define JMP_LEN_BYTES 5
static inline void codegen_addbyte(codeblock_t *block, uint8_t val)
{
if (block_pos >= BLOCK_MAX)
{
static inline void codegen_addbyte(codeblock_t *block, uint8_t val) {
if (block_pos >= BLOCK_MAX) {
fatal("codegen_addbyte over! %i\n", block_pos);
// CPU_BLOCK_END();
// CPU_BLOCK_END();
}
block_write_data[block_pos++] = val;
}
static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb)
{
if (block_pos > (BLOCK_MAX-2))
{
static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) {
if (block_pos > (BLOCK_MAX - 2)) {
fatal("codegen_addbyte2 over! %i\n", block_pos);
CPU_BLOCK_END();
}
block_write_data[block_pos++] = vala;
block_write_data[block_pos++] = valb;
}
static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc)
{
if (block_pos > (BLOCK_MAX-3))
{
static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) {
if (block_pos > (BLOCK_MAX - 3)) {
fatal("codegen_addbyte3 over! %i\n", block_pos);
CPU_BLOCK_END();
}
@@ -33,10 +27,8 @@ static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t va
block_write_data[block_pos++] = valb;
block_write_data[block_pos++] = valc;
}
static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald)
{
if (block_pos > (BLOCK_MAX-4))
{
static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) {
if (block_pos > (BLOCK_MAX - 4)) {
fatal("codegen_addbyte4 over! %i\n", block_pos);
CPU_BLOCK_END();
}
@@ -46,10 +38,8 @@ static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t va
block_write_data[block_pos++] = vald;
}
static inline void codegen_addword(codeblock_t *block, uint16_t val)
{
if (block_pos > (BLOCK_MAX-2))
{
static inline void codegen_addword(codeblock_t *block, uint16_t val) {
if (block_pos > (BLOCK_MAX - 2)) {
fatal("codegen_addword over! %i\n", block_pos);
CPU_BLOCK_END();
}
@@ -57,10 +47,8 @@ static inline void codegen_addword(codeblock_t *block, uint16_t val)
block_pos += 2;
}
static inline void codegen_addlong(codeblock_t *block, uint32_t val)
{
if (block_pos > (BLOCK_MAX-4))
{
static inline void codegen_addlong(codeblock_t *block, uint32_t val) {
if (block_pos > (BLOCK_MAX - 4)) {
fatal("codegen_addlong over! %i\n", block_pos);
CPU_BLOCK_END();
}
@@ -68,10 +56,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
block_pos += 4;
}
static inline void codegen_addquad(codeblock_t *block, uint64_t val)
{
if (block_pos > (BLOCK_MAX-8))
{
static inline void codegen_addquad(codeblock_t *block, uint64_t val) {
if (block_pos > (BLOCK_MAX - 8)) {
fatal("codegen_addquad over! %i\n", block_pos);
CPU_BLOCK_END();
}
@@ -79,10 +65,8 @@ static inline void codegen_addquad(codeblock_t *block, uint64_t val)
block_pos += 8;
}
static inline void codegen_alloc_bytes(codeblock_t *block, int size)
{
if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES))
{
static inline void codegen_alloc_bytes(codeblock_t *block, int size) {
if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) {
/*Current block is full. Allocate a new block*/
struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block));
uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block);
@@ -97,12 +81,10 @@ static inline void codegen_alloc_bytes(codeblock_t *block, int size)
}
}
static inline int is_imm8(uint32_t imm_data)
{
static inline int is_imm8(uint32_t imm_data) {
if (imm_data <= 0x7f || imm_data >= 0xffffff80)
return 1;
return 0;
}
#endif /* _CODEGEN_BACKEND_X86_64_OPS_HELPERS_H_ */

View File

@@ -4,7 +4,7 @@
void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
#define CMPPS_EQ 0
#define CMPPS_EQ 0
#define CMPPS_NLT 5
#define CMPPS_NLE 6
void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type);
@@ -36,11 +36,13 @@ void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg
void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg);
void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg);
void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift,
int src_reg);
void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg);
void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift);
void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b,
int shift);
void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
@@ -116,5 +118,4 @@ void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
#endif /* _CODEGEN_BACKEND_X86_64_OPS_SSE_H_ */

View File

@@ -10,11 +10,10 @@
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
#define HASH(l) ((l)&0x1ffff)
#define BLOCK_MAX 0x3c0
#define CODEGEN_BACKEND_HAS_MOV_IMM
#endif /* _CODEGEN_BACKEND_X86_H_ */

View File

@@ -19,7 +19,7 @@
#define REG_XMM6 6
#define REG_XMM7 7
#define REG_XMM_TEMP REG_XMM7
#define REG_XMM_TEMP REG_XMM7
#define REG_XMM_TEMP2 REG_XMM6
#define CODEGEN_HOST_REGS 3

View File

@@ -197,5 +197,4 @@ void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data);
void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data);
void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data);
#endif /* _CODEGEN_BACKEND_X86_OPS_H_ */

View File

@@ -7,5 +7,4 @@ void host_x87_FLDCW(codeblock_t *block, void *p);
void host_x87_FLDd_BASE(codeblock_t *block, int base_reg);
void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg);
#endif /* _CODEGEN_BACKEND_X86_OPS_FPU_H_ */

View File

@@ -3,30 +3,26 @@
#define JMP_LEN_BYTES 5
static inline void codegen_addbyte(codeblock_t *block, uint8_t val)
{
static inline void codegen_addbyte(codeblock_t *block, uint8_t val) {
if (block_pos >= BLOCK_MAX)
fatal("codegen_addbyte over! %i\n", block_pos);
block_write_data[block_pos++] = val;
}
static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb)
{
if (block_pos > (BLOCK_MAX-2))
static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) {
if (block_pos > (BLOCK_MAX - 2))
fatal("codegen_addbyte2 over! %i\n", block_pos);
block_write_data[block_pos++] = vala;
block_write_data[block_pos++] = valb;
}
static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc)
{
if (block_pos > (BLOCK_MAX-3))
static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) {
if (block_pos > (BLOCK_MAX - 3))
fatal("codegen_addbyte3 over! %i\n", block_pos);
block_write_data[block_pos++] = vala;
block_write_data[block_pos++] = valb;
block_write_data[block_pos++] = valc;
}
static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald)
{
if (block_pos > (BLOCK_MAX-4))
static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) {
if (block_pos > (BLOCK_MAX - 4))
fatal("codegen_addbyte4 over! %i\n", block_pos);
block_write_data[block_pos++] = vala;
block_write_data[block_pos++] = valb;
@@ -34,32 +30,28 @@ static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t va
block_write_data[block_pos++] = vald;
}
static inline void codegen_addword(codeblock_t *block, uint16_t val)
{
if (block_pos > (BLOCK_MAX-2))
static inline void codegen_addword(codeblock_t *block, uint16_t val) {
if (block_pos > (BLOCK_MAX - 2))
fatal("codegen_addword over! %i\n", block_pos);
*(uint16_t *)&block_write_data[block_pos] = val;
block_pos += 2;
}
static inline void codegen_addlong(codeblock_t *block, uint32_t val)
{
if (block_pos > (BLOCK_MAX-4))
static inline void codegen_addlong(codeblock_t *block, uint32_t val) {
if (block_pos > (BLOCK_MAX - 4))
fatal("codegen_addlong over! %i\n", block_pos);
*(uint32_t *)&block_write_data[block_pos] = val;
block_pos += 4;
}
static inline void codegen_addquad(codeblock_t *block, uint64_t val)
{
if (block_pos > (BLOCK_MAX-8))
static inline void codegen_addquad(codeblock_t *block, uint64_t val) {
if (block_pos > (BLOCK_MAX - 8))
fatal("codegen_addquad over! %i\n", block_pos);
*(uint64_t *)&block_write_data[block_pos] = val;
block_pos += 8;
}
static void codegen_allocate_new_block(codeblock_t *block)
{
static void codegen_allocate_new_block(codeblock_t *block) {
/*Current block is full. Allocate a new block*/
struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block));
uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block);
@@ -73,18 +65,15 @@ static void codegen_allocate_new_block(codeblock_t *block)
block_write_data = new_ptr;
}
static inline void codegen_alloc_bytes(codeblock_t *block, int size)
{
static inline void codegen_alloc_bytes(codeblock_t *block, int size) {
if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES))
codegen_allocate_new_block(block);
}
static inline int is_imm8(uint32_t imm_data)
{
static inline int is_imm8(uint32_t imm_data) {
if (imm_data <= 0x7f || imm_data >= 0xffffff80)
return 1;
return 0;
}
#endif /* _CODEGEN_BACKEND_X86_OPS_HELPERS_H_ */

View File

@@ -4,7 +4,7 @@
void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
#define CMPPS_EQ 0
#define CMPPS_EQ 0
#define CMPPS_NLT 5
#define CMPPS_NLE 6
void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type);
@@ -36,13 +36,15 @@ void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg
void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg);
void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg);
void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift,
int src_reg);
void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg);
void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg);
void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift);
void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b,
int shift);
void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
@@ -113,5 +115,4 @@ void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
#endif /* _CODEGEN_BACKEND_X86_OPS_SSE_H_ */

View File

@@ -8,5 +8,4 @@ ir_data_t *codegen_ir_init();
void codegen_ir_set_unroll(int count, int start, int first_instruction);
void codegen_ir_compile(ir_data_t *ir, codeblock_t *block);
#endif /* _CODEGEN_IR_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
struct ir_data_t;
typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
uint32_t op_pc);
extern RecompOpFn recomp_opcodes[512];
extern RecompOpFn recomp_opcodes_0f[512];

View File

@@ -17,5 +17,4 @@ uint32_t ropPFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_3DNOW_H_ */

View File

@@ -57,7 +57,6 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
@@ -66,5 +65,4 @@ uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_ARITH_H_ */

View File

@@ -71,5 +71,4 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_BRANCH_H_ */

View File

@@ -65,5 +65,4 @@ uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_FPU_ARITH_H_ */

View File

@@ -4,5 +4,4 @@
uint32_t ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_FPU_CONSTANT_H_ */

View File

@@ -19,5 +19,4 @@ uint32_t ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
uint32_t ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_FPU_LOADSTORE_H_ */

View File

@@ -14,5 +14,4 @@ uint32_t ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint32_t ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_FPU_MISC_H_ */

View File

@@ -4,100 +4,78 @@
#include "386_common.h"
#include "codegen_backend.h"
static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset)
{
if (stack32)
{
if (offset)
{
static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) {
if (stack32) {
if (offset) {
uop_ADD_IMM(ir, IREG_eaaddr, IREG_ESP, offset);
return IREG_eaaddr;
}
else
} else
return IREG_ESP;
}
else
{
if (offset)
{
} else {
if (offset) {
uop_ADD_IMM(ir, IREG_eaaddr_W, IREG_SP, offset);
uop_MOVZX(ir, IREG_eaaddr, IREG_eaaddr_W);
return IREG_eaaddr;
}
else
{
} else {
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
return IREG_eaaddr;
}
}
}
static inline int LOAD_SP(ir_data_t *ir)
{
return LOAD_SP_WITH_OFFSET(ir, 0);
}
static inline int LOAD_SP(ir_data_t *ir) { return LOAD_SP_WITH_OFFSET(ir, 0); }
static inline void ADD_SP(ir_data_t *ir, int offset)
{
static inline void ADD_SP(ir_data_t *ir, int offset) {
if (stack32)
uop_ADD_IMM(ir, IREG_ESP, IREG_ESP, offset);
else
uop_ADD_IMM(ir, IREG_SP, IREG_SP, offset);
}
static inline void SUB_SP(ir_data_t *ir, int offset)
{
static inline void SUB_SP(ir_data_t *ir, int offset) {
if (stack32)
uop_SUB_IMM(ir, IREG_ESP, IREG_ESP, offset);
else
uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset);
}
static inline void fpu_POP(codeblock_t *block, ir_data_t *ir)
{
static inline void fpu_POP(codeblock_t *block, ir_data_t *ir) {
if (block->flags & CODEBLOCK_STATIC_TOP)
uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 1);
else
uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1);
}
static inline void fpu_POP2(codeblock_t *block, ir_data_t *ir)
{
static inline void fpu_POP2(codeblock_t *block, ir_data_t *ir) {
if (block->flags & CODEBLOCK_STATIC_TOP)
uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 2);
else
uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 2);
}
static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir)
{
static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir) {
if (block->flags & CODEBLOCK_STATIC_TOP)
uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP - 1);
else
uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1);
}
static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset)
{
static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) {
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) ||
(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
return;
uop_CMP_JB(ir, addr_reg, ireg_seg_limit_low(seg), codegen_gpf_rout);
if (end_offset)
{
if (end_offset) {
uop_ADD_IMM(ir, IREG_temp3, addr_reg, end_offset);
uop_CMP_JNBE(ir, IREG_temp3, ireg_seg_limit_high(seg), codegen_gpf_rout);
}
else
} else
uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout);
}
static inline void LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr)
{
static inline void LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) {
uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr));
}
void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr);
static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr)
{
static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) {
if ((addr & 0xfff) == 0xfff)
LOAD_IMMEDIATE_FROM_RAM_16_unaligned(block, ir, dest_reg, addr);
else
@@ -105,8 +83,7 @@ static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir,
}
void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr);
static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr)
{
static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) {
if ((addr & 0xfff) >= 0xffd)
LOAD_IMMEDIATE_FROM_RAM_32_unaligned(block, ir, dest_reg, addr);
else
@@ -114,19 +91,17 @@ static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir,
}
int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr);
static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr)
{
static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) {
if (block->flags & CODEBLOCK_BYTE_MASK)
return 0;
/*Is dest within block?*/
if (dest_addr > next_pc)
return 0;
if ((cs+dest_addr) < block->pc)
if ((cs + dest_addr) < block->pc)
return 0;
return codegen_can_unroll_full(block, ir, next_pc, dest_addr);
}
#endif /* _CODEGEN_OPS_HELPERS_H_ */

View File

@@ -23,5 +23,4 @@ uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_JUMP_H_ */

View File

@@ -38,5 +38,4 @@ uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_LOGIC_H_ */

View File

@@ -39,5 +39,4 @@ uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc
uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_MISC_H_ */

View File

@@ -20,5 +20,4 @@ uint32_t ropPMADDWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint32_t ropPMULHW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPMULLW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_MMX_ARITH_H_ */

View File

@@ -7,5 +7,4 @@ uint32_t ropPCMPGTB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint32_t ropPCMPGTW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPCMPGTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_MMX_CMP_H_ */

View File

@@ -6,5 +6,4 @@ uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_MMX_LOADSTORE_H_ */

View File

@@ -5,5 +5,4 @@ uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_MMX_LOGIC_H_ */

View File

@@ -10,5 +10,4 @@ uint32_t ropPUNPCKHBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
uint32_t ropPUNPCKHWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPUNPCKHDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_MMX_PACK_H_ */

View File

@@ -8,5 +8,4 @@ uint32_t ropPSLLW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
uint32_t ropPSLLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPSLLQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_MMX_SHIFT_H_ */

View File

@@ -44,5 +44,4 @@ uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_MOV_H_ */

View File

@@ -17,5 +17,4 @@ uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3
uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_SHIFT_H_ */

View File

@@ -50,5 +50,4 @@ uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
#endif /* _CODEGEN_OPS_STACK_H_ */

View File

@@ -5,44 +5,43 @@
#define IREG_SIZE_SHIFT 8
#define IREG_SIZE_MASK (7 << IREG_SIZE_SHIFT)
#define IREG_GET_REG(reg) ((reg) & IREG_REG_MASK)
#define IREG_GET_SIZE(reg) ((reg) & IREG_SIZE_MASK)
#define IREG_GET_REG(reg) ((reg)&IREG_REG_MASK)
#define IREG_GET_SIZE(reg) ((reg)&IREG_SIZE_MASK)
#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT)
#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT)
#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT)
#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT)
#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT)
#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT)
#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT)
#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT)
#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT)
#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT)
#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT)
enum
{
IREG_EAX = 0,
IREG_ECX = 1,
IREG_EDX = 2,
IREG_EBX = 3,
IREG_ESP = 4,
IREG_EBP = 5,
IREG_ESI = 6,
IREG_EDI = 7,
enum {
IREG_EAX = 0,
IREG_ECX = 1,
IREG_EDX = 2,
IREG_EBX = 3,
IREG_ESP = 4,
IREG_EBP = 5,
IREG_ESI = 6,
IREG_EDI = 7,
IREG_flags_op = 8,
IREG_flags_res = 9,
IREG_flags_op1 = 10,
IREG_flags_op2 = 11,
IREG_flags_op = 8,
IREG_flags_res = 9,
IREG_flags_op1 = 10,
IREG_flags_op2 = 11,
IREG_pc = 12,
IREG_oldpc = 13,
IREG_pc = 12,
IREG_oldpc = 13,
IREG_eaaddr = 14,
IREG_ea_seg = 15,
IREG_op32 = 16,
IREG_ssegsx = 17,
IREG_rm_mod_reg = 18,
IREG_ins = 19,
IREG_cycles = 20,
IREG_eaaddr = 14,
IREG_ea_seg = 15,
IREG_op32 = 16,
IREG_ssegsx = 17,
IREG_rm_mod_reg = 18,
IREG_ins = 19,
IREG_cycles = 20,
IREG_CS_base = 21,
IREG_DS_base = 22,
@@ -58,19 +57,19 @@ enum
IREG_GS_seg = 31,
IREG_SS_seg = 32,
/*Temporary registers are stored on the stack, and are not guaranteed to
/*Temporary registers are stored on the stack, and are not guaranteed to
be preserved across uOPs. They will not be written back if they will
not be read again.*/
IREG_temp0 = 33,
IREG_temp1 = 34,
IREG_temp2 = 35,
IREG_temp3 = 36,
IREG_temp0 = 33,
IREG_temp1 = 34,
IREG_temp2 = 35,
IREG_temp3 = 36,
IREG_FPU_TOP = 37,
IREG_temp0d = 38,
IREG_temp1d = 39,
IREG_temp0d = 38,
IREG_temp1d = 39,
/*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag()
to access.
When CODEBLOCK_STATIC_TOP is set, the physical register number will be
@@ -85,7 +84,7 @@ enum
IREG_ST5 = 45,
IREG_ST6 = 46,
IREG_ST7 = 47,
IREG_tag0 = 48,
IREG_tag1 = 49,
IREG_tag2 = 50,
@@ -103,7 +102,7 @@ enum
IREG_ST5_i64 = 61,
IREG_ST6_i64 = 62,
IREG_ST7_i64 = 63,
IREG_MM0x = 64,
IREG_MM1x = 65,
IREG_MM2x = 66,
@@ -112,13 +111,13 @@ enum
IREG_MM5x = 69,
IREG_MM6x = 70,
IREG_MM7x = 71,
IREG_NPXCx = 72,
IREG_NPXSx = 73,
IREG_flagsx = 74,
IREG_eflagsx = 75,
IREG_CS_limit_low = 76,
IREG_DS_limit_low = 77,
IREG_ES_limit_low = 78,
@@ -133,62 +132,62 @@ enum
IREG_GS_limit_high = 86,
IREG_SS_limit_high = 87,
IREG_COUNT = 88,
IREG_INVALID = 255,
IREG_AX = IREG_EAX + IREG_SIZE_W,
IREG_CX = IREG_ECX + IREG_SIZE_W,
IREG_DX = IREG_EDX + IREG_SIZE_W,
IREG_BX = IREG_EBX + IREG_SIZE_W,
IREG_SP = IREG_ESP + IREG_SIZE_W,
IREG_BP = IREG_EBP + IREG_SIZE_W,
IREG_SI = IREG_ESI + IREG_SIZE_W,
IREG_DI = IREG_EDI + IREG_SIZE_W,
IREG_COUNT = 88,
IREG_AL = IREG_EAX + IREG_SIZE_B,
IREG_CL = IREG_ECX + IREG_SIZE_B,
IREG_DL = IREG_EDX + IREG_SIZE_B,
IREG_BL = IREG_EBX + IREG_SIZE_B,
IREG_INVALID = 255,
IREG_AH = IREG_EAX + IREG_SIZE_BH,
IREG_CH = IREG_ECX + IREG_SIZE_BH,
IREG_DH = IREG_EDX + IREG_SIZE_BH,
IREG_BH = IREG_EBX + IREG_SIZE_BH,
IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W,
IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W,
IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W,
IREG_AX = IREG_EAX + IREG_SIZE_W,
IREG_CX = IREG_ECX + IREG_SIZE_W,
IREG_DX = IREG_EDX + IREG_SIZE_W,
IREG_BX = IREG_EBX + IREG_SIZE_W,
IREG_SP = IREG_ESP + IREG_SIZE_W,
IREG_BP = IREG_EBP + IREG_SIZE_W,
IREG_SI = IREG_ESI + IREG_SIZE_W,
IREG_DI = IREG_EDI + IREG_SIZE_W,
IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B,
IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B,
IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B,
IREG_AL = IREG_EAX + IREG_SIZE_B,
IREG_CL = IREG_ECX + IREG_SIZE_B,
IREG_DL = IREG_EDX + IREG_SIZE_B,
IREG_BL = IREG_EBX + IREG_SIZE_B,
IREG_temp0_W = IREG_temp0 + IREG_SIZE_W,
IREG_temp1_W = IREG_temp1 + IREG_SIZE_W,
IREG_temp2_W = IREG_temp2 + IREG_SIZE_W,
IREG_temp3_W = IREG_temp3 + IREG_SIZE_W,
IREG_temp0_B = IREG_temp0 + IREG_SIZE_B,
IREG_temp1_B = IREG_temp1 + IREG_SIZE_B,
IREG_temp2_B = IREG_temp2 + IREG_SIZE_B,
IREG_temp3_B = IREG_temp3 + IREG_SIZE_B,
IREG_AH = IREG_EAX + IREG_SIZE_BH,
IREG_CH = IREG_ECX + IREG_SIZE_BH,
IREG_DH = IREG_EDX + IREG_SIZE_BH,
IREG_BH = IREG_EBX + IREG_SIZE_BH,
IREG_temp0_D = IREG_temp0d + IREG_SIZE_D,
IREG_temp1_D = IREG_temp1d + IREG_SIZE_D,
IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W,
IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W,
IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W,
IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q,
IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q,
IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B,
IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B,
IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B,
IREG_temp0_W = IREG_temp0 + IREG_SIZE_W,
IREG_temp1_W = IREG_temp1 + IREG_SIZE_W,
IREG_temp2_W = IREG_temp2 + IREG_SIZE_W,
IREG_temp3_W = IREG_temp3 + IREG_SIZE_W,
IREG_temp0_B = IREG_temp0 + IREG_SIZE_B,
IREG_temp1_B = IREG_temp1 + IREG_SIZE_B,
IREG_temp2_B = IREG_temp2 + IREG_SIZE_B,
IREG_temp3_B = IREG_temp3 + IREG_SIZE_B,
IREG_temp0_D = IREG_temp0d + IREG_SIZE_D,
IREG_temp1_D = IREG_temp1d + IREG_SIZE_D,
IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q,
IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q,
IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W,
IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W,
IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W,
IREG_DS_seg_W = IREG_DS_seg + IREG_SIZE_W,
IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W,
IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W,
IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W,
IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W,
IREG_MM0 = IREG_MM0x + IREG_SIZE_Q,
IREG_MM1 = IREG_MM1x + IREG_SIZE_Q,
IREG_MM2 = IREG_MM2x + IREG_SIZE_Q,
@@ -197,22 +196,22 @@ enum
IREG_MM5 = IREG_MM5x + IREG_SIZE_Q,
IREG_MM6 = IREG_MM6x + IREG_SIZE_Q,
IREG_MM7 = IREG_MM7x + IREG_SIZE_Q,
IREG_NPXC = IREG_NPXCx + IREG_SIZE_W,
IREG_NPXS = IREG_NPXSx + IREG_SIZE_W,
IREG_ssegs = IREG_ssegsx + IREG_SIZE_B,
IREG_flags = IREG_flagsx + IREG_SIZE_W,
IREG_eflags = IREG_eflagsx + IREG_SIZE_W
};
#define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL))
#define IREG_8(reg) (((reg)&4) ? (((reg)&3) + IREG_AH) : ((reg) + IREG_AL))
#define IREG_16(reg) ((reg) + IREG_AX)
#define IREG_32(reg) ((reg) + IREG_EAX)
#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D)
#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q)
#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D)
#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q)
#define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7))
#define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B)
@@ -220,8 +219,7 @@ enum
#define IREG_TOP_diff_stack_offset 32
static inline int ireg_seg_base(x86seg *seg)
{
static inline int ireg_seg_base(x86seg *seg) {
if (seg == &cpu_state.seg_cs)
return IREG_CS_base;
if (seg == &cpu_state.seg_ds)
@@ -238,8 +236,7 @@ static inline int ireg_seg_base(x86seg *seg)
return 0;
}
static inline int ireg_seg_limit_low(x86seg *seg)
{
static inline int ireg_seg_limit_low(x86seg *seg) {
if (seg == &cpu_state.seg_cs)
return IREG_CS_limit_low;
if (seg == &cpu_state.seg_ds)
@@ -255,8 +252,7 @@ static inline int ireg_seg_limit_low(x86seg *seg)
fatal("ireg_seg_limit_low : unknown segment\n");
return 0;
}
static inline int ireg_seg_limit_high(x86seg *seg)
{
static inline int ireg_seg_limit_high(x86seg *seg) {
if (seg == &cpu_state.seg_cs)
return IREG_CS_limit_high;
if (seg == &cpu_state.seg_ds)
@@ -279,10 +275,9 @@ extern uint8_t reg_last_version[IREG_COUNT];
apparently required or not. Do not optimise out.*/
#define REG_FLAGS_REQUIRED (1 << 0)
/*This register and the parent uOP have been optimised out.*/
#define REG_FLAGS_DEAD (1 << 1)
#define REG_FLAGS_DEAD (1 << 1)
typedef struct
{
typedef struct {
/*Refcount of pending reads on this register version*/
uint8_t refcount;
/*Flags*/
@@ -299,14 +294,12 @@ extern reg_version_t reg_version[IREG_COUNT][256];
can be optimised out*/
extern uint16_t reg_dead_list;
static inline void add_to_dead_list(reg_version_t *regv, int reg, int version)
{
static inline void add_to_dead_list(reg_version_t *regv, int reg, int version) {
regv->next = reg_dead_list;
reg_dead_list = version | (reg << 8);
}
typedef struct
{
typedef struct {
uint16_t reg;
uint16_t version;
} ir_reg_t;
@@ -320,11 +313,10 @@ extern int max_version_refcount;
#define REG_VERSION_MAX 250
#define REG_REFCOUNT_MAX 250
static inline ir_reg_t codegen_reg_read(int reg)
{
static inline ir_reg_t codegen_reg_read(int reg) {
ir_reg_t ireg;
reg_version_t *version;
#ifndef RELEASE_BUILD
if (IREG_GET_REG(reg) == IREG_INVALID)
fatal("codegen_reg_read - IREG_INVALID\n");
@@ -339,43 +331,43 @@ static inline ir_reg_t codegen_reg_read(int reg)
fatal("codegen_reg_read - refcount overflow\n");
else
#endif
if (version->refcount > REG_REFCOUNT_MAX)
if (version->refcount > REG_REFCOUNT_MAX)
CPU_BLOCK_END();
if (version->refcount > max_version_refcount)
max_version_refcount = version->refcount;
// pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]);
// pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version,
// reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]);
return ireg;
}
int reg_is_native_size(ir_reg_t ir_reg);
static inline ir_reg_t codegen_reg_write(int reg, int uop_nr)
{
static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) {
ir_reg_t ireg;
int last_version = reg_last_version[IREG_GET_REG(reg)];
reg_version_t *version;
#ifndef RELEASE_BUILD
if (IREG_GET_REG(reg) == IREG_INVALID)
fatal("codegen_reg_write - IREG_INVALID\n");
#endif
ireg.reg = reg;
ireg.version = last_version + 1;
if (IREG_GET_REG(reg) > IREG_EBX && last_version && !reg_version[IREG_GET_REG(reg)][last_version].refcount &&
!(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED))
{
if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so don't add to dead list*/
!(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) {
if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so
don't add to dead list*/
add_to_dead_list(&reg_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version);
}
reg_last_version[IREG_GET_REG(reg)]++;
#ifndef RELEASE_BUILD
if (!reg_last_version[IREG_GET_REG(reg)])
fatal("codegen_reg_write - version overflow\n");
else
#endif
if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX)
if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX)
CPU_BLOCK_END();
if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount)
max_version_refcount = reg_last_version[IREG_GET_REG(reg)];
@@ -384,14 +376,11 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr)
version->refcount = 0;
version->flags = 0;
version->parent_uop = uop_nr;
// pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK);
// pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK);
return ireg;
}
static inline int ir_reg_is_invalid(ir_reg_t ir_reg)
{
return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID);
}
static inline int ir_reg_is_invalid(ir_reg_t ir_reg) { return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); }
struct ir_data_t;

View File

@@ -5,11 +5,11 @@
/*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)
#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 DSTDEP_RM (1ull << 3)
#define SRCDEP_SHIFT 4
#define DSTDEP_SHIFT 12
@@ -42,46 +42,44 @@
/*Instruction is MMX shift or pack/unpack instruction*/
#define MMX_SHIFTPACK (1ull << 22)
/*Instruction is MMX multiply instruction*/
#define MMX_MULTIPLY (1ull << 23)
#define MMX_MULTIPLY (1ull << 23)
/*Instruction pops the FPU stack*/
#define FPU_POP (1ull << 24)
#define FPU_POP (1ull << 24)
/*Instruction pops the FPU stack twice*/
#define FPU_POP2 (1ull << 25)
#define FPU_POP2 (1ull << 25)
/*Instruction pushes onto the FPU stack*/
#define FPU_PUSH (1ull << 26)
#define FPU_PUSH (1ull << 26)
/*Instruction writes to ST(0)*/
#define FPU_WRITE_ST0 (1ull << 27)
#define FPU_WRITE_ST0 (1ull << 27)
/*Instruction reads from ST(0)*/
#define FPU_READ_ST0 (1ull << 28)
#define FPU_READ_ST0 (1ull << 28)
/*Instruction reads from and writes to ST(0)*/
#define FPU_RW_ST0 (3ull << 27)
#define FPU_RW_ST0 (3ull << 27)
/*Instruction reads from ST(1)*/
#define FPU_READ_ST1 (1ull << 29)
#define FPU_READ_ST1 (1ull << 29)
/*Instruction writes to ST(1)*/
#define FPU_WRITE_ST1 (1ull << 30)
#define FPU_WRITE_ST1 (1ull << 30)
/*Instruction reads from and writes to ST(1)*/
#define FPU_RW_ST1 (3ull << 29)
#define FPU_RW_ST1 (3ull << 29)
/*Instruction reads from ST(reg)*/
#define FPU_READ_STREG (1ull << 31)
#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_RW_STREG (3ull << 30)
#define FPU_FXCH (1ull << 33)
#define HAS_IMM8 (1ull << 34)
#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)
#define REGMASK_MULTIPLY (1 << 9)
extern uint64_t opcode_deps[256];
extern uint64_t opcode_deps_mod3[256];
@@ -120,50 +118,52 @@ 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)
{
static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) {
uint32_t addr_regmask = 0;
if (data & MODRM)
{
if (data & MODRM) {
uint8_t modrm = fetchdat & 0xff;
if ((modrm & 0xc0) != 0xc0)
{
if (op_32 & 0x200)
{
if ((modrm & 0x7) == 4)
{
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)
{
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)
{
} 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;
} 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;
}
}
}
@@ -172,22 +172,19 @@ static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op
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)
{
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)
{
if (data & SRCDEP_REG) {
int reg = (fetchdat >> 3) & 7;
if (bit8)
reg &= 3;
mask |= (1 << reg);
}
if (data & SRCDEP_RM)
{
if (data & SRCDEP_RM) {
int reg = fetchdat & 7;
if (bit8)
reg &= 3;
@@ -204,18 +201,15 @@ static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit
return mask;
}
static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8)
{
static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) {
uint32_t mask = 0;
if (data & DSTDEP_REG)
{
if (data & DSTDEP_REG) {
int reg = (fetchdat >> 3) & 7;
if (bit8)
reg &= 3;
mask |= (1 << reg);
}
if (data & DSTDEP_RM)
{
if (data & DSTDEP_RM) {
int reg = fetchdat & 7;
if (bit8)
reg &= 3;
@@ -232,5 +226,4 @@ static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit
return mask;
}
#endif /* _CODEGEN_TIMING_COMMON_H_ */

View File

@@ -7,22 +7,18 @@
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
#define HASH(l) ((l)&0x1ffff)
#define BLOCK_EXIT_OFFSET 0x7e0
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
#define BLOCK_MAX 1620
enum
{
OP_RET = 0xc3
};
enum { OP_RET = 0xc3 };
#define NR_HOST_REGS 4
extern int host_reg_mapping[NR_HOST_REGS];
#define NR_HOST_XMM_REGS 7
extern int host_reg_xmm_mapping[NR_HOST_XMM_REGS];
#endif /* _CODEGEN_X86_64_H_ */

View File

@@ -1,218 +1,280 @@
#ifndef _386_COMMON_H_
#define _386_COMMON_H_
#define readmemb(s, a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) )
#define readmemw(s, a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmeml(s, a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmemq(s, a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmemb(s, a) \
((readlookup2[(uint32_t)((s) + (a)) >> 12] == -1) \
? readmembl((s) + (a)) \
: *(uint8_t *)(readlookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))))
#define readmemw(s, a) \
((readlookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 1)) \
? readmemwl((s) + (a)) \
: *(uint16_t *)(readlookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))))
#define readmeml(s, a) \
((readlookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 3)) \
? readmemll((s) + (a)) \
: *(uint32_t *)(readlookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))))
#define readmemq(s, a) \
((readlookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 7)) \
? readmemql((s) + (a)) \
: *(uint64_t *)(readlookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))))
#define writememb(s, a, v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememw(s, a, v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememl(s, a, v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememq(s, a, v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememb(s, a, v) \
if (writelookup2[(uint32_t)((s) + (a)) >> 12] == -1) \
writemembl((s) + (a), v); \
else \
*(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememw(s, a, v) \
if (writelookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 1)) \
writememwl((s) + (a), v); \
else \
*(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememl(s, a, v) \
if (writelookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 3)) \
writememll((s) + (a), v); \
else \
*(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememq(s, a, v) \
if (writelookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 7)) \
writememql((s) + (a), v); \
else \
*(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
int checkio(int port);
#define check_io_perm(port) if (!IOPLp || (cpu_state.eflags&VM_FLAG)) \
{ \
int tempi = checkio(port); \
if (cpu_state.abrt) return 1; \
if (tempi) \
{ \
if (cpu_state.eflags & VM_FLAG) \
x86gpf_expected(NULL,0); \
else \
x86gpf(NULL,0); \
return 1; \
} \
}
#define check_io_perm(port) \
if (!IOPLp || (cpu_state.eflags & VM_FLAG)) { \
int tempi = checkio(port); \
if (cpu_state.abrt) \
return 1; \
if (tempi) { \
if (cpu_state.eflags & VM_FLAG) \
x86gpf_expected(NULL, 0); \
else \
x86gpf(NULL, 0); \
return 1; \
} \
}
#define SEG_CHECK_READ(seg) \
do \
{ \
if ((seg)->base == 0xffffffff) \
{ \
x86gpf("Segment can't read", 0);\
return 1; \
} \
#define SEG_CHECK_READ(seg) \
do { \
if ((seg)->base == 0xffffffff) { \
x86gpf("Segment can't read", 0); \
return 1; \
} \
} while (0)
#define SEG_CHECK_WRITE(seg) \
do \
{ \
if ((seg)->base == 0xffffffff) \
{ \
x86gpf("Segment can't write", 0);\
return 1; \
} \
#define SEG_CHECK_WRITE(seg) \
do { \
if ((seg)->base == 0xffffffff) { \
x86gpf("Segment can't write", 0); \
return 1; \
} \
} while (0)
#define CHECK_READ(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((seg)->access & 10) == 8))) \
{ \
x86gpf("Limit check", 0); \
return 1; \
#define CHECK_READ(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || \
((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((seg)->access & 10) == 8))) { \
x86gpf("Limit check", 0); \
return 1; \
}
#define CHECK_WRITE(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || !((seg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((seg)->access & 8))) \
{ \
x86gpf("Limit check", 0); \
return 1; \
#define CHECK_WRITE(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || !((seg)->access & 2) || \
((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((seg)->access & 8))) { \
x86gpf("Limit check", 0); \
return 1; \
}
#define CHECK_WRITE_REP(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \
{ \
x86gpf("Limit check", 0); \
break; \
#define CHECK_WRITE_REP(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) { \
x86gpf("Limit check", 0); \
break; \
}
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
{ \
x86_int(6); \
return 1; \
}
#define NOTRM \
if (!(msw & 1) || (cpu_state.eflags & VM_FLAG)) { \
x86_int(6); \
return 1; \
}
static inline uint8_t fastreadb(uint32_t a) {
uint8_t *t;
uint8_t *t;
if ((a >> 12) == pccache)
return *((uint8_t *)&pccache2[a]);
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
return *((uint8_t *)&pccache2[a]);
if ((a >> 12) == pccache)
return *((uint8_t *)&pccache2[a]);
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
return *((uint8_t *)&pccache2[a]);
}
static inline uint16_t fastreadw(uint32_t a) {
uint8_t *t;
uint16_t val;
if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a);
val |= (fastreadb(a + 1) << 8);
return val;
}
if ((a >> 12) == pccache)
return *((uint16_t *)&pccache2[a]);
t = getpccache(a);
if (cpu_state.abrt)
return 0;
uint8_t *t;
uint16_t val;
if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a);
val |= (fastreadb(a + 1) << 8);
return val;
}
if ((a >> 12) == pccache)
return *((uint16_t *)&pccache2[a]);
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
return *((uint16_t *)&pccache2[a]);
pccache = a >> 12;
pccache2 = t;
return *((uint16_t *)&pccache2[a]);
}
static inline uint32_t fastreadl(uint32_t a) {
uint8_t *t;
uint32_t val;
if ((a & 0xFFF) < 0xFFD) {
if ((a >> 12) != pccache) {
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache2 = t;
pccache = a >> 12;
//return *((uint32_t *)&pccache2[a]);
}
return *((uint32_t *)&pccache2[a]);
}
val = fastreadw(a);
val |= (fastreadw(a + 2) << 16);
return val;
uint8_t *t;
uint32_t val;
if ((a & 0xFFF) < 0xFFD) {
if ((a >> 12) != pccache) {
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache2 = t;
pccache = a >> 12;
// return *((uint32_t *)&pccache2[a]);
}
return *((uint32_t *)&pccache2[a]);
}
val = fastreadw(a);
val |= (fastreadw(a + 2) << 16);
return val;
}
static inline void *get_ram_ptr(uint32_t a) {
if ((a >> 12) == pccache)
return &pccache2[a];
else {
uint8_t *t = getpccache(a);
return &t[a];
}
if ((a >> 12) == pccache)
return &pccache2[a];
else {
uint8_t *t = getpccache(a);
return &t[a];
}
}
static inline uint8_t getbyte() {
cpu_state.pc++;
return fastreadb(cs + (cpu_state.pc - 1));
cpu_state.pc++;
return fastreadb(cs + (cpu_state.pc - 1));
}
static inline uint16_t getword() {
cpu_state.pc += 2;
return fastreadw(cs + (cpu_state.pc - 2));
cpu_state.pc += 2;
return fastreadw(cs + (cpu_state.pc - 2));
}
static inline uint32_t getlong() {
cpu_state.pc += 4;
return fastreadl(cs + (cpu_state.pc - 4));
cpu_state.pc += 4;
return fastreadl(cs + (cpu_state.pc - 4));
}
static inline uint64_t getquad() {
cpu_state.pc += 8;
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t)fastreadl(cs + (cpu_state.pc - 4)) << 32);
cpu_state.pc += 8;
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t)fastreadl(cs + (cpu_state.pc - 4)) << 32);
}
static inline uint8_t geteab() {
if (cpu_mod == 3)
return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l;
if (eal_r)
return *(uint8_t *)eal_r;
return readmemb(easeg, cpu_state.eaaddr);
if (cpu_mod == 3)
return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l;
if (eal_r)
return *(uint8_t *)eal_r;
return readmemb(easeg, cpu_state.eaaddr);
}
static inline uint16_t geteaw() {
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].w;
if (eal_r)
return *(uint16_t *)eal_r;
return readmemw(easeg, cpu_state.eaaddr);
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].w;
if (eal_r)
return *(uint16_t *)eal_r;
return readmemw(easeg, cpu_state.eaaddr);
}
static inline uint32_t geteal() {
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].l;
if (eal_r)
return *eal_r;
return readmeml(easeg, cpu_state.eaaddr);
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].l;
if (eal_r)
return *eal_r;
return readmeml(easeg, cpu_state.eaaddr);
}
static inline uint64_t geteaq() {
return readmemq(easeg, cpu_state.eaaddr);
}
static inline uint64_t geteaq() { return readmemq(easeg, cpu_state.eaaddr); }
static inline uint8_t geteab_mem() {
if (eal_r)
return *(uint8_t *)eal_r;
return readmemb(easeg, cpu_state.eaaddr);
if (eal_r)
return *(uint8_t *)eal_r;
return readmemb(easeg, cpu_state.eaaddr);
}
static inline uint16_t geteaw_mem() {
if (eal_r)
return *(uint16_t *)eal_r;
return readmemw(easeg, cpu_state.eaaddr);
if (eal_r)
return *(uint16_t *)eal_r;
return readmemw(easeg, cpu_state.eaaddr);
}
static inline uint32_t geteal_mem() {
if (eal_r)
return *eal_r;
return readmeml(easeg, cpu_state.eaaddr);
if (eal_r)
return *eal_r;
return readmeml(easeg, cpu_state.eaaddr);
}
static inline void seteaq(uint64_t v) {
writememql(easeg + cpu_state.eaaddr, v);
}
static inline void seteaq(uint64_t v) { writememql(easeg + cpu_state.eaaddr, v); }
#define seteab(v) if (cpu_mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v
#define seteaw(v) if (cpu_mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v
#define seteal(v) if (cpu_mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v
#define seteab(v) \
if (cpu_mod != 3) { \
if (eal_w) \
*(uint8_t *)eal_w = v; \
else \
writemembl(easeg + cpu_state.eaaddr, v); \
} else if (cpu_rm & 4) \
cpu_state.regs[cpu_rm & 3].b.h = v; \
else \
cpu_state.regs[cpu_rm].b.l = v
#define seteaw(v) \
if (cpu_mod != 3) { \
if (eal_w) \
*(uint16_t *)eal_w = v; \
else \
writememwl(easeg + cpu_state.eaaddr, v); \
} else \
cpu_state.regs[cpu_rm].w = v
#define seteal(v) \
if (cpu_mod != 3) { \
if (eal_w) \
*eal_w = v; \
else \
writememll(easeg + cpu_state.eaaddr, v); \
} else \
cpu_state.regs[cpu_rm].l = v
#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v);
#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v);
#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v);
#define seteab_mem(v) \
if (eal_w) \
*(uint8_t *)eal_w = v; \
else \
writemembl(easeg + cpu_state.eaaddr, v);
#define seteaw_mem(v) \
if (eal_w) \
*(uint16_t *)eal_w = v; \
else \
writememwl(easeg + cpu_state.eaaddr, v);
#define seteal_mem(v) \
if (eal_w) \
*eal_w = v; \
else \
writememll(easeg + cpu_state.eaaddr, v);
#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++
#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2
#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++
#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2
#define getbytef() \
((uint8_t)(fetchdat)); \
cpu_state.pc++
#define getwordf() \
((uint16_t)(fetchdat)); \
cpu_state.pc += 2
#define getbyte2f() \
((uint8_t)(fetchdat >> 8)); \
cpu_state.pc++
#define getword2f() \
((uint16_t)(fetchdat >> 8)); \
cpu_state.pc += 2
#endif /* _386_COMMON_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
/*This file is a series of macros to get the 386+ based x87 emulation working with
the 808x emulation*/
#define X8087
#define OP_TABLE(name) ops_808x_ ## name
#define OP_TABLE(name) ops_808x_##name
#define CLOCK_CYCLES(c) cycles -= (c)
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
@@ -16,50 +16,45 @@
#define CHECK_WRITE(seg, addr_lo, addr_hi)
#define PREFETCH_RUN(timing, bytes, rmdat, a, b, c, d, e)
static uint32_t readmeml(uint32_t seg, uint32_t addr) {
return readmemw(seg, addr) | (readmemw(seg, addr + 2) << 16);
}
static uint32_t readmeml(uint32_t seg, uint32_t addr) { return readmemw(seg, addr) | (readmemw(seg, addr + 2) << 16); }
static uint64_t readmemq(uint32_t seg, uint32_t addr) {
return (uint64_t)readmemw(seg, addr) | ((uint64_t)readmemw(seg, addr + 2) << 16) |
((uint64_t)readmemw(seg, addr + 4) << 32) |
((uint64_t)readmemw(seg, addr + 6) << 48);
return (uint64_t)readmemw(seg, addr) | ((uint64_t)readmemw(seg, addr + 2) << 16) |
((uint64_t)readmemw(seg, addr + 4) << 32) | ((uint64_t)readmemw(seg, addr + 6) << 48);
}
static void writememb_8087(uint32_t seg, uint32_t addr, uint8_t val) {
writememb(seg + addr, val);
}
static void writememb_8087(uint32_t seg, uint32_t addr, uint8_t val) { writememb(seg + addr, val); }
static void writememl(uint32_t seg, uint32_t addr, uint32_t val) {
writememw(seg, addr, val & 0xffff);
writememw(seg, addr + 2, (val >> 16) & 0xffff);
writememw(seg, addr, val & 0xffff);
writememw(seg, addr + 2, (val >> 16) & 0xffff);
}
static void writememq(uint32_t seg, uint32_t addr, uint64_t val) {
writememw(seg, addr, val & 0xffff);
writememw(seg, addr + 2, (val >> 16) & 0xffff);
writememw(seg, addr + 4, (val >> 32) & 0xffff);
writememw(seg, addr + 6, (val >> 48) & 0xffff);
writememw(seg, addr, val & 0xffff);
writememw(seg, addr + 2, (val >> 16) & 0xffff);
writememw(seg, addr + 4, (val >> 32) & 0xffff);
writememw(seg, addr + 6, (val >> 48) & 0xffff);
}
static inline uint32_t geteal() {
if (cpu_mod == 3)
fatal("geteal cpu_mod==3\n");
return readmeml(easeg, cpu_state.eaaddr);
if (cpu_mod == 3)
fatal("geteal cpu_mod==3\n");
return readmeml(easeg, cpu_state.eaaddr);
}
static inline uint64_t geteaq() {
if (cpu_mod == 3)
fatal("geteaq cpu_mod==3\n");
return readmemq(easeg, cpu_state.eaaddr);
if (cpu_mod == 3)
fatal("geteaq cpu_mod==3\n");
return readmemq(easeg, cpu_state.eaaddr);
}
static inline void seteal(uint32_t val) {
if (cpu_mod == 3)
fatal("seteal cpu_mod==3\n");
else
writememl(easeg, cpu_state.eaaddr, val);
if (cpu_mod == 3)
fatal("seteal cpu_mod==3\n");
else
writememl(easeg, cpu_state.eaaddr, val);
}
static inline void seteaq(uint64_t val) {
if (cpu_mod == 3)
fatal("seteaq cpu_mod==3\n");
else
writememq(easeg, cpu_state.eaaddr, val);
if (cpu_mod == 3)
fatal("seteaq cpu_mod==3\n");
else
writememq(easeg, cpu_state.eaaddr, val);
}
#define flags_rebuild()
@@ -70,21 +65,21 @@ static inline void seteaq(uint64_t val) {
#define VF_SET() (cpu_state.flags & V_FLAG)
#define ZF_SET() (cpu_state.flags & Z_FLAG)
#define cond_O ( VF_SET())
#define cond_NO (!VF_SET())
#define cond_B ( CF_SET())
#define cond_NB (!CF_SET())
#define cond_E ( ZF_SET())
#define cond_NE (!ZF_SET())
#define cond_BE ( CF_SET() || ZF_SET())
#define cond_O (VF_SET())
#define cond_NO (!VF_SET())
#define cond_B (CF_SET())
#define cond_NB (!CF_SET())
#define cond_E (ZF_SET())
#define cond_NE (!ZF_SET())
#define cond_BE (CF_SET() || ZF_SET())
#define cond_NBE (!CF_SET() && !ZF_SET())
#define cond_S ( NF_SET())
#define cond_NS (!NF_SET())
#define cond_P ( PF_SET())
#define cond_NP (!PF_SET())
#define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0))
#define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0))
#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET()))
#define cond_S (NF_SET())
#define cond_NS (!NF_SET())
#define cond_P (PF_SET())
#define cond_NP (!PF_SET())
#define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0))
#define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0))
#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET()))
#define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET()))
#define writememb writememb_8087

View File

@@ -14,46 +14,46 @@ extern int fpu_type;
#define CPU_286 2
/*386 class CPUs*/
#define CPU_386SX 3
#define CPU_386DX 4
#define CPU_386SX 3
#define CPU_386DX 4
#define CPU_486SLC 5
#define CPU_486DLC 6
/*486 class CPUs*/
#define CPU_i486SX 7
#define CPU_i486SX 7
#define CPU_Am486SX 8
#define CPU_Cx486S 9
#define CPU_i486DX 10
#define CPU_Cx486S 9
#define CPU_i486DX 10
#define CPU_Am486DX 11
#define CPU_Cx486DX 12
#define CPU_iDX4 13
#define CPU_Cx5x86 14
#define CPU_iDX4 13
#define CPU_Cx5x86 14
/*586 class CPUs*/
#define CPU_WINCHIP 15
#define CPU_WINCHIP2 16
#define CPU_PENTIUM 17
#define CPU_PENTIUMMMX 18
#define CPU_Cx6x86 19
#define CPU_Cx6x86MX 20
#define CPU_Cx6x86L 21
#define CPU_CxGX1 22
#define CPU_K6 23
#define CPU_K6_2 24
#define CPU_K6_3 25
#define CPU_K6_2P 26
#define CPU_K6_3P 27
#define CPU_PENTIUMPRO 28
#define CPU_PENTIUM_2 29
#define CPU_CELERON 30
#define CPU_CELERON_A 31
#define CPU_CYRIX_III 32
#define CPU_Cx6x86 19
#define CPU_Cx6x86MX 20
#define CPU_Cx6x86L 21
#define CPU_CxGX1 22
#define CPU_K6 23
#define CPU_K6_2 24
#define CPU_K6_3 25
#define CPU_K6_2P 26
#define CPU_K6_3P 27
#define CPU_PENTIUMPRO 28
#define CPU_PENTIUM_2 29
#define CPU_CELERON 30
#define CPU_CELERON_A 31
#define CPU_CYRIX_III 32
#define MANU_INTEL 0
#define MANU_AMD 1
#define MANU_AMD 1
#define MANU_CYRIX 2
#define MANU_IDT 3
#define MANU_VIA 4
#define MANU_IDT 3
#define MANU_VIA 4
extern int timing_rr;
extern int timing_mr, timing_mrl;
@@ -69,14 +69,7 @@ extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
extern int timing_misaligned;
enum {
FPU_NONE,
FPU_8087,
FPU_287,
FPU_287XL,
FPU_387,
FPU_BUILTIN
};
enum { FPU_NONE, FPU_8087, FPU_287, FPU_287XL, FPU_387, FPU_BUILTIN };
extern CPU *cpu_s;
@@ -122,24 +115,22 @@ extern int cpu_multi;
/*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/
extern int cpu_cyrix_alignment;
#define CPU_FEATURE_RDTSC (1 << 0)
#define CPU_FEATURE_MSR (1 << 1)
#define CPU_FEATURE_MMX (1 << 2)
#define CPU_FEATURE_CR4 (1 << 3)
#define CPU_FEATURE_VME (1 << 4)
#define CPU_FEATURE_CX8 (1 << 5)
#define CPU_FEATURE_3DNOW (1 << 6)
#define CPU_FEATURE_RDTSC (1 << 0)
#define CPU_FEATURE_MSR (1 << 1)
#define CPU_FEATURE_MMX (1 << 2)
#define CPU_FEATURE_CR4 (1 << 3)
#define CPU_FEATURE_VME (1 << 4)
#define CPU_FEATURE_CX8 (1 << 5)
#define CPU_FEATURE_3DNOW (1 << 6)
#define CPU_FEATURE_SYSCALL (1 << 7)
extern uint32_t cpu_features;
static inline int cpu_has_feature(int feature) {
return cpu_features & feature;
}
static inline int cpu_has_feature(int feature) { return cpu_features & feature; }
#define CR4_TSD (1 << 2)
#define CR4_DE (1 << 3)
#define CR4_MCE (1 << 6)
#define CR4_PCE (1 << 8)
#define CR4_TSD (1 << 2)
#define CR4_DE (1 << 3)
#define CR4_MCE (1 << 6)
#define CR4_PCE (1 << 8)
extern uint64_t cpu_CR4_mask;

View File

@@ -27,92 +27,92 @@
#define BH cpu_state.regs[3].b.h
typedef union {
uint32_t l;
uint16_t w;
struct {
uint8_t l, h;
} b;
uint32_t l;
uint16_t w;
struct {
uint8_t l, h;
} b;
} x86reg;
typedef struct {
uint32_t base;
uint32_t limit, limit_raw;
uint8_t access, access2;
uint16_t seg;
uint32_t limit_low, limit_high;
int checked; /*Non-zero if selector is known to be valid*/
uint32_t base;
uint32_t limit, limit_raw;
uint8_t access, access2;
uint16_t seg;
uint32_t limit_low, limit_high;
int checked; /*Non-zero if selector is known to be valid*/
} x86seg;
typedef union MMX_REG {
uint64_t q;
int64_t sq;
uint32_t l[2];
int32_t sl[2];
uint16_t w[4];
int16_t sw[4];
uint8_t b[8];
int8_t sb[8];
float f[2];
uint64_t q;
int64_t sq;
uint32_t l[2];
int32_t sl[2];
uint16_t w[4];
int16_t sw[4];
uint8_t b[8];
int8_t sb[8];
float f[2];
} MMX_REG;
struct {
x86reg regs[8];
x86reg regs[8];
uint8_t tag[8];
uint8_t tag[8];
x86seg *ea_seg;
uint32_t eaaddr;
x86seg *ea_seg;
uint32_t eaaddr;
int flags_op;
uint32_t flags_res;
uint32_t flags_op1, flags_op2;
int flags_op;
uint32_t flags_res;
uint32_t flags_op1, flags_op2;
uint32_t pc;
uint32_t oldpc;
uint32_t op32;
uint32_t pc;
uint32_t oldpc;
uint32_t op32;
int TOP;
int TOP;
union {
struct {
int8_t rm, mod, reg;
} rm_mod_reg;
uint32_t rm_mod_reg_data;
} rm_data;
union {
struct {
int8_t rm, mod, reg;
} rm_mod_reg;
uint32_t rm_mod_reg_data;
} rm_data;
int8_t ssegs;
int8_t ismmx;
int8_t abrt;
int8_t smi_pending;
int8_t ssegs;
int8_t ismmx;
int8_t abrt;
int8_t smi_pending;
int _cycles;
int cpu_recomp_ins;
int _cycles;
int cpu_recomp_ins;
uint16_t npxs, npxc;
uint16_t npxs, npxc;
double ST[8];
double ST[8];
uint16_t MM_w4[8];
uint16_t MM_w4[8];
MMX_REG MM[8];
MMX_REG MM[8];
uint32_t old_fp_control, new_fp_control;
uint32_t old_fp_control, new_fp_control;
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_
uint16_t old_fp_control2, new_fp_control2;
uint16_t old_fp_control2, new_fp_control2;
#endif
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__
uint32_t trunc_fp_control;
uint32_t trunc_fp_control;
#endif
x86seg seg_cs, seg_ds, seg_es, seg_ss, seg_fs, seg_gs;
x86seg seg_cs, seg_ds, seg_es, seg_ss, seg_fs, seg_gs;
union {
uint32_t l;
uint16_t w;
} CR0;
union {
uint32_t l;
uint16_t w;
} CR0;
uint16_t flags, eflags;
uint16_t flags, eflags;
uint32_t smbase;
uint32_t smbase;
} cpu_state;
#define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128)
@@ -140,19 +140,19 @@ extern int cycles_main;
//#define seg_fs _fs.base
#define gs cpu_state.seg_gs.base
#define CPL ((cpu_state.seg_cs.access>>5)&3)
#define CPL ((cpu_state.seg_cs.access >> 5) & 3)
#define C_FLAG 0x0001
#define P_FLAG 0x0004
#define A_FLAG 0x0010
#define Z_FLAG 0x0040
#define N_FLAG 0x0080
#define T_FLAG 0x0100
#define I_FLAG 0x0200
#define D_FLAG 0x0400
#define V_FLAG 0x0800
#define C_FLAG 0x0001
#define P_FLAG 0x0004
#define A_FLAG 0x0010
#define Z_FLAG 0x0040
#define N_FLAG 0x0080
#define T_FLAG 0x0100
#define I_FLAG 0x0200
#define D_FLAG 0x0400
#define V_FLAG 0x0800
#define NT_FLAG 0x4000
#define VM_FLAG 0x0002 /*In EFLAGS*/
#define VM_FLAG 0x0002 /*In EFLAGS*/
#define VIF_FLAG 0x0008 /*In EFLAGS*/
#define VIP_FLAG 0x0010 /*In EFLAGS*/
@@ -164,7 +164,7 @@ extern int cycles_main;
#define IOPL ((cpu_state.flags >> 12) & 3)
#define IOPLp ((!(msw&1)) || (CPL<=IOPL))
#define IOPLp ((!(msw & 1)) || (CPL <= IOPL))
extern x86seg gdt, ldt, idt, tr;
@@ -178,17 +178,17 @@ extern uint16_t cpu_cur_status;
/*The flags below must match in both cpu_cur_status and block->status for a block
to be valid*/
#define CPU_STATUS_USE32 (1 << 0)
#define CPU_STATUS_USE32 (1 << 0)
#define CPU_STATUS_STACK32 (1 << 1)
#define CPU_STATUS_PMODE (1 << 2)
#define CPU_STATUS_V86 (1 << 3)
#define CPU_STATUS_SMM (1 << 4)
#define CPU_STATUS_PMODE (1 << 2)
#define CPU_STATUS_V86 (1 << 3)
#define CPU_STATUS_SMM (1 << 4)
#define CPU_STATUS_FLAGS 0xff
/*If the flags below are set in cpu_cur_status, they must be set in block->status.
Otherwise they are ignored*/
#define CPU_STATUS_NOTFLATDS (1 << 8)
#define CPU_STATUS_NOTFLATSS (1 << 9)
#define CPU_STATUS_NOTFLATDS (1 << 8)
#define CPU_STATUS_NOTFLATSS (1 << 9)
#define CPU_STATUS_MASK 0xff00
extern uint32_t rmdat;
@@ -222,20 +222,28 @@ extern float mips, flops;
#define setznp168 setznp16
#define getr8(r) ((r&4)?cpu_state.regs[r&3].b.h:cpu_state.regs[r&3].b.l)
#define getr16(r) cpu_state.regs[r].w
#define getr32(r) cpu_state.regs[r].l
#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l)
#define getr16(r) cpu_state.regs[r].w
#define getr32(r) cpu_state.regs[r].l
#define setr8(r, v) if (r&4) cpu_state.regs[r&3].b.h=v; \
else cpu_state.regs[r&3].b.l=v;
#define setr16(r, v) cpu_state.regs[r].w=v
#define setr32(r, v) cpu_state.regs[r].l=v
#define setr8(r, v) \
if (r & 4) \
cpu_state.regs[r & 3].b.h = v; \
else \
cpu_state.regs[r & 3].b.l = v;
#define setr16(r, v) cpu_state.regs[r].w = v
#define setr32(r, v) cpu_state.regs[r].l = v
#define fetchea() { rmdat=readmemb(cs+pc); pc++; \
reg=(rmdat>>3)&7; \
mod=(rmdat>>6)&3; \
rm=rmdat&7; \
if (mod!=3) fetcheal(); }
#define fetchea() \
{ \
rmdat = readmemb(cs + pc); \
pc++; \
reg = (rmdat >> 3) & 7; \
mod = (rmdat >> 6) & 3; \
rm = rmdat & 7; \
if (mod != 3) \
fetcheal(); \
}
extern int optype;
#define JMP 1
@@ -243,26 +251,18 @@ extern int optype;
#define IRET 3
#define OPTYPE_INT 4
enum {
ABRT_NONE = 0,
ABRT_GEN,
ABRT_TS = 0xA,
ABRT_NP = 0xB,
ABRT_SS = 0xC,
ABRT_GPF = 0xD,
ABRT_PF = 0xE
};
enum { ABRT_NONE = 0, ABRT_GEN, ABRT_TS = 0xA, ABRT_NP = 0xB, ABRT_SS = 0xC, ABRT_GPF = 0xD, ABRT_PF = 0xE };
#define ABRT_MASK 0x7f
/*An 'expected' exception is one that would be expected to occur on every execution
of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is
one that would be unlikely to occur on the next exception, eg a page fault may be
fixed up by the exception handler and the next execution would not hit it.
This distinction is used by the dynarec; a block that hits an 'expected' exception
would be compiled, a block that hits an 'unexpected' exception would be rejected so
that we don't end up with an unnecessarily short block*/
#define ABRT_EXPECTED 0x80
#define ABRT_EXPECTED 0x80
extern uint32_t abrt_error;
void x86_doabrt(int x86_abrt);
@@ -319,11 +319,11 @@ void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);
#define SMHR_ADDR_MASK (0xfffffffc)
struct {
struct {
uint32_t base;
uint64_t size;
} arr[8];
uint32_t smhr;
struct {
uint32_t base;
uint64_t size;
} arr[8];
uint32_t smhr;
} cyrix;
#endif /* _X86_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -3,320 +3,340 @@
#include <math.h>
static int opPREFETCH_a16(uint32_t fetchdat) {
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
CLOCK_CYCLES(1);
return 0;
CLOCK_CYCLES(1);
return 0;
}
static int opPREFETCH_a32(uint32_t fetchdat) {
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
CLOCK_CYCLES(1);
return 0;
CLOCK_CYCLES(1);
return 0;
}
static int opFEMMS(uint32_t fetchdat) {
ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX));
if (cr0 & 0xc) {
x86_int(7);
return 1;
}
x87_emms();
CLOCK_CYCLES(1);
return 0;
ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX));
if (cr0 & 0xc) {
x86_int(7);
return 1;
}
x87_emms();
CLOCK_CYCLES(1);
return 0;
}
static int opPAVGUSB(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1;
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1;
return 0;
return 0;
}
static int opPF2ID(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0];
cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1];
cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0];
cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1];
return 0;
return 0;
}
static int opPFACC(uint32_t fetchdat) {
MMX_REG src;
float tempf;
MMX_REG src;
float tempf;
MMX_GETSRC();
MMX_GETSRC();
tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1];
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
cpu_state.MM[cpu_reg].f[0] = tempf;
tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1];
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
cpu_state.MM[cpu_reg].f[0] = tempf;
return 0;
return 0;
}
static int opPFADD(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] += src.f[0];
cpu_state.MM[cpu_reg].f[1] += src.f[1];
cpu_state.MM[cpu_reg].f[0] += src.f[0];
cpu_state.MM[cpu_reg].f[1] += src.f[1];
return 0;
return 0;
}
static int opPFCMPEQ(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0;
return 0;
return 0;
}
static int opPFCMPGE(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0;
return 0;
return 0;
}
static int opPFCMPGT(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0;
return 0;
return 0;
}
static int opPFMAX(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
if (src.f[0] > cpu_state.MM[cpu_reg].f[0])
cpu_state.MM[cpu_reg].f[0] = src.f[0];
if (src.f[1] > cpu_state.MM[cpu_reg].f[1])
cpu_state.MM[cpu_reg].f[1] = src.f[1];
if (src.f[0] > cpu_state.MM[cpu_reg].f[0])
cpu_state.MM[cpu_reg].f[0] = src.f[0];
if (src.f[1] > cpu_state.MM[cpu_reg].f[1])
cpu_state.MM[cpu_reg].f[1] = src.f[1];
return 0;
return 0;
}
static int opPFMIN(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
if (src.f[0] < cpu_state.MM[cpu_reg].f[0])
cpu_state.MM[cpu_reg].f[0] = src.f[0];
if (src.f[1] < cpu_state.MM[cpu_reg].f[1])
cpu_state.MM[cpu_reg].f[1] = src.f[1];
if (src.f[0] < cpu_state.MM[cpu_reg].f[0])
cpu_state.MM[cpu_reg].f[0] = src.f[0];
if (src.f[1] < cpu_state.MM[cpu_reg].f[1])
cpu_state.MM[cpu_reg].f[1] = src.f[1];
return 0;
return 0;
}
static int opPFMUL(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] *= src.f[0];
cpu_state.MM[cpu_reg].f[1] *= src.f[1];
cpu_state.MM[cpu_reg].f[0] *= src.f[0];
cpu_state.MM[cpu_reg].f[1] *= src.f[1];
return 0;
return 0;
}
static int opPFRCP(uint32_t fetchdat) {
union {
uint32_t i;
float f;
} src;
union {
uint32_t i;
float f;
} src;
if (cpu_mod == 3) {
src.f = cpu_state.MM[cpu_rm].f[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_READ(cpu_state.ea_seg);
src.i = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
if (cpu_mod == 3) {
src.f = cpu_state.MM[cpu_rm].f[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_READ(cpu_state.ea_seg);
src.i = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f;
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f;
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
return 0;
return 0;
}
/*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/
static int opPFRCPIT1(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = src.f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1];
cpu_state.MM[cpu_reg].f[0] = src.f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1];
return 0;
return 0;
}
static int opPFRCPIT2(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = src.f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1];
cpu_state.MM[cpu_reg].f[0] = src.f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1];
return 0;
return 0;
}
static int opPFRSQRT(uint32_t fetchdat) {
union {
uint32_t i;
float f;
} src;
union {
uint32_t i;
float f;
} src;
if (cpu_mod == 3) {
src.f = cpu_state.MM[cpu_rm].f[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_READ(cpu_state.ea_seg);
src.i = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
if (cpu_mod == 3) {
src.f = cpu_state.MM[cpu_rm].f[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_READ(cpu_state.ea_seg);
src.i = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f);
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f);
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
return 0;
return 0;
}
/*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/
static int opPFRSQIT1(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
UNUSED(src);
MMX_GETSRC();
UNUSED(src);
return 0;
return 0;
}
static int opPFSUB(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] -= src.f[0];
cpu_state.MM[cpu_reg].f[1] -= src.f[1];
cpu_state.MM[cpu_reg].f[0] -= src.f[0];
cpu_state.MM[cpu_reg].f[1] -= src.f[1];
return 0;
return 0;
}
static int opPFSUBR(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1];
cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1];
return 0;
return 0;
}
static int opPI2FD(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_GETSRC();
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0];
cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1];
cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0];
cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1];
return 0;
return 0;
}
static int opPMULHRW(uint32_t fetchdat) {
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16;
CLOCK_CYCLES(1);
} else {
MMX_REG src;
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].w[0] =
(((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[1] =
(((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[2] =
(((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[3] =
(((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16;
CLOCK_CYCLES(1);
} else {
MMX_REG src;
SEG_CHECK_READ(cpu_state.ea_seg);
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16;
CLOCK_CYCLES(2);
}
return 0;
SEG_CHECK_READ(cpu_state.ea_seg);
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16;
CLOCK_CYCLES(2);
}
return 0;
}
OpFn OP_TABLE(3DNOW)[256] =
{
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL,
/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
OpFn OP_TABLE(3DNOW)[256] = {
/* 00 01 02 03 04 05 06 07
08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL,
/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*90*/ opPFCMPGE, ILLEGAL, ILLEGAL, ILLEGAL, opPFMIN, ILLEGAL, opPFRCP, opPFRSQRT, ILLEGAL, ILLEGAL, opPFSUB, ILLEGAL, ILLEGAL, ILLEGAL, opPFADD, ILLEGAL,
/*a0*/ opPFCMPGT, ILLEGAL, ILLEGAL, ILLEGAL, opPFMAX, ILLEGAL, opPFRCPIT1, opPFRSQIT1, ILLEGAL, ILLEGAL, opPFSUBR, ILLEGAL, ILLEGAL, ILLEGAL, opPFACC, ILLEGAL,
/*b0*/ opPFCMPEQ, ILLEGAL, ILLEGAL, ILLEGAL, opPFMUL, ILLEGAL, opPFRCPIT2, opPMULHRW, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPAVGUSB,
/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*90*/ opPFCMPGE, ILLEGAL, ILLEGAL, ILLEGAL, opPFMIN, ILLEGAL, opPFRCP, opPFRSQRT,
ILLEGAL, ILLEGAL, opPFSUB, ILLEGAL, ILLEGAL, ILLEGAL, opPFADD, ILLEGAL,
/*a0*/ opPFCMPGT, ILLEGAL, ILLEGAL, ILLEGAL, opPFMAX, ILLEGAL, opPFRCPIT1, opPFRSQIT1,
ILLEGAL, ILLEGAL, opPFSUBR, ILLEGAL, ILLEGAL, ILLEGAL, opPFACC, ILLEGAL,
/*b0*/ opPFCMPEQ, ILLEGAL, ILLEGAL, ILLEGAL, opPFMUL, ILLEGAL, opPFRCPIT2, opPMULHRW,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPAVGUSB,
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
static int op3DNOW_a16(uint32_t fetchdat) {
uint8_t opcode;
uint8_t opcode;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
opcode = fastreadb(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
fetch_ea_16(fetchdat);
opcode = fastreadb(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
return x86_opcodes_3DNOW[opcode](0);
return x86_opcodes_3DNOW[opcode](0);
}
static int op3DNOW_a32(uint32_t fetchdat) {
uint8_t opcode;
uint8_t opcode;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
opcode = fastreadb(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
fetch_ea_32(fetchdat);
opcode = fastreadb(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
return x86_opcodes_3DNOW[opcode](0);
return x86_opcodes_3DNOW[opcode](0);
}
#endif /* _X86_OPS_3DNOW_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,322 +1,322 @@
#ifndef _X86_OPS_ATOMIC_H_
#define _X86_OPS_ATOMIC_H_
static int opCMPXCHG_b_a16(uint32_t fetchdat) {
uint8_t temp, temp2 = AL;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
if (AL == temp)
seteab(getr8(cpu_reg));
else
AL = temp;
if (cpu_state.abrt)
return 1;
setsub8(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
uint8_t temp, temp2 = AL;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
if (AL == temp)
seteab(getr8(cpu_reg));
else
AL = temp;
if (cpu_state.abrt)
return 1;
setsub8(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
}
static int opCMPXCHG_b_a32(uint32_t fetchdat) {
uint8_t temp, temp2 = AL;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
if (AL == temp)
seteab(getr8(cpu_reg));
else
AL = temp;
if (cpu_state.abrt)
return 1;
setsub8(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
uint8_t temp, temp2 = AL;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
if (AL == temp)
seteab(getr8(cpu_reg));
else
AL = temp;
if (cpu_state.abrt)
return 1;
setsub8(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
}
static int opCMPXCHG_w_a16(uint32_t fetchdat) {
uint16_t temp, temp2 = AX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
if (AX == temp)
seteaw(cpu_state.regs[cpu_reg].w);
else
AX = temp;
if (cpu_state.abrt)
return 1;
setsub16(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
uint16_t temp, temp2 = AX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
if (AX == temp)
seteaw(cpu_state.regs[cpu_reg].w);
else
AX = temp;
if (cpu_state.abrt)
return 1;
setsub16(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
}
static int opCMPXCHG_w_a32(uint32_t fetchdat) {
uint16_t temp, temp2 = AX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
if (AX == temp)
seteaw(cpu_state.regs[cpu_reg].w);
else
AX = temp;
if (cpu_state.abrt)
return 1;
setsub16(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
uint16_t temp, temp2 = AX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
if (AX == temp)
seteaw(cpu_state.regs[cpu_reg].w);
else
AX = temp;
if (cpu_state.abrt)
return 1;
setsub16(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
}
static int opCMPXCHG_l_a16(uint32_t fetchdat) {
uint32_t temp, temp2 = EAX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
if (EAX == temp)
seteal(cpu_state.regs[cpu_reg].l);
else
EAX = temp;
if (cpu_state.abrt)
return 1;
setsub32(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
uint32_t temp, temp2 = EAX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
if (EAX == temp)
seteal(cpu_state.regs[cpu_reg].l);
else
EAX = temp;
if (cpu_state.abrt)
return 1;
setsub32(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
}
static int opCMPXCHG_l_a32(uint32_t fetchdat) {
uint32_t temp, temp2 = EAX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
if (EAX == temp)
seteal(cpu_state.regs[cpu_reg].l);
else
EAX = temp;
if (cpu_state.abrt)
return 1;
setsub32(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
uint32_t temp, temp2 = EAX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
if (EAX == temp)
seteal(cpu_state.regs[cpu_reg].l);
else
EAX = temp;
if (cpu_state.abrt)
return 1;
setsub32(temp2, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
return 0;
}
static int opCMPXCHG8B_a16(uint32_t fetchdat) {
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 0;
if (EAX == temp && EDX == temp_hi) {
seteal(EBX);
writememl(easeg, cpu_state.eaaddr + 4, ECX);
} else {
EAX = temp;
EDX = temp_hi;
}
if (cpu_state.abrt)
return 0;
flags_rebuild();
if (temp == temp2 && temp_hi == temp2_hi)
cpu_state.flags |= Z_FLAG;
else
cpu_state.flags &= ~Z_FLAG;
cycles -= (cpu_mod == 3) ? 6 : 10;
return 0;
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 0;
if (EAX == temp && EDX == temp_hi) {
seteal(EBX);
writememl(easeg, cpu_state.eaaddr + 4, ECX);
} else {
EAX = temp;
EDX = temp_hi;
}
if (cpu_state.abrt)
return 0;
flags_rebuild();
if (temp == temp2 && temp_hi == temp2_hi)
cpu_state.flags |= Z_FLAG;
else
cpu_state.flags &= ~Z_FLAG;
cycles -= (cpu_mod == 3) ? 6 : 10;
return 0;
}
static int opCMPXCHG8B_a32(uint32_t fetchdat) {
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 0;
if (EAX == temp && EDX == temp_hi) {
seteal(EBX);
writememl(easeg, cpu_state.eaaddr + 4, ECX);
} else {
EAX = temp;
EDX = temp_hi;
}
if (cpu_state.abrt)
return 0;
flags_rebuild();
if (temp == temp2 && temp_hi == temp2_hi)
cpu_state.flags |= Z_FLAG;
else
cpu_state.flags &= ~Z_FLAG;
cycles -= (cpu_mod == 3) ? 6 : 10;
return 0;
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 0;
if (EAX == temp && EDX == temp_hi) {
seteal(EBX);
writememl(easeg, cpu_state.eaaddr + 4, ECX);
} else {
EAX = temp;
EDX = temp_hi;
}
if (cpu_state.abrt)
return 0;
flags_rebuild();
if (temp == temp2 && temp_hi == temp2_hi)
cpu_state.flags |= Z_FLAG;
else
cpu_state.flags &= ~Z_FLAG;
cycles -= (cpu_mod == 3) ? 6 : 10;
return 0;
}
static int opXADD_b_a16(uint32_t fetchdat) {
uint8_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
seteab(temp + getr8(cpu_reg));
if (cpu_state.abrt)
return 1;
setadd8(temp, getr8(cpu_reg));
setr8(cpu_reg, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
uint8_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
seteab(temp + getr8(cpu_reg));
if (cpu_state.abrt)
return 1;
setadd8(temp, getr8(cpu_reg));
setr8(cpu_reg, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_b_a32(uint32_t fetchdat) {
uint8_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
seteab(temp + getr8(cpu_reg));
if (cpu_state.abrt)
return 1;
setadd8(temp, getr8(cpu_reg));
setr8(cpu_reg, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
uint8_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
seteab(temp + getr8(cpu_reg));
if (cpu_state.abrt)
return 1;
setadd8(temp, getr8(cpu_reg));
setr8(cpu_reg, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_w_a16(uint32_t fetchdat) {
uint16_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
seteaw(temp + cpu_state.regs[cpu_reg].w);
if (cpu_state.abrt)
return 1;
setadd16(temp, cpu_state.regs[cpu_reg].w);
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
uint16_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
seteaw(temp + cpu_state.regs[cpu_reg].w);
if (cpu_state.abrt)
return 1;
setadd16(temp, cpu_state.regs[cpu_reg].w);
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_w_a32(uint32_t fetchdat) {
uint16_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
seteaw(temp + cpu_state.regs[cpu_reg].w);
if (cpu_state.abrt)
return 1;
setadd16(temp, cpu_state.regs[cpu_reg].w);
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
uint16_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
seteaw(temp + cpu_state.regs[cpu_reg].w);
if (cpu_state.abrt)
return 1;
setadd16(temp, cpu_state.regs[cpu_reg].w);
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_l_a16(uint32_t fetchdat) {
uint32_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
seteal(temp + cpu_state.regs[cpu_reg].l);
if (cpu_state.abrt)
return 1;
setadd32(temp, cpu_state.regs[cpu_reg].l);
cpu_state.regs[cpu_reg].l = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
uint32_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
seteal(temp + cpu_state.regs[cpu_reg].l);
if (cpu_state.abrt)
return 1;
setadd32(temp, cpu_state.regs[cpu_reg].l);
cpu_state.regs[cpu_reg].l = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_l_a32(uint32_t fetchdat) {
uint32_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
seteal(temp + cpu_state.regs[cpu_reg].l);
if (cpu_state.abrt)
return 1;
setadd32(temp, cpu_state.regs[cpu_reg].l);
cpu_state.regs[cpu_reg].l = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
uint32_t temp;
if (!is486) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
seteal(temp + cpu_state.regs[cpu_reg].l);
if (cpu_state.abrt)
return 1;
setadd32(temp, cpu_state.regs[cpu_reg].l);
cpu_state.regs[cpu_reg].l = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
#endif /* _X86_OPS_ATOMIC_H_ */

View File

@@ -1,107 +1,107 @@
#ifndef _X86_OPS_BCD_H_
#define _X86_OPS_BCD_H_
static int opAAA(uint32_t fetchdat) {
flags_rebuild();
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) {
AL += 6;
AH++;
cpu_state.flags |= (A_FLAG | C_FLAG);
} else
cpu_state.flags &= ~(A_FLAG | C_FLAG);
AL &= 0xF;
CLOCK_CYCLES(is486 ? 3 : 4);
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0);
return 0;
flags_rebuild();
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) {
AL += 6;
AH++;
cpu_state.flags |= (A_FLAG | C_FLAG);
} else
cpu_state.flags &= ~(A_FLAG | C_FLAG);
AL &= 0xF;
CLOCK_CYCLES(is486 ? 3 : 4);
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opAAD(uint32_t fetchdat) {
int base = getbytef();
if (cpu_manufacturer != MANU_INTEL)
base = 10;
AL = (AH * base) + AL;
AH = 0;
setznp16(AX);
CLOCK_CYCLES((is486) ? 14 : 19);
PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0, 0, 0, 0, 0);
return 0;
int base = getbytef();
if (cpu_manufacturer != MANU_INTEL)
base = 10;
AL = (AH * base) + AL;
AH = 0;
setznp16(AX);
CLOCK_CYCLES((is486) ? 14 : 19);
PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opAAM(uint32_t fetchdat) {
int base = getbytef();
if (!base || cpu_manufacturer != MANU_INTEL)
base = 10;
AH = AL / base;
AL %= base;
setznp16(AX);
CLOCK_CYCLES((is486) ? 15 : 17);
PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0, 0, 0, 0, 0);
return 0;
int base = getbytef();
if (!base || cpu_manufacturer != MANU_INTEL)
base = 10;
AH = AL / base;
AL %= base;
setznp16(AX);
CLOCK_CYCLES((is486) ? 15 : 17);
PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opAAS(uint32_t fetchdat) {
flags_rebuild();
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) {
AL -= 6;
AH--;
cpu_state.flags |= (A_FLAG | C_FLAG);
} else
cpu_state.flags &= ~(A_FLAG | C_FLAG);
AL &= 0xF;
CLOCK_CYCLES(is486 ? 3 : 4);
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0);
return 0;
flags_rebuild();
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) {
AL -= 6;
AH--;
cpu_state.flags |= (A_FLAG | C_FLAG);
} else
cpu_state.flags &= ~(A_FLAG | C_FLAG);
AL &= 0xF;
CLOCK_CYCLES(is486 ? 3 : 4);
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opDAA(uint32_t fetchdat) {
uint16_t tempw;
uint16_t tempw;
flags_rebuild();
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) {
int tempi = ((uint16_t)AL) + 6;
AL += 6;
cpu_state.flags |= A_FLAG;
if (tempi & 0x100)
cpu_state.flags |= C_FLAG;
}
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) {
AL += 0x60;
cpu_state.flags |= C_FLAG;
}
flags_rebuild();
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) {
int tempi = ((uint16_t)AL) + 6;
AL += 6;
cpu_state.flags |= A_FLAG;
if (tempi & 0x100)
cpu_state.flags |= C_FLAG;
}
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) {
AL += 0x60;
cpu_state.flags |= C_FLAG;
}
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
setznp8(AL);
flags_rebuild();
cpu_state.flags |= tempw;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0);
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
setznp8(AL);
flags_rebuild();
cpu_state.flags |= tempw;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0);
return 0;
return 0;
}
static int opDAS(uint32_t fetchdat) {
uint16_t tempw;
uint16_t tempw;
flags_rebuild();
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) {
int tempi = ((uint16_t)AL) - 6;
AL -= 6;
cpu_state.flags |= A_FLAG;
if (tempi & 0x100)
cpu_state.flags |= C_FLAG;
}
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) {
AL -= 0x60;
cpu_state.flags |= C_FLAG;
}
flags_rebuild();
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) {
int tempi = ((uint16_t)AL) - 6;
AL -= 6;
cpu_state.flags |= A_FLAG;
if (tempi & 0x100)
cpu_state.flags |= C_FLAG;
}
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) {
AL -= 0x60;
cpu_state.flags |= C_FLAG;
}
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
setznp8(AL);
flags_rebuild();
cpu_state.flags |= tempw;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0);
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
setznp8(AL);
flags_rebuild();
cpu_state.flags |= tempw;
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0);
return 0;
return 0;
}
#endif /* _X86_OPS_BCD_H_ */

View File

@@ -1,372 +1,398 @@
#ifndef _X86_OPS_BIT_H_
#define _X86_OPS_BIT_H_
static int opBT_w_r_a16(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2);
eal_r = 0;
temp = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15)))
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2);
eal_r = 0;
temp = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15)))
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 0);
return 0;
}
static int opBT_w_r_a32(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2);
eal_r = 0;
temp = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15)))
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2);
eal_r = 0;
temp = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15)))
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 1);
return 0;
}
static int opBT_l_r_a16(uint32_t fetchdat) {
uint32_t temp;
uint32_t temp;
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4);
eal_r = 0;
temp = geteal();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31)))
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4);
eal_r = 0;
temp = geteal();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31)))
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 0);
return 0;
}
static int opBT_l_r_a32(uint32_t fetchdat) {
uint32_t temp;
uint32_t temp;
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4);
eal_r = 0;
temp = geteal();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31)))
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4);
eal_r = 0;
temp = geteal();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31)))
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 1);
return 0;
}
#define opBT(name, operation) \
static int opBT ## name ## _w_r_a16(uint32_t fetchdat) \
{ \
int tempc; \
uint16_t temp; \
\
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \
temp = geteaw(); if (cpu_state.abrt) return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \
seteaw(temp); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
if (tempc) cpu_state.flags |= C_FLAG; \
else cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \
return 0; \
} \
static int opBT ## name ## _w_r_a32(uint32_t fetchdat) \
{ \
int tempc; \
uint16_t temp; \
\
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \
temp = geteaw(); if (cpu_state.abrt) return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \
seteaw(temp); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
if (tempc) cpu_state.flags |= C_FLAG; \
else cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \
return 0; \
} \
static int opBT ## name ## _l_r_a16(uint32_t fetchdat) \
{ \
int tempc; \
uint32_t temp; \
\
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \
temp = geteal(); if (cpu_state.abrt) return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \
seteal(temp); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
if (tempc) cpu_state.flags |= C_FLAG; \
else cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \
return 0; \
} \
static int opBT ## name ## _l_r_a32(uint32_t fetchdat) \
{ \
int tempc; \
uint32_t temp; \
\
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \
temp = geteal(); if (cpu_state.abrt) return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \
seteal(temp); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
if (tempc) cpu_state.flags |= C_FLAG; \
else cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \
return 0; \
#define opBT(name, operation) \
static int opBT##name##_w_r_a16(uint32_t fetchdat) { \
int tempc; \
uint16_t temp; \
\
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \
eal_r = eal_w = 0; \
temp = geteaw(); \
if (cpu_state.abrt) \
return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \
seteaw(temp); \
if (cpu_state.abrt) \
return 1; \
flags_rebuild(); \
if (tempc) \
cpu_state.flags |= C_FLAG; \
else \
cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 0); \
return 0; \
} \
static int opBT##name##_w_r_a32(uint32_t fetchdat) { \
int tempc; \
uint16_t temp; \
\
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \
eal_r = eal_w = 0; \
temp = geteaw(); \
if (cpu_state.abrt) \
return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \
seteaw(temp); \
if (cpu_state.abrt) \
return 1; \
flags_rebuild(); \
if (tempc) \
cpu_state.flags |= C_FLAG; \
else \
cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 1); \
return 0; \
} \
static int opBT##name##_l_r_a16(uint32_t fetchdat) { \
int tempc; \
uint32_t temp; \
\
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \
eal_r = eal_w = 0; \
temp = geteal(); \
if (cpu_state.abrt) \
return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \
seteal(temp); \
if (cpu_state.abrt) \
return 1; \
flags_rebuild(); \
if (tempc) \
cpu_state.flags |= C_FLAG; \
else \
cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 0); \
return 0; \
} \
static int opBT##name##_l_r_a32(uint32_t fetchdat) { \
int tempc; \
uint32_t temp; \
\
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_WRITE(cpu_state.ea_seg); \
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \
eal_r = eal_w = 0; \
temp = geteal(); \
if (cpu_state.abrt) \
return 1; \
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \
seteal(temp); \
if (cpu_state.abrt) \
return 1; \
flags_rebuild(); \
if (tempc) \
cpu_state.flags |= C_FLAG; \
else \
cpu_state.flags &= ~C_FLAG; \
\
CLOCK_CYCLES(6); \
PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 1); \
return 0; \
}
opBT(C, ^=)
opBT(R, &=~)
opBT(S, |=)
opBT(C, ^=) opBT(R, &= ~) opBT(S, |=)
static int opBA_w_a16(uint32_t fetchdat) {
int tempc, count;
uint16_t temp;
static int opBA_w_a16(uint32_t fetchdat) {
int tempc, count;
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
count = getbyte();
if (cpu_state.abrt)
return 1;
tempc = temp & (1 << count);
flags_rebuild();
switch (rmdat & 0x38) {
case 0x20: /*BT w,imm*/
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
case 0x28: /*BTS w,imm*/
temp |= (1 << count);
break;
case 0x30: /*BTR w,imm*/
temp &= ~(1 << count);
break;
case 0x38: /*BTC w,imm*/
temp ^= (1 << count);
break;
temp = geteaw();
count = getbyte();
if (cpu_state.abrt)
return 1;
tempc = temp & (1 << count);
flags_rebuild();
switch (rmdat & 0x38) {
case 0x20: /*BT w,imm*/
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
case 0x28: /*BTS w,imm*/
temp |= (1 << count);
break;
case 0x30: /*BTR w,imm*/
temp &= ~(1 << count);
break;
case 0x38: /*BTC w,imm*/
temp ^= (1 << count);
break;
default:pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
seteaw(temp);
if (cpu_state.abrt)
return 1;
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
default:
pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
seteaw(temp);
if (cpu_state.abrt)
return 1;
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
}
static int opBA_w_a32(uint32_t fetchdat) {
int tempc, count;
uint16_t temp;
int tempc, count;
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
count = getbyte();
if (cpu_state.abrt)
return 1;
tempc = temp & (1 << count);
flags_rebuild();
switch (rmdat & 0x38) {
case 0x20: /*BT w,imm*/
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
case 0x28: /*BTS w,imm*/
temp |= (1 << count);
break;
case 0x30: /*BTR w,imm*/
temp &= ~(1 << count);
break;
case 0x38: /*BTC w,imm*/
temp ^= (1 << count);
break;
temp = geteaw();
count = getbyte();
if (cpu_state.abrt)
return 1;
tempc = temp & (1 << count);
flags_rebuild();
switch (rmdat & 0x38) {
case 0x20: /*BT w,imm*/
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
case 0x28: /*BTS w,imm*/
temp |= (1 << count);
break;
case 0x30: /*BTR w,imm*/
temp &= ~(1 << count);
break;
case 0x38: /*BTC w,imm*/
temp ^= (1 << count);
break;
default:pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
seteaw(temp);
if (cpu_state.abrt)
return 1;
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
default:
pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
seteaw(temp);
if (cpu_state.abrt)
return 1;
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
}
static int opBA_l_a16(uint32_t fetchdat) {
int tempc, count;
uint32_t temp;
int tempc, count;
uint32_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
count = getbyte();
if (cpu_state.abrt)
return 1;
tempc = temp & (1 << count);
flags_rebuild();
switch (rmdat & 0x38) {
case 0x20: /*BT w,imm*/
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return 0;
case 0x28: /*BTS w,imm*/
temp |= (1 << count);
break;
case 0x30: /*BTR w,imm*/
temp &= ~(1 << count);
break;
case 0x38: /*BTC w,imm*/
temp ^= (1 << count);
break;
temp = geteal();
count = getbyte();
if (cpu_state.abrt)
return 1;
tempc = temp & (1 << count);
flags_rebuild();
switch (rmdat & 0x38) {
case 0x20: /*BT w,imm*/
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return 0;
case 0x28: /*BTS w,imm*/
temp |= (1 << count);
break;
case 0x30: /*BTR w,imm*/
temp &= ~(1 << count);
break;
case 0x38: /*BTC w,imm*/
temp ^= (1 << count);
break;
default:pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
seteal(temp);
if (cpu_state.abrt)
return 1;
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0);
return 0;
default:
pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
seteal(temp);
if (cpu_state.abrt)
return 1;
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0);
return 0;
}
static int opBA_l_a32(uint32_t fetchdat) {
int tempc, count;
uint32_t temp;
int tempc, count;
uint32_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
count = getbyte();
if (cpu_state.abrt)
return 1;
tempc = temp & (1 << count);
flags_rebuild();
switch (rmdat & 0x38) {
case 0x20: /*BT w,imm*/
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return 0;
case 0x28: /*BTS w,imm*/
temp |= (1 << count);
break;
case 0x30: /*BTR w,imm*/
temp &= ~(1 << count);
break;
case 0x38: /*BTC w,imm*/
temp ^= (1 << count);
break;
temp = geteal();
count = getbyte();
if (cpu_state.abrt)
return 1;
tempc = temp & (1 << count);
flags_rebuild();
switch (rmdat & 0x38) {
case 0x20: /*BT w,imm*/
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return 0;
case 0x28: /*BTS w,imm*/
temp |= (1 << count);
break;
case 0x30: /*BTR w,imm*/
temp &= ~(1 << count);
break;
case 0x38: /*BTC w,imm*/
temp ^= (1 << count);
break;
default:pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
seteal(temp);
if (cpu_state.abrt)
return 1;
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1);
return 0;
default:
pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
seteal(temp);
if (cpu_state.abrt)
return 1;
if (tempc)
cpu_state.flags |= C_FLAG;
else
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1);
return 0;
}
#endif /* _X86_OPS_BIT_H_ */

View File

@@ -1,170 +1,166 @@
#ifndef _X86_OPS_BITSCAN_H_
#define _X86_OPS_BITSCAN_H_
#define BS_common(start, end, dir, dest, time) \
flags_rebuild(); \
instr_cycles = 0; \
if (temp) \
{ \
int c; \
cpu_state.flags &= ~Z_FLAG; \
for (c = start; c != end; c += dir) \
{ \
CLOCK_CYCLES(time); \
instr_cycles += time; \
if (temp & (1 << c)) \
{ \
dest = c; \
break; \
} \
} \
} \
else \
#define BS_common(start, end, dir, dest, time) \
flags_rebuild(); \
instr_cycles = 0; \
if (temp) { \
int c; \
cpu_state.flags &= ~Z_FLAG; \
for (c = start; c != end; c += dir) { \
CLOCK_CYCLES(time); \
instr_cycles += time; \
if (temp & (1 << c)) { \
dest = c; \
break; \
} \
} \
} else \
cpu_state.flags |= Z_FLAG;
static int opBSF_w_a16(uint32_t fetchdat) {
uint16_t temp;
int instr_cycles;
uint16_t temp;
int instr_cycles;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opBSF_w_a32(uint32_t fetchdat) {
uint16_t temp;
int instr_cycles;
uint16_t temp;
int instr_cycles;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
static int opBSF_l_a16(uint32_t fetchdat) {
uint32_t temp;
int instr_cycles;
uint32_t temp;
int instr_cycles;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return 0;
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return 0;
}
static int opBSF_l_a32(uint32_t fetchdat) {
uint32_t temp;
int instr_cycles;
uint32_t temp;
int instr_cycles;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return 0;
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return 0;
}
static int opBSR_w_a16(uint32_t fetchdat) {
uint16_t temp;
int instr_cycles;
uint16_t temp;
int instr_cycles;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opBSR_w_a32(uint32_t fetchdat) {
uint16_t temp;
int instr_cycles;
uint16_t temp;
int instr_cycles;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
static int opBSR_l_a16(uint32_t fetchdat) {
uint32_t temp;
int instr_cycles;
uint32_t temp;
int instr_cycles;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return 0;
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return 0;
}
static int opBSR_l_a32(uint32_t fetchdat) {
uint32_t temp;
int instr_cycles;
uint32_t temp;
int instr_cycles;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return 0;
CLOCK_CYCLES((is486) ? 6 : 10);
instr_cycles += ((is486) ? 6 : 10);
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return 0;
}
#endif /* _X86_OPS_BITSCAN_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -4,229 +4,231 @@
#ifndef _X86_OPS_CYRIX_H_
#define _X86_OPS_CYRIX_H_
static void opSVDC_common(uint32_t fetchdat) {
switch (rmdat & 0x38) {
case 0x00: /*ES*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es);
writememw(0, easeg + cpu_state.eaaddr + 8, ES);
break;
case 0x08: /*CS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_cs);
writememw(0, easeg + cpu_state.eaaddr + 8, CS);
break;
case 0x18: /*DS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds);
writememw(0, easeg + cpu_state.eaaddr + 8, DS);
break;
case 0x10: /*SS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss);
writememw(0, easeg + cpu_state.eaaddr + 8, SS);
break;
case 0x20: /*FS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs);
writememw(0, easeg + cpu_state.eaaddr + 8, FS);
break;
case 0x28: /*GS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs);
writememw(0, easeg + cpu_state.eaaddr + 8, GS);
break;
default:pclog("opSVDC: unknown rmdat %02x\n", rmdat);
x86illegal();
}
switch (rmdat & 0x38) {
case 0x00: /*ES*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es);
writememw(0, easeg + cpu_state.eaaddr + 8, ES);
break;
case 0x08: /*CS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_cs);
writememw(0, easeg + cpu_state.eaaddr + 8, CS);
break;
case 0x18: /*DS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds);
writememw(0, easeg + cpu_state.eaaddr + 8, DS);
break;
case 0x10: /*SS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss);
writememw(0, easeg + cpu_state.eaaddr + 8, SS);
break;
case 0x20: /*FS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs);
writememw(0, easeg + cpu_state.eaaddr + 8, FS);
break;
case 0x28: /*GS*/
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs);
writememw(0, easeg + cpu_state.eaaddr + 8, GS);
break;
default:
pclog("opSVDC: unknown rmdat %02x\n", rmdat);
x86illegal();
}
}
static int opSVDC_a16(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
opSVDC_common(fetchdat);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
opSVDC_common(fetchdat);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opSVDC_a32(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
opSVDC_common(fetchdat);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
opSVDC_common(fetchdat);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static void opRSDC_common(uint32_t fetchdat) {
switch (rmdat & 0x38) {
case 0x00: /*ES*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss);
break;
case 0x20: /*FS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs);
break;
default:pclog("opRSDC: unknown rmdat %02x\n", rmdat);
x86illegal();
}
switch (rmdat & 0x38) {
case 0x00: /*ES*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss);
break;
case 0x20: /*FS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs);
break;
default:
pclog("opRSDC: unknown rmdat %02x\n", rmdat);
x86illegal();
}
}
static int opRSDC_a16(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
opRSDC_common(fetchdat);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
opRSDC_common(fetchdat);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opRSDC_a32(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
opRSDC_common(fetchdat);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
opRSDC_common(fetchdat);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opSVLDT_a16(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opSVLDT_a32(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opRSLDT_a16(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opRSLDT_a32(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opSVTS_a16(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opSVTS_a32(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opRSTS_a16(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opRSTS_a32(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
} else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
} else
x86illegal();
return cpu_state.abrt;
return cpu_state.abrt;
}
static int opSMINT(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opSMINT\n");
else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opSMINT\n");
else
x86illegal();
return 1;
return 1;
}
static int opRDSHR_a16(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opRDSHR_a16\n");
else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opRDSHR_a16\n");
else
x86illegal();
return 1;
return 1;
}
static int opRDSHR_a32(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opRDSHR_a32\n");
else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opRDSHR_a32\n");
else
x86illegal();
return 1;
return 1;
}
static int opWRSHR_a16(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opWRSHR_a16\n");
else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opWRSHR_a16\n");
else
x86illegal();
return 1;
return 1;
}
static int opWRSHR_a32(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opWRSHR_a32\n");
else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM)
fatal("opWRSHR_a32\n");
else
x86illegal();
return 1;
return 1;
}
#endif /* _X86_OPS_CYRIX_H_ */

View File

@@ -1,255 +1,253 @@
#ifndef _X86_OPS_FLAG_H_
#define _X86_OPS_FLAG_H_
static int opCMC(uint32_t fetchdat) {
flags_rebuild();
cpu_state.flags ^= C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
flags_rebuild();
cpu_state.flags ^= C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opCLC(uint32_t fetchdat) {
flags_rebuild();
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
flags_rebuild();
cpu_state.flags &= ~C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opCLD(uint32_t fetchdat) {
cpu_state.flags &= ~D_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
cpu_state.flags &= ~D_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opCLI(uint32_t fetchdat) {
if (!IOPLp) {
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) {
cpu_state.eflags &= ~VIF_FLAG;
} else {
x86gpf(NULL, 0);
return 1;
}
} else
cpu_state.flags &= ~I_FLAG;
if (!IOPLp) {
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) {
cpu_state.eflags &= ~VIF_FLAG;
} else {
x86gpf(NULL, 0);
return 1;
}
} else
cpu_state.flags &= ~I_FLAG;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opSTC(uint32_t fetchdat) {
flags_rebuild();
cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
flags_rebuild();
cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opSTD(uint32_t fetchdat) {
cpu_state.flags |= D_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
cpu_state.flags |= D_FLAG;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opSTI(uint32_t fetchdat) {
if (!IOPLp) {
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) {
if (cpu_state.eflags & VIP_FLAG) {
x86gpf(NULL, 0);
return 1;
} else
cpu_state.eflags |= VIF_FLAG;
} else {
x86gpf(NULL, 0);
return 1;
}
} else
cpu_state.flags |= I_FLAG;
if (!IOPLp) {
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) {
if (cpu_state.eflags & VIP_FLAG) {
x86gpf(NULL, 0);
return 1;
} else
cpu_state.eflags |= VIF_FLAG;
} else {
x86gpf(NULL, 0);
return 1;
}
} else
cpu_state.flags |= I_FLAG;
/*First instruction after STI will always execute, regardless of whether
there is a pending interrupt*/
cpu_end_block_after_ins = 2;
/*First instruction after STI will always execute, regardless of whether
there is a pending interrupt*/
cpu_end_block_after_ins = 2;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opSAHF(uint32_t fetchdat) {
flags_rebuild();
cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
flags_rebuild();
cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
codegen_flags_changed = 0;
codegen_flags_changed = 0;
return 0;
return 0;
}
static int opLAHF(uint32_t fetchdat) {
flags_rebuild();
AH = cpu_state.flags & 0xff;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
flags_rebuild();
AH = cpu_state.flags & 0xff;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opPUSHF(uint32_t fetchdat) {
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
if (cr4 & CR4_VME) {
uint16_t temp;
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
if (cr4 & CR4_VME) {
uint16_t temp;
flags_rebuild();
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
if (cpu_state.eflags & VIF_FLAG)
temp |= I_FLAG;
PUSH_W(temp);
} else {
x86gpf(NULL, 0);
return 1;
}
} else {
flags_rebuild();
PUSH_W(cpu_state.flags);
}
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0);
return cpu_state.abrt;
flags_rebuild();
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
if (cpu_state.eflags & VIF_FLAG)
temp |= I_FLAG;
PUSH_W(temp);
} else {
x86gpf(NULL, 0);
return 1;
}
} else {
flags_rebuild();
PUSH_W(cpu_state.flags);
}
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0);
return cpu_state.abrt;
}
static int opPUSHFD(uint32_t fetchdat) {
uint16_t tempw;
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
x86gpf(NULL, 0);
return 1;
}
if (cpu_CR4_mask & CR4_VME)
tempw = cpu_state.eflags & 0x3c;
else if (CPUID)
tempw = cpu_state.eflags & 0x24;
else
tempw = cpu_state.eflags & 4;
flags_rebuild();
PUSH_L(cpu_state.flags | (tempw << 16));
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
return cpu_state.abrt;
uint16_t tempw;
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
x86gpf(NULL, 0);
return 1;
}
if (cpu_CR4_mask & CR4_VME)
tempw = cpu_state.eflags & 0x3c;
else if (CPUID)
tempw = cpu_state.eflags & 0x24;
else
tempw = cpu_state.eflags & 4;
flags_rebuild();
PUSH_L(cpu_state.flags | (tempw << 16));
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
return cpu_state.abrt;
}
static int opPOPF_286(uint32_t fetchdat) {
uint16_t tempw;
uint16_t tempw;
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
x86gpf(NULL, 0);
return 1;
}
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
x86gpf(NULL, 0);
return 1;
}
tempw = POP_W();
if (cpu_state.abrt)
return 1;
tempw = POP_W();
if (cpu_state.abrt)
return 1;
if (!(msw & 1))
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
else if (!(CPL))
cpu_state.flags = (tempw & 0x7fd5) | 2;
else if (IOPLp)
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
else
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
flags_extract();
if (!(msw & 1))
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
else if (!(CPL))
cpu_state.flags = (tempw & 0x7fd5) | 2;
else if (IOPLp)
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
else
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
flags_extract();
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
codegen_flags_changed = 0;
codegen_flags_changed = 0;
return 0;
return 0;
}
static int opPOPF(uint32_t fetchdat) {
uint16_t tempw;
uint16_t tempw;
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
if (cr4 & CR4_VME) {
uint32_t old_esp = ESP;
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
if (cr4 & CR4_VME) {
uint32_t old_esp = ESP;
tempw = POP_W();
if (cpu_state.abrt) {
ESP = old_esp;
return 1;
}
tempw = POP_W();
if (cpu_state.abrt) {
ESP = old_esp;
return 1;
}
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) {
ESP = old_esp;
x86gpf(NULL, 0);
return 1;
}
if (tempw & I_FLAG)
cpu_state.eflags |= VIF_FLAG;
else
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
} else {
x86gpf(NULL, 0);
return 1;
}
} else {
tempw = POP_W();
if (cpu_state.abrt)
return 1;
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) {
ESP = old_esp;
x86gpf(NULL, 0);
return 1;
}
if (tempw & I_FLAG)
cpu_state.eflags |= VIF_FLAG;
else
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
} else {
x86gpf(NULL, 0);
return 1;
}
} else {
tempw = POP_W();
if (cpu_state.abrt)
return 1;
if (!(CPL) || !(msw & 1))
cpu_state.flags = (tempw & 0x7fd5) | 2;
else if (IOPLp)
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
else
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
}
flags_extract();
if (!(CPL) || !(msw & 1))
cpu_state.flags = (tempw & 0x7fd5) | 2;
else if (IOPLp)
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
else
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
}
flags_extract();
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
codegen_flags_changed = 0;
codegen_flags_changed = 0;
return 0;
return 0;
}
static int opPOPFD(uint32_t fetchdat) {
uint32_t templ;
uint32_t templ;
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
x86gpf(NULL, 0);
return 1;
}
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
x86gpf(NULL, 0);
return 1;
}
templ = POP_L();
if (cpu_state.abrt)
return 1;
templ = POP_L();
if (cpu_state.abrt)
return 1;
if (!(CPL) || !(msw & 1))
cpu_state.flags = (templ & 0x7fd5) | 2;
else if (IOPLp)
cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2;
else
cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2;
if (!(CPL) || !(msw & 1))
cpu_state.flags = (templ & 0x7fd5) | 2;
else if (IOPLp)
cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2;
else
cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2;
templ &= is486 ? 0x3c0000 : 0;
templ |= ((cpu_state.eflags & 3) << 16);
if (cpu_CR4_mask & CR4_VME)
cpu_state.eflags = (templ >> 16) & 0x3f;
else if (CPUID)
cpu_state.eflags = (templ >> 16) & 0x27;
else if (is486)
cpu_state.eflags = (templ >> 16) & 7;
else
cpu_state.eflags = (templ >> 16) & 3;
templ &= is486 ? 0x3c0000 : 0;
templ |= ((cpu_state.eflags & 3) << 16);
if (cpu_CR4_mask & CR4_VME)
cpu_state.eflags = (templ >> 16) & 0x3f;
else if (CPUID)
cpu_state.eflags = (templ >> 16) & 0x27;
else if (is486)
cpu_state.eflags = (templ >> 16) & 7;
else
cpu_state.eflags = (templ >> 16) & 3;
flags_extract();
flags_extract();
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0);
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0);
codegen_flags_changed = 0;
codegen_flags_changed = 0;
return 0;
return 0;
}
#endif /* _X86_OPS_FLAG_H_ */

View File

@@ -1,68 +1,36 @@
#ifndef _X86_OPS_FPU_H_
#define _X86_OPS_FPU_H_
static int opESCAPE_d8_a16(uint32_t fetchdat) {
return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int opESCAPE_d8_a32(uint32_t fetchdat) {
return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int opESCAPE_d8_a16(uint32_t fetchdat) { return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); }
static int opESCAPE_d8_a32(uint32_t fetchdat) { return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); }
static int opESCAPE_d9_a16(uint32_t fetchdat) {
return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_d9_a32(uint32_t fetchdat) {
return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_d9_a16(uint32_t fetchdat) { return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); }
static int opESCAPE_d9_a32(uint32_t fetchdat) { return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); }
static int opESCAPE_da_a16(uint32_t fetchdat) {
return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_da_a32(uint32_t fetchdat) {
return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_da_a16(uint32_t fetchdat) { return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); }
static int opESCAPE_da_a32(uint32_t fetchdat) { return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); }
static int opESCAPE_db_a16(uint32_t fetchdat) {
return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_db_a32(uint32_t fetchdat) {
return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_db_a16(uint32_t fetchdat) { return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); }
static int opESCAPE_db_a32(uint32_t fetchdat) { return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); }
static int opESCAPE_dc_a16(uint32_t fetchdat) {
return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int opESCAPE_dc_a32(uint32_t fetchdat) {
return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int opESCAPE_dc_a16(uint32_t fetchdat) { return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); }
static int opESCAPE_dc_a32(uint32_t fetchdat) { return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); }
static int opESCAPE_dd_a16(uint32_t fetchdat) {
return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_dd_a32(uint32_t fetchdat) {
return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_dd_a16(uint32_t fetchdat) { return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); }
static int opESCAPE_dd_a32(uint32_t fetchdat) { return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); }
static int opESCAPE_de_a16(uint32_t fetchdat) {
return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_de_a32(uint32_t fetchdat) {
return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_de_a16(uint32_t fetchdat) { return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); }
static int opESCAPE_de_a32(uint32_t fetchdat) { return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); }
static int opESCAPE_df_a16(uint32_t fetchdat) {
return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_df_a32(uint32_t fetchdat) {
return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_df_a16(uint32_t fetchdat) { return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); }
static int opESCAPE_df_a32(uint32_t fetchdat) { return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); }
static int opWAIT(uint32_t fetchdat) {
if ((cr0 & 0xa) == 0xa) {
x86_int(7);
return 1;
}
CLOCK_CYCLES(4);
return 0;
if ((cr0 & 0xa) == 0xa) {
x86_int(7);
return 1;
}
CLOCK_CYCLES(4);
return 0;
}
#endif /* _X86_OPS_FPU_H_ */

View File

@@ -1,13 +1,12 @@
#ifndef _X86_OPS_INC_DEC_H_
#define _X86_OPS_INC_DEC_H_
#define INC_DEC_OP(name, reg, inc, setflags) \
static int op ## name (uint32_t fetchdat) \
{ \
setflags(reg, 1); \
reg += inc; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); \
return 0; \
#define INC_DEC_OP(name, reg, inc, setflags) \
static int op##name(uint32_t fetchdat) { \
setflags(reg, 1); \
reg += inc; \
CLOCK_CYCLES(timing_rr); \
PREFETCH_RUN(timing_rr, 1, -1, 0, 0, 0, 0, 0); \
return 0; \
}
INC_DEC_OP(INC_AX, AX, 1, setadd16nc)
@@ -47,54 +46,54 @@ INC_DEC_OP(DEC_EBP, EBP, -1, setsub32nc)
INC_DEC_OP(DEC_ESP, ESP, -1, setsub32nc)
static int opINCDEC_b_a16(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
if (rmdat & 0x38) {
seteab(temp - 1);
if (cpu_state.abrt)
return 1;
setsub8nc(temp, 1);
} else {
seteab(temp + 1);
if (cpu_state.abrt)
return 1;
setadd8nc(temp, 1);
}
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
if (rmdat & 0x38) {
seteab(temp - 1);
if (cpu_state.abrt)
return 1;
setsub8nc(temp, 1);
} else {
seteab(temp + 1);
if (cpu_state.abrt)
return 1;
setadd8nc(temp, 1);
}
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
}
static int opINCDEC_b_a32(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
if (rmdat & 0x38) {
seteab(temp - 1);
if (cpu_state.abrt)
return 1;
setsub8nc(temp, 1);
} else {
seteab(temp + 1);
if (cpu_state.abrt)
return 1;
setadd8nc(temp, 1);
}
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
return 0;
if (rmdat & 0x38) {
seteab(temp - 1);
if (cpu_state.abrt)
return 1;
setsub8nc(temp, 1);
} else {
seteab(temp + 1);
if (cpu_state.abrt)
return 1;
setadd8nc(temp, 1);
}
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
return 0;
}
#endif /* _X86_OPS_INC_DEC_H_ */

View File

@@ -1,120 +1,120 @@
#ifndef _X86_OPS_INT_H_
#define _X86_OPS_INT_H_
static int opINT3(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf(NULL, 0);
return 1;
}
x86_int_sw(3);
CLOCK_CYCLES((is486) ? 44 : 59);
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
return 1;
int cycles_old = cycles;
UNUSED(cycles_old);
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf(NULL, 0);
return 1;
}
x86_int_sw(3);
CLOCK_CYCLES((is486) ? 44 : 59);
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
return 1;
}
static int opINT1(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf(NULL, 0);
return 1;
}
x86_int_sw(1);
CLOCK_CYCLES((is486) ? 44 : 59);
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
return 1;
int cycles_old = cycles;
UNUSED(cycles_old);
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf(NULL, 0);
return 1;
}
x86_int_sw(1);
CLOCK_CYCLES((is486) ? 44 : 59);
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
return 1;
}
static int opINT(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
uint8_t temp = getbytef();
int cycles_old = cycles;
UNUSED(cycles_old);
uint8_t temp = getbytef();
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
if (cr4 & CR4_VME) {
uint16_t t;
uint8_t d;
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
if (cr4 & CR4_VME) {
uint16_t t;
uint8_t d;
cpl_override = 1;
t = readmemw(tr.base, 0x66) - 32;
cpl_override = 0;
if (cpu_state.abrt)
return 1;
cpl_override = 1;
t = readmemw(tr.base, 0x66) - 32;
cpl_override = 0;
if (cpu_state.abrt)
return 1;
t += (temp >> 3);
if (t <= tr.limit) {
cpl_override = 1;
d = readmemb(tr.base, t);// + (temp >> 3));
cpl_override = 0;
if (cpu_state.abrt)
return 1;
t += (temp >> 3);
if (t <= tr.limit) {
cpl_override = 1;
d = readmemb(tr.base, t); // + (temp >> 3));
cpl_override = 0;
if (cpu_state.abrt)
return 1;
if (!(d & (1 << (temp & 7)))) {
x86_int_sw_rm(temp);
PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0);
return 1;
}
}
}
x86gpf_expected(NULL, 0);
return 1;
}
// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc);
// if (CS == 0x0028 && pc == 0xC03813C0)
// output = 3;
/* if (pc == 0x8028009A)
output = 3;
if (pc == 0x80282B6F)
{
__times++;
if (__times == 2)
fatal("WRONG\n");
if (!(d & (1 << (temp & 7)))) {
x86_int_sw_rm(temp);
PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0);
return 1;
}
}
}
x86gpf_expected(NULL, 0);
return 1;
}
if (pc == 0x802809CE)
fatal("RIGHT\n");*/
// if (CS == 0x0028 && pc == 0x80037FE9)
// output = 3;
//if (CS == 0x9087 && pc == 0x3763)
// fatal("Here\n");
//if (CS==0x9087 && pc == 0x0850)
// output = 1;
// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX,
// DX, (AL < 32) ? ' ' : AL, CS, pc); if (CS == 0x0028 && pc == 0xC03813C0)
// output = 3;
/* if (pc == 0x8028009A)
output = 3;
if (pc == 0x80282B6F)
{
__times++;
if (__times == 2)
fatal("WRONG\n");
}
if (pc == 0x802809CE)
fatal("RIGHT\n");*/
// if (CS == 0x0028 && pc == 0x80037FE9)
// output = 3;
// if (CS == 0x9087 && pc == 0x3763)
// fatal("Here\n");
// if (CS==0x9087 && pc == 0x0850)
// output = 1;
/* if (output && pc == 0x80033008)
{
__times++;
if (__times == 2)
fatal("WRONG\n");
}*/
/* if (output && pc == 0x80D8)
{
__times++;
if (__times == 2)
fatal("RIGHT\n");
}*/
/* if (output && pc == 0x80033008)
{
__times++;
if (__times == 2)
fatal("WRONG\n");
}*/
/* if (output && pc == 0x80D8)
{
__times++;
if (__times == 2)
fatal("RIGHT\n");
}*/
x86_int_sw(temp);
PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0);
return 1;
x86_int_sw(temp);
PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0);
return 1;
}
static int opINTO(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
int cycles_old = cycles;
UNUSED(cycles_old);
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf(NULL, 0);
return 1;
}
if (VF_SET()) {
cpu_state.oldpc = cpu_state.pc;
x86_int_sw(4);
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
return 1;
}
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf(NULL, 0);
return 1;
}
if (VF_SET()) {
cpu_state.oldpc = cpu_state.pc;
x86_int_sw(4);
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
return 1;
}
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
#endif /* _X86_OPS_INT_H_ */

View File

@@ -1,163 +1,163 @@
#ifndef _X86_OPS_IO_H_
#define _X86_OPS_IO_H_
static int opIN_AL_imm(uint32_t fetchdat) {
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
AL = inb(port);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
AL = inb(port);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opIN_AX_imm(uint32_t fetchdat) {
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
check_io_perm(port + 1);
AX = inw(port);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
check_io_perm(port + 1);
AX = inw(port);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opIN_EAX_imm(uint32_t fetchdat) {
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
check_io_perm(port + 1);
check_io_perm(port + 2);
check_io_perm(port + 3);
EAX = inl(port);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, -1, 0, 1, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
check_io_perm(port + 1);
check_io_perm(port + 2);
check_io_perm(port + 3);
EAX = inl(port);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, -1, 0, 1, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opOUT_AL_imm(uint32_t fetchdat) {
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
outb(port, AL);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
if (port == 0x64)
return x86_was_reset;
return 0;
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
outb(port, AL);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
if (port == 0x64)
return x86_was_reset;
return 0;
}
static int opOUT_AX_imm(uint32_t fetchdat) {
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
check_io_perm(port + 1);
outw(port, AX);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
check_io_perm(port + 1);
outw(port, AX);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opOUT_EAX_imm(uint32_t fetchdat) {
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
check_io_perm(port + 1);
check_io_perm(port + 2);
check_io_perm(port + 3);
outl(port, EAX);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0, 0, 0, 1, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
uint16_t port = (uint16_t)getbytef();
check_io_perm(port);
check_io_perm(port + 1);
check_io_perm(port + 2);
check_io_perm(port + 3);
outl(port, EAX);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0, 0, 0, 1, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opIN_AL_DX(uint32_t fetchdat) {
check_io_perm(DX);
AL = inb(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
check_io_perm(DX);
AL = inb(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opIN_AX_DX(uint32_t fetchdat) {
check_io_perm(DX);
check_io_perm(DX + 1);
AX = inw(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
check_io_perm(DX);
check_io_perm(DX + 1);
AX = inw(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opIN_EAX_DX(uint32_t fetchdat) {
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
EAX = inl(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 0, 1, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
EAX = inl(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 0, 1, 0, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opOUT_AL_DX(uint32_t fetchdat) {
check_io_perm(DX);
outb(DX, AL);
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return x86_was_reset;
check_io_perm(DX);
outb(DX, AL);
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return x86_was_reset;
}
static int opOUT_AX_DX(uint32_t fetchdat) {
//pclog("OUT_AX_DX %04X %04X\n", DX, AX);
check_io_perm(DX);
check_io_perm(DX + 1);
outw(DX, AX);
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
// pclog("OUT_AX_DX %04X %04X\n", DX, AX);
check_io_perm(DX);
check_io_perm(DX + 1);
outw(DX, AX);
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
static int opOUT_EAX_DX(uint32_t fetchdat) {
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
outl(DX, EAX);
PREFETCH_RUN(11, 1, -1, 0, 0, 0, 1, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
outl(DX, EAX);
PREFETCH_RUN(11, 1, -1, 0, 0, 0, 1, 0);
if (cpu_state.smi_pending)
return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
}
#endif /* _X86_OPS_IO_H_ */

View File

@@ -1,370 +1,351 @@
#ifndef _X86_OPS_JUMP_H_
#define _X86_OPS_JUMP_H_
#define cond_O ( VF_SET())
#define cond_NO (!VF_SET())
#define cond_B ( CF_SET())
#define cond_NB (!CF_SET())
#define cond_E ( ZF_SET())
#define cond_NE (!ZF_SET())
#define cond_BE ( CF_SET() || ZF_SET())
#define cond_O (VF_SET())
#define cond_NO (!VF_SET())
#define cond_B (CF_SET())
#define cond_NB (!CF_SET())
#define cond_E (ZF_SET())
#define cond_NE (!ZF_SET())
#define cond_BE (CF_SET() || ZF_SET())
#define cond_NBE (!CF_SET() && !ZF_SET())
#define cond_S ( NF_SET())
#define cond_NS (!NF_SET())
#define cond_P ( PF_SET())
#define cond_NP (!PF_SET())
#define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0))
#define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0))
#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET()))
#define cond_S (NF_SET())
#define cond_NS (!NF_SET())
#define cond_P (PF_SET())
#define cond_NP (!PF_SET())
#define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0))
#define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0))
#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET()))
#define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET()))
#define opJ(condition) \
static int opJ ## condition(uint32_t fetchdat) \
{ \
int8_t offset = (int8_t)getbytef(); \
CLOCK_CYCLES(timing_bnt); \
if (cond_ ## condition) \
{ \
cpu_state.pc += offset; \
if (!(cpu_state.op32 & 0x100)) \
cpu_state.pc &= 0xffff; \
CLOCK_CYCLES_ALWAYS(timing_bt); \
CPU_BLOCK_END(); \
PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \
PREFETCH_FLUSH(); \
return 1; \
} \
PREFETCH_RUN(timing_bnt, 2, -1, 0,0,0,0, 0); \
return 0; \
} \
\
static int opJ ## condition ## _w(uint32_t fetchdat) \
{ \
int16_t offset = (int16_t)getwordf(); \
CLOCK_CYCLES(timing_bnt); \
if (cond_ ## condition) \
{ \
cpu_state.pc += offset; \
cpu_state.pc &= 0xffff; \
CLOCK_CYCLES_ALWAYS(timing_bt); \
CPU_BLOCK_END(); \
PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \
PREFETCH_FLUSH(); \
return 1; \
} \
PREFETCH_RUN(timing_bnt, 3, -1, 0,0,0,0, 0); \
return 0; \
} \
\
static int opJ ## condition ## _l(uint32_t fetchdat) \
{ \
uint32_t offset = getlong(); if (cpu_state.abrt) return 1; \
CLOCK_CYCLES(timing_bnt); \
if (cond_ ## condition) \
{ \
cpu_state.pc += offset; \
CLOCK_CYCLES_ALWAYS(timing_bt); \
CPU_BLOCK_END(); \
PREFETCH_RUN(timing_bt+timing_bnt, 5, -1, 0,0,0,0, 0); \
PREFETCH_FLUSH(); \
return 1; \
} \
PREFETCH_RUN(timing_bnt, 5, -1, 0,0,0,0, 0); \
return 0; \
} \
#define opJ(condition) \
static int opJ##condition(uint32_t fetchdat) { \
int8_t offset = (int8_t)getbytef(); \
CLOCK_CYCLES(timing_bnt); \
if (cond_##condition) { \
cpu_state.pc += offset; \
if (!(cpu_state.op32 & 0x100)) \
cpu_state.pc &= 0xffff; \
CLOCK_CYCLES_ALWAYS(timing_bt); \
CPU_BLOCK_END(); \
PREFETCH_RUN(timing_bt + timing_bnt, 2, -1, 0, 0, 0, 0, 0); \
PREFETCH_FLUSH(); \
return 1; \
} \
PREFETCH_RUN(timing_bnt, 2, -1, 0, 0, 0, 0, 0); \
return 0; \
} \
\
static int opJ##condition##_w(uint32_t fetchdat) { \
int16_t offset = (int16_t)getwordf(); \
CLOCK_CYCLES(timing_bnt); \
if (cond_##condition) { \
cpu_state.pc += offset; \
cpu_state.pc &= 0xffff; \
CLOCK_CYCLES_ALWAYS(timing_bt); \
CPU_BLOCK_END(); \
PREFETCH_RUN(timing_bt + timing_bnt, 3, -1, 0, 0, 0, 0, 0); \
PREFETCH_FLUSH(); \
return 1; \
} \
PREFETCH_RUN(timing_bnt, 3, -1, 0, 0, 0, 0, 0); \
return 0; \
} \
\
static int opJ##condition##_l(uint32_t fetchdat) { \
uint32_t offset = getlong(); \
if (cpu_state.abrt) \
return 1; \
CLOCK_CYCLES(timing_bnt); \
if (cond_##condition) { \
cpu_state.pc += offset; \
CLOCK_CYCLES_ALWAYS(timing_bt); \
CPU_BLOCK_END(); \
PREFETCH_RUN(timing_bt + timing_bnt, 5, -1, 0, 0, 0, 0, 0); \
PREFETCH_FLUSH(); \
return 1; \
} \
PREFETCH_RUN(timing_bnt, 5, -1, 0, 0, 0, 0, 0); \
return 0; \
}
opJ(O)
opJ(NO)
opJ(B)
opJ(NB)
opJ(E)
opJ(NE)
opJ(BE)
opJ(NBE)
opJ(S)
opJ(NS)
opJ(P)
opJ(NP)
opJ(L)
opJ(NL)
opJ(LE)
opJ(NLE)
opJ(O) opJ(NO) opJ(B) opJ(NB) opJ(E) opJ(NE) opJ(BE) opJ(NBE) opJ(S) opJ(NS) opJ(P) opJ(NP) opJ(L) opJ(NL) opJ(LE) opJ(NLE)
static int opLOOPNE_w(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
CX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (CX && !ZF_SET()) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
static int opLOOPNE_w(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
CX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (CX && !ZF_SET()) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
}
static int opLOOPNE_l(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
ECX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (ECX && !ZF_SET()) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
int8_t offset = (int8_t)getbytef();
ECX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (ECX && !ZF_SET()) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
}
static int opLOOPE_w(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
CX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (CX && ZF_SET()) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
int8_t offset = (int8_t)getbytef();
CX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (CX && ZF_SET()) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
}
static int opLOOPE_l(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
ECX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (ECX && ZF_SET()) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
int8_t offset = (int8_t)getbytef();
ECX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (ECX && ZF_SET()) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
}
static int opLOOP_w(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
CX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (CX) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
int8_t offset = (int8_t)getbytef();
CX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (CX) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
}
static int opLOOP_l(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
ECX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (ECX) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
int8_t offset = (int8_t)getbytef();
ECX--;
CLOCK_CYCLES((is486) ? 7 : 11);
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
if (ECX) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
PREFETCH_FLUSH();
return 1;
}
return 0;
}
static int opJCXZ(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
CLOCK_CYCLES(5);
if (!CX) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CLOCK_CYCLES(4);
CPU_BLOCK_END();
PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 1;
}
PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0);
return 0;
int8_t offset = (int8_t)getbytef();
CLOCK_CYCLES(5);
if (!CX) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CLOCK_CYCLES(4);
CPU_BLOCK_END();
PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 1;
}
PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opJECXZ(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
CLOCK_CYCLES(5);
if (!ECX) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CLOCK_CYCLES(4);
CPU_BLOCK_END();
PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 1;
}
PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0);
return 0;
int8_t offset = (int8_t)getbytef();
CLOCK_CYCLES(5);
if (!ECX) {
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CLOCK_CYCLES(4);
CPU_BLOCK_END();
PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 1;
}
PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opJMP_r8(uint32_t fetchdat) {
int8_t offset = (int8_t)getbytef();
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 2, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
int8_t offset = (int8_t)getbytef();
cpu_state.pc += offset;
if (!(cpu_state.op32 & 0x100))
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 2, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opJMP_r16(uint32_t fetchdat) {
int16_t offset = (int16_t)getwordf();
cpu_state.pc += offset;
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 3, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
int16_t offset = (int16_t)getwordf();
cpu_state.pc += offset;
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 3, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opJMP_r32(uint32_t fetchdat) {
int32_t offset = (int32_t)getlong();
if (cpu_state.abrt)
return 1;
cpu_state.pc += offset;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 5, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
int32_t offset = (int32_t)getlong();
if (cpu_state.abrt)
return 1;
cpu_state.pc += offset;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 5, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opJMP_far_a16(uint32_t fetchdat) {
uint16_t addr = getwordf();
uint16_t seg = getword();
if (cpu_state.abrt)
return 1;
uint32_t old_pc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, old_pc);
CPU_BLOCK_END();
PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
uint16_t addr = getwordf();
uint16_t seg = getword();
if (cpu_state.abrt)
return 1;
uint32_t old_pc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, old_pc);
CPU_BLOCK_END();
PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opJMP_far_a32(uint32_t fetchdat) {
uint32_t addr = getlong();
uint16_t seg = getword();
if (cpu_state.abrt)
return 1;
uint32_t old_pc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, old_pc);
CPU_BLOCK_END();
PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
uint32_t addr = getlong();
uint16_t seg = getword();
if (cpu_state.abrt)
return 1;
uint32_t old_pc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, old_pc);
CPU_BLOCK_END();
PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opCALL_r16(uint32_t fetchdat) {
int16_t addr = (int16_t)getwordf();
PUSH_W(cpu_state.pc);
cpu_state.pc += addr;
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 3, -1, 0, 0, 1, 0, 0);
PREFETCH_FLUSH();
return 0;
int16_t addr = (int16_t)getwordf();
PUSH_W(cpu_state.pc);
cpu_state.pc += addr;
cpu_state.pc &= 0xffff;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 3, -1, 0, 0, 1, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opCALL_r32(uint32_t fetchdat) {
int32_t addr = getlong();
if (cpu_state.abrt)
return 1;
PUSH_L(cpu_state.pc);
cpu_state.pc += addr;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 5, -1, 0, 0, 0, 1, 0);
PREFETCH_FLUSH();
return 0;
int32_t addr = getlong();
if (cpu_state.abrt)
return 1;
PUSH_L(cpu_state.pc);
cpu_state.pc += addr;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 3 : 7);
PREFETCH_RUN(7, 5, -1, 0, 0, 0, 1, 0);
PREFETCH_FLUSH();
return 0;
}
static int opRET_w(uint32_t fetchdat) {
uint16_t ret;
uint16_t ret;
ret = POP_W();
if (cpu_state.abrt)
return 1;
cpu_state.pc = ret;
CPU_BLOCK_END();
ret = POP_W();
if (cpu_state.abrt)
return 1;
cpu_state.pc = ret;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 5 : 10);
PREFETCH_RUN(10, 1, -1, 1, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
CLOCK_CYCLES((is486) ? 5 : 10);
PREFETCH_RUN(10, 1, -1, 1, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opRET_l(uint32_t fetchdat) {
uint32_t ret;
uint32_t ret;
ret = POP_L();
if (cpu_state.abrt)
return 1;
cpu_state.pc = ret;
CPU_BLOCK_END();
ret = POP_L();
if (cpu_state.abrt)
return 1;
cpu_state.pc = ret;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 5 : 10);
PREFETCH_RUN(10, 1, -1, 0, 1, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
CLOCK_CYCLES((is486) ? 5 : 10);
PREFETCH_RUN(10, 1, -1, 0, 1, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opRET_w_imm(uint32_t fetchdat) {
uint16_t offset = getwordf();
uint16_t ret;
uint16_t offset = getwordf();
uint16_t ret;
ret = POP_W();
if (cpu_state.abrt)
return 1;
if (stack32)
ESP += offset;
else
SP += offset;
cpu_state.pc = ret;
CPU_BLOCK_END();
ret = POP_W();
if (cpu_state.abrt)
return 1;
if (stack32)
ESP += offset;
else
SP += offset;
cpu_state.pc = ret;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 5 : 10);
PREFETCH_RUN(10, 5, -1, 1, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
CLOCK_CYCLES((is486) ? 5 : 10);
PREFETCH_RUN(10, 5, -1, 1, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opRET_l_imm(uint32_t fetchdat) {
uint16_t offset = getwordf();
uint32_t ret;
uint16_t offset = getwordf();
uint32_t ret;
ret = POP_L();
if (cpu_state.abrt)
return 1;
if (stack32)
ESP += offset;
else
SP += offset;
cpu_state.pc = ret;
CPU_BLOCK_END();
ret = POP_L();
if (cpu_state.abrt)
return 1;
if (stack32)
ESP += offset;
else
SP += offset;
cpu_state.pc = ret;
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 5 : 10);
PREFETCH_RUN(10, 5, -1, 0, 1, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
CLOCK_CYCLES((is486) ? 5 : 10);
PREFETCH_RUN(10, 5, -1, 0, 1, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
#endif /* _X86_OPS_JUMP_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -5,46 +5,43 @@
#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val)))
#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val)))
#define MMX_GETSRC() \
if (cpu_mod == 3) \
{ \
src = cpu_state.MM[cpu_rm]; \
CLOCK_CYCLES(1); \
} \
else \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \
CLOCK_CYCLES(2); \
#define MMX_GETSRC() \
if (cpu_mod == 3) { \
src = cpu_state.MM[cpu_rm]; \
CLOCK_CYCLES(1); \
} else { \
SEG_CHECK_READ(cpu_state.ea_seg); \
src.q = readmemq(easeg, cpu_state.eaaddr); \
if (cpu_state.abrt) \
return 1; \
CLOCK_CYCLES(2); \
}
#define MMX_ENTER() \
if (!cpu_has_feature(CPU_FEATURE_MMX)) \
{ \
cpu_state.pc = cpu_state.oldpc; \
x86illegal(); \
return 1; \
} \
if (cr0 & 0xc) \
{ \
x86_int(7); \
return 1; \
} \
#define MMX_ENTER() \
if (!cpu_has_feature(CPU_FEATURE_MMX)) { \
cpu_state.pc = cpu_state.oldpc; \
x86illegal(); \
return 1; \
} \
if (cr0 & 0xc) { \
x86_int(7); \
return 1; \
} \
x87_set_mmx()
static int opEMMS(uint32_t fetchdat) {
if (!cpu_has_feature(CPU_FEATURE_MMX)) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
if (cr0 & 0xc) {
x86_int(7);
return 1;
}
x87_emms();
CLOCK_CYCLES(100); /*Guess*/
return 0;
if (!cpu_has_feature(CPU_FEATURE_MMX)) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
if (cr0 & 0xc) {
x86_int(7);
return 1;
}
x87_emms();
CLOCK_CYCLES(100); /*Guess*/
return 0;
}
#endif /* _X86_OPS_MMX_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,197 +1,197 @@
#ifndef _X86_OPS_MMX_CMP_H_
#define _X86_OPS_MMX_CMP_H_
static int opPCMPEQB_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
return 0;
return 0;
}
static int opPCMPEQB_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
return 0;
return 0;
}
static int opPCMPGTB_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
return 0;
return 0;
}
static int opPCMPGTB_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
return 0;
return 0;
}
static int opPCMPEQW_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
return 0;
return 0;
}
static int opPCMPEQW_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
return 0;
return 0;
}
static int opPCMPGTW_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
return 0;
return 0;
}
static int opPCMPGTW_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
return 0;
return 0;
}
static int opPCMPEQD_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
return 0;
return 0;
}
static int opPCMPEQD_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
return 0;
return 0;
}
static int opPCMPGTD_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
return 0;
return 0;
}
static int opPCMPGTD_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_REG src;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
return 0;
return 0;
}
#endif /* _X86_OPS_MMX_CMP_H_ */

View File

@@ -1,87 +1,87 @@
#ifndef _X86_OPS_MMX_LOGIC_H_
#define _X86_OPS_MMX_LOGIC_H_
static int opPAND_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q &= src.q;
return 0;
cpu_state.MM[cpu_reg].q &= src.q;
return 0;
}
static int opPAND_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q &= src.q;
return 0;
cpu_state.MM[cpu_reg].q &= src.q;
return 0;
}
static int opPANDN_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
return 0;
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
return 0;
}
static int opPANDN_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
return 0;
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
return 0;
}
static int opPOR_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q |= src.q;
return 0;
cpu_state.MM[cpu_reg].q |= src.q;
return 0;
}
static int opPOR_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q |= src.q;
return 0;
cpu_state.MM[cpu_reg].q |= src.q;
return 0;
}
static int opPXOR_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q ^= src.q;
return 0;
cpu_state.MM[cpu_reg].q ^= src.q;
return 0;
}
static int opPXOR_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q ^= src.q;
return 0;
cpu_state.MM[cpu_reg].q ^= src.q;
return 0;
}
#endif /* _X86_OPS_MMX_LOGIC_H_ */

View File

@@ -1,199 +1,199 @@
#ifndef _X86_OPS_MMX_MOV_H_
#define _X86_OPS_MMX_MOV_H_
static int opMOVD_l_mm_a16(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
cpu_state.MM[cpu_reg].l[1] = 0;
CLOCK_CYCLES(1);
} else {
uint32_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
cpu_state.MM[cpu_reg].l[1] = 0;
CLOCK_CYCLES(1);
} else {
uint32_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].l[0] = dst;
cpu_state.MM[cpu_reg].l[1] = 0;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].l[0] = dst;
cpu_state.MM[cpu_reg].l[1] = 0;
CLOCK_CYCLES(2);
}
return 0;
CLOCK_CYCLES(2);
}
return 0;
}
static int opMOVD_l_mm_a32(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
cpu_state.MM[cpu_reg].l[1] = 0;
CLOCK_CYCLES(1);
} else {
uint32_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
cpu_state.MM[cpu_reg].l[1] = 0;
CLOCK_CYCLES(1);
} else {
uint32_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].l[0] = dst;
cpu_state.MM[cpu_reg].l[1] = 0;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].l[0] = dst;
cpu_state.MM[cpu_reg].l[1] = 0;
CLOCK_CYCLES(2);
}
return 0;
CLOCK_CYCLES(2);
}
return 0;
}
static int opMOVD_mm_l_a16(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
static int opMOVD_mm_l_a32(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
/*Cyrix maps both MOVD and SMINT to the same opcode*/
static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM)
return opSMINT(fetchdat);
if (cpu_cur_status & CPU_STATUS_SMM)
return opSMINT(fetchdat);
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM)
return opSMINT(fetchdat);
if (cpu_cur_status & CPU_STATUS_SMM)
return opSMINT(fetchdat);
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
static int opMOVQ_q_mm_a16(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
CLOCK_CYCLES(1);
} else {
uint64_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
CLOCK_CYCLES(1);
} else {
uint64_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmemq(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].q = dst;
CLOCK_CYCLES(2);
}
return 0;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmemq(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].q = dst;
CLOCK_CYCLES(2);
}
return 0;
}
static int opMOVQ_q_mm_a32(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
CLOCK_CYCLES(1);
} else {
uint64_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
CLOCK_CYCLES(1);
} else {
uint64_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmemq(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].q = dst;
CLOCK_CYCLES(2);
}
return 0;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmemq(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].q = dst;
CLOCK_CYCLES(2);
}
return 0;
}
static int opMOVQ_mm_q_a16(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
static int opMOVQ_mm_q_a32(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
#endif /* _X86_OPS_MMX_MOV_H_ */

View File

@@ -1,310 +1,310 @@
#ifndef _X86_OPS_MMX_PACK_H_
#define _X86_OPS_MMX_PACK_H_
static int opPUNPCKLDQ_a16(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
CLOCK_CYCLES(1);
} else {
uint32_t src;
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
CLOCK_CYCLES(1);
} else {
uint32_t src;
SEG_CHECK_READ(cpu_state.ea_seg);
src = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].l[1] = src;
SEG_CHECK_READ(cpu_state.ea_seg);
src = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].l[1] = src;
CLOCK_CYCLES(2);
}
return 0;
CLOCK_CYCLES(2);
}
return 0;
}
static int opPUNPCKLDQ_a32(uint32_t fetchdat) {
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
CLOCK_CYCLES(1);
} else {
uint32_t src;
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
CLOCK_CYCLES(1);
} else {
uint32_t src;
SEG_CHECK_READ(cpu_state.ea_seg);
src = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].l[1] = src;
SEG_CHECK_READ(cpu_state.ea_seg);
src = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].l[1] = src;
CLOCK_CYCLES(2);
}
return 0;
CLOCK_CYCLES(2);
}
return 0;
}
static int opPUNPCKHDQ_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
cpu_state.MM[cpu_reg].l[1] = src.l[1];
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
cpu_state.MM[cpu_reg].l[1] = src.l[1];
return 0;
return 0;
}
static int opPUNPCKHDQ_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
cpu_state.MM[cpu_reg].l[1] = src.l[1];
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
cpu_state.MM[cpu_reg].l[1] = src.l[1];
return 0;
return 0;
}
static int opPUNPCKLBW_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[7] = src.b[3];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
cpu_state.MM[cpu_reg].b[5] = src.b[2];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
cpu_state.MM[cpu_reg].b[3] = src.b[1];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
cpu_state.MM[cpu_reg].b[1] = src.b[0];
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
cpu_state.MM[cpu_reg].b[7] = src.b[3];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
cpu_state.MM[cpu_reg].b[5] = src.b[2];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
cpu_state.MM[cpu_reg].b[3] = src.b[1];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
cpu_state.MM[cpu_reg].b[1] = src.b[0];
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
return 0;
return 0;
}
static int opPUNPCKLBW_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[7] = src.b[3];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
cpu_state.MM[cpu_reg].b[5] = src.b[2];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
cpu_state.MM[cpu_reg].b[3] = src.b[1];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
cpu_state.MM[cpu_reg].b[1] = src.b[0];
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
cpu_state.MM[cpu_reg].b[7] = src.b[3];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
cpu_state.MM[cpu_reg].b[5] = src.b[2];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
cpu_state.MM[cpu_reg].b[3] = src.b[1];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
cpu_state.MM[cpu_reg].b[1] = src.b[0];
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
return 0;
return 0;
}
static int opPUNPCKHBW_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
cpu_state.MM[cpu_reg].b[1] = src.b[4];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
cpu_state.MM[cpu_reg].b[3] = src.b[5];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
cpu_state.MM[cpu_reg].b[5] = src.b[6];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
cpu_state.MM[cpu_reg].b[7] = src.b[7];
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
cpu_state.MM[cpu_reg].b[1] = src.b[4];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
cpu_state.MM[cpu_reg].b[3] = src.b[5];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
cpu_state.MM[cpu_reg].b[5] = src.b[6];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
cpu_state.MM[cpu_reg].b[7] = src.b[7];
return 0;
return 0;
}
static int opPUNPCKHBW_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
cpu_state.MM[cpu_reg].b[1] = src.b[4];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
cpu_state.MM[cpu_reg].b[3] = src.b[5];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
cpu_state.MM[cpu_reg].b[5] = src.b[6];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
cpu_state.MM[cpu_reg].b[7] = src.b[7];
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
cpu_state.MM[cpu_reg].b[1] = src.b[4];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
cpu_state.MM[cpu_reg].b[3] = src.b[5];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
cpu_state.MM[cpu_reg].b[5] = src.b[6];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
cpu_state.MM[cpu_reg].b[7] = src.b[7];
return 0;
return 0;
}
static int opPUNPCKLWD_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[3] = src.w[1];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
cpu_state.MM[cpu_reg].w[1] = src.w[0];
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
cpu_state.MM[cpu_reg].w[3] = src.w[1];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
cpu_state.MM[cpu_reg].w[1] = src.w[0];
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
return 0;
return 0;
}
static int opPUNPCKLWD_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[3] = src.w[1];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
cpu_state.MM[cpu_reg].w[1] = src.w[0];
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
cpu_state.MM[cpu_reg].w[3] = src.w[1];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
cpu_state.MM[cpu_reg].w[1] = src.w[0];
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
return 0;
return 0;
}
static int opPUNPCKHWD_a16(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
fetch_ea_16(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
cpu_state.MM[cpu_reg].w[1] = src.w[2];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
cpu_state.MM[cpu_reg].w[3] = src.w[3];
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
cpu_state.MM[cpu_reg].w[1] = src.w[2];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
cpu_state.MM[cpu_reg].w[3] = src.w[3];
return 0;
return 0;
}
static int opPUNPCKHWD_a32(uint32_t fetchdat) {
MMX_REG src;
MMX_ENTER();
MMX_REG src;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
fetch_ea_32(fetchdat);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
cpu_state.MM[cpu_reg].w[1] = src.w[2];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
cpu_state.MM[cpu_reg].w[3] = src.w[3];
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
cpu_state.MM[cpu_reg].w[1] = src.w[2];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
cpu_state.MM[cpu_reg].w[3] = src.w[3];
return 0;
return 0;
}
static int opPACKSSWB_a16(uint32_t fetchdat) {
MMX_REG src, dst;
MMX_ENTER();
MMX_REG src, dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
return 0;
return 0;
}
static int opPACKSSWB_a32(uint32_t fetchdat) {
MMX_REG src, dst;
MMX_ENTER();
MMX_REG src, dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
return 0;
return 0;
}
static int opPACKUSWB_a16(uint32_t fetchdat) {
MMX_REG src, dst;
MMX_ENTER();
MMX_REG src, dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
return 0;
return 0;
}
static int opPACKUSWB_a32(uint32_t fetchdat) {
MMX_REG src, dst;
MMX_ENTER();
MMX_REG src, dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
return 0;
return 0;
}
static int opPACKSSDW_a16(uint32_t fetchdat) {
MMX_REG src, dst;
MMX_ENTER();
MMX_REG src, dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
return 0;
return 0;
}
static int opPACKSSDW_a32(uint32_t fetchdat) {
MMX_REG src, dst;
MMX_ENTER();
MMX_REG src, dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
return 0;
return 0;
}
#endif /* _X86_OPS_MMX_PACK_H_ */

View File

@@ -1,420 +1,422 @@
#ifndef _X86_OPS_MMX_SHIFT_H_
#define _X86_OPS_MMX_SHIFT_H_
#define MMX_GETSHIFT() \
if (cpu_mod == 3) \
{ \
shift = cpu_state.MM[cpu_rm].b[0]; \
CLOCK_CYCLES(1); \
} \
else \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \
CLOCK_CYCLES(2); \
#define MMX_GETSHIFT() \
if (cpu_mod == 3) { \
shift = cpu_state.MM[cpu_rm].b[0]; \
CLOCK_CYCLES(1); \
} else { \
SEG_CHECK_READ(cpu_state.ea_seg); \
shift = readmemb(easeg, cpu_state.eaaddr); \
if (cpu_state.abrt) \
return 0; \
CLOCK_CYCLES(2); \
}
static int opPSxxW_imm(uint32_t fetchdat) {
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
cpu_state.pc += 2;
MMX_ENTER();
cpu_state.pc += 2;
MMX_ENTER();
switch (op) {
case 0x10: /*PSRLW*/
if (shift > 15)
cpu_state.MM[reg].q = 0;
else {
cpu_state.MM[reg].w[0] >>= shift;
cpu_state.MM[reg].w[1] >>= shift;
cpu_state.MM[reg].w[2] >>= shift;
cpu_state.MM[reg].w[3] >>= shift;
}
break;
case 0x20: /*PSRAW*/
if (shift > 15)
shift = 15;
cpu_state.MM[reg].sw[0] >>= shift;
cpu_state.MM[reg].sw[1] >>= shift;
cpu_state.MM[reg].sw[2] >>= shift;
cpu_state.MM[reg].sw[3] >>= shift;
break;
case 0x30: /*PSLLW*/
if (shift > 15)
cpu_state.MM[reg].q = 0;
else {
cpu_state.MM[reg].w[0] <<= shift;
cpu_state.MM[reg].w[1] <<= shift;
cpu_state.MM[reg].w[2] <<= shift;
cpu_state.MM[reg].w[3] <<= shift;
}
break;
default:pclog("Bad PSxxW (0F 71) instruction %02X\n", op);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
switch (op) {
case 0x10: /*PSRLW*/
if (shift > 15)
cpu_state.MM[reg].q = 0;
else {
cpu_state.MM[reg].w[0] >>= shift;
cpu_state.MM[reg].w[1] >>= shift;
cpu_state.MM[reg].w[2] >>= shift;
cpu_state.MM[reg].w[3] >>= shift;
}
break;
case 0x20: /*PSRAW*/
if (shift > 15)
shift = 15;
cpu_state.MM[reg].sw[0] >>= shift;
cpu_state.MM[reg].sw[1] >>= shift;
cpu_state.MM[reg].sw[2] >>= shift;
cpu_state.MM[reg].sw[3] >>= shift;
break;
case 0x30: /*PSLLW*/
if (shift > 15)
cpu_state.MM[reg].q = 0;
else {
cpu_state.MM[reg].w[0] <<= shift;
cpu_state.MM[reg].w[1] <<= shift;
cpu_state.MM[reg].w[2] <<= shift;
cpu_state.MM[reg].w[3] <<= shift;
}
break;
default:
pclog("Bad PSxxW (0F 71) instruction %02X\n", op);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
CLOCK_CYCLES(1);
return 0;
CLOCK_CYCLES(1);
return 0;
}
static int opPSLLW_a16(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].w[0] <<= shift;
cpu_state.MM[cpu_reg].w[1] <<= shift;
cpu_state.MM[cpu_reg].w[2] <<= shift;
cpu_state.MM[cpu_reg].w[3] <<= shift;
}
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].w[0] <<= shift;
cpu_state.MM[cpu_reg].w[1] <<= shift;
cpu_state.MM[cpu_reg].w[2] <<= shift;
cpu_state.MM[cpu_reg].w[3] <<= shift;
}
return 0;
return 0;
}
static int opPSLLW_a32(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].w[0] <<= shift;
cpu_state.MM[cpu_reg].w[1] <<= shift;
cpu_state.MM[cpu_reg].w[2] <<= shift;
cpu_state.MM[cpu_reg].w[3] <<= shift;
}
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].w[0] <<= shift;
cpu_state.MM[cpu_reg].w[1] <<= shift;
cpu_state.MM[cpu_reg].w[2] <<= shift;
cpu_state.MM[cpu_reg].w[3] <<= shift;
}
return 0;
return 0;
}
static int opPSRLW_a16(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].w[0] >>= shift;
cpu_state.MM[cpu_reg].w[1] >>= shift;
cpu_state.MM[cpu_reg].w[2] >>= shift;
cpu_state.MM[cpu_reg].w[3] >>= shift;
}
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].w[0] >>= shift;
cpu_state.MM[cpu_reg].w[1] >>= shift;
cpu_state.MM[cpu_reg].w[2] >>= shift;
cpu_state.MM[cpu_reg].w[3] >>= shift;
}
return 0;
return 0;
}
static int opPSRLW_a32(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].w[0] >>= shift;
cpu_state.MM[cpu_reg].w[1] >>= shift;
cpu_state.MM[cpu_reg].w[2] >>= shift;
cpu_state.MM[cpu_reg].w[3] >>= shift;
}
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].w[0] >>= shift;
cpu_state.MM[cpu_reg].w[1] >>= shift;
cpu_state.MM[cpu_reg].w[2] >>= shift;
cpu_state.MM[cpu_reg].w[3] >>= shift;
}
return 0;
return 0;
}
static int opPSRAW_a16(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
if (shift > 15)
shift = 15;
if (shift > 15)
shift = 15;
cpu_state.MM[cpu_reg].sw[0] >>= shift;
cpu_state.MM[cpu_reg].sw[1] >>= shift;
cpu_state.MM[cpu_reg].sw[2] >>= shift;
cpu_state.MM[cpu_reg].sw[3] >>= shift;
cpu_state.MM[cpu_reg].sw[0] >>= shift;
cpu_state.MM[cpu_reg].sw[1] >>= shift;
cpu_state.MM[cpu_reg].sw[2] >>= shift;
cpu_state.MM[cpu_reg].sw[3] >>= shift;
return 0;
return 0;
}
static int opPSRAW_a32(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
if (shift > 15)
shift = 15;
if (shift > 15)
shift = 15;
cpu_state.MM[cpu_reg].sw[0] >>= shift;
cpu_state.MM[cpu_reg].sw[1] >>= shift;
cpu_state.MM[cpu_reg].sw[2] >>= shift;
cpu_state.MM[cpu_reg].sw[3] >>= shift;
cpu_state.MM[cpu_reg].sw[0] >>= shift;
cpu_state.MM[cpu_reg].sw[1] >>= shift;
cpu_state.MM[cpu_reg].sw[2] >>= shift;
cpu_state.MM[cpu_reg].sw[3] >>= shift;
return 0;
return 0;
}
static int opPSxxD_imm(uint32_t fetchdat) {
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
cpu_state.pc += 2;
MMX_ENTER();
cpu_state.pc += 2;
MMX_ENTER();
switch (op) {
case 0x10: /*PSRLD*/
if (shift > 31)
cpu_state.MM[reg].q = 0;
else {
cpu_state.MM[reg].l[0] >>= shift;
cpu_state.MM[reg].l[1] >>= shift;
}
break;
case 0x20: /*PSRAD*/
if (shift > 31)
shift = 31;
cpu_state.MM[reg].sl[0] >>= shift;
cpu_state.MM[reg].sl[1] >>= shift;
break;
case 0x30: /*PSLLD*/
if (shift > 31)
cpu_state.MM[reg].q = 0;
else {
cpu_state.MM[reg].l[0] <<= shift;
cpu_state.MM[reg].l[1] <<= shift;
}
break;
default:pclog("Bad PSxxD (0F 72) instruction %02X\n", op);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
switch (op) {
case 0x10: /*PSRLD*/
if (shift > 31)
cpu_state.MM[reg].q = 0;
else {
cpu_state.MM[reg].l[0] >>= shift;
cpu_state.MM[reg].l[1] >>= shift;
}
break;
case 0x20: /*PSRAD*/
if (shift > 31)
shift = 31;
cpu_state.MM[reg].sl[0] >>= shift;
cpu_state.MM[reg].sl[1] >>= shift;
break;
case 0x30: /*PSLLD*/
if (shift > 31)
cpu_state.MM[reg].q = 0;
else {
cpu_state.MM[reg].l[0] <<= shift;
cpu_state.MM[reg].l[1] <<= shift;
}
break;
default:
pclog("Bad PSxxD (0F 72) instruction %02X\n", op);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
CLOCK_CYCLES(1);
return 0;
CLOCK_CYCLES(1);
return 0;
}
static int opPSLLD_a16(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].l[0] <<= shift;
cpu_state.MM[cpu_reg].l[1] <<= shift;
}
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].l[0] <<= shift;
cpu_state.MM[cpu_reg].l[1] <<= shift;
}
return 0;
return 0;
}
static int opPSLLD_a32(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].l[0] <<= shift;
cpu_state.MM[cpu_reg].l[1] <<= shift;
}
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].l[0] <<= shift;
cpu_state.MM[cpu_reg].l[1] <<= shift;
}
return 0;
return 0;
}
static int opPSRLD_a16(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].l[0] >>= shift;
cpu_state.MM[cpu_reg].l[1] >>= shift;
}
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].l[0] >>= shift;
cpu_state.MM[cpu_reg].l[1] >>= shift;
}
return 0;
return 0;
}
static int opPSRLD_a32(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].l[0] >>= shift;
cpu_state.MM[cpu_reg].l[1] >>= shift;
}
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
else {
cpu_state.MM[cpu_reg].l[0] >>= shift;
cpu_state.MM[cpu_reg].l[1] >>= shift;
}
return 0;
return 0;
}
static int opPSRAD_a16(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
if (shift > 31)
shift = 31;
if (shift > 31)
shift = 31;
cpu_state.MM[cpu_reg].sl[0] >>= shift;
cpu_state.MM[cpu_reg].sl[1] >>= shift;
cpu_state.MM[cpu_reg].sl[0] >>= shift;
cpu_state.MM[cpu_reg].sl[1] >>= shift;
return 0;
return 0;
}
static int opPSRAD_a32(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
if (shift > 31)
shift = 31;
if (shift > 31)
shift = 31;
cpu_state.MM[cpu_reg].sl[0] >>= shift;
cpu_state.MM[cpu_reg].sl[1] >>= shift;
cpu_state.MM[cpu_reg].sl[0] >>= shift;
cpu_state.MM[cpu_reg].sl[1] >>= shift;
return 0;
return 0;
}
static int opPSxxQ_imm(uint32_t fetchdat) {
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
cpu_state.pc += 2;
MMX_ENTER();
cpu_state.pc += 2;
MMX_ENTER();
switch (op) {
case 0x10: /*PSRLW*/
if (shift > 63)
cpu_state.MM[reg].q = 0;
else
cpu_state.MM[reg].q >>= shift;
break;
case 0x20: /*PSRAW*/
if (shift > 63)
shift = 63;
cpu_state.MM[reg].sq >>= shift;
break;
case 0x30: /*PSLLW*/
if (shift > 63)
cpu_state.MM[reg].q = 0;
else
cpu_state.MM[reg].q <<= shift;
break;
default:pclog("Bad PSxxQ (0F 73) instruction %02X\n", op);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
switch (op) {
case 0x10: /*PSRLW*/
if (shift > 63)
cpu_state.MM[reg].q = 0;
else
cpu_state.MM[reg].q >>= shift;
break;
case 0x20: /*PSRAW*/
if (shift > 63)
shift = 63;
cpu_state.MM[reg].sq >>= shift;
break;
case 0x30: /*PSLLW*/
if (shift > 63)
cpu_state.MM[reg].q = 0;
else
cpu_state.MM[reg].q <<= shift;
break;
default:
pclog("Bad PSxxQ (0F 73) instruction %02X\n", op);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 0;
}
CLOCK_CYCLES(1);
return 0;
CLOCK_CYCLES(1);
return 0;
}
static int opPSLLQ_a16(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
else
cpu_state.MM[cpu_reg].q <<= shift;
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
else
cpu_state.MM[cpu_reg].q <<= shift;
return 0;
return 0;
}
static int opPSLLQ_a32(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
else
cpu_state.MM[cpu_reg].q <<= shift;
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
else
cpu_state.MM[cpu_reg].q <<= shift;
return 0;
return 0;
}
static int opPSRLQ_a16(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
fetch_ea_16(fetchdat);
MMX_GETSHIFT();
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
else
cpu_state.MM[cpu_reg].q >>= shift;
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
else
cpu_state.MM[cpu_reg].q >>= shift;
return 0;
return 0;
}
static int opPSRLQ_a32(uint32_t fetchdat) {
int shift;
int shift;
MMX_ENTER();
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
fetch_ea_32(fetchdat);
MMX_GETSHIFT();
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
else
cpu_state.MM[cpu_reg].q >>= shift;
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
else
cpu_state.MM[cpu_reg].q >>= shift;
return 0;
return 0;
}
#endif /* _X86_OPS_MMX_SHIFT_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,261 +1,275 @@
#ifndef _X86_OPS_MOV_CTRL_H_
#define _X86_OPS_MOV_CTRL_H_
static int opMOV_r_CRx_a16(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from CRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:cpu_state.regs[cpu_rm].l = cr0;
if (is486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
break;
case 2:cpu_state.regs[cpu_rm].l = cr2;
break;
case 3:cpu_state.regs[cpu_rm].l = cr3;
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
cpu_state.regs[cpu_rm].l = cr4;
break;
}
default:pclog("Bad read of CR%i %i\n", rmdat & 7, cpu_reg);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from CRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (is486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
break;
case 2:
cpu_state.regs[cpu_rm].l = cr2;
break;
case 3:
cpu_state.regs[cpu_rm].l = cr3;
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
cpu_state.regs[cpu_rm].l = cr4;
break;
}
default:
pclog("Bad read of CR%i %i\n", rmdat & 7, cpu_reg);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
}
static int opMOV_r_CRx_a32(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from CRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:cpu_state.regs[cpu_rm].l = cr0;
if (is486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
break;
case 2:cpu_state.regs[cpu_rm].l = cr2;
break;
case 3:cpu_state.regs[cpu_rm].l = cr3;
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
cpu_state.regs[cpu_rm].l = cr4;
break;
}
default:pclog("Bad read of CR%i %i\n", rmdat & 7, cpu_reg);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from CRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (is486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
break;
case 2:
cpu_state.regs[cpu_rm].l = cr2;
break;
case 3:
cpu_state.regs[cpu_rm].l = cr3;
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
cpu_state.regs[cpu_rm].l = cr4;
break;
}
default:
pclog("Bad read of CR%i %i\n", rmdat & 7, cpu_reg);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
}
static int opMOV_r_DRx_a16(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from DRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from DRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
}
static int opMOV_r_DRx_a32(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from DRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from DRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
}
static int opMOV_CRx_r_a16(uint32_t fetchdat) {
uint32_t old_cr0 = cr0;
uint32_t old_cr0 = cr0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load CRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
flushmmucache();
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
mmu_perm = 4;
if (is486 && !(cr0 & (1 << 30)))
cpu_cache_int_enabled = 1;
else
cpu_cache_int_enabled = 0;
if (is486 && ((cr0 ^ old_cr0) & (1 << 30)))
cpu_update_waitstates();
if (cr0 & 1)
cpu_cur_status |= CPU_STATUS_PMODE;
else
cpu_cur_status &= ~CPU_STATUS_PMODE;
break;
case 2:cr2 = cpu_state.regs[cpu_rm].l;
break;
case 3:cr3 = cpu_state.regs[cpu_rm].l;
flushmmucache();
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;
}
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load CRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
flushmmucache();
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
mmu_perm = 4;
if (is486 && !(cr0 & (1 << 30)))
cpu_cache_int_enabled = 1;
else
cpu_cache_int_enabled = 0;
if (is486 && ((cr0 ^ old_cr0) & (1 << 30)))
cpu_update_waitstates();
if (cr0 & 1)
cpu_cur_status |= CPU_STATUS_PMODE;
else
cpu_cur_status &= ~CPU_STATUS_PMODE;
break;
case 2:
cr2 = cpu_state.regs[cpu_rm].l;
break;
case 3:
cr3 = cpu_state.regs[cpu_rm].l;
flushmmucache();
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;
}
default:pclog("Bad load CR%i\n", cpu_reg);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
default:
pclog("Bad load CR%i\n", cpu_reg);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
}
static int opMOV_CRx_r_a32(uint32_t fetchdat) {
uint32_t old_cr0 = cr0;
uint32_t old_cr0 = cr0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load CRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
flushmmucache();
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
mmu_perm = 4;
if (is486 && !(cr0 & (1 << 30)))
cpu_cache_int_enabled = 1;
else
cpu_cache_int_enabled = 0;
if (is486 && ((cr0 ^ old_cr0) & (1 << 30)))
cpu_update_waitstates();
if (cr0 & 1)
cpu_cur_status |= CPU_STATUS_PMODE;
else
cpu_cur_status &= ~CPU_STATUS_PMODE;
break;
case 2:cr2 = cpu_state.regs[cpu_rm].l;
break;
case 3:cr3 = cpu_state.regs[cpu_rm].l;
flushmmucache();
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;
}
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load CRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
flushmmucache();
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
mmu_perm = 4;
if (is486 && !(cr0 & (1 << 30)))
cpu_cache_int_enabled = 1;
else
cpu_cache_int_enabled = 0;
if (is486 && ((cr0 ^ old_cr0) & (1 << 30)))
cpu_update_waitstates();
if (cr0 & 1)
cpu_cur_status |= CPU_STATUS_PMODE;
else
cpu_cur_status &= ~CPU_STATUS_PMODE;
break;
case 2:
cr2 = cpu_state.regs[cpu_rm].l;
break;
case 3:
cr3 = cpu_state.regs[cpu_rm].l;
flushmmucache();
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;
}
default:pclog("Bad load CR%i\n", cpu_reg);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
default:
pclog("Bad load CR%i\n", cpu_reg);
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
}
static int opMOV_DRx_r_a16(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load DRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load DRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
}
static int opMOV_DRx_r_a32(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load DRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load DRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
}
static int opMOV_r_TRx_a16(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from TRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
cpu_state.regs[cpu_rm].l = 0;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from TRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
cpu_state.regs[cpu_rm].l = 0;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
}
static int opMOV_r_TRx_a32(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from TRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
cpu_state.regs[cpu_rm].l = 0;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load from TRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
cpu_state.regs[cpu_rm].l = 0;
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
}
static int opMOV_TRx_r_a16(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load TRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load TRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
}
static int opMOV_TRx_r_a32(uint32_t fetchdat) {
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load TRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
pclog("Can't load TRx\n");
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
}
#endif /* _X86_OPS_MOV_CTRL_H_ */

View File

@@ -1,469 +1,491 @@
#ifndef _X86_OPS_MOV_SEG_H_
#define _X86_OPS_MOV_SEG_H_
static int opMOV_w_seg_a16(uint32_t fetchdat) {
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
switch (rmdat & 0x38) {
case 0x00: /*ES*/
seteaw(ES);
break;
case 0x08: /*CS*/
seteaw(CS);
break;
case 0x18: /*DS*/
seteaw(DS);
break;
case 0x10: /*SS*/
seteaw(SS);
break;
case 0x20: /*FS*/
seteaw(FS);
break;
case 0x28: /*GS*/
seteaw(GS);
break;
}
switch (rmdat & 0x38) {
case 0x00: /*ES*/
seteaw(ES);
break;
case 0x08: /*CS*/
seteaw(CS);
break;
case 0x18: /*DS*/
seteaw(DS);
break;
case 0x10: /*SS*/
seteaw(SS);
break;
case 0x20: /*FS*/
seteaw(FS);
break;
case 0x28: /*GS*/
seteaw(GS);
break;
}
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return cpu_state.abrt;
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return cpu_state.abrt;
}
static int opMOV_w_seg_a32(uint32_t fetchdat) {
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
switch (rmdat & 0x38) {
case 0x00: /*ES*/
seteaw(ES);
break;
case 0x08: /*CS*/
seteaw(CS);
break;
case 0x18: /*DS*/
seteaw(DS);
break;
case 0x10: /*SS*/
seteaw(SS);
break;
case 0x20: /*FS*/
seteaw(FS);
break;
case 0x28: /*GS*/
seteaw(GS);
break;
}
switch (rmdat & 0x38) {
case 0x00: /*ES*/
seteaw(ES);
break;
case 0x08: /*CS*/
seteaw(CS);
break;
case 0x18: /*DS*/
seteaw(DS);
break;
case 0x10: /*SS*/
seteaw(SS);
break;
case 0x20: /*FS*/
seteaw(FS);
break;
case 0x28: /*GS*/
seteaw(GS);
break;
}
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return cpu_state.abrt;
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return cpu_state.abrt;
}
static int opMOV_l_seg_a16(uint32_t fetchdat) {
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
switch (rmdat & 0x38) {
case 0x00: /*ES*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = ES;
else seteaw(ES);
break;
case 0x08: /*CS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = CS;
else seteaw(CS);
break;
case 0x18: /*DS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = DS;
else seteaw(DS);
break;
case 0x10: /*SS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = SS;
else seteaw(SS);
break;
case 0x20: /*FS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = FS;
else seteaw(FS);
break;
case 0x28: /*GS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = GS;
else seteaw(GS);
break;
}
switch (rmdat & 0x38) {
case 0x00: /*ES*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = ES;
else
seteaw(ES);
break;
case 0x08: /*CS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = CS;
else
seteaw(CS);
break;
case 0x18: /*DS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = DS;
else
seteaw(DS);
break;
case 0x10: /*SS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = SS;
else
seteaw(SS);
break;
case 0x20: /*FS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = FS;
else
seteaw(FS);
break;
case 0x28: /*GS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = GS;
else
seteaw(GS);
break;
}
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return cpu_state.abrt;
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return cpu_state.abrt;
}
static int opMOV_l_seg_a32(uint32_t fetchdat) {
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
switch (rmdat & 0x38) {
case 0x00: /*ES*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = ES;
else seteaw(ES);
break;
case 0x08: /*CS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = CS;
else seteaw(CS);
break;
case 0x18: /*DS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = DS;
else seteaw(DS);
break;
case 0x10: /*SS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = SS;
else seteaw(SS);
break;
case 0x20: /*FS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = FS;
else seteaw(FS);
break;
case 0x28: /*GS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = GS;
else seteaw(GS);
break;
}
switch (rmdat & 0x38) {
case 0x00: /*ES*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = ES;
else
seteaw(ES);
break;
case 0x08: /*CS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = CS;
else
seteaw(CS);
break;
case 0x18: /*DS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = DS;
else
seteaw(DS);
break;
case 0x10: /*SS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = SS;
else
seteaw(SS);
break;
case 0x20: /*FS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = FS;
else
seteaw(FS);
break;
case 0x28: /*GS*/
if (cpu_mod == 3)
cpu_state.regs[cpu_rm].l = GS;
else
seteaw(GS);
break;
}
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return cpu_state.abrt;
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return cpu_state.abrt;
}
static int opMOV_seg_w_a16(uint32_t fetchdat) {
uint16_t new_seg;
uint16_t new_seg;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_seg = geteaw();
if (cpu_state.abrt)
return 1;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_seg = geteaw();
if (cpu_state.abrt)
return 1;
switch (rmdat & 0x38) {
case 0x00: /*ES*/
loadseg(new_seg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
loadseg(new_seg, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
loadseg(new_seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
cpu_state.ssegs = 0;
cpu_state.ea_seg = &cpu_state.seg_ds;
fetchdat = fastreadl(cs + cpu_state.pc);
cpu_state.pc++;
if (cpu_state.abrt)
return 1;
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return 1;
case 0x20: /*FS*/
loadseg(new_seg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
loadseg(new_seg, &cpu_state.seg_gs);
break;
}
switch (rmdat & 0x38) {
case 0x00: /*ES*/
loadseg(new_seg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
loadseg(new_seg, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
loadseg(new_seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
cpu_state.ssegs = 0;
cpu_state.ea_seg = &cpu_state.seg_ds;
fetchdat = fastreadl(cs + cpu_state.pc);
cpu_state.pc++;
if (cpu_state.abrt)
return 1;
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return 1;
case 0x20: /*FS*/
loadseg(new_seg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
loadseg(new_seg, &cpu_state.seg_gs);
break;
}
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return cpu_state.abrt;
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
return cpu_state.abrt;
}
static int opMOV_seg_w_a32(uint32_t fetchdat) {
uint16_t new_seg;
uint16_t new_seg;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_seg = geteaw();
if (cpu_state.abrt)
return 1;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_seg = geteaw();
if (cpu_state.abrt)
return 1;
switch (rmdat & 0x38) {
case 0x00: /*ES*/
loadseg(new_seg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
loadseg(new_seg, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
loadseg(new_seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
cpu_state.ssegs = 0;
cpu_state.ea_seg = &cpu_state.seg_ds;
fetchdat = fastreadl(cs + cpu_state.pc);
cpu_state.pc++;
if (cpu_state.abrt)
return 1;
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return 1;
case 0x20: /*FS*/
loadseg(new_seg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
loadseg(new_seg, &cpu_state.seg_gs);
break;
}
switch (rmdat & 0x38) {
case 0x00: /*ES*/
loadseg(new_seg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
loadseg(new_seg, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
loadseg(new_seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
cpu_state.ssegs = 0;
cpu_state.ea_seg = &cpu_state.seg_ds;
fetchdat = fastreadl(cs + cpu_state.pc);
cpu_state.pc++;
if (cpu_state.abrt)
return 1;
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return 1;
case 0x20: /*FS*/
loadseg(new_seg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
loadseg(new_seg, &cpu_state.seg_gs);
break;
}
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return cpu_state.abrt;
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
return cpu_state.abrt;
}
static int opLDS_w_a16(uint32_t fetchdat) {
uint16_t addr, seg;
uint16_t addr, seg;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
return 0;
}
static int opLDS_w_a32(uint32_t fetchdat) {
uint16_t addr, seg;
uint16_t addr, seg;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
return 0;
}
static int opLDS_l_a16(uint32_t fetchdat) {
uint32_t addr;
uint16_t seg;
uint32_t addr;
uint16_t seg;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0);
return 0;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0);
return 0;
}
static int opLDS_l_a32(uint32_t fetchdat) {
uint32_t addr;
uint16_t seg;
uint32_t addr;
uint16_t seg;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1);
return 0;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1);
return 0;
}
static int opLSS_w_a16(uint32_t fetchdat) {
uint16_t addr, seg;
uint16_t addr, seg;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
return 1;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
return 1;
}
static int opLSS_w_a32(uint32_t fetchdat) {
uint16_t addr, seg;
uint16_t addr, seg;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
return 1;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
return 1;
}
static int opLSS_l_a16(uint32_t fetchdat) {
uint32_t addr;
uint16_t seg;
uint32_t addr;
uint16_t seg;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
return 1;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
return 1;
}
static int opLSS_l_a32(uint32_t fetchdat) {
uint32_t addr;
uint16_t seg;
uint32_t addr;
uint16_t seg;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
return 1;
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
return 1;
}
#define opLsel(name, sel) \
static int opL ## name ## _w_a16(uint32_t fetchdat) \
{ \
uint16_t addr, seg; \
\
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmemw(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \
loadseg(seg, &sel); if (cpu_state.abrt) return 1; \
cpu_state.regs[cpu_reg].w = addr; \
\
CLOCK_CYCLES(7); \
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); \
return 0; \
} \
\
static int opL ## name ## _w_a32(uint32_t fetchdat) \
{ \
uint16_t addr, seg; \
\
fetch_ea_32(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmemw(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \
loadseg(seg, &sel); if (cpu_state.abrt) return 1; \
cpu_state.regs[cpu_reg].w = addr; \
\
CLOCK_CYCLES(7); \
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); \
return 0; \
} \
\
static int opL ## name ## _l_a16(uint32_t fetchdat) \
{ \
uint32_t addr; \
uint16_t seg; \
\
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmeml(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \
loadseg(seg, &sel); if (cpu_state.abrt) return 1; \
cpu_state.regs[cpu_reg].l = addr; \
\
CLOCK_CYCLES(7); \
PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); \
return 0; \
} \
\
static int opL ## name ## _l_a32(uint32_t fetchdat) \
{ \
uint32_t addr; \
uint16_t seg; \
\
fetch_ea_32(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmeml(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \
loadseg(seg, &sel); if (cpu_state.abrt) return 1; \
cpu_state.regs[cpu_reg].l = addr; \
\
CLOCK_CYCLES(7); \
PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); \
return 0; \
#define opLsel(name, sel) \
static int opL##name##_w_a16(uint32_t fetchdat) { \
uint16_t addr, seg; \
\
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmemw(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
if (cpu_state.abrt) \
return 1; \
loadseg(seg, &sel); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].w = addr; \
\
CLOCK_CYCLES(7); \
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); \
return 0; \
} \
\
static int opL##name##_w_a32(uint32_t fetchdat) { \
uint16_t addr, seg; \
\
fetch_ea_32(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmemw(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
if (cpu_state.abrt) \
return 1; \
loadseg(seg, &sel); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].w = addr; \
\
CLOCK_CYCLES(7); \
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); \
return 0; \
} \
\
static int opL##name##_l_a16(uint32_t fetchdat) { \
uint32_t addr; \
uint16_t seg; \
\
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmeml(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
if (cpu_state.abrt) \
return 1; \
loadseg(seg, &sel); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].l = addr; \
\
CLOCK_CYCLES(7); \
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0); \
return 0; \
} \
\
static int opL##name##_l_a32(uint32_t fetchdat) { \
uint32_t addr; \
uint16_t seg; \
\
fetch_ea_32(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
addr = readmeml(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
if (cpu_state.abrt) \
return 1; \
loadseg(seg, &sel); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].l = addr; \
\
CLOCK_CYCLES(7); \
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1); \
return 0; \
}
opLsel(ES, cpu_state.seg_es)
opLsel(FS, cpu_state.seg_fs)
opLsel(GS, cpu_state.seg_gs)
opLsel(ES, cpu_state.seg_es) opLsel(FS, cpu_state.seg_fs) opLsel(GS, cpu_state.seg_gs)
#endif /* _X86_OPS_MOV_SEG_H_ */

View File

@@ -1,227 +1,227 @@
#ifndef _X86_OPS_MOVX_H_
#define _X86_OPS_MOVX_H_
static int opMOVZX_w_b_a16(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opMOVZX_w_b_a32(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
static int opMOVZX_l_b_a16(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opMOVZX_l_b_a32(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
static int opMOVZX_w_w_a16(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opMOVZX_w_w_a32(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
static int opMOVZX_l_w_a16(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opMOVZX_l_w_a32(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
static int opMOVSX_w_b_a16(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
if (temp & 0x80)
cpu_state.regs[cpu_reg].w |= 0xff00;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
if (temp & 0x80)
cpu_state.regs[cpu_reg].w |= 0xff00;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opMOVSX_w_b_a32(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
if (temp & 0x80)
cpu_state.regs[cpu_reg].w |= 0xff00;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
if (temp & 0x80)
cpu_state.regs[cpu_reg].w |= 0xff00;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
static int opMOVSX_l_b_a16(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x80)
cpu_state.regs[cpu_reg].l |= 0xffffff00;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x80)
cpu_state.regs[cpu_reg].l |= 0xffffff00;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opMOVSX_l_b_a32(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x80)
cpu_state.regs[cpu_reg].l |= 0xffffff00;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x80)
cpu_state.regs[cpu_reg].l |= 0xffffff00;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
static int opMOVSX_l_w_a16(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x8000)
cpu_state.regs[cpu_reg].l |= 0xffff0000;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x8000)
cpu_state.regs[cpu_reg].l |= 0xffff0000;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
return 0;
}
static int opMOVSX_l_w_a32(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x8000)
cpu_state.regs[cpu_reg].l |= 0xffff0000;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
if (temp & 0x8000)
cpu_state.regs[cpu_reg].l |= 0xffff0000;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
return 0;
}
#endif /* _X86_OPS_MOVX_H_ */

View File

@@ -1,29 +1,29 @@
#ifndef _X86_OPS_MSR_H_
#define _X86_OPS_MSR_H_
static int opRDTSC(uint32_t fetchdat) {
if (!cpu_has_feature(CPU_FEATURE_RDTSC)) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
if ((cr4 & CR4_TSD) && CPL) {
x86gpf("RDTSC when TSD set and CPL != 0", 0);
return 1;
}
EAX = tsc & 0xffffffff;
EDX = tsc >> 32;
CLOCK_CYCLES(1);
return 0;
if (!cpu_has_feature(CPU_FEATURE_RDTSC)) {
cpu_state.pc = cpu_state.oldpc;
x86illegal();
return 1;
}
if ((cr4 & CR4_TSD) && CPL) {
x86gpf("RDTSC when TSD set and CPL != 0", 0);
return 1;
}
EAX = tsc & 0xffffffff;
EDX = tsc >> 32;
CLOCK_CYCLES(1);
return 0;
}
static int opRDPMC(uint32_t fetchdat) {
if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) {
x86gpf("RDPMC not allowed", 0);
return 1;
}
EAX = EDX = 0;
CLOCK_CYCLES(1);
return 0;
if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) {
x86gpf("RDPMC not allowed", 0);
return 1;
}
EAX = EDX = 0;
CLOCK_CYCLES(1);
return 0;
}
#endif /* _X86_OPS_MSR_H_ */

View File

@@ -1,317 +1,317 @@
#ifndef _X86_OPS_MUL_H_
#define _X86_OPS_MUL_H_
static int opIMUL_w_iw_a16(uint32_t fetchdat) {
int32_t templ;
int16_t tempw, tempw2;
int32_t templ;
int16_t tempw, tempw2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt)
return 1;
tempw2 = getword();
if (cpu_state.abrt)
return 1;
tempw = geteaw();
if (cpu_state.abrt)
return 1;
tempw2 = getword();
if (cpu_state.abrt)
return 1;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 0);
return 0;
}
static int opIMUL_w_iw_a32(uint32_t fetchdat) {
int32_t templ;
int16_t tempw, tempw2;
int32_t templ;
int16_t tempw, tempw2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt)
return 1;
tempw2 = getword();
if (cpu_state.abrt)
return 1;
tempw = geteaw();
if (cpu_state.abrt)
return 1;
tempw2 = getword();
if (cpu_state.abrt)
return 1;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 1);
return 0;
}
static int opIMUL_l_il_a16(uint32_t fetchdat) {
int64_t temp64;
int32_t templ, templ2;
int64_t temp64;
int32_t templ, templ2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal();
if (cpu_state.abrt)
return 1;
templ2 = getlong();
if (cpu_state.abrt)
return 1;
templ = geteal();
if (cpu_state.abrt)
return 1;
templ2 = getlong();
if (cpu_state.abrt)
return 1;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
CLOCK_CYCLES(25);
PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 0);
return 0;
CLOCK_CYCLES(25);
PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 0);
return 0;
}
static int opIMUL_l_il_a32(uint32_t fetchdat) {
int64_t temp64;
int32_t templ, templ2;
int64_t temp64;
int32_t templ, templ2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal();
if (cpu_state.abrt)
return 1;
templ2 = getlong();
if (cpu_state.abrt)
return 1;
templ = geteal();
if (cpu_state.abrt)
return 1;
templ2 = getlong();
if (cpu_state.abrt)
return 1;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
CLOCK_CYCLES(25);
PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 1);
return 0;
CLOCK_CYCLES(25);
PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 1);
return 0;
}
static int opIMUL_w_ib_a16(uint32_t fetchdat) {
int32_t templ;
int16_t tempw, tempw2;
int32_t templ;
int16_t tempw, tempw2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt)
return 1;
tempw2 = getbyte();
if (cpu_state.abrt)
return 1;
if (tempw2 & 0x80)
tempw2 |= 0xff00;
tempw = geteaw();
if (cpu_state.abrt)
return 1;
tempw2 = getbyte();
if (cpu_state.abrt)
return 1;
if (tempw2 & 0x80)
tempw2 |= 0xff00;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 0);
return 0;
}
static int opIMUL_w_ib_a32(uint32_t fetchdat) {
int32_t templ;
int16_t tempw, tempw2;
int32_t templ;
int16_t tempw, tempw2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt)
return 1;
tempw2 = getbyte();
if (cpu_state.abrt)
return 1;
if (tempw2 & 0x80)
tempw2 |= 0xff00;
tempw = geteaw();
if (cpu_state.abrt)
return 1;
tempw2 = getbyte();
if (cpu_state.abrt)
return 1;
if (tempw2 & 0x80)
tempw2 |= 0xff00;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
templ = ((int)tempw) * ((int)tempw2);
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].w = templ & 0xffff;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 1);
return 0;
}
static int opIMUL_l_ib_a16(uint32_t fetchdat) {
int64_t temp64;
int32_t templ, templ2;
int64_t temp64;
int32_t templ, templ2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal();
if (cpu_state.abrt)
return 1;
templ2 = getbyte();
if (cpu_state.abrt)
return 1;
if (templ2 & 0x80)
templ2 |= 0xffffff00;
templ = geteal();
if (cpu_state.abrt)
return 1;
templ2 = getbyte();
if (cpu_state.abrt)
return 1;
if (templ2 & 0x80)
templ2 |= 0xffffff00;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 0);
return 0;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 0);
return 0;
}
static int opIMUL_l_ib_a32(uint32_t fetchdat) {
int64_t temp64;
int32_t templ, templ2;
int64_t temp64;
int32_t templ, templ2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal();
if (cpu_state.abrt)
return 1;
templ2 = getbyte();
if (cpu_state.abrt)
return 1;
if (templ2 & 0x80)
templ2 |= 0xffffff00;
templ = geteal();
if (cpu_state.abrt)
return 1;
templ2 = getbyte();
if (cpu_state.abrt)
return 1;
if (templ2 & 0x80)
templ2 |= 0xffffff00;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
temp64 = ((int64_t)templ) * ((int64_t)templ2);
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 1);
return 0;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 1);
return 0;
}
static int opIMUL_w_w_a16(uint32_t fetchdat) {
int32_t templ;
int32_t templ;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(18);
PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 0);
return 0;
CLOCK_CYCLES(18);
PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 0);
return 0;
}
static int opIMUL_w_w_a32(uint32_t fetchdat) {
int32_t templ;
int32_t templ;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
flags_rebuild();
if ((templ >> 15) != 0 && (templ >> 15) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(18);
PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 1);
return 0;
CLOCK_CYCLES(18);
PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 1);
return 0;
}
static int opIMUL_l_l_a16(uint32_t fetchdat) {
int64_t temp64;
int64_t temp64;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(30);
PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 0);
return 0;
CLOCK_CYCLES(30);
PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 0);
return 0;
}
static int opIMUL_l_l_a32(uint32_t fetchdat) {
int64_t temp64;
int64_t temp64;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
flags_rebuild();
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
cpu_state.flags |= C_FLAG | V_FLAG;
else
cpu_state.flags &= ~(C_FLAG | V_FLAG);
CLOCK_CYCLES(30);
PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 1);
return 0;
CLOCK_CYCLES(30);
PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 1);
return 0;
}
#endif /* _X86_OPS_MUL_H_ */

View File

@@ -1,506 +1,519 @@
#ifndef _X86_OPS_PMODE_H_
#define _X86_OPS_PMODE_H_
static int opARPL_a16(uint32_t fetchdat) {
uint16_t temp_seg;
uint16_t temp_seg;
NOTRM
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
pclog("ARPL_a16\n");
temp_seg = geteaw();
if (cpu_state.abrt)
return 1;
NOTRM
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
pclog("ARPL_a16\n");
temp_seg = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) {
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
seteaw(temp_seg);
if (cpu_state.abrt)
return 1;
cpu_state.flags |= Z_FLAG;
} else
cpu_state.flags &= ~Z_FLAG;
flags_rebuild();
if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) {
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
seteaw(temp_seg);
if (cpu_state.abrt)
return 1;
cpu_state.flags |= Z_FLAG;
} else
cpu_state.flags &= ~Z_FLAG;
CLOCK_CYCLES(is486 ? 9 : 20);
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 0);
return 0;
CLOCK_CYCLES(is486 ? 9 : 20);
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 0);
return 0;
}
static int opARPL_a32(uint32_t fetchdat) {
uint16_t temp_seg;
uint16_t temp_seg;
NOTRM
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
pclog("ARPL_a32\n");
temp_seg = geteaw();
if (cpu_state.abrt)
return 1;
NOTRM
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
pclog("ARPL_a32\n");
temp_seg = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) {
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
seteaw(temp_seg);
if (cpu_state.abrt)
return 1;
cpu_state.flags |= Z_FLAG;
} else
cpu_state.flags &= ~Z_FLAG;
flags_rebuild();
if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) {
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
seteaw(temp_seg);
if (cpu_state.abrt)
return 1;
cpu_state.flags |= Z_FLAG;
} else
cpu_state.flags &= ~Z_FLAG;
CLOCK_CYCLES(is486 ? 9 : 20);
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 1);
return 0;
CLOCK_CYCLES(is486 ? 9 : 20);
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 1);
return 0;
}
#define opLAR(name, fetch_ea, is32, ea32) \
static int opLAR_ ## name(uint32_t fetchdat) \
{ \
int valid; \
uint16_t sel, desc = 0; \
\
NOTRM \
fetch_ea(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
\
sel = geteaw(); if (cpu_state.abrt) return 1; \
\
flags_rebuild(); \
if (!(sel & 0xfffc)) { cpu_state.flags &= ~Z_FLAG; return 0; } /*Null selector*/ \
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
if (valid) \
{ \
cpl_override = 1; \
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
cpl_override = 0; if (cpu_state.abrt) return 1; \
} \
cpu_state.flags &= ~Z_FLAG; \
if ((desc & 0x1f00) == 0x000) valid = 0; \
if ((desc & 0x1f00) == 0x800) valid = 0; \
if ((desc & 0x1f00) == 0xa00) valid = 0; \
if ((desc & 0x1f00) == 0xd00) valid = 0; \
if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \
{ \
int dpl = (desc >> 13) & 3; \
if (dpl < CPL || dpl < (sel & 3)) valid = 0; \
} \
if (valid) \
{ \
cpu_state.flags |= Z_FLAG; \
cpl_override = 1; \
if (is32) \
cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \
else \
cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \
cpl_override = 0; \
} \
CLOCK_CYCLES(11); \
PREFETCH_RUN(11, 2, rmdat, 2,0,0,0, ea32); \
return cpu_state.abrt; \
#define opLAR(name, fetch_ea, is32, ea32) \
static int opLAR_##name(uint32_t fetchdat) { \
int valid; \
uint16_t sel, desc = 0; \
\
NOTRM \
fetch_ea(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
\
sel = geteaw(); \
if (cpu_state.abrt) \
return 1; \
\
flags_rebuild(); \
if (!(sel & 0xfffc)) { \
cpu_state.flags &= ~Z_FLAG; \
return 0; \
} /*Null selector*/ \
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
if (valid) { \
cpl_override = 1; \
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
cpl_override = 0; \
if (cpu_state.abrt) \
return 1; \
} \
cpu_state.flags &= ~Z_FLAG; \
if ((desc & 0x1f00) == 0x000) \
valid = 0; \
if ((desc & 0x1f00) == 0x800) \
valid = 0; \
if ((desc & 0x1f00) == 0xa00) \
valid = 0; \
if ((desc & 0x1f00) == 0xd00) \
valid = 0; \
if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \
{ \
int dpl = (desc >> 13) & 3; \
if (dpl < CPL || dpl < (sel & 3)) \
valid = 0; \
} \
if (valid) { \
cpu_state.flags |= Z_FLAG; \
cpl_override = 1; \
if (is32) \
cpu_state.regs[cpu_reg].l = \
readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \
else \
cpu_state.regs[cpu_reg].w = \
readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \
cpl_override = 0; \
} \
CLOCK_CYCLES(11); \
PREFETCH_RUN(11, 2, rmdat, 2, 0, 0, 0, ea32); \
return cpu_state.abrt; \
}
opLAR(w_a16, fetch_ea_16, 0, 0)
opLAR(w_a32, fetch_ea_32, 0, 1)
opLAR(l_a16, fetch_ea_16, 1, 0)
opLAR(l_a32, fetch_ea_32, 1, 1)
opLAR(w_a16, fetch_ea_16, 0, 0) opLAR(w_a32, fetch_ea_32, 0, 1) opLAR(l_a16, fetch_ea_16, 1, 0) opLAR(l_a32, fetch_ea_32, 1, 1)
#define opLSL(name, fetch_ea, is32, ea32) \
static int opLSL_ ## name(uint32_t fetchdat) \
{ \
int valid; \
uint16_t sel, desc = 0; \
\
NOTRM \
fetch_ea(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
\
sel = geteaw(); if (cpu_state.abrt) return 1; \
flags_rebuild(); \
cpu_state.flags &= ~Z_FLAG; \
if (!(sel & 0xfffc)) return 0; /*Null selector*/ \
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
if (valid) \
{ \
cpl_override = 1; \
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
cpl_override = 0; if (cpu_state.abrt) return 1; \
} \
if ((desc & 0x1400) == 0x400) valid = 0; /*Interrupt or trap or call gate*/ \
if ((desc & 0x1f00) == 0x000) valid = 0; /*Invalid*/ \
if ((desc & 0x1f00) == 0xa00) valid = 0; /*Invalid*/ \
if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \
{ \
int rpl = (desc >> 13) & 3; \
if (rpl < CPL || rpl < (sel & 3)) valid = 0; \
} \
if (valid) \
{ \
cpu_state.flags |= Z_FLAG; \
cpl_override = 1; \
if (is32) \
{ \
cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \
cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \
if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) \
{ \
cpu_state.regs[cpu_reg].l <<= 12; \
cpu_state.regs[cpu_reg].l |= 0xFFF; \
} \
} \
else \
cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \
cpl_override = 0; \
} \
CLOCK_CYCLES(10); \
PREFETCH_RUN(10, 2, rmdat, 4,0,0,0, ea32); \
return cpu_state.abrt; \
#define opLSL(name, fetch_ea, is32, ea32) \
static int opLSL_##name(uint32_t fetchdat) { \
int valid; \
uint16_t sel, desc = 0; \
\
NOTRM \
fetch_ea(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
\
sel = geteaw(); \
if (cpu_state.abrt) \
return 1; \
flags_rebuild(); \
cpu_state.flags &= ~Z_FLAG; \
if (!(sel & 0xfffc)) \
return 0; /*Null selector*/ \
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
if (valid) { \
cpl_override = 1; \
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
cpl_override = 0; \
if (cpu_state.abrt) \
return 1; \
} \
if ((desc & 0x1400) == 0x400) \
valid = 0; /*Interrupt or trap or call gate*/ \
if ((desc & 0x1f00) == 0x000) \
valid = 0; /*Invalid*/ \
if ((desc & 0x1f00) == 0xa00) \
valid = 0; /*Invalid*/ \
if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \
{ \
int rpl = (desc >> 13) & 3; \
if (rpl < CPL || rpl < (sel & 3)) \
valid = 0; \
} \
if (valid) { \
cpu_state.flags |= Z_FLAG; \
cpl_override = 1; \
if (is32) { \
cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \
cpu_state.regs[cpu_reg].l |= \
(readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \
if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) { \
cpu_state.regs[cpu_reg].l <<= 12; \
cpu_state.regs[cpu_reg].l |= 0xFFF; \
} \
} else \
cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \
cpl_override = 0; \
} \
CLOCK_CYCLES(10); \
PREFETCH_RUN(10, 2, rmdat, 4, 0, 0, 0, ea32); \
return cpu_state.abrt; \
}
opLSL(w_a16, fetch_ea_16, 0, 0)
opLSL(w_a32, fetch_ea_32, 0, 1)
opLSL(l_a16, fetch_ea_16, 1, 0)
opLSL(l_a32, fetch_ea_32, 1, 1)
opLSL(w_a16, fetch_ea_16, 0, 0) opLSL(w_a32, fetch_ea_32, 0, 1) opLSL(l_a16, fetch_ea_16, 1, 0)
opLSL(l_a32, fetch_ea_32, 1, 1)
static int op0F00_common(uint32_t fetchdat, int ea32) {
int dpl, valid, granularity;
uint32_t addr, base, limit;
uint16_t desc, sel;
uint8_t access, access2;
static int op0F00_common(uint32_t fetchdat, int ea32) {
int dpl, valid, granularity;
uint32_t addr, base, limit;
uint16_t desc, sel;
uint8_t access, access2;
// pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
switch (rmdat & 0x38) {
case 0x00: /*SLDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(ldt.seg);
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;
case 0x08: /*STR*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(tr.seg);
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;
case 0x10: /*LLDT*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid LLDT!\n");
x86gpf(NULL, 0);
return 1;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw();
if (cpu_state.abrt)
return 1;
addr = (sel & ~7) + gdt.base;
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
access = readmemb(0, addr + 5);
access2 = readmemb(0, addr + 6);
granularity = readmemb(0, addr + 6) & 0x80;
if (cpu_state.abrt)
return 1;
ldt.limit = limit;
ldt.limit_raw = limit;
ldt.access = access;
ldt.access2 = access2;
if (granularity) {
ldt.limit <<= 12;
ldt.limit |= 0xfff;
}
ldt.base = base;
ldt.seg = sel;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32);
break;
case 0x18: /*LTR*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid LTR!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw();
if (cpu_state.abrt)
return 1;
addr = (sel & ~7) + gdt.base;
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
access = readmemb(0, addr + 5);
access2 = readmemb(0, addr + 6);
granularity = readmemb(0, addr + 6) & 0x80;
if (cpu_state.abrt)
return 1;
access |= 2;
writememb(0, addr + 5, access);
if (cpu_state.abrt)
return 1;
tr.seg = sel;
tr.limit = limit;
tr.limit_raw = limit;
tr.access = access;
tr.access2 = access2;
if (granularity) {
tr.limit <<= 12;
tr.limit |= 0xFFF;
}
tr.base = base;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32);
break;
case 0x20: /*VERR*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
cpu_state.flags &= ~Z_FLAG;
if (!(sel & 0xfffc))
return 0; /*Null selector*/
cpl_override = 1;
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
cpl_override = 0;
if (cpu_state.abrt)
return 1;
if (!(desc & 0x1000))
valid = 0;
if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/
{
dpl = (desc >> 13) & 3; /*Check permissions*/
if (dpl < CPL || dpl < (sel & 3))
valid = 0;
}
if ((desc & 0x0800) && !(desc & 0x0200))
valid = 0; /*Non-readable code*/
if (valid)
cpu_state.flags |= Z_FLAG;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32);
break;
case 0x28: /*VERW*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
cpu_state.flags &= ~Z_FLAG;
if (!(sel & 0xfffc))
return 0; /*Null selector*/
cpl_override = 1;
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
cpl_override = 0;
if (cpu_state.abrt)
return 1;
if (!(desc & 0x1000))
valid = 0;
dpl = (desc >> 13) & 3; /*Check permissions*/
if (dpl < CPL || dpl < (sel & 3))
valid = 0;
if (desc & 0x0800)
valid = 0; /*Code*/
if (!(desc & 0x0200))
valid = 0; /*Read-only data*/
if (valid)
cpu_state.flags |= Z_FLAG;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32);
break;
// pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
switch (rmdat & 0x38) {
case 0x00: /*SLDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(ldt.seg);
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;
case 0x08: /*STR*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(tr.seg);
CLOCK_CYCLES(4);
PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;
case 0x10: /*LLDT*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid LLDT!\n");
x86gpf(NULL, 0);
return 1;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw();
if (cpu_state.abrt)
return 1;
addr = (sel & ~7) + gdt.base;
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
access = readmemb(0, addr + 5);
access2 = readmemb(0, addr + 6);
granularity = readmemb(0, addr + 6) & 0x80;
if (cpu_state.abrt)
return 1;
ldt.limit = limit;
ldt.limit_raw = limit;
ldt.access = access;
ldt.access2 = access2;
if (granularity) {
ldt.limit <<= 12;
ldt.limit |= 0xfff;
}
ldt.base = base;
ldt.seg = sel;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32);
break;
case 0x18: /*LTR*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid LTR!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw();
if (cpu_state.abrt)
return 1;
addr = (sel & ~7) + gdt.base;
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
access = readmemb(0, addr + 5);
access2 = readmemb(0, addr + 6);
granularity = readmemb(0, addr + 6) & 0x80;
if (cpu_state.abrt)
return 1;
access |= 2;
writememb(0, addr + 5, access);
if (cpu_state.abrt)
return 1;
tr.seg = sel;
tr.limit = limit;
tr.limit_raw = limit;
tr.access = access;
tr.access2 = access2;
if (granularity) {
tr.limit <<= 12;
tr.limit |= 0xFFF;
}
tr.base = base;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32);
break;
case 0x20: /*VERR*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
cpu_state.flags &= ~Z_FLAG;
if (!(sel & 0xfffc))
return 0; /*Null selector*/
cpl_override = 1;
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
cpl_override = 0;
if (cpu_state.abrt)
return 1;
if (!(desc & 0x1000))
valid = 0;
if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/
{
dpl = (desc >> 13) & 3; /*Check permissions*/
if (dpl < CPL || dpl < (sel & 3))
valid = 0;
}
if ((desc & 0x0800) && !(desc & 0x0200))
valid = 0; /*Non-readable code*/
if (valid)
cpu_state.flags |= Z_FLAG;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32);
break;
case 0x28: /*VERW*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
sel = geteaw();
if (cpu_state.abrt)
return 1;
flags_rebuild();
cpu_state.flags &= ~Z_FLAG;
if (!(sel & 0xfffc))
return 0; /*Null selector*/
cpl_override = 1;
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
cpl_override = 0;
if (cpu_state.abrt)
return 1;
if (!(desc & 0x1000))
valid = 0;
dpl = (desc >> 13) & 3; /*Check permissions*/
if (dpl < CPL || dpl < (sel & 3))
valid = 0;
if (desc & 0x0800)
valid = 0; /*Code*/
if (!(desc & 0x0200))
valid = 0; /*Read-only data*/
if (valid)
cpu_state.flags |= Z_FLAG;
CLOCK_CYCLES(20);
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32);
break;
default:pclog("Bad 0F 00 opcode %02X\n", rmdat & 0x38);
cpu_state.pc -= 3;
x86illegal();
break;
}
return cpu_state.abrt;
default:
pclog("Bad 0F 00 opcode %02X\n", rmdat & 0x38);
cpu_state.pc -= 3;
x86illegal();
break;
}
return cpu_state.abrt;
}
static int op0F00_a16(uint32_t fetchdat) {
NOTRM
NOTRM
fetch_ea_16(fetchdat);
fetch_ea_16(fetchdat);
return op0F00_common(fetchdat, 0);
return op0F00_common(fetchdat, 0);
}
static int op0F00_a32(uint32_t fetchdat) {
NOTRM
NOTRM
fetch_ea_32(fetchdat);
fetch_ea_32(fetchdat);
return op0F00_common(fetchdat, 1);
return op0F00_common(fetchdat, 1);
}
static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) {
uint32_t base;
uint16_t limit, tempw;
// pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
switch (rmdat & 0x38) {
case 0x00: /*SGDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(gdt.limit);
base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff);
if (is286)
base |= 0xff000000;
writememl(easeg, cpu_state.eaaddr + 2, base);
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32);
break;
case 0x08: /*SIDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(idt.limit);
base = idt.base;
if (is286)
base |= 0xff000000;
writememl(easeg, cpu_state.eaaddr + 2, base);
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32);
break;
case 0x10: /*LGDT*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid LGDT!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
// pclog("LGDT %08X:%08X\n", easeg, eaaddr);
limit = geteaw();
base = readmeml(0, easeg + cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
// pclog(" %08X %04X\n", base, limit);
gdt.limit = limit;
gdt.base = base;
if (!is32)
gdt.base &= 0xffffff;
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32);
break;
case 0x18: /*LIDT*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid LIDT!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
// pclog("LIDT %08X:%08X\n", easeg, eaaddr);
limit = geteaw();
base = readmeml(0, easeg + cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
// pclog(" %08X %04X\n", base, limit);
idt.limit = limit;
idt.base = base;
if (!is32)
idt.base &= 0xffffff;
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32);
break;
uint32_t base;
uint16_t limit, tempw;
// pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
switch (rmdat & 0x38) {
case 0x00: /*SGDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(gdt.limit);
base = gdt.base; // is32 ? gdt.base : (gdt.base & 0xffffff);
if (is286)
base |= 0xff000000;
writememl(easeg, cpu_state.eaaddr + 2, base);
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32);
break;
case 0x08: /*SIDT*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(idt.limit);
base = idt.base;
if (is286)
base |= 0xff000000;
writememl(easeg, cpu_state.eaaddr + 2, base);
CLOCK_CYCLES(7);
PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32);
break;
case 0x10: /*LGDT*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid LGDT!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
// pclog("LGDT %08X:%08X\n", easeg, eaaddr);
limit = geteaw();
base = readmeml(0, easeg + cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
// pclog(" %08X %04X\n", base, limit);
gdt.limit = limit;
gdt.base = base;
if (!is32)
gdt.base &= 0xffffff;
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32);
break;
case 0x18: /*LIDT*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid LIDT!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
// pclog("LIDT %08X:%08X\n", easeg, eaaddr);
limit = geteaw();
base = readmeml(0, easeg + cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
// pclog(" %08X %04X\n", base, limit);
idt.limit = limit;
idt.base = base;
if (!is32)
idt.base &= 0xffffff;
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32);
break;
case 0x20: /*SMSW*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (is486)
seteaw(msw);
else if (is386)
seteaw(msw | 0xFF00);
else seteaw(msw | 0xFFF0);
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;
case 0x30: /*LMSW*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (msw & 1)) {
pclog("LMSW - ring not zero!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt)
return 1;
if (msw & 1)
tempw |= 1;
if (is386) {
tempw &= ~0x10;
tempw |= (msw & 0x10);
} else
tempw &= 0xF;
msw = tempw;
if (msw & 1)
cpu_cur_status |= CPU_STATUS_PMODE;
else
cpu_cur_status &= ~CPU_STATUS_PMODE;
PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;
case 0x20: /*SMSW*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (is486)
seteaw(msw);
else if (is386)
seteaw(msw | 0xFF00);
else
seteaw(msw | 0xFFF0);
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;
case 0x30: /*LMSW*/
if ((CPL || cpu_state.eflags & VM_FLAG) && (msw & 1)) {
pclog("LMSW - ring not zero!\n");
x86gpf(NULL, 0);
break;
}
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt)
return 1;
if (msw & 1)
tempw |= 1;
if (is386) {
tempw &= ~0x10;
tempw |= (msw & 0x10);
} else
tempw &= 0xF;
msw = tempw;
if (msw & 1)
cpu_cur_status |= CPU_STATUS_PMODE;
else
cpu_cur_status &= ~CPU_STATUS_PMODE;
PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;
case 0x38: /*INVLPG*/
if (is486) {
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid INVLPG!\n");
x86gpf(NULL, 0);
break;
}
SEG_CHECK_READ(cpu_state.ea_seg);
mmu_invalidate(ds + cpu_state.eaaddr);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, rmdat, 0, 0, 0, 0, ea32);
break;
}
case 0x38: /*INVLPG*/
if (is486) {
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
pclog("Invalid INVLPG!\n");
x86gpf(NULL, 0);
break;
}
SEG_CHECK_READ(cpu_state.ea_seg);
mmu_invalidate(ds + cpu_state.eaaddr);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, rmdat, 0, 0, 0, 0, ea32);
break;
}
default:pclog("Bad 0F 01 opcode %02X\n", rmdat & 0x38);
cpu_state.pc -= 3;
x86illegal();
break;
}
return cpu_state.abrt;
default:
pclog("Bad 0F 01 opcode %02X\n", rmdat & 0x38);
cpu_state.pc -= 3;
x86illegal();
break;
}
return cpu_state.abrt;
}
static int op0F01_w_a16(uint32_t fetchdat) {
fetch_ea_16(fetchdat);
fetch_ea_16(fetchdat);
return op0F01_common(fetchdat, 0, 0, 0);
return op0F01_common(fetchdat, 0, 0, 0);
}
static int op0F01_w_a32(uint32_t fetchdat) {
fetch_ea_32(fetchdat);
fetch_ea_32(fetchdat);
return op0F01_common(fetchdat, 0, 0, 1);
return op0F01_common(fetchdat, 0, 0, 1);
}
static int op0F01_l_a16(uint32_t fetchdat) {
fetch_ea_16(fetchdat);
fetch_ea_16(fetchdat);
return op0F01_common(fetchdat, 1, 0, 0);
return op0F01_common(fetchdat, 1, 0, 0);
}
static int op0F01_l_a32(uint32_t fetchdat) {
fetch_ea_32(fetchdat);
fetch_ea_32(fetchdat);
return op0F01_common(fetchdat, 1, 0, 1);
return op0F01_common(fetchdat, 1, 0, 1);
}
static int op0F01_286(uint32_t fetchdat) {
fetch_ea_16(fetchdat);
fetch_ea_16(fetchdat);
return op0F01_common(fetchdat, 0, 1, 0);
return op0F01_common(fetchdat, 0, 1, 0);
}
static int opRSM(uint32_t fetchdat) {
if (cpu_cur_status & CPU_STATUS_SMM)
x86_smi_leave();
else
x86illegal();
if (cpu_cur_status & CPU_STATUS_SMM)
x86_smi_leave();
else
x86illegal();
return 1;
return 1;
}
#endif /* _X86_OPS_PMODE_H_ */

View File

@@ -1,171 +1,168 @@
#ifndef _X86_OPS_PREFIX_H_
#define _X86_OPS_PREFIX_H_
#define op_seg(name, seg, opcode_table, normal_opcode_table) \
static int op ## name ## _w_a16(uint32_t fetchdat) \
{ \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[fetchdat & 0xff]) \
return opcode_table[fetchdat & 0xff](fetchdat >> 8); \
return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \
} \
\
static int op ## name ## _l_a16(uint32_t fetchdat) \
{ \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x100]) \
return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
} \
\
static int op ## name ## _w_a32(uint32_t fetchdat) \
{ \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x200]) \
return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
} \
\
static int op ## name ## _l_a32(uint32_t fetchdat) \
{ \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x300]) \
return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
}
#define op_seg(name, seg, opcode_table, normal_opcode_table) \
static int op##name##_w_a16(uint32_t fetchdat) { \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) \
return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[fetchdat & 0xff]) \
return opcode_table[fetchdat & 0xff](fetchdat >> 8); \
return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \
} \
\
static int op##name##_l_a16(uint32_t fetchdat) { \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) \
return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x100]) \
return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
} \
\
static int op##name##_w_a32(uint32_t fetchdat) { \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) \
return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x200]) \
return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
} \
\
static int op##name##_l_a32(uint32_t fetchdat) { \
fetchdat = fastreadl(cs + cpu_state.pc); \
if (cpu_state.abrt) \
return 1; \
cpu_state.pc++; \
\
cpu_state.ea_seg = &seg; \
cpu_state.ssegs = 1; \
CLOCK_CYCLES(4); \
PREFETCH_PREFIX(); \
\
if (opcode_table[(fetchdat & 0xff) | 0x300]) \
return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
}
op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes)
op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes)
op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes)
op_seg(FS, cpu_state.seg_fs, x86_opcodes, x86_opcodes)
op_seg(GS, cpu_state.seg_gs, x86_opcodes, x86_opcodes)
op_seg(SS, cpu_state.seg_ss, x86_opcodes, x86_opcodes)
op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes) op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes)
op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes) op_seg(FS, cpu_state.seg_fs, x86_opcodes, x86_opcodes) op_seg(
GS, cpu_state.seg_gs, x86_opcodes, x86_opcodes) op_seg(SS, cpu_state.seg_ss, x86_opcodes, x86_opcodes)
op_seg(CS_REPE, cpu_state.seg_cs, x86_opcodes_REPE, x86_opcodes)
op_seg(DS_REPE, cpu_state.seg_ds, x86_opcodes_REPE, x86_opcodes)
op_seg(ES_REPE, cpu_state.seg_es, x86_opcodes_REPE, x86_opcodes)
op_seg(FS_REPE, cpu_state.seg_fs, x86_opcodes_REPE, x86_opcodes)
op_seg(GS_REPE, cpu_state.seg_gs, x86_opcodes_REPE, x86_opcodes)
op_seg(SS_REPE, cpu_state.seg_ss, x86_opcodes_REPE, x86_opcodes)
op_seg(CS_REPE, cpu_state.seg_cs, x86_opcodes_REPE,
x86_opcodes) op_seg(DS_REPE, cpu_state.seg_ds, x86_opcodes_REPE,
x86_opcodes) op_seg(ES_REPE, cpu_state.seg_es, x86_opcodes_REPE, x86_opcodes)
op_seg(FS_REPE, cpu_state.seg_fs, x86_opcodes_REPE,
x86_opcodes) op_seg(GS_REPE, cpu_state.seg_gs, x86_opcodes_REPE,
x86_opcodes) op_seg(SS_REPE, cpu_state.seg_ss, x86_opcodes_REPE, x86_opcodes)
op_seg(CS_REPNE, cpu_state.seg_cs, x86_opcodes_REPNE, x86_opcodes)
op_seg(DS_REPNE, cpu_state.seg_ds, x86_opcodes_REPNE, x86_opcodes)
op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes)
op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes)
op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes)
op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes)
op_seg(CS_REPNE, cpu_state.seg_cs, x86_opcodes_REPNE,
x86_opcodes) op_seg(DS_REPNE, cpu_state.seg_ds, x86_opcodes_REPNE, x86_opcodes)
op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes)
op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes)
op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes)
op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes)
static int op_66(uint32_t fetchdat) /*Data size select*/
static int op_66(uint32_t fetchdat) /*Data size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int op_67(uint32_t fetchdat) /*Address size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int op_66_REPE(uint32_t fetchdat) /*Data size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int op_67_REPE(uint32_t fetchdat) /*Address size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int op_66_REPNE(uint32_t fetchdat) /*Data size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int op_67_REPNE(uint32_t fetchdat) /*Address size select*/
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
#endif /* _X86_OPS_PREFIX_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,232 +1,230 @@
#ifndef _X86_OPS_RET_H_
#define _X86_OPS_RET_H_
#define RETF_a16(stack_offset) \
if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \
{ \
pmoderetf(0, stack_offset); \
return 1; \
} \
if (stack32) \
{ \
cpu_state.pc = readmemw(ss, ESP); \
loadcs(readmemw(ss, ESP + 2)); \
} \
else \
{ \
cpu_state.pc = readmemw(ss, SP); \
loadcs(readmemw(ss, SP + 2)); \
} \
if (cpu_state.abrt) return 1; \
if (stack32) ESP += 4 + stack_offset; \
else SP += 4 + stack_offset; \
cycles -= timing_retf_rm;
#define RETF_a16(stack_offset) \
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
pmoderetf(0, stack_offset); \
return 1; \
} \
if (stack32) { \
cpu_state.pc = readmemw(ss, ESP); \
loadcs(readmemw(ss, ESP + 2)); \
} else { \
cpu_state.pc = readmemw(ss, SP); \
loadcs(readmemw(ss, SP + 2)); \
} \
if (cpu_state.abrt) \
return 1; \
if (stack32) \
ESP += 4 + stack_offset; \
else \
SP += 4 + stack_offset; \
cycles -= timing_retf_rm;
#define RETF_a32(stack_offset) \
if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \
{ \
pmoderetf(1, stack_offset); \
return 1; \
} \
if (stack32) \
{ \
cpu_state.pc = readmeml(ss, ESP); \
loadcs(readmeml(ss, ESP + 4) & 0xffff); \
} \
else \
{ \
cpu_state.pc = readmeml(ss, SP); \
loadcs(readmeml(ss, SP + 4) & 0xffff); \
} \
if (cpu_state.abrt) return 1; \
if (stack32) ESP += 8 + stack_offset; \
else SP += 8 + stack_offset; \
cycles -= timing_retf_rm;
#define RETF_a32(stack_offset) \
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
pmoderetf(1, stack_offset); \
return 1; \
} \
if (stack32) { \
cpu_state.pc = readmeml(ss, ESP); \
loadcs(readmeml(ss, ESP + 4) & 0xffff); \
} else { \
cpu_state.pc = readmeml(ss, SP); \
loadcs(readmeml(ss, SP + 4) & 0xffff); \
} \
if (cpu_state.abrt) \
return 1; \
if (stack32) \
ESP += 8 + stack_offset; \
else \
SP += 8 + stack_offset; \
cycles -= timing_retf_rm;
static int opRETF_a16(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
int cycles_old = cycles;
UNUSED(cycles_old);
CPU_BLOCK_END();
RETF_a16(0);
CPU_BLOCK_END();
RETF_a16(0);
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opRETF_a32(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
int cycles_old = cycles;
UNUSED(cycles_old);
CPU_BLOCK_END();
RETF_a32(0);
CPU_BLOCK_END();
RETF_a32(0);
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
PREFETCH_FLUSH();
return 0;
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
PREFETCH_FLUSH();
return 0;
}
static int opRETF_a16_imm(uint32_t fetchdat) {
uint16_t offset = getwordf();
int cycles_old = cycles;
UNUSED(cycles_old);
uint16_t offset = getwordf();
int cycles_old = cycles;
UNUSED(cycles_old);
CPU_BLOCK_END();
RETF_a16(offset);
CPU_BLOCK_END();
RETF_a16(offset);
PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
return 0;
}
static int opRETF_a32_imm(uint32_t fetchdat) {
uint16_t offset = getwordf();
int cycles_old = cycles;
UNUSED(cycles_old);
uint16_t offset = getwordf();
int cycles_old = cycles;
UNUSED(cycles_old);
CPU_BLOCK_END();
RETF_a32(offset);
CPU_BLOCK_END();
RETF_a32(offset);
PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1);
PREFETCH_FLUSH();
return 0;
PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1);
PREFETCH_FLUSH();
return 0;
}
static int opIRET_286(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
int cycles_old = cycles;
UNUSED(cycles_old);
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf(NULL, 0);
return 1;
}
if (msw & 1) {
optype = IRET;
pmodeiret(0);
optype = 0;
} else {
uint16_t new_cs;
if (stack32) {
cpu_state.pc = readmemw(ss, ESP);
new_cs = readmemw(ss, ESP + 2);
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
ESP += 6;
} else {
cpu_state.pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
SP += 6;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
nmi_enable = 1;
CPU_BLOCK_END();
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf(NULL, 0);
return 1;
}
if (msw & 1) {
optype = IRET;
pmodeiret(0);
optype = 0;
} else {
uint16_t new_cs;
if (stack32) {
cpu_state.pc = readmemw(ss, ESP);
new_cs = readmemw(ss, ESP + 2);
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
ESP += 6;
} else {
cpu_state.pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
SP += 6;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
nmi_enable = 1;
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
return cpu_state.abrt;
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
return cpu_state.abrt;
}
static int opIRET(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
int cycles_old = cycles;
UNUSED(cycles_old);
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
if (cr4 & CR4_VME) {
uint16_t new_pc, new_cs, new_flags;
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
if (cr4 & CR4_VME) {
uint16_t new_pc, new_cs, new_flags;
new_pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
new_flags = readmemw(ss, ((SP + 4) & 0xffff));
if (cpu_state.abrt)
return 1;
new_pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
new_flags = readmemw(ss, ((SP + 4) & 0xffff));
if (cpu_state.abrt)
return 1;
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) {
x86gpf(NULL, 0);
return 1;
}
SP += 6;
if (new_flags & I_FLAG)
cpu_state.eflags |= VIF_FLAG;
else
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
loadcs(new_cs);
cpu_state.pc = new_pc;
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) {
x86gpf(NULL, 0);
return 1;
}
SP += 6;
if (new_flags & I_FLAG)
cpu_state.eflags |= VIF_FLAG;
else
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
loadcs(new_cs);
cpu_state.pc = new_pc;
cycles -= timing_iret_rm;
} else {
x86gpf_expected(NULL, 0);
return 1;
}
} else {
if (msw & 1) {
optype = IRET;
pmodeiret(0);
optype = 0;
} else {
uint16_t new_cs;
if (stack32) {
cpu_state.pc = readmemw(ss, ESP);
new_cs = readmemw(ss, ESP + 2);
cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
ESP += 6;
} else {
cpu_state.pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
SP += 6;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
}
flags_extract();
nmi_enable = 1;
CPU_BLOCK_END();
cycles -= timing_iret_rm;
} else {
x86gpf_expected(NULL, 0);
return 1;
}
} else {
if (msw & 1) {
optype = IRET;
pmodeiret(0);
optype = 0;
} else {
uint16_t new_cs;
if (stack32) {
cpu_state.pc = readmemw(ss, ESP);
new_cs = readmemw(ss, ESP + 2);
cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
ESP += 6;
} else {
cpu_state.pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
SP += 6;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
}
flags_extract();
nmi_enable = 1;
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
return cpu_state.abrt;
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
return cpu_state.abrt;
}
static int opIRETD(uint32_t fetchdat) {
int cycles_old = cycles;
UNUSED(cycles_old);
int cycles_old = cycles;
UNUSED(cycles_old);
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf_expected(NULL, 0);
return 1;
}
if (msw & 1) {
optype = IRET;
pmodeiret(1);
optype = 0;
} else {
uint16_t new_cs;
if (stack32) {
cpu_state.pc = readmeml(ss, ESP);
new_cs = readmemw(ss, ESP + 4);
cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
cpu_state.eflags = readmemw(ss, ESP + 10);
ESP += 12;
} else {
cpu_state.pc = readmeml(ss, SP);
new_cs = readmemw(ss, ((SP + 4) & 0xffff));
cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2;
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
SP += 12;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
nmi_enable = 1;
CPU_BLOCK_END();
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
x86gpf_expected(NULL, 0);
return 1;
}
if (msw & 1) {
optype = IRET;
pmodeiret(1);
optype = 0;
} else {
uint16_t new_cs;
if (stack32) {
cpu_state.pc = readmeml(ss, ESP);
new_cs = readmemw(ss, ESP + 4);
cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
cpu_state.eflags = readmemw(ss, ESP + 10);
ESP += 12;
} else {
cpu_state.pc = readmeml(ss, SP);
new_cs = readmemw(ss, ((SP + 4) & 0xffff));
cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2;
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
SP += 12;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
nmi_enable = 1;
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
PREFETCH_FLUSH();
return cpu_state.abrt;
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
PREFETCH_FLUSH();
return cpu_state.abrt;
}
#endif /* _X86_OPS_RET_H_ */

View File

@@ -1,41 +1,25 @@
#ifndef _X86_OPS_SET_H_
#define _X86_OPS_SET_H_
#define opSET(condition) \
static int opSET ## condition ## _a16(uint32_t fetchdat) \
{ \
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
seteab((cond_ ## condition) ? 1 : 0); \
CLOCK_CYCLES(4); \
return cpu_state.abrt; \
} \
\
static int opSET ## condition ## _a32(uint32_t fetchdat) \
{ \
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
seteab((cond_ ## condition) ? 1 : 0); \
CLOCK_CYCLES(4); \
return cpu_state.abrt; \
#define opSET(condition) \
static int opSET##condition##_a16(uint32_t fetchdat) { \
fetch_ea_16(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
seteab((cond_##condition) ? 1 : 0); \
CLOCK_CYCLES(4); \
return cpu_state.abrt; \
} \
\
static int opSET##condition##_a32(uint32_t fetchdat) { \
fetch_ea_32(fetchdat); \
if (cpu_mod != 3) \
SEG_CHECK_READ(cpu_state.ea_seg); \
seteab((cond_##condition) ? 1 : 0); \
CLOCK_CYCLES(4); \
return cpu_state.abrt; \
}
opSET(O)
opSET(NO)
opSET(B)
opSET(NB)
opSET(E)
opSET(NE)
opSET(BE)
opSET(NBE)
opSET(S)
opSET(NS)
opSET(P)
opSET(NP)
opSET(L)
opSET(NL)
opSET(LE)
opSET(NLE)
opSET(O) opSET(NO) opSET(B) opSET(NB) opSET(E) opSET(NE) opSET(BE) opSET(NBE) opSET(S) opSET(NS) opSET(P) opSET(NP) opSET(L)
opSET(NL) opSET(LE) opSET(NLE)
#endif /* _X86_OPS_SET_H_ */

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

View File

@@ -1,240 +1,232 @@
#ifndef _X86_OPS_XCHG_H_
#define _X86_OPS_XCHG_H_
static int opXCHG_b_a16(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
seteab(getr8(cpu_reg));
if (cpu_state.abrt)
return 1;
setr8(cpu_reg, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
seteab(getr8(cpu_reg));
if (cpu_state.abrt)
return 1;
setr8(cpu_reg, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
}
static int opXCHG_b_a32(uint32_t fetchdat) {
uint8_t temp;
uint8_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
seteab(getr8(cpu_reg));
if (cpu_state.abrt)
return 1;
setr8(cpu_reg, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
return 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
if (cpu_state.abrt)
return 1;
seteab(getr8(cpu_reg));
if (cpu_state.abrt)
return 1;
setr8(cpu_reg, temp);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
return 0;
}
static int opXCHG_w_a16(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
seteaw(cpu_state.regs[cpu_reg].w);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
seteaw(cpu_state.regs[cpu_reg].w);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
return 0;
}
static int opXCHG_w_a32(uint32_t fetchdat) {
uint16_t temp;
uint16_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
seteaw(cpu_state.regs[cpu_reg].w);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
return 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
if (cpu_state.abrt)
return 1;
seteaw(cpu_state.regs[cpu_reg].w);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
return 0;
}
static int opXCHG_l_a16(uint32_t fetchdat) {
uint32_t temp;
uint32_t temp;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
seteal(cpu_state.regs[cpu_reg].l);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0);
return 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
seteal(cpu_state.regs[cpu_reg].l);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0);
return 0;
}
static int opXCHG_l_a32(uint32_t fetchdat) {
uint32_t temp;
uint32_t temp;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
seteal(cpu_state.regs[cpu_reg].l);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1);
return 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
if (cpu_state.abrt)
return 1;
seteal(cpu_state.regs[cpu_reg].l);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = temp;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1);
return 0;
}
static int opXCHG_AX_BX(uint32_t fetchdat) {
uint16_t temp = AX;
AX = BX;
BX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint16_t temp = AX;
AX = BX;
BX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_AX_CX(uint32_t fetchdat) {
uint16_t temp = AX;
AX = CX;
CX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint16_t temp = AX;
AX = CX;
CX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_AX_DX(uint32_t fetchdat) {
uint16_t temp = AX;
AX = DX;
DX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint16_t temp = AX;
AX = DX;
DX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_AX_SI(uint32_t fetchdat) {
uint16_t temp = AX;
AX = SI;
SI = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint16_t temp = AX;
AX = SI;
SI = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_AX_DI(uint32_t fetchdat) {
uint16_t temp = AX;
AX = DI;
DI = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint16_t temp = AX;
AX = DI;
DI = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_AX_BP(uint32_t fetchdat) {
uint16_t temp = AX;
AX = BP;
BP = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint16_t temp = AX;
AX = BP;
BP = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_AX_SP(uint32_t fetchdat) {
uint16_t temp = AX;
AX = SP;
SP = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint16_t temp = AX;
AX = SP;
SP = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_EAX_EBX(uint32_t fetchdat) {
uint32_t temp = EAX;
EAX = EBX;
EBX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint32_t temp = EAX;
EAX = EBX;
EBX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_EAX_ECX(uint32_t fetchdat) {
uint32_t temp = EAX;
EAX = ECX;
ECX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint32_t temp = EAX;
EAX = ECX;
ECX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_EAX_EDX(uint32_t fetchdat) {
uint32_t temp = EAX;
EAX = EDX;
EDX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint32_t temp = EAX;
EAX = EDX;
EDX = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_EAX_ESI(uint32_t fetchdat) {
uint32_t temp = EAX;
EAX = ESI;
ESI = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint32_t temp = EAX;
EAX = ESI;
ESI = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_EAX_EDI(uint32_t fetchdat) {
uint32_t temp = EAX;
EAX = EDI;
EDI = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint32_t temp = EAX;
EAX = EDI;
EDI = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_EAX_EBP(uint32_t fetchdat) {
uint32_t temp = EAX;
EAX = EBP;
EBP = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint32_t temp = EAX;
EAX = EBP;
EBP = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
static int opXCHG_EAX_ESP(uint32_t fetchdat) {
uint32_t temp = EAX;
EAX = ESP;
ESP = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
uint32_t temp = EAX;
EAX = ESP;
ESP = temp;
CLOCK_CYCLES(3);
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
return 0;
}
#define opBSWAP(reg) \
static int opBSWAP_ ## reg(uint32_t fetchdat) \
{ \
reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \
CLOCK_CYCLES(1); \
PREFETCH_RUN(1, 1, -1, 0,0,0,0, 0); \
return 0; \
#define opBSWAP(reg) \
static int opBSWAP_##reg(uint32_t fetchdat) { \
reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \
CLOCK_CYCLES(1); \
PREFETCH_RUN(1, 1, -1, 0, 0, 0, 0, 0); \
return 0; \
}
opBSWAP(EAX)
opBSWAP(EBX)
opBSWAP(ECX)
opBSWAP(EDX)
opBSWAP(ESI)
opBSWAP(EDI)
opBSWAP(EBP)
opBSWAP(ESP)
opBSWAP(EAX) opBSWAP(EBX) opBSWAP(ECX) opBSWAP(EDX) opBSWAP(ESI) opBSWAP(EDI) opBSWAP(EBP) opBSWAP(ESP)
#endif /* _X86_OPS_XCHG_H_ */

View File

@@ -1,22 +1,22 @@
#ifndef _X87_H_
#define _X87_H_
#define C0 (1<<8)
#define C1 (1<<9)
#define C2 (1<<10)
#define C3 (1<<14)
#define C0 (1 << 8)
#define C1 (1 << 9)
#define C2 (1 << 10)
#define C3 (1 << 14)
uint32_t x87_pc_off, x87_op_off;
uint16_t x87_pc_seg, x87_op_seg;
static inline void x87_set_mmx() {
cpu_state.TOP = 0;
*(uint64_t *)cpu_state.tag = 0x0101010101010101ull;
cpu_state.ismmx = 1;
cpu_state.TOP = 0;
*(uint64_t *)cpu_state.tag = 0x0101010101010101ull;
cpu_state.ismmx = 1;
}
static inline void x87_emms() {
*(uint64_t *)cpu_state.tag = 0;
cpu_state.ismmx = 0;
*(uint64_t *)cpu_state.tag = 0;
cpu_state.ismmx = 0;
}
uint16_t x87_gettag();
@@ -24,15 +24,15 @@ void x87_settag(uint16_t new_tag);
void x87_dumpregs();
void x87_reset();
#define TAG_EMPTY 0
#define TAG_VALID (1 << 0)
#define TAG_EMPTY 0
#define TAG_VALID (1 << 0)
/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/
#define TAG_UINT64 (1 << 7)
#define X87_ROUNDING_NEAREST 0
#define X87_ROUNDING_DOWN 1
#define X87_ROUNDING_UP 2
#define X87_ROUNDING_CHOP 3
#define X87_ROUNDING_DOWN 1
#define X87_ROUNDING_UP 2
#define X87_ROUNDING_CHOP 3
void codegen_set_rounding_mode(int mode);

File diff suppressed because it is too large Load Diff

View File

@@ -1,446 +1,452 @@
#ifndef _X87_OPS_ARITH_H_
#define _X87_OPS_ARITH_H_
#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \
static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \
ST(0) += use_var; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(FE_TONEAREST); \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \
return 0; \
} \
static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
cpu_state.npxs &= ~(C0|C2|C3); \
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \
return 0; \
} \
static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
cpu_state.npxs &= ~(C0|C2|C3); \
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
x87_pop(); \
CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \
return 0; \
} \
static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
x87_div(ST(0), ST(0), use_var); \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \
return 0; \
} \
static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
x87_div(ST(0), use_var, ST(0)); \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \
return 0; \
} \
static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) *= use_var; \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fmul ## cycle_postfix); \
return 0; \
} \
static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) -= use_var; \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \
return 0; \
} \
static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) = use_var - ST(0); \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \
return 0; \
}
#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \
static int opFADD##name##_a##a_size(uint32_t fetchdat) { \
optype t; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); \
if (cpu_state.abrt) \
return 1; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \
ST(0) += use_var; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(FE_TONEAREST); \
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fadd##cycle_postfix); \
return 0; \
} \
static int opFCOM##name##_a##a_size(uint32_t fetchdat) { \
optype t; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); \
if (cpu_state.abrt) \
return 1; \
cpu_state.npxs &= ~(C0 | C2 | C3); \
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
CLOCK_CYCLES(x87_timings.fcom##cycle_postfix); \
return 0; \
} \
static int opFCOMP##name##_a##a_size(uint32_t fetchdat) { \
optype t; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); \
if (cpu_state.abrt) \
return 1; \
cpu_state.npxs &= ~(C0 | C2 | C3); \
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
x87_pop(); \
CLOCK_CYCLES(x87_timings.fcom##cycle_postfix); \
return 0; \
} \
static int opFDIV##name##_a##a_size(uint32_t fetchdat) { \
optype t; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); \
if (cpu_state.abrt) \
return 1; \
x87_div(ST(0), ST(0), use_var); \
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fdiv##cycle_postfix); \
return 0; \
} \
static int opFDIVR##name##_a##a_size(uint32_t fetchdat) { \
optype t; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); \
if (cpu_state.abrt) \
return 1; \
x87_div(ST(0), use_var, ST(0)); \
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fdiv##cycle_postfix); \
return 0; \
} \
static int opFMUL##name##_a##a_size(uint32_t fetchdat) { \
optype t; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); \
if (cpu_state.abrt) \
return 1; \
ST(0) *= use_var; \
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fmul##cycle_postfix); \
return 0; \
} \
static int opFSUB##name##_a##a_size(uint32_t fetchdat) { \
optype t; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); \
if (cpu_state.abrt) \
return 1; \
ST(0) -= use_var; \
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fadd##cycle_postfix); \
return 0; \
} \
static int opFSUBR##name##_a##a_size(uint32_t fetchdat) { \
optype t; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); \
if (cpu_state.abrt) \
return 1; \
ST(0) = use_var - ST(0); \
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \
CLOCK_CYCLES(x87_timings.fadd##cycle_postfix); \
return 0; \
}
opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32)
opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32)
opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64)
opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64)
opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32)
opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64)
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16)
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16)
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32)
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32)
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16)
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16)
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32)
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32)
static int opFADD(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FADD\n");
ST(0) = ST(0) + ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
static int opFADD(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FADD\n");
ST(0) = ST(0) + ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFADDr(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FADD\n");
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FADD\n");
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFADDP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FADDP\n");
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FADDP\n");
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFCOM(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FCOM\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
if (ST(0) == ST(fetchdat & 7))
cpu_state.npxs |= C3;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.npxs |= C0;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FCOM\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
if (ST(0) == ST(fetchdat & 7))
cpu_state.npxs |= C3;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.npxs |= C0;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFCOMP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FCOMP\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FCOMP\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFCOMPP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FCOMPP\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
if (*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0)
cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/
else
cpu_state.npxs |= x87_compare(ST(0), ST(1));
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FCOMPP\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
if (*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0)
cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/
else
cpu_state.npxs |= x87_compare(ST(0), ST(1));
x87_pop();
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
x87_pop();
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFUCOMPP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOMPP\n", easeg, cpu_state.eaaddr);
cpu_state.npxs &= ~(C0 | C2 | C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
x87_pop();
x87_pop();
CLOCK_CYCLES(x87_timings.fucom);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOMPP\n", easeg, cpu_state.eaaddr);
cpu_state.npxs &= ~(C0 | C2 | C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
x87_pop();
x87_pop();
CLOCK_CYCLES(x87_timings.fucom);
return 0;
}
static int opFCOMI(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FICOM\n");
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7))
cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(x87_timings.fcom);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FICOM\n");
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7))
cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(x87_timings.fcom);
return 0;
}
static int opFCOMIP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FICOMP\n");
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7))
cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.flags |= C_FLAG;
x87_pop();
CLOCK_CYCLES(x87_timings.fcom);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FICOMP\n");
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7))
cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.flags |= C_FLAG;
x87_pop();
CLOCK_CYCLES(x87_timings.fcom);
return 0;
}
static int opFDIV(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIV\n");
x87_div(ST(0), ST(0), ST(fetchdat & 7));
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIV\n");
x87_div(ST(0), ST(0), ST(fetchdat & 7));
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
}
static int opFDIVr(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIV\n");
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIV\n");
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
}
static int opFDIVP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIVP\n");
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIVP\n");
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
}
static int opFDIVR(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIVR\n");
x87_div(ST(0), ST(fetchdat & 7), ST(0));
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIVR\n");
x87_div(ST(0), ST(fetchdat & 7), ST(0));
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
}
static int opFDIVRr(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIVR\n");
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIVR\n");
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
}
static int opFDIVRP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIVR\n");
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FDIVR\n");
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fdiv);
return 0;
}
static int opFMUL(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FMUL\n");
ST(0) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fmul);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FMUL\n");
ST(0) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fmul);
return 0;
}
static int opFMULr(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FMUL\n");
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fmul);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FMUL\n");
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fmul);
return 0;
}
static int opFMULP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FMULP\n");
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fmul);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FMULP\n");
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fmul);
return 0;
}
static int opFSUB(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUB\n");
ST(0) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUB\n");
ST(0) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFSUBr(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUB\n");
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUB\n");
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFSUBP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUBP\n");
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUBP\n");
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFSUBR(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUBR\n");
ST(0) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUBR\n");
ST(0) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFSUBRr(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUBR\n");
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUBR\n");
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFSUBRP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUBRP\n");
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FSUBRP\n");
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
x87_pop();
CLOCK_CYCLES(x87_timings.fadd);
return 0;
}
static int opFUCOM(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOM\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
CLOCK_CYCLES(x87_timings.fucom);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOM\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
CLOCK_CYCLES(x87_timings.fucom);
return 0;
}
static int opFUCOMP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOMP\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
x87_pop();
CLOCK_CYCLES(x87_timings.fucom);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOMP\n");
cpu_state.npxs &= ~(C0 | C2 | C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
x87_pop();
CLOCK_CYCLES(x87_timings.fucom);
return 0;
}
static int opFUCOMI(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOMI\n");
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7))
cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(x87_timings.fucom);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOMI\n");
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7))
cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(x87_timings.fucom);
return 0;
}
static int opFUCOMIP(uint32_t fetchdat) {
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOMIP\n");
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7))
cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.flags |= C_FLAG;
x87_pop();
CLOCK_CYCLES(x87_timings.fucom);
return 0;
FP_ENTER();
cpu_state.pc++;
if (fplog)
pclog("FUCOMIP\n");
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7))
cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7))
cpu_state.flags |= C_FLAG;
x87_pop();
CLOCK_CYCLES(x87_timings.fucom);
return 0;
}
#endif /* _X87_OPS_ARITH_H_ */

Some files were not shown because too many files have changed in this diff Show More