Skip to content

Commit

Permalink
MMX/SSE support
Browse files Browse the repository at this point in the history
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1205 c046a42c-6fe2-441c-8c8c-71466251a162
  • Loading branch information
bellard committed Jan 8, 2005
1 parent 085339a commit 664e0f1
Show file tree
Hide file tree
Showing 12 changed files with 2,402 additions and 171 deletions.
1 change: 1 addition & 0 deletions Changelog
Expand Up @@ -11,6 +11,7 @@ version 0.6.2:
- added generic 64 bit target support
- initial x86_64 target support
- initial APIC support
- MMX/SSE/SSE2/PNI support

version 0.6.1:

Expand Down
2 changes: 1 addition & 1 deletion Makefile.target
Expand Up @@ -392,7 +392,7 @@ helper.o: helper.c
$(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<

ifeq ($(TARGET_BASE_ARCH), i386)
op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h
op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h ops_sse.h
endif

ifeq ($(TARGET_ARCH), arm)
Expand Down
4 changes: 2 additions & 2 deletions linux-user/main.c
Expand Up @@ -1052,8 +1052,8 @@ int main(int argc, char **argv)
cpu_x86_set_cpl(env, 3);

env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
env->hflags |= HF_PE_MASK;

env->hflags |= HF_PE_MASK | HF_OSFXSR_MASK;
/* flags setup : we activate the IRQs by default as in user mode */
env->eflags |= IF_MASK;

Expand Down
30 changes: 24 additions & 6 deletions target-i386/cpu.h
Expand Up @@ -135,6 +135,7 @@
#define HF_IOPL_SHIFT 12 /* must be same as eflags */
#define HF_LMA_SHIFT 14 /* only used on x86_64: long mode active */
#define HF_CS64_SHIFT 15 /* only used on x86_64: 64 bit code segment */
#define HF_OSFXSR_SHIFT 16 /* CR4.OSFXSR */
#define HF_VM_SHIFT 17 /* must be same as eflags */

#define HF_CPL_MASK (3 << HF_CPL_SHIFT)
Expand All @@ -150,6 +151,7 @@
#define HF_TS_MASK (1 << HF_TS_SHIFT)
#define HF_LMA_MASK (1 << HF_LMA_SHIFT)
#define HF_CS64_MASK (1 << HF_CS64_SHIFT)
#define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT)

#define CR0_PE_MASK (1 << 0)
#define CR0_MP_MASK (1 << 1)
Expand Down Expand Up @@ -340,10 +342,12 @@ typedef struct SegmentCache {
} SegmentCache;

typedef union {
uint8_t _b[16];
uint16_t _w[8];
uint32_t _l[4];
uint64_t _q[2];
uint8_t _b[16];
uint16_t _w[8];
uint32_t _l[4];
uint64_t _q[2];
float _s[4];
double _d[2];
} XMMReg;

typedef union {
Expand All @@ -357,7 +361,9 @@ typedef union {
#define XMM_B(n) _b[15 - (n)]
#define XMM_W(n) _w[7 - (n)]
#define XMM_L(n) _l[3 - (n)]
#define XMM_S(n) _s[3 - (n)]
#define XMM_Q(n) _q[1 - (n)]
#define XMM_D(n) _d[1 - (n)]

#define MMX_B(n) _b[7 - (n)]
#define MMX_W(n) _w[3 - (n)]
Expand All @@ -366,12 +372,15 @@ typedef union {
#define XMM_B(n) _b[n]
#define XMM_W(n) _w[n]
#define XMM_L(n) _l[n]
#define XMM_S(n) _s[n]
#define XMM_Q(n) _q[n]
#define XMM_D(n) _d[n]

#define MMX_B(n) _b[n]
#define MMX_W(n) _w[n]
#define MMX_L(n) _l[n]
#endif
#define MMX_Q(n) q

#ifdef TARGET_X86_64
#define CPU_NB_REGS 16
Expand Down Expand Up @@ -404,7 +413,14 @@ typedef struct CPUX86State {
unsigned int fpus;
unsigned int fpuc;
uint8_t fptags[8]; /* 0 = valid, 1 = empty */
CPU86_LDouble fpregs[8];
union {
#ifdef USE_X86LDOUBLE
CPU86_LDouble d __attribute__((aligned(16)));
#else
CPU86_LDouble d;
#endif
MMXReg mmx;
} fpregs[8];

/* emulator internal variables */
CPU86_LDouble ft0;
Expand All @@ -421,9 +437,11 @@ typedef struct CPUX86State {
SegmentCache tr;
SegmentCache gdt; /* only base and limit are used */
SegmentCache idt; /* only base and limit are used */


uint32_t mxcsr;
XMMReg xmm_regs[CPU_NB_REGS];
XMMReg xmm_t0;
MMXReg mmx_t0;

/* sysenter registers */
uint32_t sysenter_cs;
Expand Down
9 changes: 6 additions & 3 deletions target-i386/exec.h
Expand Up @@ -131,8 +131,8 @@ extern int loglevel;

/* float macros */
#define FT0 (env->ft0)
#define ST0 (env->fpregs[env->fpstt])
#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7])
#define ST0 (env->fpregs[env->fpstt].d)
#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
#define ST1 ST(1)

#ifdef USE_FP_CONVERT
Expand Down Expand Up @@ -459,7 +459,7 @@ static inline CPU86_LDouble helper_fldt(target_ulong ptr)
return temp.d;
}

static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
{
CPU86_LDoubleU temp;
int e;
Expand Down Expand Up @@ -557,6 +557,9 @@ void helper_fxsave(target_ulong ptr, int data64);
void helper_fxrstor(target_ulong ptr, int data64);
void restore_native_fp_state(CPUState *env);
void save_native_fp_state(CPUState *env);
float approx_rsqrt(float a);
float approx_rcp(float a);
int fpu_isnan(double a);

extern const uint8_t parity_table[256];
extern const uint8_t rclw_table[32];
Expand Down
26 changes: 22 additions & 4 deletions target-i386/helper.c
Expand Up @@ -2444,7 +2444,7 @@ void helper_fldt_ST0_A0(void)
{
int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
env->fpregs[new_fpstt] = helper_fldt(A0);
env->fpregs[new_fpstt].d = helper_fldt(A0);
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
}
Expand Down Expand Up @@ -2804,9 +2804,10 @@ void helper_fstenv(target_ulong ptr, int data32)
if (env->fptags[i]) {
fptag |= 3;
} else {
tmp.d = env->fpregs[i];
tmp.d = env->fpregs[i].d;
exp = EXPD(tmp);
mant = MANTD(tmp);
printf("mant=%llx exp=%x\n", mant, exp);
if (exp == 0 && mant == 0) {
/* zero */
fptag |= 1;
Expand Down Expand Up @@ -2930,7 +2931,7 @@ void helper_fxsave(target_ulong ptr, int data64)

if (env->cr[4] & CR4_OSFXSR_MASK) {
/* XXX: finish it */
stl(ptr + 0x18, 0); /* mxcsr */
stl(ptr + 0x18, env->mxcsr); /* mxcsr */
stl(ptr + 0x1c, 0); /* mxcsr_mask */
nb_xmm_regs = 8 << data64;
addr = ptr + 0xa0;
Expand Down Expand Up @@ -2967,7 +2968,7 @@ void helper_fxrstor(target_ulong ptr, int data64)

if (env->cr[4] & CR4_OSFXSR_MASK) {
/* XXX: finish it, endianness */
//ldl(ptr + 0x18);
env->mxcsr = ldl(ptr + 0x18);
//ldl(ptr + 0x1c);
nb_xmm_regs = 8 << data64;
addr = ptr + 0xa0;
Expand Down Expand Up @@ -3209,6 +3210,23 @@ void helper_idivq_EAX_T0(void)

#endif

/* XXX: do it */
int fpu_isnan(double a)
{
return 0;
}

float approx_rsqrt(float a)
{
return 1.0 / sqrt(a);
}

float approx_rcp(float a)
{
return 1.0 / a;
}


#if !defined(CONFIG_USER_ONLY)

#define MMUSUFFIX _mmu
Expand Down
30 changes: 20 additions & 10 deletions target-i386/helper2.c
Expand Up @@ -158,6 +158,8 @@ void cpu_reset(CPUX86State *env)
for(i = 0;i < 8; i++)
env->fptags[i] = 1;
env->fpuc = 0x37f;

env->mxcsr = 0x1f80;
}

void cpu_x86_close(CPUX86State *env)
Expand Down Expand Up @@ -376,15 +378,15 @@ void cpu_dump_state(CPUState *env, FILE *f,
}
if (flags & X86_DUMP_FPU) {
cpu_fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n",
(double)env->fpregs[0],
(double)env->fpregs[1],
(double)env->fpregs[2],
(double)env->fpregs[3]);
(double)env->fpregs[0].d,
(double)env->fpregs[1].d,
(double)env->fpregs[2].d,
(double)env->fpregs[3].d);
cpu_fprintf(f, "ST4=%f ST5=%f ST6=%f ST7=%f\n",
(double)env->fpregs[4],
(double)env->fpregs[5],
(double)env->fpregs[7],
(double)env->fpregs[8]);
(double)env->fpregs[4].d,
(double)env->fpregs[5].d,
(double)env->fpregs[7].d,
(double)env->fpregs[8].d);
}
}

Expand Down Expand Up @@ -471,6 +473,14 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
(env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
tlb_flush(env, 1);
}
/* SSE handling */
if (!(env->cpuid_features & CPUID_SSE))
new_cr4 &= ~CR4_OSFXSR_MASK;
if (new_cr4 & CR4_OSFXSR_MASK)
env->hflags |= HF_OSFXSR_MASK;
else
env->hflags &= ~HF_OSFXSR_MASK;

env->cr[4] = new_cr4;
}

Expand Down Expand Up @@ -800,7 +810,7 @@ void restore_native_fp_state(CPUState *env)
fp->fptag = fptag;
j = env->fpstt;
for(i = 0;i < 8; i++) {
memcpy(&fp->fpregs1[i * 10], &env->fpregs[j], 10);
memcpy(&fp->fpregs1[i * 10], &env->fpregs[j].d, 10);
j = (j + 1) & 7;
}
asm volatile ("frstor %0" : "=m" (*fp));
Expand All @@ -824,7 +834,7 @@ void save_native_fp_state(CPUState *env)
}
j = env->fpstt;
for(i = 0;i < 8; i++) {
memcpy(&env->fpregs[j], &fp->fpregs1[i * 10], 10);
memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 10], 10);
j = (j + 1) & 7;
}
/* we must restore the default rounding state */
Expand Down

0 comments on commit 664e0f1

Please sign in to comment.