mirror of
https://github.com/86Box/86Box.git
synced 2026-02-25 04:45:31 -07:00
clang format in codegen & codegen_new
This commit is contained in:
@@ -16,21 +16,23 @@ void (*codegen_timing_block_start)(void);
|
||||
void (*codegen_timing_block_end)(void);
|
||||
int (*codegen_timing_jump_cycles)(void);
|
||||
|
||||
void codegen_timing_set(codegen_timing_t *timing)
|
||||
void
|
||||
codegen_timing_set(codegen_timing_t *timing)
|
||||
{
|
||||
codegen_timing_start = timing->start;
|
||||
codegen_timing_prefix = timing->prefix;
|
||||
codegen_timing_opcode = timing->opcode;
|
||||
codegen_timing_block_start = timing->block_start;
|
||||
codegen_timing_block_end = timing->block_end;
|
||||
codegen_timing_jump_cycles = timing->jump_cycles;
|
||||
codegen_timing_start = timing->start;
|
||||
codegen_timing_prefix = timing->prefix;
|
||||
codegen_timing_opcode = timing->opcode;
|
||||
codegen_timing_block_start = timing->block_start;
|
||||
codegen_timing_block_end = timing->block_end;
|
||||
codegen_timing_jump_cycles = timing->jump_cycles;
|
||||
}
|
||||
|
||||
int codegen_in_recompile;
|
||||
|
||||
/* This is for compatibility with new x87 code. */
|
||||
void codegen_set_rounding_mode(int mode)
|
||||
void
|
||||
codegen_set_rounding_mode(int mode)
|
||||
{
|
||||
/* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10);
|
||||
/* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10);
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
#include "x86_ops.h"
|
||||
|
||||
#ifdef __amd64__
|
||||
#include "codegen_x86-64.h"
|
||||
# include "codegen_x86-64.h"
|
||||
#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64
|
||||
#include "codegen_x86.h"
|
||||
# include "codegen_x86.h"
|
||||
#else
|
||||
#error Dynamic recompiler not implemented on your platform
|
||||
# error Dynamic recompiler not implemented on your platform
|
||||
#endif
|
||||
|
||||
/*Handling self-modifying code (of which there is a lot on x86) :
|
||||
@@ -73,38 +73,37 @@
|
||||
same page).
|
||||
*/
|
||||
|
||||
typedef struct codeblock_t
|
||||
{
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t *dirty_mask, *dirty_mask2;
|
||||
uint64_t cmp;
|
||||
typedef struct codeblock_t {
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t *dirty_mask, *dirty_mask2;
|
||||
uint64_t cmp;
|
||||
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
struct codeblock_t *prev, *next;
|
||||
struct codeblock_t *prev_2, *next_2;
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
struct codeblock_t *prev, *next;
|
||||
struct codeblock_t *prev_2, *next_2;
|
||||
|
||||
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
||||
fails.*/
|
||||
struct codeblock_t *parent, *left, *right;
|
||||
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
||||
fails.*/
|
||||
struct codeblock_t *parent, *left, *right;
|
||||
|
||||
int pnt;
|
||||
int ins;
|
||||
int pnt;
|
||||
int ins;
|
||||
|
||||
int valid;
|
||||
|
||||
int was_recompiled;
|
||||
int TOP;
|
||||
int was_recompiled;
|
||||
int TOP;
|
||||
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t endpc;
|
||||
uint32_t phys, phys_2;
|
||||
uint32_t status;
|
||||
uint32_t flags;
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t endpc;
|
||||
uint32_t phys, phys_2;
|
||||
uint32_t status;
|
||||
uint32_t flags;
|
||||
|
||||
uint8_t data[2048];
|
||||
uint8_t data[2048];
|
||||
} codeblock_t;
|
||||
|
||||
/*Code block uses FPU*/
|
||||
@@ -112,181 +111,155 @@ typedef struct codeblock_t
|
||||
/*Code block is always entered with the same FPU top-of-stack*/
|
||||
#define CODEBLOCK_STATIC_TOP 2
|
||||
|
||||
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 = pages[phys >> 12].head;
|
||||
uint64_t a = _cs | ((uint64_t)phys << 32);
|
||||
codeblock_t *block = pages[phys >> 12].head;
|
||||
uint64_t a = _cs | ((uint64_t) phys << 32);
|
||||
|
||||
while (block)
|
||||
{
|
||||
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)))
|
||||
break;
|
||||
}
|
||||
if (a < block->cmp)
|
||||
block = block->left;
|
||||
else
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static inline void codeblock_tree_add(codeblock_t *new_block)
|
||||
{
|
||||
codeblock_t *block = pages[new_block->phys >> 12].head;
|
||||
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
|
||||
new_block->cmp = a;
|
||||
|
||||
if (!block)
|
||||
{
|
||||
pages[new_block->phys >> 12].head = new_block;
|
||||
new_block->parent = new_block->left = new_block->right = NULL;
|
||||
while (block) {
|
||||
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)))
|
||||
break;
|
||||
}
|
||||
if (a < block->cmp)
|
||||
block = block->left;
|
||||
else
|
||||
{
|
||||
codeblock_t *old_block = NULL;
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
while (block)
|
||||
{
|
||||
old_block = block;
|
||||
if (a < old_block->cmp)
|
||||
block = block->left;
|
||||
else
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
if (a < old_block->cmp)
|
||||
old_block->left = new_block;
|
||||
else
|
||||
old_block->right = new_block;
|
||||
|
||||
new_block->parent = old_block;
|
||||
new_block->left = new_block->right = NULL;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
static inline void codeblock_tree_delete(codeblock_t *block)
|
||||
static inline void
|
||||
codeblock_tree_add(codeblock_t *new_block)
|
||||
{
|
||||
codeblock_t *parent = block->parent;
|
||||
codeblock_t *block = pages[new_block->phys >> 12].head;
|
||||
uint64_t a = new_block->_cs | ((uint64_t) new_block->phys << 32);
|
||||
new_block->cmp = a;
|
||||
|
||||
if (!block->left && !block->right)
|
||||
{
|
||||
/*Easy case - remove from parent*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = NULL;
|
||||
else
|
||||
{
|
||||
if (parent->left == block)
|
||||
parent->left = NULL;
|
||||
if (parent->right == block)
|
||||
parent->right = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!block->left)
|
||||
{
|
||||
/*Only right node*/
|
||||
if (!parent)
|
||||
{
|
||||
pages[block->phys >> 12].head = block->right;
|
||||
pages[block->phys >> 12].head->parent = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent->left == block)
|
||||
{
|
||||
parent->left = block->right;
|
||||
parent->left->parent = parent;
|
||||
}
|
||||
if (parent->right == block)
|
||||
{
|
||||
parent->right = block->right;
|
||||
parent->right->parent = parent;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!block->right)
|
||||
{
|
||||
/*Only left node*/
|
||||
if (!parent)
|
||||
{
|
||||
pages[block->phys >> 12].head = block->left;
|
||||
pages[block->phys >> 12].head->parent = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent->left == block)
|
||||
{
|
||||
parent->left = block->left;
|
||||
parent->left->parent = parent;
|
||||
}
|
||||
if (parent->right == block)
|
||||
{
|
||||
parent->right = block->left;
|
||||
parent->right->parent = parent;
|
||||
}
|
||||
}
|
||||
return;
|
||||
if (!block) {
|
||||
pages[new_block->phys >> 12].head = new_block;
|
||||
new_block->parent = new_block->left = new_block->right = NULL;
|
||||
} else {
|
||||
codeblock_t *old_block = NULL;
|
||||
|
||||
while (block) {
|
||||
old_block = block;
|
||||
if (a < old_block->cmp)
|
||||
block = block->left;
|
||||
else
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
if (a < old_block->cmp)
|
||||
old_block->left = new_block;
|
||||
else
|
||||
{
|
||||
/*Difficult case - node has two children. Walk right child to find lowest node*/
|
||||
codeblock_t *lowest = block->right, *highest;
|
||||
codeblock_t *old_parent;
|
||||
old_block->right = new_block;
|
||||
|
||||
while (lowest->left)
|
||||
lowest = lowest->left;
|
||||
|
||||
old_parent = lowest->parent;
|
||||
|
||||
/*Replace deleted node with lowest node*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = lowest;
|
||||
else
|
||||
{
|
||||
if (parent->left == block)
|
||||
parent->left = lowest;
|
||||
if (parent->right == block)
|
||||
parent->right = lowest;
|
||||
}
|
||||
|
||||
lowest->parent = parent;
|
||||
lowest->left = block->left;
|
||||
if (lowest->left)
|
||||
lowest->left->parent = lowest;
|
||||
|
||||
old_parent->left = NULL;
|
||||
|
||||
highest = lowest->right;
|
||||
if (!highest)
|
||||
{
|
||||
if (lowest != block->right)
|
||||
{
|
||||
lowest->right = block->right;
|
||||
block->right->parent = lowest;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (highest->right)
|
||||
highest = highest->right;
|
||||
|
||||
if (block->right && block->right != lowest)
|
||||
{
|
||||
highest->right = block->right;
|
||||
block->right->parent = highest;
|
||||
}
|
||||
}
|
||||
new_block->parent = old_block;
|
||||
new_block->left = new_block->right = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define PAGE_MASK_INDEX_MASK 3
|
||||
static inline void
|
||||
codeblock_tree_delete(codeblock_t *block)
|
||||
{
|
||||
codeblock_t *parent = block->parent;
|
||||
|
||||
if (!block->left && !block->right) {
|
||||
/*Easy case - remove from parent*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = NULL;
|
||||
else {
|
||||
if (parent->left == block)
|
||||
parent->left = NULL;
|
||||
if (parent->right == block)
|
||||
parent->right = NULL;
|
||||
}
|
||||
return;
|
||||
} else if (!block->left) {
|
||||
/*Only right node*/
|
||||
if (!parent) {
|
||||
pages[block->phys >> 12].head = block->right;
|
||||
pages[block->phys >> 12].head->parent = NULL;
|
||||
} else {
|
||||
if (parent->left == block) {
|
||||
parent->left = block->right;
|
||||
parent->left->parent = parent;
|
||||
}
|
||||
if (parent->right == block) {
|
||||
parent->right = block->right;
|
||||
parent->right->parent = parent;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (!block->right) {
|
||||
/*Only left node*/
|
||||
if (!parent) {
|
||||
pages[block->phys >> 12].head = block->left;
|
||||
pages[block->phys >> 12].head->parent = NULL;
|
||||
} else {
|
||||
if (parent->left == block) {
|
||||
parent->left = block->left;
|
||||
parent->left->parent = parent;
|
||||
}
|
||||
if (parent->right == block) {
|
||||
parent->right = block->left;
|
||||
parent->right->parent = parent;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
/*Difficult case - node has two children. Walk right child to find lowest node*/
|
||||
codeblock_t *lowest = block->right, *highest;
|
||||
codeblock_t *old_parent;
|
||||
|
||||
while (lowest->left)
|
||||
lowest = lowest->left;
|
||||
|
||||
old_parent = lowest->parent;
|
||||
|
||||
/*Replace deleted node with lowest node*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = lowest;
|
||||
else {
|
||||
if (parent->left == block)
|
||||
parent->left = lowest;
|
||||
if (parent->right == block)
|
||||
parent->right = lowest;
|
||||
}
|
||||
|
||||
lowest->parent = parent;
|
||||
lowest->left = block->left;
|
||||
if (lowest->left)
|
||||
lowest->left->parent = lowest;
|
||||
|
||||
old_parent->left = NULL;
|
||||
|
||||
highest = lowest->right;
|
||||
if (!highest) {
|
||||
if (lowest != block->right) {
|
||||
lowest->right = block->right;
|
||||
block->right->parent = lowest;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (highest->right)
|
||||
highest = highest->right;
|
||||
|
||||
if (block->right && block->right != lowest) {
|
||||
highest->right = block->right;
|
||||
block->right->parent = highest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PAGE_MASK_INDEX_MASK 3
|
||||
#define PAGE_MASK_INDEX_SHIFT 10
|
||||
#define PAGE_MASK_MASK 63
|
||||
#define PAGE_MASK_SHIFT 4
|
||||
#define PAGE_MASK_MASK 63
|
||||
#define PAGE_MASK_SHIFT 4
|
||||
|
||||
extern codeblock_t *codeblock;
|
||||
|
||||
@@ -305,7 +278,7 @@ extern void codegen_set_op32(void);
|
||||
extern void codegen_flush(void);
|
||||
extern void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr);
|
||||
|
||||
extern int cpu_block_end;
|
||||
extern int cpu_block_end;
|
||||
extern uint32_t codegen_endpc;
|
||||
|
||||
extern int codegen_block_cycles;
|
||||
@@ -317,14 +290,13 @@ extern void (*codegen_timing_block_start)(void);
|
||||
extern void (*codegen_timing_block_end)(void);
|
||||
extern int (*codegen_timing_jump_cycles)(void);
|
||||
|
||||
typedef struct codegen_timing_t
|
||||
{
|
||||
void (*start)(void);
|
||||
void (*prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*block_start)(void);
|
||||
void (*block_end)(void);
|
||||
int (*jump_cycles)(void);
|
||||
typedef struct codegen_timing_t {
|
||||
void (*start)(void);
|
||||
void (*prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*block_start)(void);
|
||||
void (*block_end)(void);
|
||||
int (*jump_cycles)(void);
|
||||
} codegen_timing_t;
|
||||
|
||||
extern codegen_timing_t codegen_timing_pentium;
|
||||
@@ -342,53 +314,53 @@ extern int block_pos;
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
static inline void addbyte(uint8_t val)
|
||||
static inline void
|
||||
addbyte(uint8_t val)
|
||||
{
|
||||
codeblock[block_current].data[block_pos++] = val;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
codeblock[block_current].data[block_pos++] = val;
|
||||
if (block_pos >= BLOCK_MAX) {
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void addword(uint16_t val)
|
||||
static inline void
|
||||
addword(uint16_t val)
|
||||
{
|
||||
uint16_t *p = (uint16_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 2;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
*p = val;
|
||||
block_pos += 2;
|
||||
if (block_pos >= BLOCK_MAX) {
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void addlong(uint32_t val)
|
||||
static inline void
|
||||
addlong(uint32_t val)
|
||||
{
|
||||
uint32_t *p = (uint32_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 4;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
*p = val;
|
||||
block_pos += 4;
|
||||
if (block_pos >= BLOCK_MAX) {
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void addquad(uint64_t val)
|
||||
static inline void
|
||||
addquad(uint64_t val)
|
||||
{
|
||||
uint64_t *p = (uint64_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 8;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
*p = val;
|
||||
block_pos += 8;
|
||||
if (block_pos >= BLOCK_MAX) {
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
}
|
||||
|
||||
/*Current physical page of block being recompiled. -1 if no recompilation taking place */
|
||||
extern uint32_t recomp_page;
|
||||
|
||||
extern x86seg *op_ea_seg;
|
||||
extern int op_ssegs;
|
||||
extern x86seg *op_ea_seg;
|
||||
extern int op_ssegs;
|
||||
extern uint32_t op_old_pc;
|
||||
|
||||
/*Set to 1 if flags have been changed in the block being recompiled, and hence
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
enum
|
||||
{
|
||||
ACCREG_cycles = 0,
|
||||
enum {
|
||||
ACCREG_cycles = 0,
|
||||
|
||||
ACCREG_COUNT
|
||||
ACCREG_COUNT
|
||||
};
|
||||
|
||||
struct ir_data_t;
|
||||
|
||||
@@ -9,59 +9,61 @@
|
||||
|
||||
static struct
|
||||
{
|
||||
int count;
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_cycles] = {0, (uintptr_t) &(cycles)},
|
||||
int count;
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] = {
|
||||
[ACCREG_cycles] = {0, (uintptr_t) & (cycles)},
|
||||
};
|
||||
|
||||
void codegen_accumulate(int acc_reg, int delta)
|
||||
void
|
||||
codegen_accumulate(int acc_reg, int delta)
|
||||
{
|
||||
acc_regs[acc_reg].count += delta;
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
#ifdef USE_ACYCS
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong(-delta);
|
||||
}
|
||||
}
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
addlong(-delta);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(void)
|
||||
void
|
||||
codegen_accumulate_flush(void)
|
||||
{
|
||||
if (acc_regs[0].count) {
|
||||
/* To reduce the size of the generated code, we take advantage of
|
||||
the fact that the target offset points to _cycles within cpu_state,
|
||||
so we can just use our existing infrastracture for variables
|
||||
relative to cpu_state. */
|
||||
addbyte(0x81); /*ADDL $acc_regs[0].count,(_cycles)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t)cpu_state_offset(_cycles));
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
/* To reduce the size of the generated code, we take advantage of
|
||||
the fact that the target offset points to _cycles within cpu_state,
|
||||
so we can just use our existing infrastracture for variables
|
||||
relative to cpu_state. */
|
||||
addbyte(0x81); /*ADDL $acc_regs[0].count,(_cycles)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t) cpu_state_offset(_cycles));
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset(void)
|
||||
void
|
||||
codegen_accumulate_reset(void)
|
||||
{
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -9,56 +9,58 @@
|
||||
|
||||
static struct
|
||||
{
|
||||
int count;
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_cycles] = {0, (uintptr_t) &(cycles)}
|
||||
int count;
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] = {
|
||||
[ACCREG_cycles] = {0, (uintptr_t) & (cycles)}
|
||||
};
|
||||
|
||||
void codegen_accumulate(int acc_reg, int delta)
|
||||
void
|
||||
codegen_accumulate(int acc_reg, int delta)
|
||||
{
|
||||
acc_regs[acc_reg].count += delta;
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
#ifdef USE_ACYCS
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0d);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong((uintptr_t) -delta);
|
||||
}
|
||||
}
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0d);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
addlong((uintptr_t) -delta);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(void)
|
||||
void
|
||||
codegen_accumulate_flush(void)
|
||||
{
|
||||
if (acc_regs[0].count) {
|
||||
/* To reduce the size of the generated code, we take advantage of
|
||||
the fact that the target offset points to _cycles within cpu_state,
|
||||
so we can just use our existing infrastracture for variables
|
||||
relative to cpu_state. */
|
||||
addbyte(0x81); /*MOVL $acc_regs[0].count,(_cycles)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t)cpu_state_offset(_cycles));
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
/* To reduce the size of the generated code, we take advantage of
|
||||
the fact that the target offset points to _cycles within cpu_state,
|
||||
so we can just use our existing infrastracture for variables
|
||||
relative to cpu_state. */
|
||||
addbyte(0x81); /*MOVL $acc_regs[0].count,(_cycles)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t) cpu_state_offset(_cycles));
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset(void)
|
||||
void
|
||||
codegen_accumulate_reset(void)
|
||||
{
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include "codegen_ops.h"
|
||||
|
||||
#if defined __amd64__ || defined _M_X64
|
||||
#include "codegen_ops_x86-64.h"
|
||||
# include "codegen_ops_x86-64.h"
|
||||
#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
#include "codegen_ops_x86.h"
|
||||
# include "codegen_ops_x86.h"
|
||||
#endif
|
||||
|
||||
#include "codegen_ops_arith.h"
|
||||
|
||||
@@ -26,21 +26,21 @@ extern RecompOpFn recomp_opcodes_REPNE[512];
|
||||
#define REG_EBP 5
|
||||
#define REG_ESI 6
|
||||
#define REG_EDI 7
|
||||
#define REG_AX 0
|
||||
#define REG_CX 1
|
||||
#define REG_DX 2
|
||||
#define REG_BX 3
|
||||
#define REG_SP 4
|
||||
#define REG_BP 5
|
||||
#define REG_SI 6
|
||||
#define REG_DI 7
|
||||
#define REG_AL 0
|
||||
#define REG_AH 4
|
||||
#define REG_CL 1
|
||||
#define REG_CH 5
|
||||
#define REG_DL 2
|
||||
#define REG_DH 6
|
||||
#define REG_BL 3
|
||||
#define REG_BH 7
|
||||
#define REG_AX 0
|
||||
#define REG_CX 1
|
||||
#define REG_DX 2
|
||||
#define REG_BX 3
|
||||
#define REG_SP 4
|
||||
#define REG_BP 5
|
||||
#define REG_SI 6
|
||||
#define REG_DI 7
|
||||
#define REG_AL 0
|
||||
#define REG_AH 4
|
||||
#define REG_CL 1
|
||||
#define REG_CH 5
|
||||
#define REG_DL 2
|
||||
#define REG_DH 6
|
||||
#define REG_BL 3
|
||||
#define REG_BH 7
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,256 +1,268 @@
|
||||
static uint32_t ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_ENTER();
|
||||
|
||||
FP_FXCH(opcode & 7);
|
||||
FP_FXCH(opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_ENTER();
|
||||
|
||||
FP_FLD(opcode & 7);
|
||||
FP_FLD(opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_ENTER();
|
||||
|
||||
FP_FST(opcode & 7);
|
||||
FP_FST(opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_ENTER();
|
||||
|
||||
FP_FST(opcode & 7);
|
||||
FP_POP();
|
||||
FP_FST(opcode & 7);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
|
||||
FP_LOAD_S();
|
||||
FP_LOAD_S();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
|
||||
FP_LOAD_D();
|
||||
FP_LOAD_D();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
|
||||
FP_LOAD_IW();
|
||||
FP_LOAD_IW();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
|
||||
FP_LOAD_IL();
|
||||
FP_LOAD_IL();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
|
||||
FP_LOAD_IQ();
|
||||
FP_LOAD_IQ();
|
||||
|
||||
codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1;
|
||||
codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1;
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
host_reg = FP_LOAD_REG(0);
|
||||
host_reg = FP_LOAD_REG(0);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg1, host_reg2 = 0;
|
||||
x86seg *target_seg;
|
||||
int host_reg1, host_reg2 = 0;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
FP_LOAD_REG_D(0, &host_reg1, &host_reg2);
|
||||
FP_LOAD_REG_D(0, &host_reg1, &host_reg2);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 7);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 7);
|
||||
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return new_pc;
|
||||
return new_pc;
|
||||
}
|
||||
static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return new_pc;
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
#define ropFarith(name, size, load, op) \
|
||||
static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
op_pc--; \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
load(target_seg); \
|
||||
\
|
||||
op(FPU_ ## name); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
}
|
||||
#define ropFarith(name, size, load, op) \
|
||||
static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
op_pc--; \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
load(target_seg); \
|
||||
\
|
||||
op(FPU_##name); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
}
|
||||
|
||||
ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
|
||||
#define ropFcompare(name, size, load, op) \
|
||||
static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
op_pc--; \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
load(target_seg); \
|
||||
\
|
||||
op(); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block); \
|
||||
\
|
||||
FP_POP(); \
|
||||
\
|
||||
return new_pc; \
|
||||
}
|
||||
#define ropFcompare(name, size, load, op) \
|
||||
static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
op_pc--; \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
load(target_seg); \
|
||||
\
|
||||
op(); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t ropF##name##P##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t new_pc = ropF##name##size(opcode, fetchdat, op_32, op_pc, block); \
|
||||
\
|
||||
FP_POP(); \
|
||||
\
|
||||
return new_pc; \
|
||||
}
|
||||
|
||||
ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S);
|
||||
ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D);
|
||||
@@ -326,320 +338,346 @@ static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
return op_pc + 1;
|
||||
}*/
|
||||
|
||||
|
||||
static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, opcode & 7);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, opcode & 7);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, 1);
|
||||
FP_POP2();
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, 1);
|
||||
FP_POP2();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX);
|
||||
FP_ENTER();
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxs);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
host_reg = FP_LOAD_REG_INT_W(0);
|
||||
host_reg = FP_LOAD_REG_INT_W(0);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
host_reg = FP_LOAD_REG_INT(0);
|
||||
host_reg = FP_LOAD_REG_INT(0);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return new_pc;
|
||||
return new_pc;
|
||||
}
|
||||
static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return new_pc;
|
||||
return new_pc;
|
||||
}
|
||||
static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg1, host_reg2;
|
||||
x86seg *target_seg;
|
||||
int host_reg1, host_reg2;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2);
|
||||
FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0);
|
||||
UPDATE_NPXC(0);
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t) &cpu_state.npxc, 0);
|
||||
UPDATE_NPXC(0);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc);
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxc);
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_FCHS();
|
||||
FP_ENTER();
|
||||
FP_FCHS();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
#define opFLDimm(name, v) \
|
||||
static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
static double fp_imm = v; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define opFLDimm(name, v) \
|
||||
static uint32_t ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
static double fp_imm = v; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
opFLDimm(1, 1.0)
|
||||
opFLDimm(L2T, 3.3219280948873623)
|
||||
opFLDimm(L2E, 1.4426950408889634);
|
||||
opFLDimm(L2T, 3.3219280948873623)
|
||||
opFLDimm(L2E, 1.4426950408889634);
|
||||
opFLDimm(PI, 3.141592653589793);
|
||||
opFLDimm(EG2, 0.3010299956639812);
|
||||
opFLDimm(Z, 0.0)
|
||||
|
||||
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
|
||||
FP_ENTER();
|
||||
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +1,263 @@
|
||||
static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
CLEAR_BITS((uintptr_t)&cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
CLEAR_BITS((uintptr_t) &cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
SET_BITS((uintptr_t)&cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
SET_BITS((uintptr_t) &cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
CLEAR_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
CLEAR_BITS((uintptr_t) &cpu_state.flags, I_FLAG);
|
||||
#ifdef CHECK_INT
|
||||
CLEAR_BITS((uintptr_t)&pic_pending, 0xffffffff);
|
||||
CLEAR_BITS((uintptr_t) &pic_pending, 0xffffffff);
|
||||
#endif
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
SET_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
|
||||
return op_pc;
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
SET_BITS((uintptr_t) &cpu_state.flags, I_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00)
|
||||
return 0;
|
||||
if ((fetchdat & 0x30) != 0x00)
|
||||
return 0;
|
||||
|
||||
CALL_FUNC((uintptr_t)flags_rebuild_c);
|
||||
CALL_FUNC((uintptr_t) flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
else
|
||||
{
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
else {
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg);
|
||||
}
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg);
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM_B(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
break;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_B(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
break;
|
||||
}
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM_B(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
break;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_B(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t codegen_temp;
|
||||
static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
CALL_FUNC((uintptr_t)flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_W(fetchdat & 7);
|
||||
else
|
||||
{
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00)
|
||||
{
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
host_reg = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE_W(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg);
|
||||
}
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM_W(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_W(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
|
||||
case 0x10: /*CALL*/
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if (!host_reg)
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
return op_pc + 1;
|
||||
}
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
CALL_FUNC((uintptr_t) flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_W(fetchdat & 7);
|
||||
else {
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00) {
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
host_reg = 0;
|
||||
} else {
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE_W(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg);
|
||||
}
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM_W(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_W(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
|
||||
case 0x10: /*CALL*/
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &codegen_temp);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t) &cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if (!host_reg)
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
return op_pc + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
CALL_FUNC((uintptr_t)flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
else
|
||||
{
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00)
|
||||
{
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
host_reg = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE_L(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg);
|
||||
}
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
|
||||
case 0x10: /*CALL*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if (!host_reg)
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
return op_pc + 1;
|
||||
}
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
CALL_FUNC((uintptr_t) flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
else {
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00) {
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
host_reg = 0;
|
||||
} else {
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE_L(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg);
|
||||
}
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
|
||||
case 0x10: /*CALL*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
host_reg = LOAD_VAR_L((uintptr_t) &codegen_temp);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if (!host_reg)
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
return op_pc + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,277 +1,267 @@
|
||||
static uint32_t ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg1, host_reg2 = 0;
|
||||
int host_reg1, host_reg2 = 0;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2);
|
||||
LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
if ((fetchdat & 0xc0) == 0xc0) {
|
||||
STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2);
|
||||
} else {
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 7);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 7);
|
||||
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
}
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg1, host_reg2;
|
||||
if ((fetchdat & 0xc0) == 0xc0) {
|
||||
int host_reg1, host_reg2;
|
||||
|
||||
LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2);
|
||||
STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2);
|
||||
STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2);
|
||||
} else {
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2);
|
||||
}
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
host_reg = LOAD_MMX_D((fetchdat >> 3) & 7);
|
||||
host_reg = LOAD_MMX_D((fetchdat >> 3) & 7);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
if ((fetchdat & 0xc0) == 0xc0) {
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
|
||||
} else {
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 3);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 3);
|
||||
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
}
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
if ((fetchdat & 0xc0) == 0xc0) {
|
||||
int host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg);
|
||||
} else {
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
STORE_MMX_LQ((fetchdat >> 3) & 7, 0);
|
||||
}
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
STORE_MMX_LQ((fetchdat >> 3) & 7, 0);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
#define MMX_OP(name, func) \
|
||||
static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int src_reg1, src_reg2; \
|
||||
int xmm_src, xmm_dst; \
|
||||
\
|
||||
MMX_ENTER(); \
|
||||
\
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
if ((fetchdat & 0xc0) == 0xc0) { \
|
||||
xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \
|
||||
} else { \
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
\
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg); \
|
||||
src_reg1 = LOAD_Q_REG_1; \
|
||||
src_reg2 = LOAD_Q_REG_2; \
|
||||
xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg); \
|
||||
src_reg1 = LOAD_Q_REG_1; \
|
||||
src_reg2 = LOAD_Q_REG_2; \
|
||||
xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \
|
||||
} \
|
||||
xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \
|
||||
func(xmm_dst, xmm_src); \
|
||||
func(xmm_dst, xmm_src); \
|
||||
STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
}
|
||||
}
|
||||
|
||||
MMX_OP(ropPAND, MMX_AND)
|
||||
MMX_OP(ropPAND, MMX_AND)
|
||||
MMX_OP(ropPANDN, MMX_ANDN)
|
||||
MMX_OP(ropPOR, MMX_OR)
|
||||
MMX_OP(ropPXOR, MMX_XOR)
|
||||
MMX_OP(ropPOR, MMX_OR)
|
||||
MMX_OP(ropPXOR, MMX_XOR)
|
||||
|
||||
MMX_OP(ropPADDB, MMX_ADDB)
|
||||
MMX_OP(ropPADDW, MMX_ADDW)
|
||||
MMX_OP(ropPADDD, MMX_ADDD)
|
||||
MMX_OP(ropPADDSB, MMX_ADDSB)
|
||||
MMX_OP(ropPADDSW, MMX_ADDSW)
|
||||
MMX_OP(ropPADDUSB, MMX_ADDUSB)
|
||||
MMX_OP(ropPADDUSW, MMX_ADDUSW)
|
||||
MMX_OP(ropPADDB, MMX_ADDB)
|
||||
MMX_OP(ropPADDW, MMX_ADDW)
|
||||
MMX_OP(ropPADDD, MMX_ADDD)
|
||||
MMX_OP(ropPADDSB, MMX_ADDSB)
|
||||
MMX_OP(ropPADDSW, MMX_ADDSW)
|
||||
MMX_OP(ropPADDUSB, MMX_ADDUSB)
|
||||
MMX_OP(ropPADDUSW, MMX_ADDUSW)
|
||||
|
||||
MMX_OP(ropPSUBB, MMX_SUBB)
|
||||
MMX_OP(ropPSUBW, MMX_SUBW)
|
||||
MMX_OP(ropPSUBD, MMX_SUBD)
|
||||
MMX_OP(ropPSUBSB, MMX_SUBSB)
|
||||
MMX_OP(ropPSUBSW, MMX_SUBSW)
|
||||
MMX_OP(ropPSUBUSB, MMX_SUBUSB)
|
||||
MMX_OP(ropPSUBUSW, MMX_SUBUSW)
|
||||
MMX_OP(ropPSUBB, MMX_SUBB)
|
||||
MMX_OP(ropPSUBW, MMX_SUBW)
|
||||
MMX_OP(ropPSUBD, MMX_SUBD)
|
||||
MMX_OP(ropPSUBSB, MMX_SUBSB)
|
||||
MMX_OP(ropPSUBSW, MMX_SUBSW)
|
||||
MMX_OP(ropPSUBUSB, MMX_SUBUSB)
|
||||
MMX_OP(ropPSUBUSW, MMX_SUBUSW)
|
||||
|
||||
MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW);
|
||||
MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD);
|
||||
MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ);
|
||||
MMX_OP(ropPACKSSWB, MMX_PACKSSWB);
|
||||
MMX_OP(ropPCMPGTB, MMX_PCMPGTB);
|
||||
MMX_OP(ropPCMPGTW, MMX_PCMPGTW);
|
||||
MMX_OP(ropPCMPGTD, MMX_PCMPGTD);
|
||||
MMX_OP(ropPACKUSWB, MMX_PACKUSWB);
|
||||
MMX_OP(ropPACKSSWB, MMX_PACKSSWB);
|
||||
MMX_OP(ropPCMPGTB, MMX_PCMPGTB);
|
||||
MMX_OP(ropPCMPGTW, MMX_PCMPGTW);
|
||||
MMX_OP(ropPCMPGTD, MMX_PCMPGTD);
|
||||
MMX_OP(ropPACKUSWB, MMX_PACKUSWB);
|
||||
MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW);
|
||||
MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD);
|
||||
MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ);
|
||||
MMX_OP(ropPACKSSDW, MMX_PACKSSDW);
|
||||
MMX_OP(ropPACKSSDW, MMX_PACKSSDW);
|
||||
|
||||
MMX_OP(ropPCMPEQB, MMX_PCMPEQB);
|
||||
MMX_OP(ropPCMPEQW, MMX_PCMPEQW);
|
||||
MMX_OP(ropPCMPEQD, MMX_PCMPEQD);
|
||||
MMX_OP(ropPCMPEQB, MMX_PCMPEQB);
|
||||
MMX_OP(ropPCMPEQW, MMX_PCMPEQW);
|
||||
MMX_OP(ropPCMPEQD, MMX_PCMPEQD);
|
||||
|
||||
MMX_OP(ropPSRLW, MMX_PSRLW)
|
||||
MMX_OP(ropPSRLD, MMX_PSRLD)
|
||||
MMX_OP(ropPSRLQ, MMX_PSRLQ)
|
||||
MMX_OP(ropPSRAW, MMX_PSRAW)
|
||||
MMX_OP(ropPSRAD, MMX_PSRAD)
|
||||
MMX_OP(ropPSLLW, MMX_PSLLW)
|
||||
MMX_OP(ropPSLLD, MMX_PSLLD)
|
||||
MMX_OP(ropPSLLQ, MMX_PSLLQ)
|
||||
MMX_OP(ropPSRLW, MMX_PSRLW)
|
||||
MMX_OP(ropPSRLD, MMX_PSRLD)
|
||||
MMX_OP(ropPSRLQ, MMX_PSRLQ)
|
||||
MMX_OP(ropPSRAW, MMX_PSRAW)
|
||||
MMX_OP(ropPSRAD, MMX_PSRAD)
|
||||
MMX_OP(ropPSLLW, MMX_PSLLW)
|
||||
MMX_OP(ropPSLLD, MMX_PSLLD)
|
||||
MMX_OP(ropPSLLQ, MMX_PSLLQ)
|
||||
|
||||
MMX_OP(ropPMULLW, MMX_PMULLW);
|
||||
MMX_OP(ropPMULHW, MMX_PMULHW);
|
||||
MMX_OP(ropPMADDWD, MMX_PMADDWD);
|
||||
MMX_OP(ropPMULLW, MMX_PMULLW);
|
||||
MMX_OP(ropPMULHW, MMX_PMULHW);
|
||||
MMX_OP(ropPMADDWD, MMX_PMADDWD);
|
||||
|
||||
static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x10: /*PSRLW*/
|
||||
MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x10: /*PSRLD*/
|
||||
MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAD*/
|
||||
MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLD*/
|
||||
MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x10: /*PSRLQ*/
|
||||
MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAQ*/
|
||||
MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLQ*/
|
||||
MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
||||
static uint32_t ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
codegen_mmx_entered = 0;
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x10: /*PSRLW*/
|
||||
MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t
|
||||
ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x10: /*PSRLD*/
|
||||
MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAD*/
|
||||
MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLD*/
|
||||
MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t
|
||||
ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x10: /*PSRLQ*/
|
||||
MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAQ*/
|
||||
MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLQ*/
|
||||
MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
codegen_mmx_entered = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,125 +1,129 @@
|
||||
#define SHIFT(size, size2, res_store, immediate) \
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
reg = LOAD_REG_ ## size(fetchdat & 7); \
|
||||
if (immediate) count = (fetchdat >> 8) & 0x1f; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
SAVE_EA(); \
|
||||
MEM_CHECK_WRITE_ ## size(target_seg); \
|
||||
reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \
|
||||
if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \
|
||||
} \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \
|
||||
\
|
||||
res_store((uintptr_t)&cpu_state.flags_op1, reg); \
|
||||
\
|
||||
switch (fetchdat & 0x38) \
|
||||
{ \
|
||||
case 0x20: case 0x30: /*SHL*/ \
|
||||
SHL_ ## size ## _IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \
|
||||
break; \
|
||||
\
|
||||
case 0x28: /*SHR*/ \
|
||||
SHR_ ## size ## _IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \
|
||||
break; \
|
||||
\
|
||||
case 0x38: /*SAR*/ \
|
||||
SAR_ ## size ## _IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
res_store((uintptr_t)&cpu_state.flags_res, reg); \
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
STORE_REG_ ## size ## _RELEASE(reg); \
|
||||
else \
|
||||
{ \
|
||||
LOAD_EA(); \
|
||||
MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg); \
|
||||
}
|
||||
#define SHIFT(size, size2, res_store, immediate) \
|
||||
if ((fetchdat & 0xc0) == 0xc0) { \
|
||||
reg = LOAD_REG_##size(fetchdat & 7); \
|
||||
if (immediate) \
|
||||
count = (fetchdat >> 8) & 0x1f; \
|
||||
} else { \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
SAVE_EA(); \
|
||||
MEM_CHECK_WRITE_##size(target_seg); \
|
||||
reg = MEM_LOAD_ADDR_EA_##size##_NO_ABRT(target_seg); \
|
||||
if (immediate) \
|
||||
count = fastreadb(cs + op_pc + 1) & 0x1f; \
|
||||
} \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, count); \
|
||||
\
|
||||
res_store((uintptr_t) &cpu_state.flags_op1, reg); \
|
||||
\
|
||||
switch (fetchdat & 0x38) { \
|
||||
case 0x20: \
|
||||
case 0x30: /*SHL*/ \
|
||||
SHL_##size##_IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SHL##size2); \
|
||||
break; \
|
||||
\
|
||||
case 0x28: /*SHR*/ \
|
||||
SHR_##size##_IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SHR##size2); \
|
||||
break; \
|
||||
\
|
||||
case 0x38: /*SAR*/ \
|
||||
SAR_##size##_IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SAR##size2); \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
res_store((uintptr_t) &cpu_state.flags_res, reg); \
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
STORE_REG_##size##_RELEASE(reg); \
|
||||
else { \
|
||||
LOAD_EA(); \
|
||||
MEM_STORE_ADDR_EA_##size##_NO_ABRT(target_seg, reg); \
|
||||
}
|
||||
|
||||
static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1);
|
||||
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1);
|
||||
|
||||
return op_pc + 2;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1);
|
||||
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1);
|
||||
|
||||
return op_pc + 2;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(L, 32, STORE_HOST_REG_ADDR, 1);
|
||||
SHIFT(L, 32, STORE_HOST_REG_ADDR, 1);
|
||||
|
||||
return op_pc + 2;
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
||||
static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0);
|
||||
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0);
|
||||
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(L, 32, STORE_HOST_REG_ADDR, 0);
|
||||
SHIFT(L, 32, STORE_HOST_REG_ADDR, 0);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
@@ -1,238 +1,254 @@
|
||||
static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_W(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_W(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_L(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_L(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t imm = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
uint16_t imm = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc+2;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t imm = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
uint32_t imm = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc+4;
|
||||
return op_pc + 4;
|
||||
}
|
||||
|
||||
static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
uint16_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
|
||||
if (imm & 0x80)
|
||||
imm |= 0xff00;
|
||||
if (imm & 0x80)
|
||||
imm |= 0xff00;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc+1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
uint32_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
|
||||
if (imm & 0x80)
|
||||
imm |= 0xffffff00;
|
||||
if (imm & 0x80)
|
||||
imm |= 0xffffff00;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc+1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
SP_MODIFY(2);
|
||||
STORE_REG_TARGET_W_RELEASE(0, opcode & 7);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
SP_MODIFY(2);
|
||||
STORE_REG_TARGET_W_RELEASE(0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
SP_MODIFY(4);
|
||||
STORE_REG_TARGET_L_RELEASE(0, opcode & 7);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
SP_MODIFY(4);
|
||||
STORE_REG_TARGET_L_RELEASE(0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0);
|
||||
SP_MODIFY(2);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0);
|
||||
SP_MODIFY(4);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(2+offset);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0);
|
||||
SP_MODIFY(2 + offset);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(4+offset);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0);
|
||||
SP_MODIFY(4 + offset);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc+2);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 2);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, (op_pc + 2 + offset) & 0xffff);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc+4);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 4);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 4 + offset);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/
|
||||
ADD_HOST_REG_IMM_W(host_reg, 2);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
|
||||
STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/
|
||||
ADD_HOST_REG_IMM_W(host_reg, 2);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
|
||||
STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/
|
||||
ADD_HOST_REG_IMM(host_reg, 4);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
|
||||
STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/
|
||||
ADD_HOST_REG_IMM(host_reg, 4);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
|
||||
STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
#define ROP_PUSH_SEG(seg) \
|
||||
static uint32_t ropPUSH_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-2); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-4); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define ROP_PUSH_SEG(seg) \
|
||||
static uint32_t ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-2); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &seg); \
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-4); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &seg); \
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
ROP_PUSH_SEG(CS)
|
||||
ROP_PUSH_SEG(DS)
|
||||
@@ -241,27 +257,27 @@ ROP_PUSH_SEG(FS)
|
||||
ROP_PUSH_SEG(GS)
|
||||
ROP_PUSH_SEG(SS)
|
||||
|
||||
#define ROP_POP_SEG(seg, rseg) \
|
||||
static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define ROP_POP_SEG(seg, rseg) \
|
||||
static uint32_t ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
ROP_POP_SEG(DS, cpu_state.seg_ds)
|
||||
ROP_POP_SEG(ES, cpu_state.seg_es)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,16 @@
|
||||
#define OP_XCHG_AX_(reg) \
|
||||
static uint32_t ropXCHG_AX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int ax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
ax_reg = LOAD_REG_W(REG_AX); \
|
||||
host_reg = LOAD_REG_W(REG_ ## reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define OP_XCHG_AX_(reg) \
|
||||
static uint32_t ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int ax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
ax_reg = LOAD_REG_W(REG_AX); \
|
||||
host_reg = LOAD_REG_W(REG_##reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
OP_XCHG_AX_(BX)
|
||||
OP_XCHG_AX_(CX)
|
||||
@@ -20,19 +20,19 @@ OP_XCHG_AX_(DI)
|
||||
OP_XCHG_AX_(SP)
|
||||
OP_XCHG_AX_(BP)
|
||||
|
||||
#define OP_XCHG_EAX_(reg) \
|
||||
static uint32_t ropXCHG_EAX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int eax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
eax_reg = LOAD_REG_L(REG_EAX); \
|
||||
host_reg = LOAD_REG_L(REG_ ## reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define OP_XCHG_EAX_(reg) \
|
||||
static uint32_t ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int eax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
eax_reg = LOAD_REG_L(REG_EAX); \
|
||||
host_reg = LOAD_REG_L(REG_##reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
OP_XCHG_EAX_(EBX)
|
||||
OP_XCHG_EAX_(ECX)
|
||||
@@ -42,48 +42,51 @@ OP_XCHG_EAX_(EDI)
|
||||
OP_XCHG_EAX_(ESP)
|
||||
OP_XCHG_EAX_(EBP)
|
||||
|
||||
static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_B(fetchdat & 7);
|
||||
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7);
|
||||
dst_reg = LOAD_REG_B(fetchdat & 7);
|
||||
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_W(fetchdat & 7);
|
||||
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7);
|
||||
dst_reg = LOAD_REG_W(fetchdat & 7);
|
||||
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_L(fetchdat & 7);
|
||||
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7);
|
||||
dst_reg = LOAD_REG_L(fetchdat & 7);
|
||||
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,23 @@
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 0
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 0
|
||||
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
|
||||
#define HASH(l) ((l) & 0x1ffff)
|
||||
#define HASH(l) ((l) &0x1ffff)
|
||||
|
||||
#define BLOCK_EXIT_OFFSET 0x7e0
|
||||
#ifdef OLD_GPF
|
||||
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
|
||||
# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
|
||||
#else
|
||||
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 12)
|
||||
# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 12)
|
||||
#endif
|
||||
|
||||
#define BLOCK_MAX 1620
|
||||
|
||||
enum
|
||||
{
|
||||
OP_RET = 0xc3
|
||||
enum {
|
||||
OP_RET = 0xc3
|
||||
};
|
||||
|
||||
#define NR_HOST_REGS 4
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,23 @@
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 0
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 0
|
||||
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
|
||||
#define HASH(l) ((l) & 0x1ffff)
|
||||
#define HASH(l) ((l) &0x1ffff)
|
||||
|
||||
#define BLOCK_EXIT_OFFSET 0x7f0
|
||||
#ifdef OLD_GPF
|
||||
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
|
||||
# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
|
||||
#else
|
||||
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14)
|
||||
# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14)
|
||||
#endif
|
||||
|
||||
#define BLOCK_MAX 1720
|
||||
|
||||
enum
|
||||
{
|
||||
OP_RET = 0xc3
|
||||
enum {
|
||||
OP_RET = 0xc3
|
||||
};
|
||||
|
||||
#define NR_HOST_REGS 4
|
||||
|
||||
Reference in New Issue
Block a user