mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-30 12:44:10 +08:00
6df01ab8ab
The defs.h header will take care of including the various config.h headers. For now, it's just config.h, but we'll add more when we integrate gnulib in. This header should be used instead of config.h, and should be the first include in every .c file. We won't rely on the old behavior where we expected files to include the port's sim-main.h which then includes the common sim-basics.h which then includes config.h. We have a ton of code that includes things before sim-main.h, and it sometimes needs to be that way. Creating a dedicated header avoids the ordering mess and implicit inclusion that shows up otherwise.
173 lines
4.0 KiB
C
173 lines
4.0 KiB
C
/* This must come before any other includes. */
|
|
#include "defs.h"
|
|
|
|
#include "sim-main.h"
|
|
#include "sim-syscall.h"
|
|
#include "targ-vals.h"
|
|
|
|
#include <time.h>
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
#define REG0(X) ((X) & 0x3)
|
|
#define REG1(X) (((X) & 0xc) >> 2)
|
|
#define REG0_4(X) (((X) & 0x30) >> 4)
|
|
#define REG0_8(X) (((X) & 0x300) >> 8)
|
|
#define REG1_8(X) (((X) & 0xc00) >> 10)
|
|
#define REG0_16(X) (((X) & 0x30000) >> 16)
|
|
#define REG1_16(X) (((X) & 0xc0000) >> 18)
|
|
|
|
|
|
INLINE_SIM_MAIN (void)
|
|
genericAdd(unsigned32 source, unsigned32 destReg)
|
|
{
|
|
int z, c, n, v;
|
|
unsigned32 dest, sum;
|
|
|
|
dest = State.regs[destReg];
|
|
sum = source + dest;
|
|
State.regs[destReg] = sum;
|
|
|
|
z = (sum == 0);
|
|
n = (sum & 0x80000000);
|
|
c = (sum < source) || (sum < dest);
|
|
v = ((dest & 0x80000000) == (source & 0x80000000)
|
|
&& (dest & 0x80000000) != (sum & 0x80000000));
|
|
|
|
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
|
|
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
|
|
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
|
|
}
|
|
|
|
|
|
|
|
|
|
INLINE_SIM_MAIN (void)
|
|
genericSub(unsigned32 source, unsigned32 destReg)
|
|
{
|
|
int z, c, n, v;
|
|
unsigned32 dest, difference;
|
|
|
|
dest = State.regs[destReg];
|
|
difference = dest - source;
|
|
State.regs[destReg] = difference;
|
|
|
|
z = (difference == 0);
|
|
n = (difference & 0x80000000);
|
|
c = (source > dest);
|
|
v = ((dest & 0x80000000) != (source & 0x80000000)
|
|
&& (dest & 0x80000000) != (difference & 0x80000000));
|
|
|
|
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
|
|
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
|
|
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
|
|
}
|
|
|
|
INLINE_SIM_MAIN (void)
|
|
genericCmp(unsigned32 leftOpnd, unsigned32 rightOpnd)
|
|
{
|
|
int z, c, n, v;
|
|
unsigned32 value;
|
|
|
|
value = rightOpnd - leftOpnd;
|
|
|
|
z = (value == 0);
|
|
n = (value & 0x80000000);
|
|
c = (leftOpnd > rightOpnd);
|
|
v = ((rightOpnd & 0x80000000) != (leftOpnd & 0x80000000)
|
|
&& (rightOpnd & 0x80000000) != (value & 0x80000000));
|
|
|
|
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
|
|
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
|
|
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
|
|
}
|
|
|
|
|
|
INLINE_SIM_MAIN (void)
|
|
genericOr(unsigned32 source, unsigned32 destReg)
|
|
{
|
|
int n, z;
|
|
|
|
State.regs[destReg] |= source;
|
|
z = (State.regs[destReg] == 0);
|
|
n = (State.regs[destReg] & 0x80000000) != 0;
|
|
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
|
|
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
|
|
}
|
|
|
|
|
|
INLINE_SIM_MAIN (void)
|
|
genericXor(unsigned32 source, unsigned32 destReg)
|
|
{
|
|
int n, z;
|
|
|
|
State.regs[destReg] ^= source;
|
|
z = (State.regs[destReg] == 0);
|
|
n = (State.regs[destReg] & 0x80000000) != 0;
|
|
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
|
|
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
|
|
}
|
|
|
|
|
|
INLINE_SIM_MAIN (void)
|
|
genericBtst(unsigned32 leftOpnd, unsigned32 rightOpnd)
|
|
{
|
|
unsigned32 temp;
|
|
int z, n;
|
|
|
|
temp = rightOpnd;
|
|
temp &= leftOpnd;
|
|
n = (temp & 0x80000000) != 0;
|
|
z = (temp == 0);
|
|
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
|
|
PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0);
|
|
}
|
|
|
|
/* syscall */
|
|
INLINE_SIM_MAIN (void)
|
|
do_syscall (void)
|
|
{
|
|
/* Registers passed to trap 0. */
|
|
|
|
/* Function number. */
|
|
reg_t func = State.regs[0];
|
|
/* Parameters. */
|
|
reg_t parm1 = State.regs[1];
|
|
reg_t parm2 = load_word (State.regs[REG_SP] + 12);
|
|
reg_t parm3 = load_word (State.regs[REG_SP] + 16);
|
|
reg_t parm4 = load_word (State.regs[REG_SP] + 20);
|
|
|
|
/* We use this for simulated system calls; we may need to change
|
|
it to a reserved instruction if we conflict with uses at
|
|
Matsushita. */
|
|
int save_errno = errno;
|
|
errno = 0;
|
|
|
|
if (func == TARGET_SYS_exit)
|
|
{
|
|
/* EXIT - caller can look in parm1 to work out the reason */
|
|
sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
|
|
(parm1 == 0xdead ? SIM_SIGABRT : sim_exited), parm1);
|
|
}
|
|
else
|
|
{
|
|
long result, result2;
|
|
int errcode;
|
|
|
|
sim_syscall_multi (STATE_CPU (simulator, 0), func, parm1, parm2,
|
|
parm3, parm4, &result, &result2, &errcode);
|
|
|
|
/* Registers set by trap 0. */
|
|
State.regs[0] = errcode;
|
|
State.regs[1] = result;
|
|
}
|
|
|
|
errno = save_errno;
|
|
}
|