1#include "sim-main.h"
2#include "targ-vals.h"
3
4#ifdef HAVE_UTIME_H
5#include <utime.h>
6#endif
7
8#ifdef HAVE_TIME_H
9#include <time.h>
10#endif
11
12#ifdef HAVE_UNISTD_H
13#include <unistd.h>
14#endif
15
16#ifdef HAVE_STRING_H
17#include <string.h>
18#else
19#ifdef HAVE_STRINGS_H
20#include <strings.h>
21#endif
22#endif
23#include <sys/stat.h>
24#include <sys/times.h>
25#include <sys/time.h>
26
27
28
29#define REG0(X) ((X) & 0x3)
30#define REG1(X) (((X) & 0xc) >> 2)
31#define REG0_4(X) (((X) & 0x30) >> 4)
32#define REG0_8(X) (((X) & 0x300) >> 8)
33#define REG1_8(X) (((X) & 0xc00) >> 10)
34#define REG0_16(X) (((X) & 0x30000) >> 16)
35#define REG1_16(X) (((X) & 0xc0000) >> 18)
36
37
38INLINE_SIM_MAIN (void)
39genericAdd(unsigned32 source, unsigned32 destReg)
40{
41  int z, c, n, v;
42  unsigned32 dest, sum;
43
44  dest = State.regs[destReg];
45  sum = source + dest;
46  State.regs[destReg] = sum;
47
48  z = (sum == 0);
49  n = (sum & 0x80000000);
50  c = (sum < source) || (sum < dest);
51  v = ((dest & 0x80000000) == (source & 0x80000000)
52       && (dest & 0x80000000) != (sum & 0x80000000));
53
54  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
55  PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
56	  | (c ? PSW_C : 0) | (v ? PSW_V : 0));
57}
58
59
60
61
62INLINE_SIM_MAIN (void)
63genericSub(unsigned32 source, unsigned32 destReg)
64{
65  int z, c, n, v;
66  unsigned32 dest, difference;
67
68  dest = State.regs[destReg];
69  difference = dest - source;
70  State.regs[destReg] = difference;
71
72  z = (difference == 0);
73  n = (difference & 0x80000000);
74  c = (source > dest);
75  v = ((dest & 0x80000000) != (source & 0x80000000)
76       && (dest & 0x80000000) != (difference & 0x80000000));
77
78  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
79  PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
80	  | (c ? PSW_C : 0) | (v ? PSW_V : 0));
81}
82
83INLINE_SIM_MAIN (void)
84genericCmp(unsigned32 leftOpnd, unsigned32 rightOpnd)
85{
86  int z, c, n, v;
87  unsigned32 value;
88
89  value = rightOpnd - leftOpnd;
90
91  z = (value == 0);
92  n = (value & 0x80000000);
93  c = (leftOpnd > rightOpnd);
94  v = ((rightOpnd & 0x80000000) != (leftOpnd & 0x80000000)
95       && (rightOpnd & 0x80000000) != (value & 0x80000000));
96
97  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
98  PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
99	  | (c ? PSW_C : 0) | (v ? PSW_V : 0));
100}
101
102
103INLINE_SIM_MAIN (void)
104genericOr(unsigned32 source, unsigned32 destReg)
105{
106  int n, z;
107
108  State.regs[destReg] |= source;
109  z = (State.regs[destReg] == 0);
110  n = (State.regs[destReg] & 0x80000000) != 0;
111  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
112  PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
113}
114
115
116INLINE_SIM_MAIN (void)
117genericXor(unsigned32 source, unsigned32 destReg)
118{
119  int n, z;
120
121  State.regs[destReg] ^= source;
122  z = (State.regs[destReg] == 0);
123  n = (State.regs[destReg] & 0x80000000) != 0;
124  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
125  PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
126}
127
128
129INLINE_SIM_MAIN (void)
130genericBtst(unsigned32 leftOpnd, unsigned32 rightOpnd)
131{
132  unsigned32 temp;
133  int z, n;
134
135  temp = rightOpnd;
136  temp &= leftOpnd;
137  n = (temp & 0x80000000) != 0;
138  z = (temp == 0);
139  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
140  PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0);
141}
142
143/* Read/write functions for system call interface.  */
144INLINE_SIM_MAIN (int)
145syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
146		  unsigned long taddr, char *buf, int bytes)
147{
148  SIM_DESC sd = (SIM_DESC) sc->p1;
149  sim_cpu *cpu = STATE_CPU(sd, 0);
150
151  return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
152}
153
154INLINE_SIM_MAIN (int)
155syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
156		   unsigned long taddr, const char *buf, int bytes)
157{
158  SIM_DESC sd = (SIM_DESC) sc->p1;
159  sim_cpu *cpu = STATE_CPU(sd, 0);
160
161  return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
162}
163
164
165/* syscall */
166INLINE_SIM_MAIN (void)
167do_syscall (void)
168{
169
170  /* We use this for simulated system calls; we may need to change
171     it to a reserved instruction if we conflict with uses at
172     Matsushita.  */
173  int save_errno = errno;
174  errno = 0;
175
176/* Registers passed to trap 0 */
177
178/* Function number.  */
179#define FUNC   (State.regs[0])
180
181/* Parameters.  */
182#define PARM1   (State.regs[1])
183#define PARM2   (load_word (State.regs[REG_SP] + 12))
184#define PARM3   (load_word (State.regs[REG_SP] + 16))
185
186/* Registers set by trap 0 */
187
188#define RETVAL State.regs[0]	/* return value */
189#define RETERR State.regs[1]	/* return error code */
190
191/* Turn a pointer in a register into a pointer into real memory. */
192#define MEMPTR(x) (State.mem + x)
193
194  if ( FUNC == TARGET_SYS_exit )
195    {
196      /* EXIT - caller can look in PARM1 to work out the reason */
197      if (PARM1 == 0xdead)
198	State.exception = SIGABRT;
199      else
200	{
201	  sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
202			   sim_exited, PARM1);
203	  State.exception = SIGQUIT;
204	}
205      State.exited = 1;
206    }
207  else
208    {
209      CB_SYSCALL syscall;
210
211      CB_SYSCALL_INIT (&syscall);
212      syscall.arg1 = PARM1;
213      syscall.arg2 = PARM2;
214      syscall.arg3 = PARM3;
215      syscall.func = FUNC;
216      syscall.p1 = (PTR) simulator;
217      syscall.read_mem = syscall_read_mem;
218      syscall.write_mem = syscall_write_mem;
219      cb_syscall (STATE_CALLBACK (simulator), &syscall);
220      RETERR = syscall.errcode;
221      RETVAL = syscall.result;
222    }
223
224
225  errno = save_errno;
226}
227
228