Fix FPA condition codes (Ulrich Hecht).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1784 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
b55669bf57
commit
19b045dec9
@ -345,7 +345,7 @@ void cpu_loop(CPUARMState *env)
|
|||||||
/* we get the opcode */
|
/* we get the opcode */
|
||||||
opcode = ldl_raw((uint8_t *)env->regs[15]);
|
opcode = ldl_raw((uint8_t *)env->regs[15]);
|
||||||
|
|
||||||
if (EmulateAll(opcode, &ts->fpa, env->regs) == 0) {
|
if (EmulateAll(opcode, &ts->fpa, env) == 0) {
|
||||||
info.si_signo = SIGILL;
|
info.si_signo = SIGILL;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
info.si_code = TARGET_ILL_ILLOPN;
|
info.si_code = TARGET_ILL_ILLOPN;
|
||||||
|
@ -36,7 +36,7 @@ unsigned int EmulateCPDT(const unsigned int);
|
|||||||
unsigned int EmulateCPRT(const unsigned int);
|
unsigned int EmulateCPRT(const unsigned int);
|
||||||
|
|
||||||
FPA11* qemufpa=0;
|
FPA11* qemufpa=0;
|
||||||
unsigned int* user_registers=0;
|
CPUARMState* user_registers;
|
||||||
|
|
||||||
/* Reset the FPA11 chip. Called to initialize and reset the emulator. */
|
/* Reset the FPA11 chip. Called to initialize and reset the emulator. */
|
||||||
void resetFPA11(void)
|
void resetFPA11(void)
|
||||||
@ -137,7 +137,8 @@ void SetRoundingPrecision(const unsigned int opcode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Emulate the instruction in the opcode. */
|
/* Emulate the instruction in the opcode. */
|
||||||
unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, unsigned int* qregs)
|
/* ??? This is not thread safe. */
|
||||||
|
unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
|
||||||
{
|
{
|
||||||
unsigned int nRc = 0;
|
unsigned int nRc = 0;
|
||||||
// unsigned long flags;
|
// unsigned long flags;
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
#define GET_FPA11() (qemufpa)
|
#define GET_FPA11() (qemufpa)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -33,7 +35,7 @@
|
|||||||
* stack+task struct. Use the same method as 'current' uses to
|
* stack+task struct. Use the same method as 'current' uses to
|
||||||
* reach them.
|
* reach them.
|
||||||
*/
|
*/
|
||||||
extern unsigned int *user_registers;
|
extern CPUARMState *user_registers;
|
||||||
|
|
||||||
#define GET_USERREG() (user_registers)
|
#define GET_USERREG() (user_registers)
|
||||||
|
|
||||||
@ -94,7 +96,7 @@ extern void SetRoundingPrecision(const unsigned int);
|
|||||||
|
|
||||||
static inline unsigned int readRegister(unsigned int reg)
|
static inline unsigned int readRegister(unsigned int reg)
|
||||||
{
|
{
|
||||||
return (user_registers[(reg)]);
|
return (user_registers->regs[(reg)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void writeRegister(unsigned int x, unsigned int y)
|
static inline void writeRegister(unsigned int x, unsigned int y)
|
||||||
@ -102,34 +104,17 @@ static inline void writeRegister(unsigned int x, unsigned int y)
|
|||||||
#if 0
|
#if 0
|
||||||
printf("writing %d to r%d\n",y,x);
|
printf("writing %d to r%d\n",y,x);
|
||||||
#endif
|
#endif
|
||||||
user_registers[(x)]=(y);
|
user_registers->regs[(x)]=(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void writeConditionCodes(unsigned int x)
|
static inline void writeConditionCodes(unsigned int x)
|
||||||
{
|
{
|
||||||
#if 0
|
cpsr_write(user_registers,x,CPSR_NZCV);
|
||||||
unsigned int y;
|
|
||||||
unsigned int ZF;
|
|
||||||
printf("setting flags to %x from %x\n",x,user_registers[16]);
|
|
||||||
#endif
|
|
||||||
user_registers[16]=(x); // cpsr
|
|
||||||
user_registers[17]=(x>>29)&1; // cf
|
|
||||||
user_registers[18]=(x<<3)&(1<<31); // vf
|
|
||||||
user_registers[19]=x&(1<<31); // nzf
|
|
||||||
if(!(x&(1<<30))) user_registers[19]++; // nzf must be non-zero for zf to be cleared
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
ZF = (user_registers[19] == 0);
|
|
||||||
y=user_registers[16] | (user_registers[19] & 0x80000000) | (ZF << 30) |
|
|
||||||
(user_registers[17] << 29) | ((user_registers[18] & 0x80000000) >> 3);
|
|
||||||
if(y != x)
|
|
||||||
printf("GODDAM SHIIIIIIIIIIIIIIIIT! %x %x nzf %x zf %x\n",x,y,user_registers[19],ZF);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REG_PC 15
|
#define REG_PC 15
|
||||||
|
|
||||||
unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, unsigned int* qregs);
|
unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs);
|
||||||
|
|
||||||
/* included only for get_user/put_user macros */
|
/* included only for get_user/put_user macros */
|
||||||
#include "qemu.h"
|
#include "qemu.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user