summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Vignatti <tiago.vignatti@nokia.com>2008-03-11 02:42:13 -0300
committerTiago Vignatti <tiago.vignatti@nokia.com>2009-11-10 20:21:16 +0200
commita40e38a271fdf8909ff12f8fed41df606009ef88 (patch)
treef55c24a798f6aa90d7eb6e8e8da2daacc46ec752
parentc2d64f84c2babb287552965efe39a759075d22c2 (diff)
drop the first blob of xorg's x86emu
yeah, I know is not the best way to do it... Signed-off-by: Tiago Vignatti <tiago.vignatti@nokia.com>
-rw-r--r--.gitignore26
-rw-r--r--configure.ac1
-rw-r--r--src/Makefile.am7
-rw-r--r--src/thunk.c10
-rw-r--r--src/x86emu/Makefile.am23
-rw-r--r--src/x86emu/debug.c155
-rw-r--r--src/x86emu/decode.c85
-rw-r--r--src/x86emu/ops.c29
-rw-r--r--src/x86emu/ops2.c88
-rw-r--r--src/x86emu/prim_ops.c326
-rw-r--r--src/x86emu/sys.c83
-rw-r--r--src/x86emu/x86emu.h (renamed from src/x86emu/x86emu/x86emu.h)17
-rw-r--r--src/x86emu/x86emu/debug.h10
-rw-r--r--src/x86emu/x86emu/fpu_regs.h8
-rw-r--r--src/x86emu/x86emu/prim_ops.h1
-rw-r--r--src/x86emu/x86emu/prim_x86_gcc.h79
-rw-r--r--src/x86emu/x86emu/regs.h8
-rw-r--r--src/x86emu/x86emu/types.h2
-rw-r--r--src/x86emu/x86emu/x86emui.h18
19 files changed, 533 insertions, 443 deletions
diff --git a/.gitignore b/.gitignore
index 2b1030a..bad5791 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,29 @@ src/lrmi.lo
src/x86-common.lo
stamp-h1
x86.pc
+src/debug.lo
+src/debug.o
+src/decode.lo
+src/decode.o
+src/fpu.lo
+src/fpu.o
+src/ops.lo
+src/ops.o
+src/ops2.lo
+src/ops2.o
+src/prim_ops.lo
+src/prim_ops.o
+src/sys.lo
+src/sys.o
+src/thunk.lo
+compile
+src/decode.loT
+src/x86emu/.deps
+src/x86emu/debug.o
+src/x86emu/decode.o
+src/x86emu/fpu.o
+src/x86emu/libx86emu.a
+src/x86emu/ops.o
+src/x86emu/ops2.o
+src/x86emu/prim_ops.o
+src/x86emu/sys.o
diff --git a/configure.ac b/configure.ac
index 0089702..317e188 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ fi
AC_OUTPUT([Makefile
src/Makefile
+ src/x86emu/Makefile
x86.pc])
dnl Configuration output
diff --git a/src/Makefile.am b/src/Makefile.am
index ea1d8b9..3f7adbc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,9 +1,10 @@
+SUBDIRS = x86emu
+
lib_LTLIBRARIES = libx86.la
if X86EMU
-libx86_la_SOURCES = x86-common.c thunk.c x86emu/decode.c x86emu/debug.c \
- x86emu/fpu.c x86emu/ops.c x86emu/ops2.c \
- x86emu/prim_ops.c x86emu/sys.c
+libx86_la_SOURCES = x86-common.c thunk.c
+libx86_la_LIBADD = x86emu/libx86emu.la
else
libx86_la_SOURCES = x86-common.c lrmi.c
endif
diff --git a/src/thunk.c b/src/thunk.c
index b2b365f..4f392d0 100644
--- a/src/thunk.c
+++ b/src/thunk.c
@@ -1,7 +1,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
-#include "x86emu/x86emu/x86emu.h"
+#include "x86emu/x86emu.h"
#include "libx86.h"
#include "x86-common.h"
@@ -63,6 +63,14 @@
#define X86_VIP_MASK 0x00100000 /* virtual interrupt pending */
#define X86_ID_MASK 0x00200000
+#define MEM_RB(name, addr) (*name->mem->rb)(name, addr)
+#define MEM_RW(name, addr) (*name->mem->rw)(name, addr)
+#define MEM_RL(name, addr) (*name->mem->rl)(name, addr)
+#define MEM_WB(name, addr, val) (*name->mem->wb)(name, addr, val)
+#define MEM_WW(addr, val) wrw(addr, val)
+#define MEM_WL(name, addr, val) (*name->mem->wl)(name, addr, val)
+
+
#define SHMERRORPTR (pointer)(-1)
#define __BUILDIO(bwl,bw,type) \
diff --git a/src/x86emu/Makefile.am b/src/x86emu/Makefile.am
new file mode 100644
index 0000000..2fc9337
--- /dev/null
+++ b/src/x86emu/Makefile.am
@@ -0,0 +1,23 @@
+noinst_LTLIBRARIES = libx86emu.la
+
+libx86emu_la_SOURCES = debug.c \
+ decode.c \
+ fpu.c \
+ ops2.c \
+ ops.c \
+ prim_ops.c \
+ sys.c \
+ x86emu.h
+
+EXTRA_DIST = validate.c \
+ x86emu/debug.h \
+ x86emu/decode.h \
+ x86emu/fpu.h \
+ x86emu/fpu_regs.h \
+ x86emu/ops.h \
+ x86emu/prim_asm.h \
+ x86emu/prim_ops.h \
+ x86emu/prim_x86_gcc.h \
+ x86emu/regs.h \
+ x86emu/types.h \
+ x86emu/x86emui.h
diff --git a/src/x86emu/debug.c b/src/x86emu/debug.c
index 837dc18..5eda908 100644
--- a/src/x86emu/debug.c
+++ b/src/x86emu/debug.c
@@ -38,9 +38,9 @@
****************************************************************************/
#include "x86emu/x86emui.h"
-#ifdef IN_MODULE
-#include "xf86_ansic.h"
-#else
+#include <stdio.h>
+#include <string.h>
+#ifndef NO_SYS_HEADERS
#include <stdarg.h>
#include <stdlib.h>
#endif
@@ -56,18 +56,14 @@ static int parse_line (char *s, int *ps, int *n);
/* should look something like debug's output. */
void X86EMU_trace_regs (void)
{
-return;
if (DEBUG_TRACE()) {
x86emu_dump_regs();
}
if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) {
- printf("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
+ printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
print_decoded_instruction();
}
- printf("%04x:%04x \n",M.x86.saved_cs, M.x86.saved_ip);
- print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
- print_decoded_instruction();
}
void X86EMU_trace_xregs (void)
@@ -83,7 +79,7 @@ void x86emu_just_disassemble (void)
* This routine called if the flag DEBUG_DISASSEMBLE is set kind
* of a hack!
*/
- printf("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
+ printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
print_decoded_instruction();
}
@@ -194,12 +190,12 @@ static void print_encoded_bytes (u16 s, u16 o)
for (i=0; i< M.x86.enc_pos; i++) {
sprintf(buf1+2*i,"%02x", fetch_data_byte_abs(s,o+i));
}
- printf("%-20s",buf1);
+ printk("%-20s",buf1);
}
static void print_decoded_instruction (void)
{
- printf("%s", M.x86.decoded_buf);
+ printk("%s", M.x86.decoded_buf);
}
void x86emu_print_int_vect (u16 iv)
@@ -209,7 +205,7 @@ void x86emu_print_int_vect (u16 iv)
if (iv > 256) return;
seg = fetch_data_word_abs(0,iv*4);
off = fetch_data_word_abs(0,iv*4+2);
- printf("%04x:%04x ", seg, off);
+ printk("%04x:%04x ", seg, off);
}
void X86EMU_dump_memory (u16 seg, u16 off, u32 amt)
@@ -221,12 +217,12 @@ void X86EMU_dump_memory (u16 seg, u16 off, u32 amt)
current = start;
while (end <= off + amt) {
- printf("%04x:%04x ", seg, start);
+ printk("%04x:%04x ", seg, start);
for (i=start; i< off; i++)
- printf(" ");
+ printk(" ");
for ( ; i< end; i++)
- printf("%02x ", fetch_data_byte_abs(seg,i));
- printf("\n");
+ printk("%02x ", fetch_data_byte_abs(seg,i));
+ printk("\n");
start = end;
end = start + 16;
}
@@ -260,7 +256,7 @@ void x86emu_single_step (void)
done=0;
offset = M.x86.saved_ip;
while (!done) {
- printf("-");
+ printk("-");
p = fgets(s, 1023, stdin);
cmd = parse_line(s, ps, &ntok);
switch(cmd) {
@@ -310,10 +306,11 @@ void x86emu_single_step (void)
}
break;
case 'q':
- exit(1);
+ M.x86.debug |= DEBUG_EXIT;
+ return;
case 'P':
noDecode = (noDecode)?0:1;
- printf("Toggled decoding to %s\n",(noDecode)?"FALSE":"TRUE");
+ printk("Toggled decoding to %s\n",(noDecode)?"FALSE":"TRUE");
break;
case 't':
case 0:
@@ -366,68 +363,68 @@ static int parse_line (char *s, int *ps, int *n)
void x86emu_dump_regs (void)
{
- fprintf(stderr, "\tAX=%04x ", M.x86.R_AX );
- fprintf(stderr, "BX=%04x ", M.x86.R_BX );
- fprintf(stderr, "CX=%04x ", M.x86.R_CX );
- fprintf(stderr, "DX=%04x ", M.x86.R_DX );
- fprintf(stderr, "SP=%04x ", M.x86.R_SP );
- fprintf(stderr, "BP=%04x ", M.x86.R_BP );
- fprintf(stderr, "SI=%04x ", M.x86.R_SI );
- fprintf(stderr, "DI=%04x\n", M.x86.R_DI );
- fprintf(stderr, "\tDS=%04x ", M.x86.R_DS );
- fprintf(stderr, "ES=%04x ", M.x86.R_ES );
- fprintf(stderr, "SS=%04x ", M.x86.R_SS );
- fprintf(stderr, "CS=%04x ", M.x86.R_CS );
- fprintf(stderr, "IP=%04x ", M.x86.R_IP );
- if (ACCESS_FLAG(F_OF)) fprintf(stderr, "OV "); /* CHECKED... */
- else fprintf(stderr, "NV ");
- if (ACCESS_FLAG(F_DF)) fprintf(stderr, "DN ");
- else fprintf(stderr, "UP ");
- if (ACCESS_FLAG(F_IF)) fprintf(stderr, "EI ");
- else fprintf(stderr, "DI ");
- if (ACCESS_FLAG(F_SF)) fprintf(stderr, "NG ");
- else fprintf(stderr, "PL ");
- if (ACCESS_FLAG(F_ZF)) fprintf(stderr, "ZR ");
- else fprintf(stderr, "NZ ");
- if (ACCESS_FLAG(F_AF)) fprintf(stderr, "AC ");
- else fprintf(stderr, "NA ");
- if (ACCESS_FLAG(F_PF)) fprintf(stderr, "PE ");
- else fprintf(stderr, "PO ");
- if (ACCESS_FLAG(F_CF)) fprintf(stderr, "CY ");
- else fprintf(stderr, "NC ");
- fprintf(stderr, "\n");
+ printk("\tAX=%04x ", M.x86.R_AX );
+ printk("BX=%04x ", M.x86.R_BX );
+ printk("CX=%04x ", M.x86.R_CX );
+ printk("DX=%04x ", M.x86.R_DX );
+ printk("SP=%04x ", M.x86.R_SP );
+ printk("BP=%04x ", M.x86.R_BP );
+ printk("SI=%04x ", M.x86.R_SI );
+ printk("DI=%04x\n", M.x86.R_DI );
+ printk("\tDS=%04x ", M.x86.R_DS );
+ printk("ES=%04x ", M.x86.R_ES );
+ printk("SS=%04x ", M.x86.R_SS );
+ printk("CS=%04x ", M.x86.R_CS );
+ printk("IP=%04x ", M.x86.R_IP );
+ if (ACCESS_FLAG(F_OF)) printk("OV "); /* CHECKED... */
+ else printk("NV ");
+ if (ACCESS_FLAG(F_DF)) printk("DN ");
+ else printk("UP ");
+ if (ACCESS_FLAG(F_IF)) printk("EI ");
+ else printk("DI ");
+ if (ACCESS_FLAG(F_SF)) printk("NG ");
+ else printk("PL ");
+ if (ACCESS_FLAG(F_ZF)) printk("ZR ");
+ else printk("NZ ");
+ if (ACCESS_FLAG(F_AF)) printk("AC ");
+ else printk("NA ");
+ if (ACCESS_FLAG(F_PF)) printk("PE ");
+ else printk("PO ");
+ if (ACCESS_FLAG(F_CF)) printk("CY ");
+ else printk("NC ");
+ printk("\n");
}
void x86emu_dump_xregs (void)
{
- printf("\tEAX=%08x ", M.x86.R_EAX );
- printf("EBX=%08x ", M.x86.R_EBX );
- printf("ECX=%08x ", M.x86.R_ECX );
- printf("EDX=%08x \n", M.x86.R_EDX );
- printf("\tESP=%08x ", M.x86.R_ESP );
- printf("EBP=%08x ", M.x86.R_EBP );
- printf("ESI=%08x ", M.x86.R_ESI );
- printf("EDI=%08x\n", M.x86.R_EDI );
- printf("\tDS=%04x ", M.x86.R_DS );
- printf("ES=%04x ", M.x86.R_ES );
- printf("SS=%04x ", M.x86.R_SS );
- printf("CS=%04x ", M.x86.R_CS );
- printf("EIP=%08x\n\t", M.x86.R_EIP );
- if (ACCESS_FLAG(F_OF)) printf("OV "); /* CHECKED... */
- else printf("NV ");
- if (ACCESS_FLAG(F_DF)) printf("DN ");
- else printf("UP ");
- if (ACCESS_FLAG(F_IF)) printf("EI ");
- else printf("DI ");
- if (ACCESS_FLAG(F_SF)) printf("NG ");
- else printf("PL ");
- if (ACCESS_FLAG(F_ZF)) printf("ZR ");
- else printf("NZ ");
- if (ACCESS_FLAG(F_AF)) printf("AC ");
- else printf("NA ");
- if (ACCESS_FLAG(F_PF)) printf("PE ");
- else printf("PO ");
- if (ACCESS_FLAG(F_CF)) printf("CY ");
- else printf("NC ");
- printf("\n");
+ printk("\tEAX=%08x ", M.x86.R_EAX );
+ printk("EBX=%08x ", M.x86.R_EBX );
+ printk("ECX=%08x ", M.x86.R_ECX );
+ printk("EDX=%08x \n", M.x86.R_EDX );
+ printk("\tESP=%08x ", M.x86.R_ESP );
+ printk("EBP=%08x ", M.x86.R_EBP );
+ printk("ESI=%08x ", M.x86.R_ESI );
+ printk("EDI=%08x\n", M.x86.R_EDI );
+ printk("\tDS=%04x ", M.x86.R_DS );
+ printk("ES=%04x ", M.x86.R_ES );
+ printk("SS=%04x ", M.x86.R_SS );
+ printk("CS=%04x ", M.x86.R_CS );
+ printk("EIP=%08x\n\t", M.x86.R_EIP );
+ if (ACCESS_FLAG(F_OF)) printk("OV "); /* CHECKED... */
+ else printk("NV ");
+ if (ACCESS_FLAG(F_DF)) printk("DN ");
+ else printk("UP ");
+ if (ACCESS_FLAG(F_IF)) printk("EI ");
+ else printk("DI ");
+ if (ACCESS_FLAG(F_SF)) printk("NG ");
+ else printk("PL ");
+ if (ACCESS_FLAG(F_ZF)) printk("ZR ");
+ else printk("NZ ");
+ if (ACCESS_FLAG(F_AF)) printk("AC ");
+ else printk("NA ");
+ if (ACCESS_FLAG(F_PF)) printk("PE ");
+ else printk("PO ");
+ if (ACCESS_FLAG(F_CF)) printk("CY ");
+ else printk("NC ");
+ printk("\n");
}
diff --git a/src/x86emu/decode.c b/src/x86emu/decode.c
index 9071649..9339f4c 100644
--- a/src/x86emu/decode.c
+++ b/src/x86emu/decode.c
@@ -37,7 +37,7 @@
*
****************************************************************************/
-
+#include <stdlib.h>
#include "x86emu/x86emui.h"
/*----------------------------- Implementation ----------------------------*/
@@ -103,8 +103,14 @@ DB( if (CHECK_IP_FETCH())
INC_DECODED_INST_LEN(1);
if (M.x86.intr) {
if (M.x86.intr & INTR_HALTED) {
-DB(
- X86EMU_trace_regs();)
+DB( if (M.x86.R_SP != 0) {
+ printk("halted\n");
+ X86EMU_trace_regs();
+ }
+ else {
+ if (M.x86.debug)
+ printk("Service completed successfully\n");
+ })
return;
}
if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) ||
@@ -112,16 +118,12 @@ DB(
x86emu_intr_handle();
}
}
- if ((M.x86.R_CS == 0) && (M.x86.R_IP == 0)) {
-DB(
- X86EMU_trace_regs();)
- return;
- }
-
op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
- // fprintf (stderr, "%s", M.x86.decoded_buf);
- // x86emu_dump_regs();
(*x86emu_optab[op1])(op1);
+ if (M.x86.debug & DEBUG_EXIT) {
+ M.x86.debug &= ~DEBUG_EXIT;
+ return;
+ }
}
}
@@ -716,10 +718,7 @@ u16* decode_rm_seg_register(
DECODE_PRINTF("ILLEGAL SEGREG");
break;
}
- printf("reg %d\n", reg);
- //DECODE_PRINTF("CS");
- //return &M.x86.R_CS;
- /*HALT_SYS();*/
+ HALT_SYS();
return NULL; /* NOT REACHED OR REACHED ON ERROR */
}
@@ -843,6 +842,7 @@ u32 decode_rm00_address(
int sib;
if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+ /* 32-bit addressing */
switch (rm) {
case 0:
DECODE_PRINTF("[EAX]");
@@ -872,21 +872,22 @@ u32 decode_rm00_address(
}
HALT_SYS();
} else {
+ /* 16-bit addressing */
switch (rm) {
case 0:
DECODE_PRINTF("[BX+SI]");
- return M.x86.R_BX + M.x86.R_SI;
+ return (M.x86.R_BX + M.x86.R_SI) & 0xffff;
case 1:
DECODE_PRINTF("[BX+DI]");
- return M.x86.R_BX + M.x86.R_DI;
+ return (M.x86.R_BX + M.x86.R_DI) & 0xffff;
case 2:
DECODE_PRINTF("[BP+SI]");
M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_SI;
+ return (M.x86.R_BP + M.x86.R_SI) & 0xffff;
case 3:
DECODE_PRINTF("[BP+DI]");
M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_DI;
+ return (M.x86.R_BP + M.x86.R_DI) & 0xffff;
case 4:
DECODE_PRINTF("[SI]");
return M.x86.R_SI;
@@ -928,6 +929,7 @@ u32 decode_rm01_address(
displacement = (s8)fetch_byte_imm();
if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+ /* 32-bit addressing */
switch (rm) {
case 0:
DECODE_PRINTF2("%d[EAX]", displacement);
@@ -958,34 +960,35 @@ u32 decode_rm01_address(
}
HALT_SYS();
} else {
+ /* 16-bit addressing */
switch (rm) {
case 0:
DECODE_PRINTF2("%d[BX+SI]", displacement);
- return M.x86.R_BX + M.x86.R_SI + displacement;
+ return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
case 1:
DECODE_PRINTF2("%d[BX+DI]", displacement);
- return M.x86.R_BX + M.x86.R_DI + displacement;
+ return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
case 2:
DECODE_PRINTF2("%d[BP+SI]", displacement);
M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_SI + displacement;
+ return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
case 3:
DECODE_PRINTF2("%d[BP+DI]", displacement);
M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_DI + displacement;
+ return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
case 4:
DECODE_PRINTF2("%d[SI]", displacement);
- return M.x86.R_SI + displacement;
+ return (M.x86.R_SI + displacement) & 0xffff;
case 5:
DECODE_PRINTF2("%d[DI]", displacement);
- return M.x86.R_DI + displacement;
+ return (M.x86.R_DI + displacement) & 0xffff;
case 6:
DECODE_PRINTF2("%d[BP]", displacement);
M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + displacement;
+ return (M.x86.R_BP + displacement) & 0xffff;
case 7:
DECODE_PRINTF2("%d[BX]", displacement);
- return M.x86.R_BX + displacement;
+ return (M.x86.R_BX + displacement) & 0xffff;
}
HALT_SYS();
}
@@ -1019,6 +1022,7 @@ u32 decode_rm10_address(
}
if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+ /* 32-bit addressing */
switch (rm) {
case 0:
DECODE_PRINTF2("%08x[EAX]", displacement);
@@ -1051,34 +1055,35 @@ u32 decode_rm10_address(
}
HALT_SYS();
} else {
+ /* 16-bit addressing */
switch (rm) {
case 0:
- DECODE_PRINTF2("%04x[BX+SI]", displacement);
- return M.x86.R_BX + M.x86.R_SI + displacement;
+ DECODE_PRINTF2("%04x[BX+SI]", displacement);
+ return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
case 1:
- DECODE_PRINTF2("%04x[BX+DI]", displacement);
- return M.x86.R_BX + M.x86.R_DI + displacement;
+ DECODE_PRINTF2("%04x[BX+DI]", displacement);
+ return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
case 2:
DECODE_PRINTF2("%04x[BP+SI]", displacement);
M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_SI + displacement;
+ return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
case 3:
DECODE_PRINTF2("%04x[BP+DI]", displacement);
M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_DI + displacement;
+ return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
case 4:
- DECODE_PRINTF2("%04x[SI]", displacement);
- return M.x86.R_SI + displacement;
+ DECODE_PRINTF2("%04x[SI]", displacement);
+ return (M.x86.R_SI + displacement) & 0xffff;
case 5:
- DECODE_PRINTF2("%04x[DI]", displacement);
- return M.x86.R_DI + displacement;
+ DECODE_PRINTF2("%04x[DI]", displacement);
+ return (M.x86.R_DI + displacement) & 0xffff;
case 6:
DECODE_PRINTF2("%04x[BP]", displacement);
M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + displacement;
+ return (M.x86.R_BP + displacement) & 0xffff;
case 7:
- DECODE_PRINTF2("%04x[BX]", displacement);
- return M.x86.R_BX + displacement;
+ DECODE_PRINTF2("%04x[BX]", displacement);
+ return (M.x86.R_BX + displacement) & 0xffff;
}
HALT_SYS();
}
diff --git a/src/x86emu/ops.c b/src/x86emu/ops.c
index 7431863..37ae2c9 100644
--- a/src/x86emu/ops.c
+++ b/src/x86emu/ops.c
@@ -70,7 +70,6 @@
*
****************************************************************************/
-
#include "x86emu/x86emui.h"
/*----------------------------- Implementation ----------------------------*/
@@ -86,11 +85,22 @@ static void x86emuOp_illegal_op(
u8 op1)
{
START_OF_INSTR();
+ if (M.x86.R_SP != 0) {
DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
TRACE_REGS();
- printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
- M.x86.R_CS, M.x86.R_IP-1,op1);
+ DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
+ M.x86.R_CS, M.x86.R_IP-1,op1));
HALT_SYS();
+ }
+ else {
+ /* If we get here, it means the stack pointer is back to zero
+ * so we are just returning from an emulator service call
+ * so therte is no need to display an error message. We trap
+ * the emulator with an 0xF1 opcode to finish the service
+ * call.
+ */
+ X86EMU_halt_sys();
+ }
END_OF_INSTR();
}
@@ -9403,6 +9413,8 @@ static void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
DECODE_PRINTF("AAM\n");
a = fetch_byte_imm(); /* this is a stupid encoding. */
if (a != 10) {
+ /* fix: add base decoding
+ aam_word(u8 val, int base a) */
DECODE_PRINTF("ERROR DECODING AAM\n");
TRACE_REGS();
HALT_SYS();
@@ -9420,9 +9432,18 @@ Handles opcode 0xd5
****************************************************************************/
static void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
{
+ u8 a;
+
START_OF_INSTR();
DECODE_PRINTF("AAD\n");
- (void) fetch_byte_imm();
+ a = fetch_byte_imm();
+ if (a != 10) {
+ /* fix: add base decoding
+ aad_word(u16 val, int base a) */
+ DECODE_PRINTF("ERROR DECODING AAM\n");
+ TRACE_REGS();
+ HALT_SYS();
+ }
TRACE_AND_STEP();
M.x86.R_AX = aad_word(M.x86.R_AX);
DECODE_CLEAR_SEGOVR();
diff --git a/src/x86emu/ops2.c b/src/x86emu/ops2.c
index 4bf95c1..324de8a 100644
--- a/src/x86emu/ops2.c
+++ b/src/x86emu/ops2.c
@@ -65,6 +65,40 @@ static void x86emuOp2_illegal_op(
/****************************************************************************
REMARKS:
+Handles opcode 0x0f,0x31
+****************************************************************************/
+static void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
+{
+#ifdef __HAS_LONG_LONG__
+ static u64 counter = 0;
+#else
+ static u32 counter = 0;
+#endif
+
+ counter += 0x10000;
+
+ /* read timestamp counter */
+ /*
+ * Note that instead of actually trying to accurately measure this, we just
+ * increase the counter by a fixed amount every time we hit one of these
+ * instructions. Feel free to come up with a better method.
+ */
+ START_OF_INSTR();
+ DECODE_PRINTF("RDTSC\n");
+ TRACE_AND_STEP();
+#ifdef __HAS_LONG_LONG__
+ M.x86.R_EAX = counter & 0xffffffff;
+ M.x86.R_EDX = counter >> 32;
+#else
+ M.x86.R_EAX = counter;
+ M.x86.R_EDX = 0;
+#endif
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
Handles opcode 0x0f,0x80-0x8F
****************************************************************************/
static void x86emuOp2_long_jump(u8 op2)
@@ -294,6 +328,20 @@ static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
}
/****************************************************************************
+REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
+Handles opcode 0x0f,0xa2
+****************************************************************************/
+static void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
+{
+ START_OF_INSTR();
+ DECODE_PRINTF("CPUID\n");
+ TRACE_AND_STEP();
+ cpuid();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
REMARKS:
Handles opcode 0x0f,0xa3
****************************************************************************/
@@ -2129,7 +2177,7 @@ static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
uint srcoffset;
START_OF_INSTR();
- DECODE_PRINTF("BSF\n");
+ DECODE_PRINTF("BSF\t");
FETCH_DECODE_MODRM(mod, rh, rl);
switch(mod) {
case 0:
@@ -2209,25 +2257,25 @@ static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
break;
case 3: /* register to register */
if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg, *dstreg;
+ u32 srcval, *dstreg;
- srcreg = DECODE_RM_LONG_REGISTER(rl);
+ srcval = *DECODE_RM_LONG_REGISTER(rl);
DECODE_PRINTF(",");
dstreg = DECODE_RM_LONG_REGISTER(rh);
TRACE_AND_STEP();
- CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
+ CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
- if ((*srcreg >> *dstreg) & 1) break;
+ if ((srcval >> *dstreg) & 1) break;
} else {
- u16 *srcreg, *dstreg;
+ u16 srcval, *dstreg;
- srcreg = DECODE_RM_WORD_REGISTER(rl);
+ srcval = *DECODE_RM_WORD_REGISTER(rl);
DECODE_PRINTF(",");
dstreg = DECODE_RM_WORD_REGISTER(rh);
TRACE_AND_STEP();
- CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
+ CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
- if ((*srcreg >> *dstreg) & 1) break;
+ if ((srcval >> *dstreg) & 1) break;
}
break;
}
@@ -2245,7 +2293,7 @@ static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
uint srcoffset;
START_OF_INSTR();
- DECODE_PRINTF("BSF\n");
+ DECODE_PRINTF("BSR\t");
FETCH_DECODE_MODRM(mod, rh, rl);
switch(mod) {
case 0:
@@ -2325,25 +2373,25 @@ static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
break;
case 3: /* register to register */
if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg, *dstreg;
+ u32 srcval, *dstreg;
- srcreg = DECODE_RM_LONG_REGISTER(rl);
+ srcval = *DECODE_RM_LONG_REGISTER(rl);
DECODE_PRINTF(",");
dstreg = DECODE_RM_LONG_REGISTER(rh);
TRACE_AND_STEP();
- CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
+ CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
- if ((*srcreg >> *dstreg) & 1) break;
+ if ((srcval >> *dstreg) & 1) break;
} else {
- u16 *srcreg, *dstreg;
+ u16 srcval, *dstreg;
- srcreg = DECODE_RM_WORD_REGISTER(rl);
+ srcval = *DECODE_RM_WORD_REGISTER(rl);
DECODE_PRINTF(",");
dstreg = DECODE_RM_WORD_REGISTER(rh);
TRACE_AND_STEP();
- CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
+ CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
- if ((*srcreg >> *dstreg) & 1) break;
+ if ((srcval >> *dstreg) & 1) break;
}
break;
}
@@ -2580,7 +2628,7 @@ void (*x86emu_optab2[256])(u8) =
/* 0x2f */ x86emuOp2_illegal_op,
/* 0x30 */ x86emuOp2_illegal_op,
-/* 0x31 */ x86emuOp2_illegal_op,
+/* 0x31 */ x86emuOp2_rdtsc,
/* 0x32 */ x86emuOp2_illegal_op,
/* 0x33 */ x86emuOp2_illegal_op,
/* 0x34 */ x86emuOp2_illegal_op,
@@ -2700,7 +2748,7 @@ void (*x86emu_optab2[256])(u8) =
/* 0xa0 */ x86emuOp2_push_FS,
/* 0xa1 */ x86emuOp2_pop_FS,
-/* 0xa2 */ x86emuOp2_illegal_op,
+/* 0xa2 */ x86emuOp2_cpuid,
/* 0xa3 */ x86emuOp2_bt_R,
/* 0xa4 */ x86emuOp2_shld_IMM,
/* 0xa5 */ x86emuOp2_shld_CL,
diff --git a/src/x86emu/prim_ops.c b/src/x86emu/prim_ops.c
index ba4ffde..b42cdc0 100644
--- a/src/x86emu/prim_ops.c
+++ b/src/x86emu/prim_ops.c
@@ -97,12 +97,18 @@
*
****************************************************************************/
+#include <stdlib.h>
+
#define PRIM_OPS_NO_REDEFINE_ASM
#include "x86emu/x86emui.h"
-/*------------------------- Global Variables ------------------------------*/
+#if defined(__GNUC__)
+# if defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__)
+# include "x86emu/prim_x86_gcc.h"
+# endif
+#endif
-#ifndef __HAVE_INLINE_ASSEMBLER__
+/*------------------------- Global Variables ------------------------------*/
static u32 x86emu_parity_tab[8] =
{
@@ -116,15 +122,11 @@ static u32 x86emu_parity_tab[8] =
0x69969669,
};
-#endif
-
#define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
#define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
/*----------------------------- Implementation ----------------------------*/
-#ifndef __HAVE_INLINE_ASSEMBLER__
-
/****************************************************************************
REMARKS:
Implements the AAA instruction and side effects.
@@ -2086,7 +2088,7 @@ Implements the IMUL instruction and side effects.
void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
{
#ifdef __HAS_LONG_LONG__
- s64 res = (s32)d * (s32)s;
+ s64 res = (s64)(s32)d * (s32)s;
*res_lo = (u32)res;
*res_hi = (u32)(res >> 32);
@@ -2178,7 +2180,7 @@ Implements the MUL instruction and side effects.
void mul_long(u32 s)
{
#ifdef __HAS_LONG_LONG__
- u64 res = (u32)M.x86.R_EAX * (u32)s;
+ u64 res = (u64)M.x86.R_EAX * s;
M.x86.R_EAX = (u32)res;
M.x86.R_EDX = (u32)(res >> 32);
@@ -2454,8 +2456,6 @@ void div_long(u32 s)
M.x86.R_EDX = (u32)mod;
}
-#endif /* __HAVE_INLINE_ASSEMBLER__ */
-
/****************************************************************************
REMARKS:
Implements the IN string instruction and side effects.
@@ -2660,255 +2660,63 @@ DB( if (CHECK_SP_ACCESS())
return res;
}
-#ifdef __HAVE_INLINE_ASSEMBLER__
-
-u16 aaa_word (u16 d)
-{ return aaa_word_asm(&M.x86.R_EFLG,d); }
-
-u16 aas_word (u16 d)
-{ return aas_word_asm(&M.x86.R_EFLG,d); }
-
-u16 aad_word (u16 d)
-{ return aad_word_asm(&M.x86.R_EFLG,d); }
-
-u16 aam_word (u8 d)
-{ return aam_word_asm(&M.x86.R_EFLG,d); }
-
-u8 adc_byte (u8 d, u8 s)
-{ return adc_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 adc_word (u16 d, u16 s)
-{ return adc_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 adc_long (u32 d, u32 s)
-{ return adc_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 add_byte (u8 d, u8 s)
-{ return add_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 add_word (u16 d, u16 s)
-{ return add_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 add_long (u32 d, u32 s)
-{ return add_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 and_byte (u8 d, u8 s)
-{ return and_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 and_word (u16 d, u16 s)
-{ return and_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 and_long (u32 d, u32 s)
-{ return and_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 cmp_byte (u8 d, u8 s)
-{ return cmp_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 cmp_word (u16 d, u16 s)
-{ return cmp_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 cmp_long (u32 d, u32 s)
-{ return cmp_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 daa_byte (u8 d)
-{ return daa_byte_asm(&M.x86.R_EFLG,d); }
-
-u8 das_byte (u8 d)
-{ return das_byte_asm(&M.x86.R_EFLG,d); }
-
-u8 dec_byte (u8 d)
-{ return dec_byte_asm(&M.x86.R_EFLG,d); }
-
-u16 dec_word (u16 d)
-{ return dec_word_asm(&M.x86.R_EFLG,d); }
-
-u32 dec_long (u32 d)
-{ return dec_long_asm(&M.x86.R_EFLG,d); }
-
-u8 inc_byte (u8 d)
-{ return inc_byte_asm(&M.x86.R_EFLG,d); }
-
-u16 inc_word (u16 d)
-{ return inc_word_asm(&M.x86.R_EFLG,d); }
-
-u32 inc_long (u32 d)
-{ return inc_long_asm(&M.x86.R_EFLG,d); }
-
-u8 or_byte (u8 d, u8 s)
-{ return or_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 or_word (u16 d, u16 s)
-{ return or_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 or_long (u32 d, u32 s)
-{ return or_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 neg_byte (u8 s)
-{ return neg_byte_asm(&M.x86.R_EFLG,s); }
-
-u16 neg_word (u16 s)
-{ return neg_word_asm(&M.x86.R_EFLG,s); }
-
-u32 neg_long (u32 s)
-{ return neg_long_asm(&M.x86.R_EFLG,s); }
-
-u8 not_byte (u8 s)
-{ return not_byte_asm(&M.x86.R_EFLG,s); }
-
-u16 not_word (u16 s)
-{ return not_word_asm(&M.x86.R_EFLG,s); }
-
-u32 not_long (u32 s)
-{ return not_long_asm(&M.x86.R_EFLG,s); }
-
-u8 rcl_byte (u8 d, u8 s)
-{ return rcl_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 rcl_word (u16 d, u8 s)
-{ return rcl_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 rcl_long (u32 d, u8 s)
-{ return rcl_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 rcr_byte (u8 d, u8 s)
-{ return rcr_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 rcr_word (u16 d, u8 s)
-{ return rcr_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 rcr_long (u32 d, u8 s)
-{ return rcr_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 rol_byte (u8 d, u8 s)
-{ return rol_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 rol_word (u16 d, u8 s)
-{ return rol_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 rol_long (u32 d, u8 s)
-{ return rol_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 ror_byte (u8 d, u8 s)
-{ return ror_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 ror_word (u16 d, u8 s)
-{ return ror_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 ror_long (u32 d, u8 s)
-{ return ror_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 shl_byte (u8 d, u8 s)
-{ return shl_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 shl_word (u16 d, u8 s)
-{ return shl_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 shl_long (u32 d, u8 s)
-{ return shl_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 shr_byte (u8 d, u8 s)
-{ return shr_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 shr_word (u16 d, u8 s)
-{ return shr_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 shr_long (u32 d, u8 s)
-{ return shr_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 sar_byte (u8 d, u8 s)
-{ return sar_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 sar_word (u16 d, u8 s)
-{ return sar_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 sar_long (u32 d, u8 s)
-{ return sar_long_asm(&M.x86.R_EFLG,d,s); }
-
-u16 shld_word (u16 d, u16 fill, u8 s)
-{ return shld_word_asm(&M.x86.R_EFLG,d,fill,s); }
-
-u32 shld_long (u32 d, u32 fill, u8 s)
-{ return shld_long_asm(&M.x86.R_EFLG,d,fill,s); }
-
-u16 shrd_word (u16 d, u16 fill, u8 s)
-{ return shrd_word_asm(&M.x86.R_EFLG,d,fill,s); }
-
-u32 shrd_long (u32 d, u32 fill, u8 s)
-{ return shrd_long_asm(&M.x86.R_EFLG,d,fill,s); }
-
-u8 sbb_byte (u8 d, u8 s)
-{ return sbb_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 sbb_word (u16 d, u16 s)
-{ return sbb_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 sbb_long (u32 d, u32 s)
-{ return sbb_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 sub_byte (u8 d, u8 s)
-{ return sub_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 sub_word (u16 d, u16 s)
-{ return sub_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 sub_long (u32 d, u32 s)
-{ return sub_long_asm(&M.x86.R_EFLG,d,s); }
-
-void test_byte (u8 d, u8 s)
-{ test_byte_asm(&M.x86.R_EFLG,d,s); }
-
-void test_word (u16 d, u16 s)
-{ test_word_asm(&M.x86.R_EFLG,d,s); }
-
-void test_long (u32 d, u32 s)
-{ test_long_asm(&M.x86.R_EFLG,d,s); }
-
-u8 xor_byte (u8 d, u8 s)
-{ return xor_byte_asm(&M.x86.R_EFLG,d,s); }
-
-u16 xor_word (u16 d, u16 s)
-{ return xor_word_asm(&M.x86.R_EFLG,d,s); }
-
-u32 xor_long (u32 d, u32 s)
-{ return xor_long_asm(&M.x86.R_EFLG,d,s); }
-
-void imul_byte (u8 s)
-{ imul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); }
-
-void imul_word (u16 s)
-{ imul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); }
-
-void imul_long (u32 s)
-{ imul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); }
-
-void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
-{ imul_long_asm(&M.x86.R_EFLG,res_lo,res_hi,d,s); }
-
-void mul_byte (u8 s)
-{ mul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); }
-
-void mul_word (u16 s)
-{ mul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); }
-
-void mul_long (u32 s)
-{ mul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); }
-
-void idiv_byte (u8 s)
-{ idiv_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); }
-
-void idiv_word (u16 s)
-{ idiv_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); }
-
-void idiv_long (u32 s)
-{ idiv_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); }
-
-void div_byte (u8 s)
-{ div_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); }
-
-void div_word (u16 s)
-{ div_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); }
+/****************************************************************************
+REMARKS:
+CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
+****************************************************************************/
+void cpuid (void)
+{
+ u32 feature = M.x86.R_EAX;
-void div_long (u32 s)
-{ div_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); }
+#ifdef X86EMU_HAS_HW_CPUID
+ /* If the platform allows it, we will base our values on the real
+ * results from the CPUID instruction. We limit support to the
+ * first two features, and the results of those are sanitized.
+ */
+ if (feature <= 1)
+ hw_cpuid(&M.x86.R_EAX, &M.x86.R_EBX, &M.x86.R_ECX, &M.x86.R_EDX);
+#endif
+ switch (feature) {
+ case 0:
+ /* Regardless if we have real data from the hardware, the emulator
+ * will only support upto feature 1, which we set in register EAX.
+ * Registers EBX:EDX:ECX contain a string identifying the CPU.
+ */
+ M.x86.R_EAX = 1;
+#ifndef X86EMU_HAS_HW_CPUID
+ /* EBX:EDX:ECX = "GenuineIntel" */
+ M.x86.R_EBX = 0x756e6547;
+ M.x86.R_EDX = 0x49656e69;
+ M.x86.R_ECX = 0x6c65746e;
#endif
+ break;
+ case 1:
+#ifndef X86EMU_HAS_HW_CPUID
+ /* If we don't have x86 compatible hardware, we return values from an
+ * Intel 486dx4; which was one of the first processors to have CPUID.
+ */
+ M.x86.R_EAX = 0x00000480;
+ M.x86.R_EBX = 0x00000000;
+ M.x86.R_ECX = 0x00000000;
+ M.x86.R_EDX = 0x00000002; /* VME */
+#else
+ /* In the case that we have hardware CPUID instruction, we make sure
+ * that the features reported are limited to TSC and VME.
+ */
+ M.x86.R_EDX &= 0x00000012;
+#endif
+ break;
+ default:
+ /* Finally, we don't support any additional features. Most CPUs
+ * return all zeros when queried for invalid or unsupported feature
+ * numbers.
+ */
+ M.x86.R_EAX = 0;
+ M.x86.R_EBX = 0;
+ M.x86.R_ECX = 0;
+ M.x86.R_EDX = 0;
+ break;
+ }
+}
+
diff --git a/src/x86emu/sys.c b/src/x86emu/sys.c
index 73fc66e..4d90ea3 100644
--- a/src/x86emu/sys.c
+++ b/src/x86emu/sys.c
@@ -40,14 +40,12 @@
*
****************************************************************************/
-#include "x86emu/x86emu.h"
+#include "x86emu.h"
#include "x86emu/x86emui.h"
#include "x86emu/regs.h"
#include "x86emu/debug.h"
#include "x86emu/prim_ops.h"
-#ifdef IN_MODULE
-#include "xf86_ansic.h"
-#else
+#ifndef NO_SYS_HEADERS
#include <string.h>
#endif
/*------------------------- Global Variables ------------------------------*/
@@ -59,6 +57,7 @@ X86EMU_intrFuncs _X86EMU_intrTab[256];
#if defined(__alpha__) || defined(__alpha)
/* to cope with broken egcs-1.1.2 :-(((( */
+#define ALPHA_UALOADS
/*
* inline functions to do unaligned accesses
* from linux/include/asm-alpha/unaligned.h
@@ -210,6 +209,60 @@ static __inline__ void stw_u(unsigned long r5, unsigned short * r11)
:"r" (r5), "r" (r11));
#endif
}
+
+#elif defined(__GNUC__) && ((__GNUC__ < 3)) && \
+ (defined (__ia64__) || defined (ia64__))
+#define IA64_UALOADS
+/*
+ * EGCS 1.1 knows about arbitrary unaligned loads. Define some
+ * packed structures to talk about such things with.
+ */
+struct __una_u64 { unsigned long x __attribute__((packed)); };
+struct __una_u32 { unsigned int x __attribute__((packed)); };
+struct __una_u16 { unsigned short x __attribute__((packed)); };
+
+static __inline__ unsigned long
+__uldq (const unsigned long * r11)
+{
+ const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
+ return ptr->x;
+}
+
+static __inline__ unsigned long
+uldl (const unsigned int * r11)
+{
+ const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
+ return ptr->x;
+}
+
+static __inline__ unsigned long
+uldw (const unsigned short * r11)
+{
+ const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
+ return ptr->x;
+}
+
+static __inline__ void
+ustq (unsigned long r5, unsigned long * r11)
+{
+ struct __una_u64 *ptr = (struct __una_u64 *) r11;
+ ptr->x = r5;
+}
+
+static __inline__ void
+ustl (unsigned long r5, unsigned int * r11)
+{
+ struct __una_u32 *ptr = (struct __una_u32 *) r11;
+ ptr->x = r5;
+}
+
+static __inline__ void
+ustw (unsigned long r5, unsigned short * r11)
+{
+ struct __una_u16 *ptr = (struct __una_u16 *) r11;
+ ptr->x = r5;
+}
+
#endif
/****************************************************************************
@@ -263,8 +316,10 @@ u16 X86API rdw(
}
else
#endif
-#if defined(__alpha__) || defined(__alpha)
+#if defined(ALPHA_UALOADS)
val = ldw_u((u16*)(M.mem_base + addr));
+#elif defined(IA64_UALOADS)
+ val = uldw((u16*)(M.mem_base + addr));
#else
val = *(u16*)(M.mem_base + addr);
#endif
@@ -300,8 +355,10 @@ u32 X86API rdl(
}
else
#endif
-#if defined(__alpha__) || defined(__alpha)
+#if defined(ALPHA_UALOADS)
val = ldl_u((u32*)(M.mem_base + addr));
+#elif defined(IA64_UALOADS)
+ val = uldl((u32*)(M.mem_base + addr));
#else
val = *(u32*)(M.mem_base + addr);
#endif
@@ -356,8 +413,10 @@ DB( if (DEBUG_MEM_TRACE())
}
else
#endif
-#if defined(__alpha__) || defined(__alpha)
+#if defined(ALPHA_UALOADS)
stw_u(val,(u16*)(M.mem_base + addr));
+#elif defined(IA64_UALOADS)
+ ustw(val,(u16*)(M.mem_base + addr));
#else
*(u16*)(M.mem_base + addr) = val;
#endif
@@ -390,8 +449,10 @@ DB( if (DEBUG_MEM_TRACE())
}
else
#endif
-#if defined(__alpha__) || defined(__alpha)
+#if defined(ALPHA_UALOADS)
stl_u(val,(u32*)(M.mem_base + addr));
+#elif defined(IA64_UALOADS)
+ ustl(val,(u32*)(M.mem_base + addr));
#else
*(u32*)(M.mem_base + addr) = val;
#endif
@@ -408,7 +469,6 @@ Default PIO byte read function. Doesn't perform real inb.
static u8 X86API p_inb(
X86EMU_pioAddr addr)
{
- printf("No real inb\n");
DB( if (DEBUG_IO_TRACE())
printk("inb %#04x \n", addr);)
return 0;
@@ -425,7 +485,6 @@ Default PIO word read function. Doesn't perform real inw.
static u16 X86API p_inw(
X86EMU_pioAddr addr)
{
- printf("No real inw\n");
DB( if (DEBUG_IO_TRACE())
printk("inw %#04x \n", addr);)
return 0;
@@ -442,7 +501,6 @@ Default PIO long read function. Doesn't perform real inl.
static u32 X86API p_inl(
X86EMU_pioAddr addr)
{
- printf("No real inl\n");
DB( if (DEBUG_IO_TRACE())
printk("inl %#04x \n", addr);)
return 0;
@@ -459,7 +517,6 @@ static void X86API p_outb(
X86EMU_pioAddr addr,
u8 val)
{
- printf("No real outb\n");
DB( if (DEBUG_IO_TRACE())
printk("outb %#02x -> %#04x \n", val, addr);)
return;
@@ -476,7 +533,6 @@ static void X86API p_outw(
X86EMU_pioAddr addr,
u16 val)
{
- printf("No real outw\n");
DB( if (DEBUG_IO_TRACE())
printk("outw %#04x -> %#04x \n", val, addr);)
return;
@@ -493,7 +549,6 @@ static void X86API p_outl(
X86EMU_pioAddr addr,
u32 val)
{
- printf("No real outl\n");
DB( if (DEBUG_IO_TRACE())
printk("outl %#08x -> %#04x \n", val, addr);)
return;
diff --git a/src/x86emu/x86emu/x86emu.h b/src/x86emu/x86emu.h
index 8a83eed..795e2d6 100644
--- a/src/x86emu/x86emu/x86emu.h
+++ b/src/x86emu/x86emu.h
@@ -47,15 +47,17 @@
#define X86APIP _ASMAPIP
typedef int X86EMU_pioAddr;
#else
-#include "types.h"
+#include "x86emu/types.h"
#define X86API
#define X86APIP *
#endif
-#include "regs.h"
+#include "x86emu/regs.h"
/*---------------------- Macros and type definitions ----------------------*/
-/* #pragma pack(1) */ /* Don't pack structs with function pointers! */
+#ifdef PACK
+# pragma PACK /* Don't pack structs with function pointers! */
+#endif
/****************************************************************************
REMARKS:
@@ -128,8 +130,10 @@ extern u32 X86API rdl(u32 addr);
extern void X86API wrb(u32 addr, u8 val);
extern void X86API wrw(u32 addr, u16 val);
extern void X86API wrl(u32 addr, u32 val);
-
-/* #pragma pack() */
+
+#ifdef END_PACK
+# pragma END_PACK
+#endif
/*--------------------- type definitions -----------------------------------*/
@@ -168,6 +172,7 @@ void X86EMU_halt_sys(void);
#define DEBUG_DISASSEMBLE_F 0x000008
#define DEBUG_BREAK_F 0x000010
#define DEBUG_SVC_F 0x000020
+#define DEBUG_SAVE_IP_CS_F 0x000040
#define DEBUG_FS_F 0x000080
#define DEBUG_PROC_F 0x000100
#define DEBUG_SYSINT_F 0x000200 /* bios system interrupts. */
@@ -177,7 +182,7 @@ void X86EMU_halt_sys(void);
#define DEBUG_IO_TRACE_F 0x002000
#define DEBUG_TRACECALL_REGS_F 0x004000
#define DEBUG_DECODE_NOPRINT_F 0x008000
-#define DEBUG_SAVE_IP_CS_F 0x010000
+#define DEBUG_EXIT 0x010000
#define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
void X86EMU_trace_regs(void);
diff --git a/src/x86emu/x86emu/debug.h b/src/x86emu/x86emu/debug.h
index 0886a76..57f3546 100644
--- a/src/x86emu/x86emu/debug.h
+++ b/src/x86emu/x86emu/debug.h
@@ -101,12 +101,10 @@
#ifdef DEBUG
-# define DECODE_PRINTF(x) \
- if (DEBUG_DECODE()) \
+# define DECODE_PRINTF(x) if (DEBUG_DECODE()) \
x86emu_decode_printf(x)
-# define DECODE_PRINTF2(x,y) \
- if (DEBUG_DECODE()) \
+# define DECODE_PRINTF2(x,y) if (DEBUG_DECODE()) \
x86emu_decode_printf2(x,y)
/*
@@ -137,8 +135,8 @@
if (DEBUG_DISASSEMBLE()) { \
x86emu_just_disassemble(); \
goto EndOfTheInstructionProcedure; \
- } /*\
- if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()*/
+ } \
+ if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()
#else
# define TRACE_REGS()
#endif
diff --git a/src/x86emu/x86emu/fpu_regs.h b/src/x86emu/x86emu/fpu_regs.h
index f349f18..e59b807 100644
--- a/src/x86emu/x86emu/fpu_regs.h
+++ b/src/x86emu/x86emu/fpu_regs.h
@@ -41,6 +41,10 @@
#ifdef X86_FPU_SUPPORT
+#ifdef PACK
+# pragma PACK
+#endif
+
/* Basic 8087 register can hold any of the following values: */
union x86_fpu_reg_u {
@@ -85,6 +89,10 @@ struct x86_fpu_registers {
short x86_fpu_tos, x86_fpu_bos;
};
+#ifdef END_PACK
+# pragma END_PACK
+#endif
+
/*
* There are two versions of the following macro.
*
diff --git a/src/x86emu/x86emu/prim_ops.h b/src/x86emu/x86emu/prim_ops.h
index f9f87eb..d4441c7 100644
--- a/src/x86emu/x86emu/prim_ops.h
+++ b/src/x86emu/x86emu/prim_ops.h
@@ -135,6 +135,7 @@ void push_word (u16 w);
void push_long (u32 w);
u16 pop_word (void);
u32 pop_long (void);
+void cpuid (void);
#if defined(__HAVE_INLINE_ASSEMBLER__) && !defined(PRIM_OPS_NO_REDEFINE_ASM)
diff --git a/src/x86emu/x86emu/prim_x86_gcc.h b/src/x86emu/x86emu/prim_x86_gcc.h
new file mode 100644
index 0000000..af61e20
--- /dev/null
+++ b/src/x86emu/x86emu/prim_x86_gcc.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+*
+* Inline helpers for x86emu
+*
+* Copyright (C) 2008 Bart Trojanowski, Symbio Technologies, LLC
+*
+* ========================================================================
+*
+* Permission to use, copy, modify, distribute, and sell this software and
+* its documentation for any purpose is hereby granted without fee,
+* provided that the above copyright notice appear in all copies and that
+* both that copyright notice and this permission notice appear in
+* supporting documentation, and that the name of the authors not be used
+* in advertising or publicity pertaining to distribution of the software
+* without specific, written prior permission. The authors makes no
+* representations about the suitability of this software for any purpose.
+* It is provided "as is" without express or implied warranty.
+*
+* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*
+* ========================================================================
+*
+* Language: GNU C
+* Environment: GCC on i386 or x86-64
+* Developer: Bart Trojanowski
+*
+* Description: This file defines a few x86 macros that can be used by the
+* emulator to execute native instructions.
+*
+* For PIC vs non-PIC code refer to:
+* http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well
+*
+****************************************************************************/
+#ifndef __X86EMU_PRIM_X86_GCC_H
+#define __X86EMU_PRIM_X86_GCC_H
+
+#include "x86emu/types.h"
+
+#if !defined(__GNUC__) || !(defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__))
+#error This file is intended to be used by gcc on i386 or x86-64 system
+#endif
+
+#if defined(__PIC__) && defined(__i386__)
+
+#define X86EMU_HAS_HW_CPUID 1
+static inline void hw_cpuid (u32 *a, u32 *b, u32 *c, u32 *d)
+{
+ __asm__ __volatile__ ("pushl %%ebx \n\t"
+ "cpuid \n\t"
+ "movl %%ebx, %1 \n\t"
+ "popl %%ebx \n\t"
+ : "=a" (*a), "=r" (*b),
+ "=c" (*c), "=d" (*d)
+ : "a" (*a), "c" (*c)
+ : "cc");
+}
+
+#else // ! (__PIC__ && __i386__)
+
+#define x86EMU_HAS_HW_CPUID 1
+static inline void hw_cpuid (u32 *a, u32 *b, u32 *c, u32 *d)
+{
+ __asm__ __volatile__ ("cpuid"
+ : "=a" (*a), "=b" (*b),
+ "=c" (*c), "=d" (*d)
+ : "a" (*a), "c" (*c)
+ : "cc");
+}
+
+#endif // __PIC__ && __i386__
+
+
+#endif // __X86EMU_PRIM_X86_GCC_H
diff --git a/src/x86emu/x86emu/regs.h b/src/x86emu/x86emu/regs.h
index 46d9f12..52cf8e4 100644
--- a/src/x86emu/x86emu/regs.h
+++ b/src/x86emu/x86emu/regs.h
@@ -41,6 +41,10 @@
/*---------------------- Macros and type definitions ----------------------*/
+#ifdef PACK
+# pragma PACK
+#endif
+
/*
* General EAX, EBX, ECX, EDX type registers. Note that for
* portability, and speed, the issue of byte swapping is not addressed
@@ -302,6 +306,10 @@ typedef struct {
X86EMU_regs x86;
} X86EMU_sysEnv;
+#ifdef END_PACK
+# pragma END_PACK
+#endif
+
/*----------------------------- Global Variables --------------------------*/
#ifdef __cplusplus
diff --git a/src/x86emu/x86emu/types.h b/src/x86emu/x86emu/types.h
index c2b5dab..c0c09c1 100644
--- a/src/x86emu/x86emu/types.h
+++ b/src/x86emu/x86emu/types.h
@@ -40,7 +40,7 @@
#ifndef __X86EMU_TYPES_H
#define __X86EMU_TYPES_H
-#ifndef IN_MODULE
+#ifndef NO_SYS_HEADERS
#include <sys/types.h>
#endif
diff --git a/src/x86emu/x86emu/x86emui.h b/src/x86emu/x86emu/x86emui.h
index ed82604..112ee36 100644
--- a/src/x86emu/x86emu/x86emui.h
+++ b/src/x86emu/x86emu/x86emui.h
@@ -62,17 +62,15 @@
#endif
#include "x86emu.h"
-#include "regs.h"
-#include "debug.h"
-#include "decode.h"
-#include "ops.h"
-#include "prim_ops.h"
-#include "fpu.h"
-#include "fpu_regs.h"
+#include "x86emu/regs.h"
+#include "x86emu/debug.h"
+#include "x86emu/decode.h"
+#include "x86emu/ops.h"
+#include "x86emu/prim_ops.h"
+#include "x86emu/fpu.h"
+#include "x86emu/fpu_regs.h"
-#ifdef IN_MODULE
-#include <xf86_ansic.h>
-#else
+#ifndef NO_SYS_HEADERS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>