compile.c revision 1.1.1.3 1 1.1 christos /*
2 1.1 christos * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
3 1.1 christos *
4 1.1 christos * Written by Steve Chamberlain of Cygnus Support. sac (at) cygnus.com
5 1.1 christos *
6 1.1 christos * This file is part of H8/300 sim
7 1.1 christos *
8 1.1 christos *
9 1.1 christos * THIS SOFTWARE IS NOT COPYRIGHTED
10 1.1 christos *
11 1.1 christos * Cygnus offers the following for use in the public domain. Cygnus makes no
12 1.1 christos * warranty with regard to the software or its performance and the user
13 1.1 christos * accepts the software "AS IS" with all faults.
14 1.1 christos *
15 1.1 christos * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
16 1.1 christos * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17 1.1 christos * AND FITNESS FOR A PARTICULAR PURPOSE.
18 1.1 christos */
19 1.1 christos
20 1.1 christos #include "config.h"
21 1.1 christos #include <signal.h>
22 1.1 christos #ifdef HAVE_TIME_H
23 1.1 christos #include <time.h>
24 1.1 christos #endif
25 1.1 christos #ifdef HAVE_STDLIB_H
26 1.1 christos #include <stdlib.h>
27 1.1 christos #endif
28 1.1 christos #ifdef HAVE_SYS_PARAM_H
29 1.1 christos #include <sys/param.h>
30 1.1 christos #endif
31 1.1 christos
32 1.1 christos #include "bfd.h"
33 1.1 christos #include "sim-main.h"
34 1.1 christos #include "gdb/sim-h8300.h"
35 1.1 christos #include "sys/stat.h"
36 1.1 christos #include "sys/types.h"
37 1.1.1.3 christos #include "sim-options.h"
38 1.1 christos
39 1.1 christos #ifndef SIGTRAP
40 1.1 christos # define SIGTRAP 5
41 1.1 christos #endif
42 1.1 christos
43 1.1 christos int debug;
44 1.1 christos
45 1.1 christos host_callback *sim_callback;
46 1.1 christos
47 1.1 christos static SIM_OPEN_KIND sim_kind;
48 1.1 christos static char *myname;
49 1.1 christos
50 1.1 christos /* FIXME: Needs to live in header file.
51 1.1 christos This header should also include the things in remote-sim.h.
52 1.1 christos One could move this to remote-sim.h but this function isn't needed
53 1.1 christos by gdb. */
54 1.1 christos static void set_simcache_size (SIM_DESC, int);
55 1.1 christos
56 1.1 christos #define X(op, size) (op * 4 + size)
57 1.1 christos
58 1.1 christos #define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
59 1.1 christos
60 1.1 christos #define h8_opcodes ops
61 1.1 christos #define DEFINE_TABLE
62 1.1 christos #include "opcode/h8300.h"
63 1.1 christos
64 1.1 christos /* CPU data object: */
65 1.1 christos
66 1.1 christos static int
67 1.1 christos sim_state_initialize (SIM_DESC sd, sim_cpu *cpu)
68 1.1 christos {
69 1.1 christos /* FIXME: not really necessary, since sim_cpu_alloc calls zalloc. */
70 1.1 christos
71 1.1 christos memset (&cpu->regs, 0, sizeof(cpu->regs));
72 1.1 christos cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
73 1.1 christos cpu->pc = 0;
74 1.1 christos cpu->delayed_branch = 0;
75 1.1 christos cpu->memory = NULL;
76 1.1 christos cpu->eightbit = NULL;
77 1.1 christos cpu->mask = 0;
78 1.1 christos
79 1.1 christos /* Initialize local simulator state. */
80 1.1 christos sd->sim_cache = NULL;
81 1.1 christos sd->sim_cache_size = 0;
82 1.1 christos sd->cache_idx = NULL;
83 1.1 christos sd->cache_top = 0;
84 1.1 christos sd->memory_size = 0;
85 1.1 christos sd->compiles = 0;
86 1.1 christos #ifdef ADEBUG
87 1.1 christos memset (&cpu->stats, 0, sizeof (cpu->stats));
88 1.1 christos #endif
89 1.1 christos return 0;
90 1.1 christos }
91 1.1 christos
92 1.1 christos static unsigned int
93 1.1 christos h8_get_pc (SIM_DESC sd)
94 1.1 christos {
95 1.1 christos return (STATE_CPU (sd, 0)) -> pc;
96 1.1 christos }
97 1.1 christos
98 1.1 christos static void
99 1.1 christos h8_set_pc (SIM_DESC sd, unsigned int val)
100 1.1 christos {
101 1.1 christos (STATE_CPU (sd, 0)) -> pc = val;
102 1.1 christos }
103 1.1 christos
104 1.1 christos static unsigned int
105 1.1 christos h8_get_ccr (SIM_DESC sd)
106 1.1 christos {
107 1.1 christos return (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM];
108 1.1 christos }
109 1.1 christos
110 1.1 christos static void
111 1.1 christos h8_set_ccr (SIM_DESC sd, unsigned int val)
112 1.1 christos {
113 1.1 christos (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM] = val;
114 1.1 christos }
115 1.1 christos
116 1.1 christos static unsigned int
117 1.1 christos h8_get_exr (SIM_DESC sd)
118 1.1 christos {
119 1.1 christos return (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM];
120 1.1 christos }
121 1.1 christos
122 1.1 christos static void
123 1.1 christos h8_set_exr (SIM_DESC sd, unsigned int val)
124 1.1 christos {
125 1.1 christos (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM] = val;
126 1.1 christos }
127 1.1 christos
128 1.1 christos static int
129 1.1 christos h8_get_sbr (SIM_DESC sd)
130 1.1 christos {
131 1.1 christos return (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM];
132 1.1 christos }
133 1.1 christos
134 1.1 christos static void
135 1.1 christos h8_set_sbr (SIM_DESC sd, int val)
136 1.1 christos {
137 1.1 christos (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM] = val;
138 1.1 christos }
139 1.1 christos
140 1.1 christos static int
141 1.1 christos h8_get_vbr (SIM_DESC sd)
142 1.1 christos {
143 1.1 christos return (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM];
144 1.1 christos }
145 1.1 christos
146 1.1 christos static void
147 1.1 christos h8_set_vbr (SIM_DESC sd, int val)
148 1.1 christos {
149 1.1 christos (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM] = val;
150 1.1 christos }
151 1.1 christos
152 1.1 christos static int
153 1.1 christos h8_get_cache_top (SIM_DESC sd)
154 1.1 christos {
155 1.1 christos return sd -> cache_top;
156 1.1 christos }
157 1.1 christos
158 1.1 christos static void
159 1.1 christos h8_set_cache_top (SIM_DESC sd, int val)
160 1.1 christos {
161 1.1 christos sd -> cache_top = val;
162 1.1 christos }
163 1.1 christos
164 1.1 christos static int
165 1.1 christos h8_get_mask (SIM_DESC sd)
166 1.1 christos {
167 1.1 christos return (STATE_CPU (sd, 0)) -> mask;
168 1.1 christos }
169 1.1 christos
170 1.1 christos static void
171 1.1 christos h8_set_mask (SIM_DESC sd, int val)
172 1.1 christos {
173 1.1 christos (STATE_CPU (sd, 0)) -> mask = val;
174 1.1 christos }
175 1.1 christos #if 0
176 1.1 christos static int
177 1.1 christos h8_get_exception (SIM_DESC sd)
178 1.1 christos {
179 1.1 christos return (STATE_CPU (sd, 0)) -> exception;
180 1.1 christos }
181 1.1 christos
182 1.1 christos static void
183 1.1 christos h8_set_exception (SIM_DESC sd, int val)
184 1.1 christos {
185 1.1 christos (STATE_CPU (sd, 0)) -> exception = val;
186 1.1 christos }
187 1.1 christos
188 1.1 christos static enum h8300_sim_state
189 1.1 christos h8_get_state (SIM_DESC sd)
190 1.1 christos {
191 1.1 christos return sd -> state;
192 1.1 christos }
193 1.1 christos
194 1.1 christos static void
195 1.1 christos h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
196 1.1 christos {
197 1.1 christos sd -> state = val;
198 1.1 christos }
199 1.1 christos #endif
200 1.1 christos static unsigned int
201 1.1 christos h8_get_cycles (SIM_DESC sd)
202 1.1 christos {
203 1.1 christos return (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM];
204 1.1 christos }
205 1.1 christos
206 1.1 christos static void
207 1.1 christos h8_set_cycles (SIM_DESC sd, unsigned int val)
208 1.1 christos {
209 1.1 christos (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM] = val;
210 1.1 christos }
211 1.1 christos
212 1.1 christos static unsigned int
213 1.1 christos h8_get_insts (SIM_DESC sd)
214 1.1 christos {
215 1.1 christos return (STATE_CPU (sd, 0)) -> regs[INST_REGNUM];
216 1.1 christos }
217 1.1 christos
218 1.1 christos static void
219 1.1 christos h8_set_insts (SIM_DESC sd, unsigned int val)
220 1.1 christos {
221 1.1 christos (STATE_CPU (sd, 0)) -> regs[INST_REGNUM] = val;
222 1.1 christos }
223 1.1 christos
224 1.1 christos static unsigned int
225 1.1 christos h8_get_ticks (SIM_DESC sd)
226 1.1 christos {
227 1.1 christos return (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM];
228 1.1 christos }
229 1.1 christos
230 1.1 christos static void
231 1.1 christos h8_set_ticks (SIM_DESC sd, unsigned int val)
232 1.1 christos {
233 1.1 christos (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM] = val;
234 1.1 christos }
235 1.1 christos
236 1.1 christos static unsigned int
237 1.1 christos h8_get_mach (SIM_DESC sd)
238 1.1 christos {
239 1.1 christos return (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM];
240 1.1 christos }
241 1.1 christos
242 1.1 christos static void
243 1.1 christos h8_set_mach (SIM_DESC sd, unsigned int val)
244 1.1 christos {
245 1.1 christos (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM] = val;
246 1.1 christos }
247 1.1 christos
248 1.1 christos static unsigned int
249 1.1 christos h8_get_macl (SIM_DESC sd)
250 1.1 christos {
251 1.1 christos return (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM];
252 1.1 christos }
253 1.1 christos
254 1.1 christos static void
255 1.1 christos h8_set_macl (SIM_DESC sd, unsigned int val)
256 1.1 christos {
257 1.1 christos (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM] = val;
258 1.1 christos }
259 1.1 christos
260 1.1 christos static int
261 1.1 christos h8_get_compiles (SIM_DESC sd)
262 1.1 christos {
263 1.1 christos return sd -> compiles;
264 1.1 christos }
265 1.1 christos
266 1.1 christos static void
267 1.1 christos h8_increment_compiles (SIM_DESC sd)
268 1.1 christos {
269 1.1 christos sd -> compiles ++;
270 1.1 christos }
271 1.1 christos
272 1.1 christos static unsigned int *
273 1.1 christos h8_get_reg_buf (SIM_DESC sd)
274 1.1 christos {
275 1.1 christos return &(((STATE_CPU (sd, 0)) -> regs)[0]);
276 1.1 christos }
277 1.1 christos
278 1.1 christos static unsigned int
279 1.1 christos h8_get_reg (SIM_DESC sd, int regnum)
280 1.1 christos {
281 1.1 christos return (STATE_CPU (sd, 0)) -> regs[regnum];
282 1.1 christos }
283 1.1 christos
284 1.1 christos static void
285 1.1 christos h8_set_reg (SIM_DESC sd, int regnum, int val)
286 1.1 christos {
287 1.1 christos (STATE_CPU (sd, 0)) -> regs[regnum] = val;
288 1.1 christos }
289 1.1 christos
290 1.1 christos #ifdef ADEBUG
291 1.1 christos static int
292 1.1 christos h8_get_stats (SIM_DESC sd, int idx)
293 1.1 christos {
294 1.1 christos return sd -> stats[idx];
295 1.1 christos }
296 1.1 christos
297 1.1 christos static void
298 1.1 christos h8_increment_stats (SIM_DESC sd, int idx)
299 1.1 christos {
300 1.1 christos sd -> stats[idx] ++;
301 1.1 christos }
302 1.1 christos #endif /* ADEBUG */
303 1.1 christos
304 1.1 christos static unsigned short *
305 1.1 christos h8_get_cache_idx_buf (SIM_DESC sd)
306 1.1 christos {
307 1.1 christos return sd -> cache_idx;
308 1.1 christos }
309 1.1 christos
310 1.1 christos static void
311 1.1 christos h8_set_cache_idx_buf (SIM_DESC sd, unsigned short *ptr)
312 1.1 christos {
313 1.1 christos sd -> cache_idx = ptr;
314 1.1 christos }
315 1.1 christos
316 1.1 christos static unsigned short
317 1.1 christos h8_get_cache_idx (SIM_DESC sd, unsigned int idx)
318 1.1 christos {
319 1.1 christos if (idx > sd->memory_size)
320 1.1 christos return (unsigned short) -1;
321 1.1 christos return sd -> cache_idx[idx];
322 1.1 christos }
323 1.1 christos
324 1.1 christos static void
325 1.1 christos h8_set_cache_idx (SIM_DESC sd, int idx, unsigned int val)
326 1.1 christos {
327 1.1 christos sd -> cache_idx[idx] = (unsigned short) val;
328 1.1 christos }
329 1.1 christos
330 1.1 christos static unsigned char *
331 1.1 christos h8_get_memory_buf (SIM_DESC sd)
332 1.1 christos {
333 1.1 christos return (STATE_CPU (sd, 0)) -> memory;
334 1.1 christos }
335 1.1 christos
336 1.1 christos static void
337 1.1 christos h8_set_memory_buf (SIM_DESC sd, unsigned char *ptr)
338 1.1 christos {
339 1.1 christos (STATE_CPU (sd, 0)) -> memory = ptr;
340 1.1 christos }
341 1.1 christos
342 1.1 christos static unsigned char
343 1.1 christos h8_get_memory (SIM_DESC sd, int idx)
344 1.1 christos {
345 1.1 christos return (STATE_CPU (sd, 0)) -> memory[idx];
346 1.1 christos }
347 1.1 christos
348 1.1 christos static void
349 1.1 christos h8_set_memory (SIM_DESC sd, int idx, unsigned int val)
350 1.1 christos {
351 1.1 christos (STATE_CPU (sd, 0)) -> memory[idx] = (unsigned char) val;
352 1.1 christos }
353 1.1 christos
354 1.1 christos static unsigned char *
355 1.1 christos h8_get_eightbit_buf (SIM_DESC sd)
356 1.1 christos {
357 1.1 christos return (STATE_CPU (sd, 0)) -> eightbit;
358 1.1 christos }
359 1.1 christos
360 1.1 christos static void
361 1.1 christos h8_set_eightbit_buf (SIM_DESC sd, unsigned char *ptr)
362 1.1 christos {
363 1.1 christos (STATE_CPU (sd, 0)) -> eightbit = ptr;
364 1.1 christos }
365 1.1 christos
366 1.1 christos static unsigned char
367 1.1 christos h8_get_eightbit (SIM_DESC sd, int idx)
368 1.1 christos {
369 1.1 christos return (STATE_CPU (sd, 0)) -> eightbit[idx];
370 1.1 christos }
371 1.1 christos
372 1.1 christos static void
373 1.1 christos h8_set_eightbit (SIM_DESC sd, int idx, unsigned int val)
374 1.1 christos {
375 1.1 christos (STATE_CPU (sd, 0)) -> eightbit[idx] = (unsigned char) val;
376 1.1 christos }
377 1.1 christos
378 1.1 christos static unsigned int
379 1.1 christos h8_get_delayed_branch (SIM_DESC sd)
380 1.1 christos {
381 1.1 christos return (STATE_CPU (sd, 0)) -> delayed_branch;
382 1.1 christos }
383 1.1 christos
384 1.1 christos static void
385 1.1 christos h8_set_delayed_branch (SIM_DESC sd, unsigned int dest)
386 1.1 christos {
387 1.1 christos (STATE_CPU (sd, 0)) -> delayed_branch = dest;
388 1.1 christos }
389 1.1 christos
390 1.1 christos static char **
391 1.1 christos h8_get_command_line (SIM_DESC sd)
392 1.1 christos {
393 1.1 christos return (STATE_CPU (sd, 0)) -> command_line;
394 1.1 christos }
395 1.1 christos
396 1.1 christos static void
397 1.1 christos h8_set_command_line (SIM_DESC sd, char ** val)
398 1.1 christos {
399 1.1 christos (STATE_CPU (sd, 0)) -> command_line = val;
400 1.1 christos }
401 1.1 christos
402 1.1 christos static char *
403 1.1 christos h8_get_cmdline_arg (SIM_DESC sd, int index)
404 1.1 christos {
405 1.1 christos return (STATE_CPU (sd, 0)) -> command_line[index];
406 1.1 christos }
407 1.1 christos
408 1.1 christos static void
409 1.1 christos h8_set_cmdline_arg (SIM_DESC sd, int index, char * val)
410 1.1 christos {
411 1.1 christos (STATE_CPU (sd, 0)) -> command_line[index] = val;
412 1.1 christos }
413 1.1 christos
414 1.1 christos /* MAC Saturation Mode */
415 1.1 christos static int
416 1.1 christos h8_get_macS (SIM_DESC sd)
417 1.1 christos {
418 1.1 christos return (STATE_CPU (sd, 0)) -> macS;
419 1.1 christos }
420 1.1 christos
421 1.1 christos static void
422 1.1 christos h8_set_macS (SIM_DESC sd, int val)
423 1.1 christos {
424 1.1 christos (STATE_CPU (sd, 0)) -> macS = (val != 0);
425 1.1 christos }
426 1.1 christos
427 1.1 christos /* MAC Zero Flag */
428 1.1 christos static int
429 1.1 christos h8_get_macZ (SIM_DESC sd)
430 1.1 christos {
431 1.1 christos return (STATE_CPU (sd, 0)) -> macZ;
432 1.1 christos }
433 1.1 christos
434 1.1 christos static void
435 1.1 christos h8_set_macZ (SIM_DESC sd, int val)
436 1.1 christos {
437 1.1 christos (STATE_CPU (sd, 0)) -> macZ = (val != 0);
438 1.1 christos }
439 1.1 christos
440 1.1 christos /* MAC Negative Flag */
441 1.1 christos static int
442 1.1 christos h8_get_macN (SIM_DESC sd)
443 1.1 christos {
444 1.1 christos return (STATE_CPU (sd, 0)) -> macN;
445 1.1 christos }
446 1.1 christos
447 1.1 christos static void
448 1.1 christos h8_set_macN (SIM_DESC sd, int val)
449 1.1 christos {
450 1.1 christos (STATE_CPU (sd, 0)) -> macN = (val != 0);
451 1.1 christos }
452 1.1 christos
453 1.1 christos /* MAC Overflow Flag */
454 1.1 christos static int
455 1.1 christos h8_get_macV (SIM_DESC sd)
456 1.1 christos {
457 1.1 christos return (STATE_CPU (sd, 0)) -> macV;
458 1.1 christos }
459 1.1 christos
460 1.1 christos static void
461 1.1 christos h8_set_macV (SIM_DESC sd, int val)
462 1.1 christos {
463 1.1 christos (STATE_CPU (sd, 0)) -> macV = (val != 0);
464 1.1 christos }
465 1.1 christos
466 1.1 christos /* End CPU data object. */
467 1.1 christos
468 1.1 christos /* The rate at which to call the host's poll_quit callback. */
469 1.1 christos
470 1.1 christos enum { POLL_QUIT_INTERVAL = 0x80000 };
471 1.1 christos
472 1.1 christos #define LOW_BYTE(x) ((x) & 0xff)
473 1.1 christos #define HIGH_BYTE(x) (((x) >> 8) & 0xff)
474 1.1 christos #define P(X, Y) ((X << 8) | Y)
475 1.1 christos
476 1.1 christos #define C (c != 0)
477 1.1 christos #define Z (nz == 0)
478 1.1 christos #define V (v != 0)
479 1.1 christos #define N (n != 0)
480 1.1 christos #define U (u != 0)
481 1.1 christos #define H (h != 0)
482 1.1 christos #define UI (ui != 0)
483 1.1 christos #define I (intMaskBit != 0)
484 1.1 christos
485 1.1 christos #define BUILDSR(SD) \
486 1.1 christos h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4) \
487 1.1 christos | (N << 3) | (Z << 2) | (V << 1) | C)
488 1.1 christos
489 1.1 christos #define GETSR(SD) \
490 1.1 christos /* Get Status Register (flags). */ \
491 1.1 christos c = (h8_get_ccr (sd) >> 0) & 1; \
492 1.1 christos v = (h8_get_ccr (sd) >> 1) & 1; \
493 1.1 christos nz = !((h8_get_ccr (sd) >> 2) & 1); \
494 1.1 christos n = (h8_get_ccr (sd) >> 3) & 1; \
495 1.1 christos u = (h8_get_ccr (sd) >> 4) & 1; \
496 1.1 christos h = (h8_get_ccr (sd) >> 5) & 1; \
497 1.1 christos ui = ((h8_get_ccr (sd) >> 6) & 1); \
498 1.1 christos intMaskBit = (h8_get_ccr (sd) >> 7) & 1
499 1.1 christos
500 1.1 christos
501 1.1 christos #ifdef __CHAR_IS_SIGNED__
502 1.1 christos #define SEXTCHAR(x) ((char) (x))
503 1.1 christos #endif
504 1.1 christos
505 1.1 christos #ifndef SEXTCHAR
506 1.1 christos #define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff)
507 1.1 christos #endif
508 1.1 christos
509 1.1 christos #define UEXTCHAR(x) ((x) & 0xff)
510 1.1 christos #define UEXTSHORT(x) ((x) & 0xffff)
511 1.1 christos #define SEXTSHORT(x) ((short) (x))
512 1.1 christos
513 1.1 christos int h8300hmode = 0;
514 1.1 christos int h8300smode = 0;
515 1.1 christos int h8300_normal_mode = 0;
516 1.1 christos int h8300sxmode = 0;
517 1.1 christos
518 1.1 christos static int memory_size;
519 1.1 christos
520 1.1 christos static int
521 1.1 christos get_now (void)
522 1.1 christos {
523 1.1 christos return time (0); /* WinXX HAS UNIX like 'time', so why not use it? */
524 1.1 christos }
525 1.1 christos
526 1.1 christos static int
527 1.1 christos now_persec (void)
528 1.1 christos {
529 1.1 christos return 1;
530 1.1 christos }
531 1.1 christos
532 1.1 christos static int
533 1.1 christos bitfrom (int x)
534 1.1 christos {
535 1.1 christos switch (x & SIZE)
536 1.1 christos {
537 1.1 christos case L_8:
538 1.1 christos return SB;
539 1.1 christos case L_16:
540 1.1 christos case L_16U:
541 1.1 christos return SW;
542 1.1 christos case L_32:
543 1.1 christos return SL;
544 1.1 christos case L_P:
545 1.1 christos return (h8300hmode && !h8300_normal_mode)? SL : SW;
546 1.1 christos }
547 1.1 christos return 0;
548 1.1 christos }
549 1.1 christos
550 1.1 christos /* Simulate an indirection / dereference.
551 1.1 christos return 0 for success, -1 for failure.
552 1.1 christos */
553 1.1 christos
554 1.1 christos static unsigned int
555 1.1 christos lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
556 1.1 christos {
557 1.1 christos if (val == NULL) /* Paranoia. */
558 1.1 christos return -1;
559 1.1 christos
560 1.1 christos switch (x / 4)
561 1.1 christos {
562 1.1 christos case OP_DISP:
563 1.1 christos if (rn == ZERO_REGNUM)
564 1.1 christos *val = X (OP_IMM, SP);
565 1.1 christos else
566 1.1 christos *val = X (OP_REG, SP);
567 1.1 christos break;
568 1.1 christos case OP_MEM:
569 1.1 christos *val = X (OP_MEM, SP);
570 1.1 christos break;
571 1.1 christos default:
572 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
573 1.1 christos return -1;
574 1.1 christos }
575 1.1 christos return 0;
576 1.1 christos }
577 1.1 christos
578 1.1 christos static int
579 1.1 christos cmdline_location()
580 1.1 christos {
581 1.1 christos if (h8300smode && !h8300_normal_mode)
582 1.1 christos return 0xffff00L;
583 1.1 christos else if (h8300hmode && !h8300_normal_mode)
584 1.1 christos return 0x2ff00L;
585 1.1 christos else
586 1.1 christos return 0xff00L;
587 1.1 christos }
588 1.1 christos
589 1.1 christos static void
590 1.1 christos decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
591 1.1 christos {
592 1.1 christos int cst[3] = {0, 0, 0};
593 1.1 christos int reg[3] = {0, 0, 0};
594 1.1 christos int rdisp[3] = {0, 0, 0};
595 1.1 christos int opnum;
596 1.1 christos const struct h8_opcode *q;
597 1.1 christos
598 1.1 christos dst->dst.type = -1;
599 1.1 christos dst->src.type = -1;
600 1.1 christos
601 1.1 christos /* Find the exact opcode/arg combo. */
602 1.1 christos for (q = h8_opcodes; q->name; q++)
603 1.1 christos {
604 1.1 christos const op_type *nib = q->data.nib;
605 1.1 christos unsigned int len = 0;
606 1.1 christos
607 1.1 christos if ((q->available == AV_H8SX && !h8300sxmode) ||
608 1.1 christos (q->available == AV_H8S && !h8300smode) ||
609 1.1 christos (q->available == AV_H8H && !h8300hmode))
610 1.1 christos continue;
611 1.1 christos
612 1.1 christos cst[0] = cst[1] = cst[2] = 0;
613 1.1 christos reg[0] = reg[1] = reg[2] = 0;
614 1.1 christos rdisp[0] = rdisp[1] = rdisp[2] = 0;
615 1.1 christos
616 1.1 christos while (1)
617 1.1 christos {
618 1.1 christos op_type looking_for = *nib;
619 1.1 christos int thisnib = data[len / 2];
620 1.1 christos
621 1.1 christos thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
622 1.1 christos opnum = ((looking_for & OP3) ? 2 :
623 1.1 christos (looking_for & DST) ? 1 : 0);
624 1.1 christos
625 1.1 christos if (looking_for < 16 && looking_for >= 0)
626 1.1 christos {
627 1.1 christos if (looking_for != thisnib)
628 1.1 christos goto fail;
629 1.1 christos }
630 1.1 christos else
631 1.1 christos {
632 1.1 christos if (looking_for & B31)
633 1.1 christos {
634 1.1 christos if (!((thisnib & 0x8) != 0))
635 1.1 christos goto fail;
636 1.1 christos
637 1.1 christos looking_for = (op_type) (looking_for & ~B31);
638 1.1 christos thisnib &= 0x7;
639 1.1 christos }
640 1.1 christos else if (looking_for & B30)
641 1.1 christos {
642 1.1 christos if (!((thisnib & 0x8) == 0))
643 1.1 christos goto fail;
644 1.1 christos
645 1.1 christos looking_for = (op_type) (looking_for & ~B30);
646 1.1 christos }
647 1.1 christos
648 1.1 christos if (looking_for & B21)
649 1.1 christos {
650 1.1 christos if (!((thisnib & 0x4) != 0))
651 1.1 christos goto fail;
652 1.1 christos
653 1.1 christos looking_for = (op_type) (looking_for & ~B21);
654 1.1 christos thisnib &= 0xb;
655 1.1 christos }
656 1.1 christos else if (looking_for & B20)
657 1.1 christos {
658 1.1 christos if (!((thisnib & 0x4) == 0))
659 1.1 christos goto fail;
660 1.1 christos
661 1.1 christos looking_for = (op_type) (looking_for & ~B20);
662 1.1 christos }
663 1.1 christos
664 1.1 christos if (looking_for & B11)
665 1.1 christos {
666 1.1 christos if (!((thisnib & 0x2) != 0))
667 1.1 christos goto fail;
668 1.1 christos
669 1.1 christos looking_for = (op_type) (looking_for & ~B11);
670 1.1 christos thisnib &= 0xd;
671 1.1 christos }
672 1.1 christos else if (looking_for & B10)
673 1.1 christos {
674 1.1 christos if (!((thisnib & 0x2) == 0))
675 1.1 christos goto fail;
676 1.1 christos
677 1.1 christos looking_for = (op_type) (looking_for & ~B10);
678 1.1 christos }
679 1.1 christos
680 1.1 christos if (looking_for & B01)
681 1.1 christos {
682 1.1 christos if (!((thisnib & 0x1) != 0))
683 1.1 christos goto fail;
684 1.1 christos
685 1.1 christos looking_for = (op_type) (looking_for & ~B01);
686 1.1 christos thisnib &= 0xe;
687 1.1 christos }
688 1.1 christos else if (looking_for & B00)
689 1.1 christos {
690 1.1 christos if (!((thisnib & 0x1) == 0))
691 1.1 christos goto fail;
692 1.1 christos
693 1.1 christos looking_for = (op_type) (looking_for & ~B00);
694 1.1 christos }
695 1.1 christos
696 1.1 christos if (looking_for & IGNORE)
697 1.1 christos {
698 1.1 christos /* Hitachi has declared that IGNORE must be zero. */
699 1.1 christos if (thisnib != 0)
700 1.1 christos goto fail;
701 1.1 christos }
702 1.1 christos else if ((looking_for & MODE) == DATA)
703 1.1 christos {
704 1.1 christos ; /* Skip embedded data. */
705 1.1 christos }
706 1.1 christos else if ((looking_for & MODE) == DBIT)
707 1.1 christos {
708 1.1 christos /* Exclude adds/subs by looking at bit 0 and 2, and
709 1.1 christos make sure the operand size, either w or l,
710 1.1 christos matches by looking at bit 1. */
711 1.1 christos if ((looking_for & 7) != (thisnib & 7))
712 1.1 christos goto fail;
713 1.1 christos
714 1.1 christos cst[opnum] = (thisnib & 0x8) ? 2 : 1;
715 1.1 christos }
716 1.1 christos else if ((looking_for & MODE) == REG ||
717 1.1 christos (looking_for & MODE) == LOWREG ||
718 1.1 christos (looking_for & MODE) == IND ||
719 1.1 christos (looking_for & MODE) == PREINC ||
720 1.1 christos (looking_for & MODE) == POSTINC ||
721 1.1 christos (looking_for & MODE) == PREDEC ||
722 1.1 christos (looking_for & MODE) == POSTDEC)
723 1.1 christos {
724 1.1 christos reg[opnum] = thisnib;
725 1.1 christos }
726 1.1 christos else if (looking_for & CTRL)
727 1.1 christos {
728 1.1 christos thisnib &= 7;
729 1.1 christos if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) ||
730 1.1 christos ((looking_for & MODE) == EXR && (thisnib != C_EXR)) ||
731 1.1 christos ((looking_for & MODE) == MACH && (thisnib != C_MACH)) ||
732 1.1 christos ((looking_for & MODE) == MACL && (thisnib != C_MACL)) ||
733 1.1 christos ((looking_for & MODE) == VBR && (thisnib != C_VBR)) ||
734 1.1 christos ((looking_for & MODE) == SBR && (thisnib != C_SBR)))
735 1.1 christos goto fail;
736 1.1 christos if (((looking_for & MODE) == CCR_EXR &&
737 1.1 christos (thisnib != C_CCR && thisnib != C_EXR)) ||
738 1.1 christos ((looking_for & MODE) == VBR_SBR &&
739 1.1 christos (thisnib != C_VBR && thisnib != C_SBR)) ||
740 1.1 christos ((looking_for & MODE) == MACREG &&
741 1.1 christos (thisnib != C_MACH && thisnib != C_MACL)))
742 1.1 christos goto fail;
743 1.1 christos if (((looking_for & MODE) == CC_EX_VB_SB &&
744 1.1 christos (thisnib != C_CCR && thisnib != C_EXR &&
745 1.1 christos thisnib != C_VBR && thisnib != C_SBR)))
746 1.1 christos goto fail;
747 1.1 christos
748 1.1 christos reg[opnum] = thisnib;
749 1.1 christos }
750 1.1 christos else if ((looking_for & MODE) == ABS)
751 1.1 christos {
752 1.1 christos /* Absolute addresses are unsigned. */
753 1.1 christos switch (looking_for & SIZE)
754 1.1 christos {
755 1.1 christos case L_8:
756 1.1 christos cst[opnum] = UEXTCHAR (data[len / 2]);
757 1.1 christos break;
758 1.1 christos case L_16:
759 1.1 christos case L_16U:
760 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
761 1.1 christos break;
762 1.1 christos case L_32:
763 1.1 christos cst[opnum] =
764 1.1 christos (data[len / 2 + 0] << 24) +
765 1.1 christos (data[len / 2 + 1] << 16) +
766 1.1 christos (data[len / 2 + 2] << 8) +
767 1.1 christos (data[len / 2 + 3]);
768 1.1 christos break;
769 1.1 christos default:
770 1.1 christos printf ("decode: bad size ABS: %d\n",
771 1.1 christos (looking_for & SIZE));
772 1.1 christos goto end;
773 1.1 christos }
774 1.1 christos }
775 1.1 christos else if ((looking_for & MODE) == DISP ||
776 1.1 christos (looking_for & MODE) == PCREL ||
777 1.1 christos (looking_for & MODE) == INDEXB ||
778 1.1 christos (looking_for & MODE) == INDEXW ||
779 1.1 christos (looking_for & MODE) == INDEXL)
780 1.1 christos {
781 1.1 christos switch (looking_for & SIZE)
782 1.1 christos {
783 1.1 christos case L_2:
784 1.1 christos cst[opnum] = thisnib & 3;
785 1.1 christos break;
786 1.1 christos case L_8:
787 1.1 christos cst[opnum] = SEXTCHAR (data[len / 2]);
788 1.1 christos break;
789 1.1 christos case L_16:
790 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
791 1.1 christos cst[opnum] = (short) cst[opnum]; /* Sign extend. */
792 1.1 christos break;
793 1.1 christos case L_16U:
794 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
795 1.1 christos break;
796 1.1 christos case L_32:
797 1.1 christos cst[opnum] =
798 1.1 christos (data[len / 2 + 0] << 24) +
799 1.1 christos (data[len / 2 + 1] << 16) +
800 1.1 christos (data[len / 2 + 2] << 8) +
801 1.1 christos (data[len / 2 + 3]);
802 1.1 christos break;
803 1.1 christos default:
804 1.1 christos printf ("decode: bad size DISP/PCREL/INDEX: %d\n",
805 1.1 christos (looking_for & SIZE));
806 1.1 christos goto end;
807 1.1 christos }
808 1.1 christos }
809 1.1 christos else if ((looking_for & SIZE) == L_16 ||
810 1.1 christos (looking_for & SIZE) == L_16U)
811 1.1 christos {
812 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
813 1.1 christos /* Immediates are always unsigned. */
814 1.1 christos if ((looking_for & SIZE) != L_16U &&
815 1.1 christos (looking_for & MODE) != IMM)
816 1.1 christos cst[opnum] = (short) cst[opnum]; /* Sign extend. */
817 1.1 christos }
818 1.1 christos else if (looking_for & ABSJMP)
819 1.1 christos {
820 1.1 christos switch (looking_for & SIZE) {
821 1.1 christos case L_24:
822 1.1 christos cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]);
823 1.1 christos break;
824 1.1 christos case L_32:
825 1.1 christos cst[opnum] =
826 1.1 christos (data[len / 2 + 0] << 24) +
827 1.1 christos (data[len / 2 + 1] << 16) +
828 1.1 christos (data[len / 2 + 2] << 8) +
829 1.1 christos (data[len / 2 + 3]);
830 1.1 christos break;
831 1.1 christos default:
832 1.1 christos printf ("decode: bad size ABSJMP: %d\n",
833 1.1 christos (looking_for & SIZE));
834 1.1 christos goto end;
835 1.1 christos }
836 1.1 christos }
837 1.1 christos else if ((looking_for & MODE) == MEMIND)
838 1.1 christos {
839 1.1 christos cst[opnum] = data[1];
840 1.1 christos }
841 1.1 christos else if ((looking_for & MODE) == VECIND)
842 1.1 christos {
843 1.1 christos if(h8300_normal_mode)
844 1.1 christos cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
845 1.1 christos else
846 1.1 christos cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
847 1.1 christos cst[opnum] += h8_get_vbr (sd); /* Add vector base reg. */
848 1.1 christos }
849 1.1 christos else if ((looking_for & SIZE) == L_32)
850 1.1 christos {
851 1.1 christos int i = len / 2;
852 1.1 christos
853 1.1 christos cst[opnum] =
854 1.1 christos (data[i + 0] << 24) |
855 1.1 christos (data[i + 1] << 16) |
856 1.1 christos (data[i + 2] << 8) |
857 1.1 christos (data[i + 3]);
858 1.1 christos }
859 1.1 christos else if ((looking_for & SIZE) == L_24)
860 1.1 christos {
861 1.1 christos int i = len / 2;
862 1.1 christos
863 1.1 christos cst[opnum] =
864 1.1 christos (data[i + 0] << 16) |
865 1.1 christos (data[i + 1] << 8) |
866 1.1 christos (data[i + 2]);
867 1.1 christos }
868 1.1 christos else if (looking_for & DISPREG)
869 1.1 christos {
870 1.1 christos rdisp[opnum] = thisnib & 0x7;
871 1.1 christos }
872 1.1 christos else if ((looking_for & MODE) == KBIT)
873 1.1 christos {
874 1.1 christos switch (thisnib)
875 1.1 christos {
876 1.1 christos case 9:
877 1.1 christos cst[opnum] = 4;
878 1.1 christos break;
879 1.1 christos case 8:
880 1.1 christos cst[opnum] = 2;
881 1.1 christos break;
882 1.1 christos case 0:
883 1.1 christos cst[opnum] = 1;
884 1.1 christos break;
885 1.1 christos default:
886 1.1 christos goto fail;
887 1.1 christos }
888 1.1 christos }
889 1.1 christos else if ((looking_for & SIZE) == L_8)
890 1.1 christos {
891 1.1 christos if ((looking_for & MODE) == ABS)
892 1.1 christos {
893 1.1 christos /* Will be combined with contents of SBR_REGNUM
894 1.1 christos by fetch (). For all modes except h8sx, this
895 1.1 christos will always contain the value 0xFFFFFF00. */
896 1.1 christos cst[opnum] = data[len / 2] & 0xff;
897 1.1 christos }
898 1.1 christos else
899 1.1 christos {
900 1.1 christos cst[opnum] = data[len / 2] & 0xff;
901 1.1 christos }
902 1.1 christos }
903 1.1 christos else if ((looking_for & SIZE) == L_2)
904 1.1 christos {
905 1.1 christos cst[opnum] = thisnib & 3;
906 1.1 christos }
907 1.1 christos else if ((looking_for & SIZE) == L_3 ||
908 1.1 christos (looking_for & SIZE) == L_3NZ)
909 1.1 christos {
910 1.1 christos cst[opnum] = thisnib & 7;
911 1.1 christos if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ)
912 1.1 christos goto fail;
913 1.1 christos }
914 1.1 christos else if ((looking_for & SIZE) == L_4)
915 1.1 christos {
916 1.1 christos cst[opnum] = thisnib & 15;
917 1.1 christos }
918 1.1 christos else if ((looking_for & SIZE) == L_5)
919 1.1 christos {
920 1.1 christos cst[opnum] = data[len / 2] & 0x1f;
921 1.1 christos }
922 1.1 christos else if (looking_for == E)
923 1.1 christos {
924 1.1 christos #ifdef ADEBUG
925 1.1 christos dst->op = q;
926 1.1 christos #endif
927 1.1 christos /* Fill in the args. */
928 1.1 christos {
929 1.1 christos const op_type *args = q->args.nib;
930 1.1 christos int hadone = 0;
931 1.1 christos int nargs;
932 1.1 christos
933 1.1 christos for (nargs = 0;
934 1.1 christos nargs < 3 && *args != E;
935 1.1 christos nargs++)
936 1.1 christos {
937 1.1 christos int x = *args;
938 1.1 christos ea_type *p;
939 1.1 christos
940 1.1 christos opnum = ((x & OP3) ? 2 :
941 1.1 christos (x & DST) ? 1 : 0);
942 1.1 christos if (x & DST)
943 1.1 christos p = &dst->dst;
944 1.1 christos else if (x & OP3)
945 1.1 christos p = &dst->op3;
946 1.1 christos else
947 1.1 christos p = &dst->src;
948 1.1 christos
949 1.1 christos if ((x & MODE) == IMM ||
950 1.1 christos (x & MODE) == KBIT ||
951 1.1 christos (x & MODE) == DBIT)
952 1.1 christos {
953 1.1 christos /* Use the instruction to determine
954 1.1 christos the operand size. */
955 1.1 christos p->type = X (OP_IMM, OP_SIZE (q->how));
956 1.1 christos p->literal = cst[opnum];
957 1.1 christos }
958 1.1 christos else if ((x & MODE) == CONST_2 ||
959 1.1 christos (x & MODE) == CONST_4 ||
960 1.1 christos (x & MODE) == CONST_8 ||
961 1.1 christos (x & MODE) == CONST_16)
962 1.1 christos {
963 1.1 christos /* Use the instruction to determine
964 1.1 christos the operand size. */
965 1.1 christos p->type = X (OP_IMM, OP_SIZE (q->how));
966 1.1 christos switch (x & MODE) {
967 1.1 christos case CONST_2: p->literal = 2; break;
968 1.1 christos case CONST_4: p->literal = 4; break;
969 1.1 christos case CONST_8: p->literal = 8; break;
970 1.1 christos case CONST_16: p->literal = 16; break;
971 1.1 christos }
972 1.1 christos }
973 1.1 christos else if ((x & MODE) == REG)
974 1.1 christos {
975 1.1 christos p->type = X (OP_REG, bitfrom (x));
976 1.1 christos p->reg = reg[opnum];
977 1.1 christos }
978 1.1 christos else if ((x & MODE) == LOWREG)
979 1.1 christos {
980 1.1 christos p->type = X (OP_LOWREG, bitfrom (x));
981 1.1 christos p->reg = reg[opnum];
982 1.1 christos }
983 1.1 christos else if ((x & MODE) == PREINC)
984 1.1 christos {
985 1.1 christos /* Use the instruction to determine
986 1.1 christos the operand size. */
987 1.1 christos p->type = X (OP_PREINC, OP_SIZE (q->how));
988 1.1 christos p->reg = reg[opnum] & 0x7;
989 1.1 christos }
990 1.1 christos else if ((x & MODE) == POSTINC)
991 1.1 christos {
992 1.1 christos /* Use the instruction to determine
993 1.1 christos the operand size. */
994 1.1 christos p->type = X (OP_POSTINC, OP_SIZE (q->how));
995 1.1 christos p->reg = reg[opnum] & 0x7;
996 1.1 christos }
997 1.1 christos else if ((x & MODE) == PREDEC)
998 1.1 christos {
999 1.1 christos /* Use the instruction to determine
1000 1.1 christos the operand size. */
1001 1.1 christos p->type = X (OP_PREDEC, OP_SIZE (q->how));
1002 1.1 christos p->reg = reg[opnum] & 0x7;
1003 1.1 christos }
1004 1.1 christos else if ((x & MODE) == POSTDEC)
1005 1.1 christos {
1006 1.1 christos /* Use the instruction to determine
1007 1.1 christos the operand size. */
1008 1.1 christos p->type = X (OP_POSTDEC, OP_SIZE (q->how));
1009 1.1 christos p->reg = reg[opnum] & 0x7;
1010 1.1 christos }
1011 1.1 christos else if ((x & MODE) == IND)
1012 1.1 christos {
1013 1.1 christos /* Note: an indirect is transformed into
1014 1.1 christos a displacement of zero.
1015 1.1 christos */
1016 1.1 christos /* Use the instruction to determine
1017 1.1 christos the operand size. */
1018 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how));
1019 1.1 christos p->reg = reg[opnum] & 0x7;
1020 1.1 christos p->literal = 0;
1021 1.1 christos if (OP_KIND (q->how) == O_JSR ||
1022 1.1 christos OP_KIND (q->how) == O_JMP)
1023 1.1 christos if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
1024 1.1 christos goto end;
1025 1.1 christos }
1026 1.1 christos else if ((x & MODE) == ABS)
1027 1.1 christos {
1028 1.1 christos /* Note: a 16 or 32 bit ABS is transformed into a
1029 1.1 christos displacement from pseudo-register ZERO_REGNUM,
1030 1.1 christos which is always zero. An 8 bit ABS becomes
1031 1.1 christos a displacement from SBR_REGNUM.
1032 1.1 christos */
1033 1.1 christos /* Use the instruction to determine
1034 1.1 christos the operand size. */
1035 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how));
1036 1.1 christos p->literal = cst[opnum];
1037 1.1 christos
1038 1.1 christos /* 8-bit ABS is displacement from SBR.
1039 1.1 christos 16 and 32-bit ABS are displacement from ZERO.
1040 1.1 christos (SBR will always be zero except for h8/sx)
1041 1.1 christos */
1042 1.1 christos if ((x & SIZE) == L_8)
1043 1.1 christos p->reg = SBR_REGNUM;
1044 1.1 christos else
1045 1.1 christos p->reg = ZERO_REGNUM;;
1046 1.1 christos }
1047 1.1 christos else if ((x & MODE) == MEMIND ||
1048 1.1 christos (x & MODE) == VECIND)
1049 1.1 christos {
1050 1.1 christos /* Size doesn't matter. */
1051 1.1 christos p->type = X (OP_MEM, SB);
1052 1.1 christos p->literal = cst[opnum];
1053 1.1 christos if (OP_KIND (q->how) == O_JSR ||
1054 1.1 christos OP_KIND (q->how) == O_JMP)
1055 1.1 christos if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
1056 1.1 christos goto end;
1057 1.1 christos }
1058 1.1 christos else if ((x & MODE) == PCREL)
1059 1.1 christos {
1060 1.1 christos /* Size doesn't matter. */
1061 1.1 christos p->type = X (OP_PCREL, SB);
1062 1.1 christos p->literal = cst[opnum];
1063 1.1 christos }
1064 1.1 christos else if (x & ABSJMP)
1065 1.1 christos {
1066 1.1 christos p->type = X (OP_IMM, SP);
1067 1.1 christos p->literal = cst[opnum];
1068 1.1 christos }
1069 1.1 christos else if ((x & MODE) == INDEXB)
1070 1.1 christos {
1071 1.1 christos p->type = X (OP_INDEXB, OP_SIZE (q->how));
1072 1.1 christos p->literal = cst[opnum];
1073 1.1 christos p->reg = rdisp[opnum];
1074 1.1 christos }
1075 1.1 christos else if ((x & MODE) == INDEXW)
1076 1.1 christos {
1077 1.1 christos p->type = X (OP_INDEXW, OP_SIZE (q->how));
1078 1.1 christos p->literal = cst[opnum];
1079 1.1 christos p->reg = rdisp[opnum];
1080 1.1 christos }
1081 1.1 christos else if ((x & MODE) == INDEXL)
1082 1.1 christos {
1083 1.1 christos p->type = X (OP_INDEXL, OP_SIZE (q->how));
1084 1.1 christos p->literal = cst[opnum];
1085 1.1 christos p->reg = rdisp[opnum];
1086 1.1 christos }
1087 1.1 christos else if ((x & MODE) == DISP)
1088 1.1 christos {
1089 1.1 christos /* Yuck -- special for mova args. */
1090 1.1 christos if (strncmp (q->name, "mova", 4) == 0 &&
1091 1.1 christos (x & SIZE) == L_2)
1092 1.1 christos {
1093 1.1 christos /* Mova can have a DISP2 dest, with an
1094 1.1 christos INDEXB or INDEXW src. The multiplier
1095 1.1 christos for the displacement value is determined
1096 1.1 christos by the src operand, not by the insn. */
1097 1.1 christos
1098 1.1 christos switch (OP_KIND (dst->src.type))
1099 1.1 christos {
1100 1.1 christos case OP_INDEXB:
1101 1.1 christos p->type = X (OP_DISP, SB);
1102 1.1 christos p->literal = cst[opnum];
1103 1.1 christos break;
1104 1.1 christos case OP_INDEXW:
1105 1.1 christos p->type = X (OP_DISP, SW);
1106 1.1 christos p->literal = cst[opnum] * 2;
1107 1.1 christos break;
1108 1.1 christos default:
1109 1.1 christos goto fail;
1110 1.1 christos }
1111 1.1 christos }
1112 1.1 christos else
1113 1.1 christos {
1114 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how));
1115 1.1 christos p->literal = cst[opnum];
1116 1.1 christos /* DISP2 is special. */
1117 1.1 christos if ((x & SIZE) == L_2)
1118 1.1 christos switch (OP_SIZE (q->how))
1119 1.1 christos {
1120 1.1 christos case SB: break;
1121 1.1 christos case SW: p->literal *= 2; break;
1122 1.1 christos case SL: p->literal *= 4; break;
1123 1.1 christos }
1124 1.1 christos }
1125 1.1 christos p->reg = rdisp[opnum];
1126 1.1 christos }
1127 1.1 christos else if (x & CTRL)
1128 1.1 christos {
1129 1.1 christos switch (reg[opnum])
1130 1.1 christos {
1131 1.1 christos case C_CCR:
1132 1.1 christos p->type = X (OP_CCR, SB);
1133 1.1 christos break;
1134 1.1 christos case C_EXR:
1135 1.1 christos p->type = X (OP_EXR, SB);
1136 1.1 christos break;
1137 1.1 christos case C_MACH:
1138 1.1 christos p->type = X (OP_MACH, SL);
1139 1.1 christos break;
1140 1.1 christos case C_MACL:
1141 1.1 christos p->type = X (OP_MACL, SL);
1142 1.1 christos break;
1143 1.1 christos case C_VBR:
1144 1.1 christos p->type = X (OP_VBR, SL);
1145 1.1 christos break;
1146 1.1 christos case C_SBR:
1147 1.1 christos p->type = X (OP_SBR, SL);
1148 1.1 christos break;
1149 1.1 christos }
1150 1.1 christos }
1151 1.1 christos else if ((x & MODE) == CCR)
1152 1.1 christos {
1153 1.1 christos p->type = OP_CCR;
1154 1.1 christos }
1155 1.1 christos else if ((x & MODE) == EXR)
1156 1.1 christos {
1157 1.1 christos p->type = OP_EXR;
1158 1.1 christos }
1159 1.1 christos else
1160 1.1 christos printf ("Hmmmm 0x%x...\n", x);
1161 1.1 christos
1162 1.1 christos args++;
1163 1.1 christos }
1164 1.1 christos }
1165 1.1 christos
1166 1.1 christos /* Unary operators: treat src and dst as equivalent. */
1167 1.1 christos if (dst->dst.type == -1)
1168 1.1 christos dst->dst = dst->src;
1169 1.1 christos if (dst->src.type == -1)
1170 1.1 christos dst->src = dst->dst;
1171 1.1 christos
1172 1.1 christos dst->opcode = q->how;
1173 1.1 christos dst->cycles = q->time;
1174 1.1 christos
1175 1.1 christos /* And jsr's to these locations are turned into
1176 1.1 christos magic traps. */
1177 1.1 christos
1178 1.1 christos if (OP_KIND (dst->opcode) == O_JSR)
1179 1.1 christos {
1180 1.1 christos switch (dst->src.literal)
1181 1.1 christos {
1182 1.1 christos case 0xc5:
1183 1.1 christos dst->opcode = O (O_SYS_OPEN, SB);
1184 1.1 christos break;
1185 1.1 christos case 0xc6:
1186 1.1 christos dst->opcode = O (O_SYS_READ, SB);
1187 1.1 christos break;
1188 1.1 christos case 0xc7:
1189 1.1 christos dst->opcode = O (O_SYS_WRITE, SB);
1190 1.1 christos break;
1191 1.1 christos case 0xc8:
1192 1.1 christos dst->opcode = O (O_SYS_LSEEK, SB);
1193 1.1 christos break;
1194 1.1 christos case 0xc9:
1195 1.1 christos dst->opcode = O (O_SYS_CLOSE, SB);
1196 1.1 christos break;
1197 1.1 christos case 0xca:
1198 1.1 christos dst->opcode = O (O_SYS_STAT, SB);
1199 1.1 christos break;
1200 1.1 christos case 0xcb:
1201 1.1 christos dst->opcode = O (O_SYS_FSTAT, SB);
1202 1.1 christos break;
1203 1.1 christos case 0xcc:
1204 1.1 christos dst->opcode = O (O_SYS_CMDLINE, SB);
1205 1.1 christos break;
1206 1.1 christos }
1207 1.1 christos /* End of Processing for system calls. */
1208 1.1 christos }
1209 1.1 christos
1210 1.1 christos dst->next_pc = addr + len / 2;
1211 1.1 christos return;
1212 1.1 christos }
1213 1.1 christos else
1214 1.1 christos printf ("Don't understand 0x%x \n", looking_for);
1215 1.1 christos }
1216 1.1 christos
1217 1.1 christos len++;
1218 1.1 christos nib++;
1219 1.1 christos }
1220 1.1 christos
1221 1.1 christos fail:
1222 1.1 christos ;
1223 1.1 christos }
1224 1.1 christos end:
1225 1.1 christos /* Fell off the end. */
1226 1.1 christos dst->opcode = O (O_ILL, SB);
1227 1.1 christos }
1228 1.1 christos
1229 1.1 christos static void
1230 1.1 christos compile (SIM_DESC sd, int pc)
1231 1.1 christos {
1232 1.1 christos int idx;
1233 1.1 christos
1234 1.1 christos /* Find the next cache entry to use. */
1235 1.1 christos idx = h8_get_cache_top (sd) + 1;
1236 1.1 christos h8_increment_compiles (sd);
1237 1.1 christos if (idx >= sd->sim_cache_size)
1238 1.1 christos {
1239 1.1 christos idx = 1;
1240 1.1 christos }
1241 1.1 christos h8_set_cache_top (sd, idx);
1242 1.1 christos
1243 1.1 christos /* Throw away its old meaning. */
1244 1.1 christos h8_set_cache_idx (sd, sd->sim_cache[idx].oldpc, 0);
1245 1.1 christos
1246 1.1 christos /* Set to new address. */
1247 1.1 christos sd->sim_cache[idx].oldpc = pc;
1248 1.1 christos
1249 1.1 christos /* Fill in instruction info. */
1250 1.1 christos decode (sd, pc, h8_get_memory_buf (sd) + pc, sd->sim_cache + idx);
1251 1.1 christos
1252 1.1 christos /* Point to new cache entry. */
1253 1.1 christos h8_set_cache_idx (sd, pc, idx);
1254 1.1 christos }
1255 1.1 christos
1256 1.1 christos
1257 1.1 christos static unsigned char *breg[32];
1258 1.1 christos static unsigned short *wreg[16];
1259 1.1 christos static unsigned int *lreg[18];
1260 1.1 christos
1261 1.1 christos #define GET_B_REG(X) *(breg[X])
1262 1.1 christos #define SET_B_REG(X, Y) (*(breg[X])) = (Y)
1263 1.1 christos #define GET_W_REG(X) *(wreg[X])
1264 1.1 christos #define SET_W_REG(X, Y) (*(wreg[X])) = (Y)
1265 1.1 christos #define GET_L_REG(X) h8_get_reg (sd, X)
1266 1.1 christos #define SET_L_REG(X, Y) h8_set_reg (sd, X, Y)
1267 1.1 christos
1268 1.1 christos #define GET_MEMORY_L(X) \
1269 1.1 christos ((X) < memory_size \
1270 1.1 christos ? ((h8_get_memory (sd, (X)+0) << 24) | (h8_get_memory (sd, (X)+1) << 16) \
1271 1.1 christos | (h8_get_memory (sd, (X)+2) << 8) | (h8_get_memory (sd, (X)+3) << 0)) \
1272 1.1 christos : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 24) \
1273 1.1 christos | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 16) \
1274 1.1 christos | (h8_get_eightbit (sd, ((X)+2) & 0xff) << 8) \
1275 1.1 christos | (h8_get_eightbit (sd, ((X)+3) & 0xff) << 0)))
1276 1.1 christos
1277 1.1 christos #define GET_MEMORY_W(X) \
1278 1.1 christos ((X) < memory_size \
1279 1.1 christos ? ((h8_get_memory (sd, (X)+0) << 8) \
1280 1.1 christos | (h8_get_memory (sd, (X)+1) << 0)) \
1281 1.1 christos : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 8) \
1282 1.1 christos | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 0)))
1283 1.1 christos
1284 1.1 christos
1285 1.1 christos #define GET_MEMORY_B(X) \
1286 1.1 christos ((X) < memory_size ? (h8_get_memory (sd, (X))) \
1287 1.1 christos : (h8_get_eightbit (sd, (X) & 0xff)))
1288 1.1 christos
1289 1.1 christos #define SET_MEMORY_L(X, Y) \
1290 1.1 christos { register unsigned char *_p; register int __y = (Y); \
1291 1.1 christos _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \
1292 1.1 christos h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
1293 1.1 christos _p[0] = __y >> 24; _p[1] = __y >> 16; \
1294 1.1 christos _p[2] = __y >> 8; _p[3] = __y >> 0; \
1295 1.1 christos }
1296 1.1 christos
1297 1.1 christos #define SET_MEMORY_W(X, Y) \
1298 1.1 christos { register unsigned char *_p; register int __y = (Y); \
1299 1.1 christos _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \
1300 1.1 christos h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
1301 1.1 christos _p[0] = __y >> 8; _p[1] = __y; \
1302 1.1 christos }
1303 1.1 christos
1304 1.1 christos #define SET_MEMORY_B(X, Y) \
1305 1.1 christos ((X) < memory_size ? (h8_set_memory (sd, (X), (Y))) \
1306 1.1 christos : (h8_set_eightbit (sd, (X) & 0xff, (Y))))
1307 1.1 christos
1308 1.1 christos /* Simulate a memory fetch.
1309 1.1 christos Return 0 for success, -1 for failure.
1310 1.1 christos */
1311 1.1 christos
1312 1.1 christos static int
1313 1.1 christos fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
1314 1.1 christos {
1315 1.1 christos int rn = arg->reg;
1316 1.1 christos int abs = arg->literal;
1317 1.1 christos int r;
1318 1.1 christos int t;
1319 1.1 christos
1320 1.1 christos if (val == NULL)
1321 1.1 christos return -1; /* Paranoia. */
1322 1.1 christos
1323 1.1 christos switch (arg->type)
1324 1.1 christos {
1325 1.1 christos /* Indexed register plus displacement mode:
1326 1.1 christos
1327 1.1 christos This new family of addressing modes are similar to OP_DISP
1328 1.1 christos (register plus displacement), with two differences:
1329 1.1 christos 1) INDEXB uses only the least significant byte of the register,
1330 1.1 christos INDEXW uses only the least significant word, and
1331 1.1 christos INDEXL uses the entire register (just like OP_DISP).
1332 1.1 christos and
1333 1.1 christos 2) The displacement value in abs is multiplied by two
1334 1.1 christos for SW-sized operations, and by four for SL-size.
1335 1.1 christos
1336 1.1 christos This gives nine possible variations.
1337 1.1 christos */
1338 1.1 christos
1339 1.1 christos case X (OP_INDEXB, SB):
1340 1.1 christos case X (OP_INDEXB, SW):
1341 1.1 christos case X (OP_INDEXB, SL):
1342 1.1 christos case X (OP_INDEXW, SB):
1343 1.1 christos case X (OP_INDEXW, SW):
1344 1.1 christos case X (OP_INDEXW, SL):
1345 1.1 christos case X (OP_INDEXL, SB):
1346 1.1 christos case X (OP_INDEXL, SW):
1347 1.1 christos case X (OP_INDEXL, SL):
1348 1.1 christos t = GET_L_REG (rn);
1349 1.1 christos switch (OP_KIND (arg->type)) {
1350 1.1 christos case OP_INDEXB: t &= 0xff; break;
1351 1.1 christos case OP_INDEXW: t &= 0xffff; break;
1352 1.1 christos case OP_INDEXL:
1353 1.1 christos default: break;
1354 1.1 christos }
1355 1.1 christos switch (OP_SIZE (arg->type)) {
1356 1.1 christos case SB:
1357 1.1 christos *val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd));
1358 1.1 christos break;
1359 1.1 christos case SW:
1360 1.1 christos *val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd));
1361 1.1 christos break;
1362 1.1 christos case SL:
1363 1.1 christos *val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd));
1364 1.1 christos break;
1365 1.1 christos }
1366 1.1 christos break;
1367 1.1 christos
1368 1.1 christos case X (OP_LOWREG, SB):
1369 1.1 christos *val = GET_L_REG (rn) & 0xff;
1370 1.1 christos break;
1371 1.1 christos case X (OP_LOWREG, SW):
1372 1.1 christos *val = GET_L_REG (rn) & 0xffff;
1373 1.1 christos break;
1374 1.1 christos
1375 1.1 christos case X (OP_REG, SB): /* Register direct, byte. */
1376 1.1 christos *val = GET_B_REG (rn);
1377 1.1 christos break;
1378 1.1 christos case X (OP_REG, SW): /* Register direct, word. */
1379 1.1 christos *val = GET_W_REG (rn);
1380 1.1 christos break;
1381 1.1 christos case X (OP_REG, SL): /* Register direct, long. */
1382 1.1 christos *val = GET_L_REG (rn);
1383 1.1 christos break;
1384 1.1 christos case X (OP_IMM, SB): /* Immediate, byte. */
1385 1.1 christos case X (OP_IMM, SW): /* Immediate, word. */
1386 1.1 christos case X (OP_IMM, SL): /* Immediate, long. */
1387 1.1 christos *val = abs;
1388 1.1 christos break;
1389 1.1 christos case X (OP_POSTINC, SB): /* Register indirect w/post-incr: byte. */
1390 1.1 christos t = GET_L_REG (rn);
1391 1.1 christos r = GET_MEMORY_B (t & h8_get_mask (sd));
1392 1.1 christos if (!twice)
1393 1.1 christos t += 1;
1394 1.1 christos SET_L_REG (rn, t);
1395 1.1 christos *val = r;
1396 1.1 christos break;
1397 1.1 christos case X (OP_POSTINC, SW): /* Register indirect w/post-incr: word. */
1398 1.1 christos t = GET_L_REG (rn);
1399 1.1 christos r = GET_MEMORY_W (t & h8_get_mask (sd));
1400 1.1 christos if (!twice)
1401 1.1 christos t += 2;
1402 1.1 christos SET_L_REG (rn, t);
1403 1.1 christos *val = r;
1404 1.1 christos break;
1405 1.1 christos case X (OP_POSTINC, SL): /* Register indirect w/post-incr: long. */
1406 1.1 christos t = GET_L_REG (rn);
1407 1.1 christos r = GET_MEMORY_L (t & h8_get_mask (sd));
1408 1.1 christos if (!twice)
1409 1.1 christos t += 4;
1410 1.1 christos SET_L_REG (rn, t);
1411 1.1 christos *val = r;
1412 1.1 christos break;
1413 1.1 christos
1414 1.1 christos case X (OP_POSTDEC, SB): /* Register indirect w/post-decr: byte. */
1415 1.1 christos t = GET_L_REG (rn);
1416 1.1 christos r = GET_MEMORY_B (t & h8_get_mask (sd));
1417 1.1 christos if (!twice)
1418 1.1 christos t -= 1;
1419 1.1 christos SET_L_REG (rn, t);
1420 1.1 christos *val = r;
1421 1.1 christos break;
1422 1.1 christos case X (OP_POSTDEC, SW): /* Register indirect w/post-decr: word. */
1423 1.1 christos t = GET_L_REG (rn);
1424 1.1 christos r = GET_MEMORY_W (t & h8_get_mask (sd));
1425 1.1 christos if (!twice)
1426 1.1 christos t -= 2;
1427 1.1 christos SET_L_REG (rn, t);
1428 1.1 christos *val = r;
1429 1.1 christos break;
1430 1.1 christos case X (OP_POSTDEC, SL): /* Register indirect w/post-decr: long. */
1431 1.1 christos t = GET_L_REG (rn);
1432 1.1 christos r = GET_MEMORY_L (t & h8_get_mask (sd));
1433 1.1 christos if (!twice)
1434 1.1 christos t -= 4;
1435 1.1 christos SET_L_REG (rn, t);
1436 1.1 christos *val = r;
1437 1.1 christos break;
1438 1.1 christos
1439 1.1 christos case X (OP_PREDEC, SB): /* Register indirect w/pre-decr: byte. */
1440 1.1 christos t = GET_L_REG (rn) - 1;
1441 1.1 christos SET_L_REG (rn, t);
1442 1.1 christos t &= h8_get_mask (sd);
1443 1.1 christos *val = GET_MEMORY_B (t);
1444 1.1 christos break;
1445 1.1 christos
1446 1.1 christos case X (OP_PREDEC, SW): /* Register indirect w/pre-decr: word. */
1447 1.1 christos t = GET_L_REG (rn) - 2;
1448 1.1 christos SET_L_REG (rn, t);
1449 1.1 christos t &= h8_get_mask (sd);
1450 1.1 christos *val = GET_MEMORY_W (t);
1451 1.1 christos break;
1452 1.1 christos
1453 1.1 christos case X (OP_PREDEC, SL): /* Register indirect w/pre-decr: long. */
1454 1.1 christos t = GET_L_REG (rn) - 4;
1455 1.1 christos SET_L_REG (rn, t);
1456 1.1 christos t &= h8_get_mask (sd);
1457 1.1 christos *val = GET_MEMORY_L (t);
1458 1.1 christos break;
1459 1.1 christos
1460 1.1 christos case X (OP_PREINC, SB): /* Register indirect w/pre-incr: byte. */
1461 1.1 christos t = GET_L_REG (rn) + 1;
1462 1.1 christos SET_L_REG (rn, t);
1463 1.1 christos t &= h8_get_mask (sd);
1464 1.1 christos *val = GET_MEMORY_B (t);
1465 1.1 christos break;
1466 1.1 christos
1467 1.1 christos case X (OP_PREINC, SW): /* Register indirect w/pre-incr: long. */
1468 1.1 christos t = GET_L_REG (rn) + 2;
1469 1.1 christos SET_L_REG (rn, t);
1470 1.1 christos t &= h8_get_mask (sd);
1471 1.1 christos *val = GET_MEMORY_W (t);
1472 1.1 christos break;
1473 1.1 christos
1474 1.1 christos case X (OP_PREINC, SL): /* Register indirect w/pre-incr: long. */
1475 1.1 christos t = GET_L_REG (rn) + 4;
1476 1.1 christos SET_L_REG (rn, t);
1477 1.1 christos t &= h8_get_mask (sd);
1478 1.1 christos *val = GET_MEMORY_L (t);
1479 1.1 christos break;
1480 1.1 christos
1481 1.1 christos case X (OP_DISP, SB): /* Register indirect w/displacement: byte. */
1482 1.1 christos t = GET_L_REG (rn) + abs;
1483 1.1 christos t &= h8_get_mask (sd);
1484 1.1 christos *val = GET_MEMORY_B (t);
1485 1.1 christos break;
1486 1.1 christos
1487 1.1 christos case X (OP_DISP, SW): /* Register indirect w/displacement: word. */
1488 1.1 christos t = GET_L_REG (rn) + abs;
1489 1.1 christos t &= h8_get_mask (sd);
1490 1.1 christos *val = GET_MEMORY_W (t);
1491 1.1 christos break;
1492 1.1 christos
1493 1.1 christos case X (OP_DISP, SL): /* Register indirect w/displacement: long. */
1494 1.1 christos t = GET_L_REG (rn) + abs;
1495 1.1 christos t &= h8_get_mask (sd);
1496 1.1 christos *val =GET_MEMORY_L (t);
1497 1.1 christos break;
1498 1.1 christos
1499 1.1 christos case X (OP_MEM, SL): /* Absolute memory address, long. */
1500 1.1 christos t = GET_MEMORY_L (abs);
1501 1.1 christos t &= h8_get_mask (sd);
1502 1.1 christos *val = t;
1503 1.1 christos break;
1504 1.1 christos
1505 1.1 christos case X (OP_MEM, SW): /* Absolute memory address, word. */
1506 1.1 christos t = GET_MEMORY_W (abs);
1507 1.1 christos t &= h8_get_mask (sd);
1508 1.1 christos *val = t;
1509 1.1 christos break;
1510 1.1 christos
1511 1.1 christos case X (OP_PCREL, SB): /* PC relative (for jump, branch etc). */
1512 1.1 christos case X (OP_PCREL, SW):
1513 1.1 christos case X (OP_PCREL, SL):
1514 1.1 christos case X (OP_PCREL, SN):
1515 1.1 christos *val = abs;
1516 1.1 christos break;
1517 1.1 christos
1518 1.1 christos case X (OP_MEM, SB): /* Why isn't this implemented? */
1519 1.1 christos default:
1520 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
1521 1.1 christos return -1;
1522 1.1 christos }
1523 1.1 christos return 0; /* Success. */
1524 1.1 christos }
1525 1.1 christos
1526 1.1 christos /* Normal fetch. */
1527 1.1 christos
1528 1.1 christos static int
1529 1.1 christos fetch (SIM_DESC sd, ea_type *arg, int *val)
1530 1.1 christos {
1531 1.1 christos return fetch_1 (sd, arg, val, 0);
1532 1.1 christos }
1533 1.1 christos
1534 1.1 christos /* Fetch which will be followed by a store to the same location.
1535 1.1 christos The difference being that we don't want to do a post-increment
1536 1.1 christos or post-decrement at this time: we'll do it when we store. */
1537 1.1 christos
1538 1.1 christos static int
1539 1.1 christos fetch2 (SIM_DESC sd, ea_type *arg, int *val)
1540 1.1 christos {
1541 1.1 christos return fetch_1 (sd, arg, val, 1);
1542 1.1 christos }
1543 1.1 christos
1544 1.1 christos /* Simulate a memory store.
1545 1.1 christos Return 0 for success, -1 for failure.
1546 1.1 christos */
1547 1.1 christos
1548 1.1 christos static int
1549 1.1 christos store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
1550 1.1 christos {
1551 1.1 christos int rn = arg->reg;
1552 1.1 christos int abs = arg->literal;
1553 1.1 christos int t;
1554 1.1 christos
1555 1.1 christos switch (arg->type)
1556 1.1 christos {
1557 1.1 christos /* Indexed register plus displacement mode:
1558 1.1 christos
1559 1.1 christos This new family of addressing modes are similar to OP_DISP
1560 1.1 christos (register plus displacement), with two differences:
1561 1.1 christos 1) INDEXB uses only the least significant byte of the register,
1562 1.1 christos INDEXW uses only the least significant word, and
1563 1.1 christos INDEXL uses the entire register (just like OP_DISP).
1564 1.1 christos and
1565 1.1 christos 2) The displacement value in abs is multiplied by two
1566 1.1 christos for SW-sized operations, and by four for SL-size.
1567 1.1 christos
1568 1.1 christos This gives nine possible variations.
1569 1.1 christos */
1570 1.1 christos
1571 1.1 christos case X (OP_INDEXB, SB):
1572 1.1 christos case X (OP_INDEXB, SW):
1573 1.1 christos case X (OP_INDEXB, SL):
1574 1.1 christos case X (OP_INDEXW, SB):
1575 1.1 christos case X (OP_INDEXW, SW):
1576 1.1 christos case X (OP_INDEXW, SL):
1577 1.1 christos case X (OP_INDEXL, SB):
1578 1.1 christos case X (OP_INDEXL, SW):
1579 1.1 christos case X (OP_INDEXL, SL):
1580 1.1 christos t = GET_L_REG (rn);
1581 1.1 christos switch (OP_KIND (arg->type)) {
1582 1.1 christos case OP_INDEXB: t &= 0xff; break;
1583 1.1 christos case OP_INDEXW: t &= 0xffff; break;
1584 1.1 christos case OP_INDEXL:
1585 1.1 christos default: break;
1586 1.1 christos }
1587 1.1 christos switch (OP_SIZE (arg->type)) {
1588 1.1 christos case SB:
1589 1.1 christos SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd), n);
1590 1.1 christos break;
1591 1.1 christos case SW:
1592 1.1 christos SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd), n);
1593 1.1 christos break;
1594 1.1 christos case SL:
1595 1.1 christos SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd), n);
1596 1.1 christos break;
1597 1.1 christos }
1598 1.1 christos break;
1599 1.1 christos
1600 1.1 christos case X (OP_REG, SB): /* Register direct, byte. */
1601 1.1 christos SET_B_REG (rn, n);
1602 1.1 christos break;
1603 1.1 christos case X (OP_REG, SW): /* Register direct, word. */
1604 1.1 christos SET_W_REG (rn, n);
1605 1.1 christos break;
1606 1.1 christos case X (OP_REG, SL): /* Register direct, long. */
1607 1.1 christos SET_L_REG (rn, n);
1608 1.1 christos break;
1609 1.1 christos
1610 1.1 christos case X (OP_PREDEC, SB): /* Register indirect w/pre-decr, byte. */
1611 1.1 christos t = GET_L_REG (rn);
1612 1.1 christos if (!twice)
1613 1.1 christos t -= 1;
1614 1.1 christos SET_L_REG (rn, t);
1615 1.1 christos t &= h8_get_mask (sd);
1616 1.1 christos SET_MEMORY_B (t, n);
1617 1.1 christos
1618 1.1 christos break;
1619 1.1 christos case X (OP_PREDEC, SW): /* Register indirect w/pre-decr, word. */
1620 1.1 christos t = GET_L_REG (rn);
1621 1.1 christos if (!twice)
1622 1.1 christos t -= 2;
1623 1.1 christos SET_L_REG (rn, t);
1624 1.1 christos t &= h8_get_mask (sd);
1625 1.1 christos SET_MEMORY_W (t, n);
1626 1.1 christos break;
1627 1.1 christos
1628 1.1 christos case X (OP_PREDEC, SL): /* Register indirect w/pre-decr, long. */
1629 1.1 christos t = GET_L_REG (rn);
1630 1.1 christos if (!twice)
1631 1.1 christos t -= 4;
1632 1.1 christos SET_L_REG (rn, t);
1633 1.1 christos t &= h8_get_mask (sd);
1634 1.1 christos SET_MEMORY_L (t, n);
1635 1.1 christos break;
1636 1.1 christos
1637 1.1 christos case X (OP_PREINC, SB): /* Register indirect w/pre-incr, byte. */
1638 1.1 christos t = GET_L_REG (rn);
1639 1.1 christos if (!twice)
1640 1.1 christos t += 1;
1641 1.1 christos SET_L_REG (rn, t);
1642 1.1 christos t &= h8_get_mask (sd);
1643 1.1 christos SET_MEMORY_B (t, n);
1644 1.1 christos
1645 1.1 christos break;
1646 1.1 christos case X (OP_PREINC, SW): /* Register indirect w/pre-incr, word. */
1647 1.1 christos t = GET_L_REG (rn);
1648 1.1 christos if (!twice)
1649 1.1 christos t += 2;
1650 1.1 christos SET_L_REG (rn, t);
1651 1.1 christos t &= h8_get_mask (sd);
1652 1.1 christos SET_MEMORY_W (t, n);
1653 1.1 christos break;
1654 1.1 christos
1655 1.1 christos case X (OP_PREINC, SL): /* Register indirect w/pre-incr, long. */
1656 1.1 christos t = GET_L_REG (rn);
1657 1.1 christos if (!twice)
1658 1.1 christos t += 4;
1659 1.1 christos SET_L_REG (rn, t);
1660 1.1 christos t &= h8_get_mask (sd);
1661 1.1 christos SET_MEMORY_L (t, n);
1662 1.1 christos break;
1663 1.1 christos
1664 1.1 christos case X (OP_POSTDEC, SB): /* Register indirect w/post-decr, byte. */
1665 1.1 christos t = GET_L_REG (rn);
1666 1.1 christos SET_L_REG (rn, t - 1);
1667 1.1 christos t &= h8_get_mask (sd);
1668 1.1 christos SET_MEMORY_B (t, n);
1669 1.1 christos break;
1670 1.1 christos
1671 1.1 christos case X (OP_POSTDEC, SW): /* Register indirect w/post-decr, word. */
1672 1.1 christos t = GET_L_REG (rn);
1673 1.1 christos SET_L_REG (rn, t - 2);
1674 1.1 christos t &= h8_get_mask (sd);
1675 1.1 christos SET_MEMORY_W (t, n);
1676 1.1 christos break;
1677 1.1 christos
1678 1.1 christos case X (OP_POSTDEC, SL): /* Register indirect w/post-decr, long. */
1679 1.1 christos t = GET_L_REG (rn);
1680 1.1 christos SET_L_REG (rn, t - 4);
1681 1.1 christos t &= h8_get_mask (sd);
1682 1.1 christos SET_MEMORY_L (t, n);
1683 1.1 christos break;
1684 1.1 christos
1685 1.1 christos case X (OP_POSTINC, SB): /* Register indirect w/post-incr, byte. */
1686 1.1 christos t = GET_L_REG (rn);
1687 1.1 christos SET_L_REG (rn, t + 1);
1688 1.1 christos t &= h8_get_mask (sd);
1689 1.1 christos SET_MEMORY_B (t, n);
1690 1.1 christos break;
1691 1.1 christos
1692 1.1 christos case X (OP_POSTINC, SW): /* Register indirect w/post-incr, word. */
1693 1.1 christos t = GET_L_REG (rn);
1694 1.1 christos SET_L_REG (rn, t + 2);
1695 1.1 christos t &= h8_get_mask (sd);
1696 1.1 christos SET_MEMORY_W (t, n);
1697 1.1 christos break;
1698 1.1 christos
1699 1.1 christos case X (OP_POSTINC, SL): /* Register indirect w/post-incr, long. */
1700 1.1 christos t = GET_L_REG (rn);
1701 1.1 christos SET_L_REG (rn, t + 4);
1702 1.1 christos t &= h8_get_mask (sd);
1703 1.1 christos SET_MEMORY_L (t, n);
1704 1.1 christos break;
1705 1.1 christos
1706 1.1 christos case X (OP_DISP, SB): /* Register indirect w/displacement, byte. */
1707 1.1 christos t = GET_L_REG (rn) + abs;
1708 1.1 christos t &= h8_get_mask (sd);
1709 1.1 christos SET_MEMORY_B (t, n);
1710 1.1 christos break;
1711 1.1 christos
1712 1.1 christos case X (OP_DISP, SW): /* Register indirect w/displacement, word. */
1713 1.1 christos t = GET_L_REG (rn) + abs;
1714 1.1 christos t &= h8_get_mask (sd);
1715 1.1 christos SET_MEMORY_W (t, n);
1716 1.1 christos break;
1717 1.1 christos
1718 1.1 christos case X (OP_DISP, SL): /* Register indirect w/displacement, long. */
1719 1.1 christos t = GET_L_REG (rn) + abs;
1720 1.1 christos t &= h8_get_mask (sd);
1721 1.1 christos SET_MEMORY_L (t, n);
1722 1.1 christos break;
1723 1.1 christos
1724 1.1 christos
1725 1.1 christos case X (OP_MEM, SB): /* Why isn't this implemented? */
1726 1.1 christos case X (OP_MEM, SW): /* Why isn't this implemented? */
1727 1.1 christos case X (OP_MEM, SL): /* Why isn't this implemented? */
1728 1.1 christos default:
1729 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
1730 1.1 christos return -1;
1731 1.1 christos }
1732 1.1 christos return 0;
1733 1.1 christos }
1734 1.1 christos
1735 1.1 christos /* Normal store. */
1736 1.1 christos
1737 1.1 christos static int
1738 1.1 christos store (SIM_DESC sd, ea_type *arg, int n)
1739 1.1 christos {
1740 1.1 christos return store_1 (sd, arg, n, 0);
1741 1.1 christos }
1742 1.1 christos
1743 1.1 christos /* Store which follows a fetch from the same location.
1744 1.1 christos The difference being that we don't want to do a pre-increment
1745 1.1 christos or pre-decrement at this time: it was already done when we fetched. */
1746 1.1 christos
1747 1.1 christos static int
1748 1.1 christos store2 (SIM_DESC sd, ea_type *arg, int n)
1749 1.1 christos {
1750 1.1 christos return store_1 (sd, arg, n, 1);
1751 1.1 christos }
1752 1.1 christos
1753 1.1 christos static union
1754 1.1 christos {
1755 1.1 christos short int i;
1756 1.1 christos struct
1757 1.1 christos {
1758 1.1 christos char low;
1759 1.1 christos char high;
1760 1.1 christos }
1761 1.1 christos u;
1762 1.1 christos } littleendian;
1763 1.1 christos
1764 1.1 christos /* Flag to be set whenever a new SIM_DESC object is created. */
1765 1.1 christos static int init_pointers_needed = 1;
1766 1.1 christos
1767 1.1 christos static void
1768 1.1 christos init_pointers (SIM_DESC sd)
1769 1.1 christos {
1770 1.1 christos if (init_pointers_needed)
1771 1.1 christos {
1772 1.1 christos int i;
1773 1.1 christos
1774 1.1 christos littleendian.i = 1;
1775 1.1 christos
1776 1.1 christos if (h8300smode && !h8300_normal_mode)
1777 1.1 christos memory_size = H8300S_MSIZE;
1778 1.1 christos else if (h8300hmode && !h8300_normal_mode)
1779 1.1 christos memory_size = H8300H_MSIZE;
1780 1.1 christos else
1781 1.1 christos memory_size = H8300_MSIZE;
1782 1.1 christos /* `msize' must be a power of two. */
1783 1.1 christos if ((memory_size & (memory_size - 1)) != 0)
1784 1.1 christos {
1785 1.1 christos (*sim_callback->printf_filtered)
1786 1.1 christos (sim_callback,
1787 1.1 christos "init_pointers: bad memory size %d, defaulting to %d.\n",
1788 1.1 christos memory_size, memory_size = H8300S_MSIZE);
1789 1.1 christos }
1790 1.1 christos
1791 1.1 christos if (h8_get_memory_buf (sd))
1792 1.1 christos free (h8_get_memory_buf (sd));
1793 1.1 christos if (h8_get_cache_idx_buf (sd))
1794 1.1 christos free (h8_get_cache_idx_buf (sd));
1795 1.1 christos if (h8_get_eightbit_buf (sd))
1796 1.1 christos free (h8_get_eightbit_buf (sd));
1797 1.1 christos
1798 1.1 christos h8_set_memory_buf (sd, (unsigned char *)
1799 1.1 christos calloc (sizeof (char), memory_size));
1800 1.1 christos h8_set_cache_idx_buf (sd, (unsigned short *)
1801 1.1 christos calloc (sizeof (short), memory_size));
1802 1.1 christos sd->memory_size = memory_size;
1803 1.1 christos h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
1804 1.1 christos
1805 1.1 christos h8_set_mask (sd, memory_size - 1);
1806 1.1 christos
1807 1.1 christos memset (h8_get_reg_buf (sd), 0, sizeof (((STATE_CPU (sd, 0))->regs)));
1808 1.1 christos
1809 1.1 christos for (i = 0; i < 8; i++)
1810 1.1 christos {
1811 1.1 christos /* FIXME: rewrite using local buffer. */
1812 1.1 christos unsigned char *p = (unsigned char *) (h8_get_reg_buf (sd) + i);
1813 1.1 christos unsigned char *e = (unsigned char *) (h8_get_reg_buf (sd) + i + 1);
1814 1.1 christos unsigned short *q = (unsigned short *) (h8_get_reg_buf (sd) + i);
1815 1.1 christos unsigned short *u = (unsigned short *) (h8_get_reg_buf (sd) + i + 1);
1816 1.1 christos h8_set_reg (sd, i, 0x00112233);
1817 1.1 christos
1818 1.1 christos while (p < e)
1819 1.1 christos {
1820 1.1 christos if (*p == 0x22)
1821 1.1 christos breg[i] = p;
1822 1.1 christos if (*p == 0x33)
1823 1.1 christos breg[i + 8] = p;
1824 1.1 christos if (*p == 0x11)
1825 1.1 christos breg[i + 16] = p;
1826 1.1 christos if (*p == 0x00)
1827 1.1 christos breg[i + 24] = p;
1828 1.1 christos p++;
1829 1.1 christos }
1830 1.1 christos
1831 1.1 christos wreg[i] = wreg[i + 8] = 0;
1832 1.1 christos while (q < u)
1833 1.1 christos {
1834 1.1 christos if (*q == 0x2233)
1835 1.1 christos {
1836 1.1 christos wreg[i] = q;
1837 1.1 christos }
1838 1.1 christos if (*q == 0x0011)
1839 1.1 christos {
1840 1.1 christos wreg[i + 8] = q;
1841 1.1 christos }
1842 1.1 christos q++;
1843 1.1 christos }
1844 1.1 christos
1845 1.1 christos if (wreg[i] == 0 || wreg[i + 8] == 0)
1846 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
1847 1.1 christos "init_pointers: internal error.\n");
1848 1.1 christos
1849 1.1 christos h8_set_reg (sd, i, 0);
1850 1.1 christos lreg[i] = h8_get_reg_buf (sd) + i;
1851 1.1 christos }
1852 1.1 christos
1853 1.1 christos /* Note: sim uses pseudo-register ZERO as a zero register. */
1854 1.1 christos lreg[ZERO_REGNUM] = h8_get_reg_buf (sd) + ZERO_REGNUM;
1855 1.1 christos init_pointers_needed = 0;
1856 1.1 christos
1857 1.1 christos /* Initialize the seg registers. */
1858 1.1 christos if (!sd->sim_cache)
1859 1.1 christos set_simcache_size (sd, CSIZE);
1860 1.1 christos }
1861 1.1 christos }
1862 1.1 christos
1863 1.1 christos int
1864 1.1 christos sim_stop (SIM_DESC sd)
1865 1.1 christos {
1866 1.1 christos /* FIXME: use a real signal value. */
1867 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGINT);
1868 1.1 christos return 1;
1869 1.1 christos }
1870 1.1 christos
1871 1.1 christos #define OBITOP(name, f, s, op) \
1872 1.1 christos case O (name, SB): \
1873 1.1 christos { \
1874 1.1 christos int m, tmp; \
1875 1.1 christos \
1876 1.1 christos if (f) \
1877 1.1 christos if (fetch (sd, &code->dst, &ea)) \
1878 1.1 christos goto end; \
1879 1.1 christos if (fetch (sd, &code->src, &tmp)) \
1880 1.1 christos goto end; \
1881 1.1 christos m = 1 << (tmp & 7); \
1882 1.1 christos op; \
1883 1.1 christos if (s) \
1884 1.1 christos if (store (sd, &code->dst,ea)) \
1885 1.1 christos goto end; \
1886 1.1 christos goto next; \
1887 1.1 christos }
1888 1.1 christos
1889 1.1 christos void
1890 1.1 christos sim_resume (SIM_DESC sd, int step, int siggnal)
1891 1.1 christos {
1892 1.1 christos static int init1;
1893 1.1 christos int cycles = 0;
1894 1.1 christos int insts = 0;
1895 1.1 christos int tick_start = get_now ();
1896 1.1 christos int poll_count = 0;
1897 1.1 christos int res;
1898 1.1 christos int tmp;
1899 1.1 christos int rd;
1900 1.1 christos int ea;
1901 1.1 christos int bit;
1902 1.1 christos int pc;
1903 1.1 christos int c, nz, v, n, u, h, ui, intMaskBit;
1904 1.1 christos int trace, intMask;
1905 1.1 christos int oldmask;
1906 1.1 christos enum sim_stop reason;
1907 1.1 christos int sigrc;
1908 1.1 christos
1909 1.1 christos init_pointers (sd);
1910 1.1 christos
1911 1.1 christos if (step)
1912 1.1 christos {
1913 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
1914 1.1 christos }
1915 1.1 christos else
1916 1.1 christos {
1917 1.1 christos sim_engine_set_run_state (sd, sim_running, 0);
1918 1.1 christos }
1919 1.1 christos
1920 1.1 christos pc = h8_get_pc (sd);
1921 1.1 christos
1922 1.1 christos /* The PC should never be odd. */
1923 1.1 christos if (pc & 0x1)
1924 1.1 christos {
1925 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGBUS);
1926 1.1 christos return;
1927 1.1 christos }
1928 1.1 christos
1929 1.1 christos /* Get Status Register (flags). */
1930 1.1 christos GETSR (sd);
1931 1.1 christos
1932 1.1 christos if (h8300smode) /* Get exr. */
1933 1.1 christos {
1934 1.1 christos trace = (h8_get_exr (sd) >> 7) & 1;
1935 1.1 christos intMask = h8_get_exr (sd) & 7;
1936 1.1 christos }
1937 1.1 christos
1938 1.1 christos oldmask = h8_get_mask (sd);
1939 1.1 christos if (!h8300hmode || h8300_normal_mode)
1940 1.1 christos h8_set_mask (sd, 0xffff);
1941 1.1 christos do
1942 1.1 christos {
1943 1.1 christos unsigned short cidx;
1944 1.1 christos decoded_inst *code;
1945 1.1 christos
1946 1.1 christos top:
1947 1.1 christos cidx = h8_get_cache_idx (sd, pc);
1948 1.1 christos if (cidx == (unsigned short) -1 ||
1949 1.1 christos cidx >= sd->sim_cache_size)
1950 1.1 christos goto illegal;
1951 1.1 christos
1952 1.1 christos code = sd->sim_cache + cidx;
1953 1.1 christos
1954 1.1 christos #if ADEBUG
1955 1.1 christos if (debug)
1956 1.1 christos {
1957 1.1 christos printf ("%x %d %s\n", pc, code->opcode,
1958 1.1 christos code->op ? code->op->name : "**");
1959 1.1 christos }
1960 1.1 christos h8_increment_stats (sd, code->opcode);
1961 1.1 christos #endif
1962 1.1 christos
1963 1.1 christos if (code->opcode)
1964 1.1 christos {
1965 1.1 christos cycles += code->cycles;
1966 1.1 christos insts++;
1967 1.1 christos }
1968 1.1 christos
1969 1.1 christos switch (code->opcode)
1970 1.1 christos {
1971 1.1 christos case 0:
1972 1.1 christos /*
1973 1.1 christos * This opcode is a fake for when we get to an
1974 1.1 christos * instruction which hasnt been compiled
1975 1.1 christos */
1976 1.1 christos compile (sd, pc);
1977 1.1 christos goto top;
1978 1.1 christos break;
1979 1.1 christos
1980 1.1 christos case O (O_MOVAB, SL):
1981 1.1 christos case O (O_MOVAW, SL):
1982 1.1 christos case O (O_MOVAL, SL):
1983 1.1 christos /* 1) Evaluate 2nd argument (dst).
1984 1.1 christos 2) Mask / zero extend according to whether 1st argument (src)
1985 1.1 christos is INDEXB, INDEXW, or INDEXL.
1986 1.1 christos 3) Left-shift the result by 0, 1 or 2, according to size of mova
1987 1.1 christos (mova/b, mova/w, mova/l).
1988 1.1 christos 4) Add literal value of 1st argument (src).
1989 1.1 christos 5) Store result in 3rd argument (op3).
1990 1.1 christos */
1991 1.1 christos
1992 1.1 christos /* Alas, since this is the only instruction with 3 arguments,
1993 1.1 christos decode doesn't handle them very well. Some fix-up is required.
1994 1.1 christos
1995 1.1 christos a) The size of dst is determined by whether src is
1996 1.1 christos INDEXB or INDEXW. */
1997 1.1 christos
1998 1.1 christos if (OP_KIND (code->src.type) == OP_INDEXB)
1999 1.1 christos code->dst.type = X (OP_KIND (code->dst.type), SB);
2000 1.1 christos else if (OP_KIND (code->src.type) == OP_INDEXW)
2001 1.1 christos code->dst.type = X (OP_KIND (code->dst.type), SW);
2002 1.1 christos
2003 1.1 christos /* b) If op3 == null, then this is the short form of the insn.
2004 1.1 christos Dst is the dispreg of src, and op3 is the 32-bit form
2005 1.1 christos of the same register.
2006 1.1 christos */
2007 1.1 christos
2008 1.1 christos if (code->op3.type == 0)
2009 1.1 christos {
2010 1.1 christos /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
2011 1.1 christos We get to compose dst and op3 as follows:
2012 1.1 christos
2013 1.1 christos op3 is a 32-bit register, ID == src.reg.
2014 1.1 christos dst is the same register, but 8 or 16 bits
2015 1.1 christos depending on whether src is INDEXB or INDEXW.
2016 1.1 christos */
2017 1.1 christos
2018 1.1 christos code->op3.type = X (OP_REG, SL);
2019 1.1 christos code->op3.reg = code->src.reg;
2020 1.1 christos code->op3.literal = 0;
2021 1.1 christos
2022 1.1 christos if (OP_KIND (code->src.type) == OP_INDEXB)
2023 1.1 christos {
2024 1.1 christos code->dst.type = X (OP_REG, SB);
2025 1.1 christos code->dst.reg = code->op3.reg + 8;
2026 1.1 christos }
2027 1.1 christos else
2028 1.1 christos code->dst.type = X (OP_REG, SW);
2029 1.1 christos }
2030 1.1 christos
2031 1.1 christos if (fetch (sd, &code->dst, &ea))
2032 1.1 christos goto end;
2033 1.1 christos
2034 1.1 christos switch (OP_KIND (code->src.type)) {
2035 1.1 christos case OP_INDEXB: ea = ea & 0xff; break;
2036 1.1 christos case OP_INDEXW: ea = ea & 0xffff; break;
2037 1.1 christos case OP_INDEXL: break;
2038 1.1 christos default: goto illegal;
2039 1.1 christos }
2040 1.1 christos
2041 1.1 christos switch (code->opcode) {
2042 1.1 christos case O (O_MOVAB, SL): break;
2043 1.1 christos case O (O_MOVAW, SL): ea = ea << 1; break;
2044 1.1 christos case O (O_MOVAL, SL): ea = ea << 2; break;
2045 1.1 christos default: goto illegal;
2046 1.1 christos }
2047 1.1 christos
2048 1.1 christos ea = ea + code->src.literal;
2049 1.1 christos
2050 1.1 christos if (store (sd, &code->op3, ea))
2051 1.1 christos goto end;
2052 1.1 christos
2053 1.1 christos goto next;
2054 1.1 christos
2055 1.1 christos case O (O_SUBX, SB): /* subx, extended sub */
2056 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2057 1.1 christos goto end;
2058 1.1 christos if (fetch (sd, &code->src, &ea))
2059 1.1 christos goto end;
2060 1.1 christos ea = -(ea + C);
2061 1.1 christos res = rd + ea;
2062 1.1 christos goto alu8;
2063 1.1 christos
2064 1.1 christos case O (O_SUBX, SW): /* subx, extended sub */
2065 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2066 1.1 christos goto end;
2067 1.1 christos if (fetch (sd, &code->src, &ea))
2068 1.1 christos goto end;
2069 1.1 christos ea = -(ea + C);
2070 1.1 christos res = rd + ea;
2071 1.1 christos goto alu16;
2072 1.1 christos
2073 1.1 christos case O (O_SUBX, SL): /* subx, extended sub */
2074 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2075 1.1 christos goto end;
2076 1.1 christos if (fetch (sd, &code->src, &ea))
2077 1.1 christos goto end;
2078 1.1 christos ea = -(ea + C);
2079 1.1 christos res = rd + ea;
2080 1.1 christos goto alu32;
2081 1.1 christos
2082 1.1 christos case O (O_ADDX, SB): /* addx, extended add */
2083 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2084 1.1 christos goto end;
2085 1.1 christos if (fetch (sd, &code->src, &ea))
2086 1.1 christos goto end;
2087 1.1 christos ea = ea + C;
2088 1.1 christos res = rd + ea;
2089 1.1 christos goto alu8;
2090 1.1 christos
2091 1.1 christos case O (O_ADDX, SW): /* addx, extended add */
2092 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2093 1.1 christos goto end;
2094 1.1 christos if (fetch (sd, &code->src, &ea))
2095 1.1 christos goto end;
2096 1.1 christos ea = ea + C;
2097 1.1 christos res = rd + ea;
2098 1.1 christos goto alu16;
2099 1.1 christos
2100 1.1 christos case O (O_ADDX, SL): /* addx, extended add */
2101 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2102 1.1 christos goto end;
2103 1.1 christos if (fetch (sd, &code->src, &ea))
2104 1.1 christos goto end;
2105 1.1 christos ea = ea + C;
2106 1.1 christos res = rd + ea;
2107 1.1 christos goto alu32;
2108 1.1 christos
2109 1.1 christos case O (O_SUB, SB): /* sub.b */
2110 1.1 christos /* Fetch rd and ea. */
2111 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2112 1.1 christos goto end;
2113 1.1 christos ea = -ea;
2114 1.1 christos res = rd + ea;
2115 1.1 christos goto alu8;
2116 1.1 christos
2117 1.1 christos case O (O_SUB, SW): /* sub.w */
2118 1.1 christos /* Fetch rd and ea. */
2119 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2120 1.1 christos goto end;
2121 1.1 christos ea = -ea;
2122 1.1 christos res = rd + ea;
2123 1.1 christos goto alu16;
2124 1.1 christos
2125 1.1 christos case O (O_SUB, SL): /* sub.l */
2126 1.1 christos /* Fetch rd and ea. */
2127 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2128 1.1 christos goto end;
2129 1.1 christos ea = -ea;
2130 1.1 christos res = rd + ea;
2131 1.1 christos goto alu32;
2132 1.1 christos
2133 1.1 christos case O (O_NEG, SB): /* neg.b */
2134 1.1 christos /* Fetch ea. */
2135 1.1 christos if (fetch2 (sd, &code->src, &ea))
2136 1.1 christos goto end;
2137 1.1 christos ea = -ea;
2138 1.1 christos rd = 0;
2139 1.1 christos res = rd + ea;
2140 1.1 christos goto alu8;
2141 1.1 christos
2142 1.1 christos case O (O_NEG, SW): /* neg.w */
2143 1.1 christos /* Fetch ea. */
2144 1.1 christos if (fetch2 (sd, &code->src, &ea))
2145 1.1 christos goto end;
2146 1.1 christos ea = -ea;
2147 1.1 christos rd = 0;
2148 1.1 christos res = rd + ea;
2149 1.1 christos goto alu16;
2150 1.1 christos
2151 1.1 christos case O (O_NEG, SL): /* neg.l */
2152 1.1 christos /* Fetch ea. */
2153 1.1 christos if (fetch2 (sd, &code->src, &ea))
2154 1.1 christos goto end;
2155 1.1 christos ea = -ea;
2156 1.1 christos rd = 0;
2157 1.1 christos res = rd + ea;
2158 1.1 christos goto alu32;
2159 1.1 christos
2160 1.1 christos case O (O_ADD, SB): /* add.b */
2161 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2162 1.1 christos goto end;
2163 1.1 christos if (fetch (sd, &code->src, &ea))
2164 1.1 christos goto end;
2165 1.1 christos res = rd + ea;
2166 1.1 christos goto alu8;
2167 1.1 christos
2168 1.1 christos case O (O_ADD, SW): /* add.w */
2169 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2170 1.1 christos goto end;
2171 1.1 christos if (fetch (sd, &code->src, &ea))
2172 1.1 christos goto end;
2173 1.1 christos res = rd + ea;
2174 1.1 christos goto alu16;
2175 1.1 christos
2176 1.1 christos case O (O_ADD, SL): /* add.l */
2177 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2178 1.1 christos goto end;
2179 1.1 christos if (fetch (sd, &code->src, &ea))
2180 1.1 christos goto end;
2181 1.1 christos res = rd + ea;
2182 1.1 christos goto alu32;
2183 1.1 christos
2184 1.1 christos case O (O_AND, SB): /* and.b */
2185 1.1 christos /* Fetch rd and ea. */
2186 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2187 1.1 christos goto end;
2188 1.1 christos res = rd & ea;
2189 1.1 christos goto log8;
2190 1.1 christos
2191 1.1 christos case O (O_AND, SW): /* and.w */
2192 1.1 christos /* Fetch rd and ea. */
2193 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2194 1.1 christos goto end;
2195 1.1 christos res = rd & ea;
2196 1.1 christos goto log16;
2197 1.1 christos
2198 1.1 christos case O (O_AND, SL): /* and.l */
2199 1.1 christos /* Fetch rd and ea. */
2200 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2201 1.1 christos goto end;
2202 1.1 christos res = rd & ea;
2203 1.1 christos goto log32;
2204 1.1 christos
2205 1.1 christos case O (O_OR, SB): /* or.b */
2206 1.1 christos /* Fetch rd and ea. */
2207 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2208 1.1 christos goto end;
2209 1.1 christos res = rd | ea;
2210 1.1 christos goto log8;
2211 1.1 christos
2212 1.1 christos case O (O_OR, SW): /* or.w */
2213 1.1 christos /* Fetch rd and ea. */
2214 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2215 1.1 christos goto end;
2216 1.1 christos res = rd | ea;
2217 1.1 christos goto log16;
2218 1.1 christos
2219 1.1 christos case O (O_OR, SL): /* or.l */
2220 1.1 christos /* Fetch rd and ea. */
2221 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2222 1.1 christos goto end;
2223 1.1 christos res = rd | ea;
2224 1.1 christos goto log32;
2225 1.1 christos
2226 1.1 christos case O (O_XOR, SB): /* xor.b */
2227 1.1 christos /* Fetch rd and ea. */
2228 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2229 1.1 christos goto end;
2230 1.1 christos res = rd ^ ea;
2231 1.1 christos goto log8;
2232 1.1 christos
2233 1.1 christos case O (O_XOR, SW): /* xor.w */
2234 1.1 christos /* Fetch rd and ea. */
2235 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2236 1.1 christos goto end;
2237 1.1 christos res = rd ^ ea;
2238 1.1 christos goto log16;
2239 1.1 christos
2240 1.1 christos case O (O_XOR, SL): /* xor.l */
2241 1.1 christos /* Fetch rd and ea. */
2242 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2243 1.1 christos goto end;
2244 1.1 christos res = rd ^ ea;
2245 1.1 christos goto log32;
2246 1.1 christos
2247 1.1 christos case O (O_MOV, SB):
2248 1.1 christos if (fetch (sd, &code->src, &res))
2249 1.1 christos goto end;
2250 1.1 christos if (store (sd, &code->dst, res))
2251 1.1 christos goto end;
2252 1.1 christos goto just_flags_log8;
2253 1.1 christos case O (O_MOV, SW):
2254 1.1 christos if (fetch (sd, &code->src, &res))
2255 1.1 christos goto end;
2256 1.1 christos if (store (sd, &code->dst, res))
2257 1.1 christos goto end;
2258 1.1 christos goto just_flags_log16;
2259 1.1 christos case O (O_MOV, SL):
2260 1.1 christos if (fetch (sd, &code->src, &res))
2261 1.1 christos goto end;
2262 1.1 christos if (store (sd, &code->dst, res))
2263 1.1 christos goto end;
2264 1.1 christos goto just_flags_log32;
2265 1.1 christos
2266 1.1 christos case O (O_MOVMD, SB): /* movmd.b */
2267 1.1 christos ea = GET_W_REG (4);
2268 1.1 christos if (ea == 0)
2269 1.1 christos ea = 0x10000;
2270 1.1 christos
2271 1.1 christos while (ea--)
2272 1.1 christos {
2273 1.1 christos rd = GET_MEMORY_B (GET_L_REG (5));
2274 1.1 christos SET_MEMORY_B (GET_L_REG (6), rd);
2275 1.1 christos SET_L_REG (5, GET_L_REG (5) + 1);
2276 1.1 christos SET_L_REG (6, GET_L_REG (6) + 1);
2277 1.1 christos SET_W_REG (4, ea);
2278 1.1 christos }
2279 1.1 christos goto next;
2280 1.1 christos
2281 1.1 christos case O (O_MOVMD, SW): /* movmd.w */
2282 1.1 christos ea = GET_W_REG (4);
2283 1.1 christos if (ea == 0)
2284 1.1 christos ea = 0x10000;
2285 1.1 christos
2286 1.1 christos while (ea--)
2287 1.1 christos {
2288 1.1 christos rd = GET_MEMORY_W (GET_L_REG (5));
2289 1.1 christos SET_MEMORY_W (GET_L_REG (6), rd);
2290 1.1 christos SET_L_REG (5, GET_L_REG (5) + 2);
2291 1.1 christos SET_L_REG (6, GET_L_REG (6) + 2);
2292 1.1 christos SET_W_REG (4, ea);
2293 1.1 christos }
2294 1.1 christos goto next;
2295 1.1 christos
2296 1.1 christos case O (O_MOVMD, SL): /* movmd.l */
2297 1.1 christos ea = GET_W_REG (4);
2298 1.1 christos if (ea == 0)
2299 1.1 christos ea = 0x10000;
2300 1.1 christos
2301 1.1 christos while (ea--)
2302 1.1 christos {
2303 1.1 christos rd = GET_MEMORY_L (GET_L_REG (5));
2304 1.1 christos SET_MEMORY_L (GET_L_REG (6), rd);
2305 1.1 christos SET_L_REG (5, GET_L_REG (5) + 4);
2306 1.1 christos SET_L_REG (6, GET_L_REG (6) + 4);
2307 1.1 christos SET_W_REG (4, ea);
2308 1.1 christos }
2309 1.1 christos goto next;
2310 1.1 christos
2311 1.1 christos case O (O_MOVSD, SB): /* movsd.b */
2312 1.1 christos /* This instruction implements strncpy, with a conditional branch.
2313 1.1 christos r4 contains n, r5 contains src, and r6 contains dst.
2314 1.1 christos The 16-bit displacement operand is added to the pc
2315 1.1 christos if and only if the end of string is reached before
2316 1.1 christos n bytes are transferred. */
2317 1.1 christos
2318 1.1 christos ea = GET_L_REG (4) & 0xffff;
2319 1.1 christos if (ea == 0)
2320 1.1 christos ea = 0x10000;
2321 1.1 christos
2322 1.1 christos while (ea--)
2323 1.1 christos {
2324 1.1 christos rd = GET_MEMORY_B (GET_L_REG (5));
2325 1.1 christos SET_MEMORY_B (GET_L_REG (6), rd);
2326 1.1 christos SET_L_REG (5, GET_L_REG (5) + 1);
2327 1.1 christos SET_L_REG (6, GET_L_REG (6) + 1);
2328 1.1 christos SET_W_REG (4, ea);
2329 1.1 christos if (rd == 0)
2330 1.1 christos goto condtrue;
2331 1.1 christos }
2332 1.1 christos goto next;
2333 1.1 christos
2334 1.1 christos case O (O_EEPMOV, SB): /* eepmov.b */
2335 1.1 christos case O (O_EEPMOV, SW): /* eepmov.w */
2336 1.1 christos if (h8300hmode || h8300smode)
2337 1.1 christos {
2338 1.1 christos register unsigned char *_src, *_dst;
2339 1.1 christos unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
2340 1.1 christos ? h8_get_reg (sd, R4_REGNUM) & 0xffff
2341 1.1 christos : h8_get_reg (sd, R4_REGNUM) & 0xff);
2342 1.1 christos
2343 1.1 christos _src = (h8_get_reg (sd, R5_REGNUM) < memory_size
2344 1.1 christos ? h8_get_memory_buf (sd) + h8_get_reg (sd, R5_REGNUM)
2345 1.1 christos : h8_get_eightbit_buf (sd) +
2346 1.1 christos (h8_get_reg (sd, R5_REGNUM) & 0xff));
2347 1.1 christos if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size))
2348 1.1 christos {
2349 1.1 christos if ((_src + count) >= (h8_get_eightbit_buf (sd) + 0x100))
2350 1.1 christos goto illegal;
2351 1.1 christos }
2352 1.1 christos _dst = (h8_get_reg (sd, R6_REGNUM) < memory_size
2353 1.1 christos ? h8_get_memory_buf (sd) + h8_get_reg (sd, R6_REGNUM)
2354 1.1 christos : h8_get_eightbit_buf (sd) +
2355 1.1 christos (h8_get_reg (sd, R6_REGNUM) & 0xff));
2356 1.1 christos
2357 1.1 christos if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size))
2358 1.1 christos {
2359 1.1 christos if ((_dst + count) >= (h8_get_eightbit_buf (sd) + 0x100))
2360 1.1 christos goto illegal;
2361 1.1 christos }
2362 1.1 christos memcpy (_dst, _src, count);
2363 1.1 christos
2364 1.1 christos h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count);
2365 1.1 christos h8_set_reg (sd, R6_REGNUM, h8_get_reg (sd, R6_REGNUM) + count);
2366 1.1 christos h8_set_reg (sd, R4_REGNUM, h8_get_reg (sd, R4_REGNUM) &
2367 1.1 christos ((code->opcode == O (O_EEPMOV, SW))
2368 1.1 christos ? (~0xffff) : (~0xff)));
2369 1.1 christos cycles += 2 * count;
2370 1.1 christos goto next;
2371 1.1 christos }
2372 1.1 christos goto illegal;
2373 1.1 christos
2374 1.1 christos case O (O_ADDS, SL): /* adds (.l) */
2375 1.1 christos /* FIXME fetch.
2376 1.1 christos * This insn only uses register operands, but still
2377 1.1 christos * it would be cleaner to use fetch and store... */
2378 1.1 christos SET_L_REG (code->dst.reg,
2379 1.1 christos GET_L_REG (code->dst.reg)
2380 1.1 christos + code->src.literal);
2381 1.1 christos
2382 1.1 christos goto next;
2383 1.1 christos
2384 1.1 christos case O (O_SUBS, SL): /* subs (.l) */
2385 1.1 christos /* FIXME fetch.
2386 1.1 christos * This insn only uses register operands, but still
2387 1.1 christos * it would be cleaner to use fetch and store... */
2388 1.1 christos SET_L_REG (code->dst.reg,
2389 1.1 christos GET_L_REG (code->dst.reg)
2390 1.1 christos - code->src.literal);
2391 1.1 christos goto next;
2392 1.1 christos
2393 1.1 christos case O (O_CMP, SB): /* cmp.b */
2394 1.1 christos if (fetch (sd, &code->dst, &rd))
2395 1.1 christos goto end;
2396 1.1 christos if (fetch (sd, &code->src, &ea))
2397 1.1 christos goto end;
2398 1.1 christos ea = -ea;
2399 1.1 christos res = rd + ea;
2400 1.1 christos goto just_flags_alu8;
2401 1.1 christos
2402 1.1 christos case O (O_CMP, SW): /* cmp.w */
2403 1.1 christos if (fetch (sd, &code->dst, &rd))
2404 1.1 christos goto end;
2405 1.1 christos if (fetch (sd, &code->src, &ea))
2406 1.1 christos goto end;
2407 1.1 christos ea = -ea;
2408 1.1 christos res = rd + ea;
2409 1.1 christos goto just_flags_alu16;
2410 1.1 christos
2411 1.1 christos case O (O_CMP, SL): /* cmp.l */
2412 1.1 christos if (fetch (sd, &code->dst, &rd))
2413 1.1 christos goto end;
2414 1.1 christos if (fetch (sd, &code->src, &ea))
2415 1.1 christos goto end;
2416 1.1 christos ea = -ea;
2417 1.1 christos res = rd + ea;
2418 1.1 christos goto just_flags_alu32;
2419 1.1 christos
2420 1.1 christos case O (O_DEC, SB): /* dec.b */
2421 1.1 christos /* FIXME fetch.
2422 1.1 christos * This insn only uses register operands, but still
2423 1.1 christos * it would be cleaner to use fetch and store... */
2424 1.1 christos rd = GET_B_REG (code->src.reg);
2425 1.1 christos ea = -1;
2426 1.1 christos res = rd + ea;
2427 1.1 christos SET_B_REG (code->src.reg, res);
2428 1.1 christos goto just_flags_inc8;
2429 1.1 christos
2430 1.1 christos case O (O_DEC, SW): /* dec.w */
2431 1.1 christos /* FIXME fetch.
2432 1.1 christos * This insn only uses register operands, but still
2433 1.1 christos * it would be cleaner to use fetch and store... */
2434 1.1 christos rd = GET_W_REG (code->dst.reg);
2435 1.1 christos ea = -code->src.literal;
2436 1.1 christos res = rd + ea;
2437 1.1 christos SET_W_REG (code->dst.reg, res);
2438 1.1 christos goto just_flags_inc16;
2439 1.1 christos
2440 1.1 christos case O (O_DEC, SL): /* dec.l */
2441 1.1 christos /* FIXME fetch.
2442 1.1 christos * This insn only uses register operands, but still
2443 1.1 christos * it would be cleaner to use fetch and store... */
2444 1.1 christos rd = GET_L_REG (code->dst.reg);
2445 1.1 christos ea = -code->src.literal;
2446 1.1 christos res = rd + ea;
2447 1.1 christos SET_L_REG (code->dst.reg, res);
2448 1.1 christos goto just_flags_inc32;
2449 1.1 christos
2450 1.1 christos case O (O_INC, SB): /* inc.b */
2451 1.1 christos /* FIXME fetch.
2452 1.1 christos * This insn only uses register operands, but still
2453 1.1 christos * it would be cleaner to use fetch and store... */
2454 1.1 christos rd = GET_B_REG (code->src.reg);
2455 1.1 christos ea = 1;
2456 1.1 christos res = rd + ea;
2457 1.1 christos SET_B_REG (code->src.reg, res);
2458 1.1 christos goto just_flags_inc8;
2459 1.1 christos
2460 1.1 christos case O (O_INC, SW): /* inc.w */
2461 1.1 christos /* FIXME fetch.
2462 1.1 christos * This insn only uses register operands, but still
2463 1.1 christos * it would be cleaner to use fetch and store... */
2464 1.1 christos rd = GET_W_REG (code->dst.reg);
2465 1.1 christos ea = code->src.literal;
2466 1.1 christos res = rd + ea;
2467 1.1 christos SET_W_REG (code->dst.reg, res);
2468 1.1 christos goto just_flags_inc16;
2469 1.1 christos
2470 1.1 christos case O (O_INC, SL): /* inc.l */
2471 1.1 christos /* FIXME fetch.
2472 1.1 christos * This insn only uses register operands, but still
2473 1.1 christos * it would be cleaner to use fetch and store... */
2474 1.1 christos rd = GET_L_REG (code->dst.reg);
2475 1.1 christos ea = code->src.literal;
2476 1.1 christos res = rd + ea;
2477 1.1 christos SET_L_REG (code->dst.reg, res);
2478 1.1 christos goto just_flags_inc32;
2479 1.1 christos
2480 1.1 christos case O (O_LDC, SB): /* ldc.b */
2481 1.1 christos if (fetch (sd, &code->src, &res))
2482 1.1 christos goto end;
2483 1.1 christos goto setc;
2484 1.1 christos
2485 1.1 christos case O (O_LDC, SW): /* ldc.w */
2486 1.1 christos if (fetch (sd, &code->src, &res))
2487 1.1 christos goto end;
2488 1.1 christos
2489 1.1 christos /* Word operand, value from MSB, must be shifted. */
2490 1.1 christos res >>= 8;
2491 1.1 christos goto setc;
2492 1.1 christos
2493 1.1 christos case O (O_LDC, SL): /* ldc.l */
2494 1.1 christos if (fetch (sd, &code->src, &res))
2495 1.1 christos goto end;
2496 1.1 christos switch (code->dst.type) {
2497 1.1 christos case X (OP_SBR, SL):
2498 1.1 christos h8_set_sbr (sd, res);
2499 1.1 christos break;
2500 1.1 christos case X (OP_VBR, SL):
2501 1.1 christos h8_set_vbr (sd, res);
2502 1.1 christos break;
2503 1.1 christos default:
2504 1.1 christos goto illegal;
2505 1.1 christos }
2506 1.1 christos goto next;
2507 1.1 christos
2508 1.1 christos case O (O_STC, SW): /* stc.w */
2509 1.1 christos case O (O_STC, SB): /* stc.b */
2510 1.1 christos if (code->src.type == X (OP_CCR, SB))
2511 1.1 christos {
2512 1.1 christos BUILDSR (sd);
2513 1.1 christos res = h8_get_ccr (sd);
2514 1.1 christos }
2515 1.1 christos else if (code->src.type == X (OP_EXR, SB) && h8300smode)
2516 1.1 christos {
2517 1.1 christos if (h8300smode)
2518 1.1 christos h8_set_exr (sd, (trace << 7) | intMask);
2519 1.1 christos res = h8_get_exr (sd);
2520 1.1 christos }
2521 1.1 christos else
2522 1.1 christos goto illegal;
2523 1.1 christos
2524 1.1 christos /* Word operand, value to MSB, must be shifted. */
2525 1.1 christos if (code->opcode == X (O_STC, SW))
2526 1.1 christos res <<= 8;
2527 1.1 christos if (store (sd, &code->dst, res))
2528 1.1 christos goto end;
2529 1.1 christos goto next;
2530 1.1 christos case O (O_STC, SL): /* stc.l */
2531 1.1 christos switch (code->src.type) {
2532 1.1 christos case X (OP_SBR, SL):
2533 1.1 christos res = h8_get_sbr (sd);
2534 1.1 christos break;
2535 1.1 christos case X (OP_VBR, SL):
2536 1.1 christos res = h8_get_vbr (sd);
2537 1.1 christos break;
2538 1.1 christos default:
2539 1.1 christos goto illegal;
2540 1.1 christos }
2541 1.1 christos if (store (sd, &code->dst, res))
2542 1.1 christos goto end;
2543 1.1 christos goto next;
2544 1.1 christos
2545 1.1 christos case O (O_ANDC, SB): /* andc.b */
2546 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2547 1.1 christos {
2548 1.1 christos BUILDSR (sd);
2549 1.1 christos rd = h8_get_ccr (sd);
2550 1.1 christos }
2551 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2552 1.1 christos {
2553 1.1 christos if (h8300smode)
2554 1.1 christos h8_set_exr (sd, (trace << 7) | intMask);
2555 1.1 christos rd = h8_get_exr (sd);
2556 1.1 christos }
2557 1.1 christos else
2558 1.1 christos goto illegal;
2559 1.1 christos ea = code->src.literal;
2560 1.1 christos res = rd & ea;
2561 1.1 christos goto setc;
2562 1.1 christos
2563 1.1 christos case O (O_ORC, SB): /* orc.b */
2564 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2565 1.1 christos {
2566 1.1 christos BUILDSR (sd);
2567 1.1 christos rd = h8_get_ccr (sd);
2568 1.1 christos }
2569 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2570 1.1 christos {
2571 1.1 christos if (h8300smode)
2572 1.1 christos h8_set_exr (sd, (trace << 7) | intMask);
2573 1.1 christos rd = h8_get_exr (sd);
2574 1.1 christos }
2575 1.1 christos else
2576 1.1 christos goto illegal;
2577 1.1 christos ea = code->src.literal;
2578 1.1 christos res = rd | ea;
2579 1.1 christos goto setc;
2580 1.1 christos
2581 1.1 christos case O (O_XORC, SB): /* xorc.b */
2582 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2583 1.1 christos {
2584 1.1 christos BUILDSR (sd);
2585 1.1 christos rd = h8_get_ccr (sd);
2586 1.1 christos }
2587 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2588 1.1 christos {
2589 1.1 christos if (h8300smode)
2590 1.1 christos h8_set_exr (sd, (trace << 7) | intMask);
2591 1.1 christos rd = h8_get_exr (sd);
2592 1.1 christos }
2593 1.1 christos else
2594 1.1 christos goto illegal;
2595 1.1 christos ea = code->src.literal;
2596 1.1 christos res = rd ^ ea;
2597 1.1 christos goto setc;
2598 1.1 christos
2599 1.1 christos case O (O_BRAS, SB): /* bra/s */
2600 1.1 christos /* This is basically an ordinary branch, with a delay slot. */
2601 1.1 christos if (fetch (sd, &code->src, &res))
2602 1.1 christos goto end;
2603 1.1 christos
2604 1.1 christos if ((res & 1) == 0)
2605 1.1 christos goto illegal;
2606 1.1 christos
2607 1.1 christos res -= 1;
2608 1.1 christos
2609 1.1 christos /* Execution continues at next instruction, but
2610 1.1 christos delayed_branch is set up for next cycle. */
2611 1.1 christos h8_set_delayed_branch (sd, code->next_pc + res);
2612 1.1 christos pc = code->next_pc;
2613 1.1 christos goto end;
2614 1.1 christos
2615 1.1 christos case O (O_BRAB, SB): /* bra rd.b */
2616 1.1 christos case O (O_BRAW, SW): /* bra rd.w */
2617 1.1 christos case O (O_BRAL, SL): /* bra erd.l */
2618 1.1 christos if (fetch (sd, &code->src, &rd))
2619 1.1 christos goto end;
2620 1.1 christos switch (OP_SIZE (code->opcode)) {
2621 1.1 christos case SB: rd &= 0xff; break;
2622 1.1 christos case SW: rd &= 0xffff; break;
2623 1.1 christos case SL: rd &= 0xffffffff; break;
2624 1.1 christos }
2625 1.1 christos pc = code->next_pc + rd;
2626 1.1 christos goto end;
2627 1.1 christos
2628 1.1 christos case O (O_BRABC, SB): /* bra/bc, branch if bit clear */
2629 1.1 christos case O (O_BRABS, SB): /* bra/bs, branch if bit set */
2630 1.1 christos case O (O_BSRBC, SB): /* bsr/bc, call if bit clear */
2631 1.1 christos case O (O_BSRBS, SB): /* bsr/bs, call if bit set */
2632 1.1 christos if (fetch (sd, &code->dst, &rd) ||
2633 1.1 christos fetch (sd, &code->src, &bit))
2634 1.1 christos goto end;
2635 1.1 christos
2636 1.1 christos if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
2637 1.1 christos code->opcode == O (O_BSRBC, SB)) /* call if clear */
2638 1.1 christos {
2639 1.1 christos if ((rd & (1 << bit))) /* no branch */
2640 1.1 christos goto next;
2641 1.1 christos }
2642 1.1 christos else /* branch/call if set */
2643 1.1 christos {
2644 1.1 christos if (!(rd & (1 << bit))) /* no branch */
2645 1.1 christos goto next;
2646 1.1 christos }
2647 1.1 christos
2648 1.1 christos if (fetch (sd, &code->op3, &res)) /* branch */
2649 1.1 christos goto end;
2650 1.1 christos pc = code->next_pc + res;
2651 1.1 christos
2652 1.1 christos if (code->opcode == O (O_BRABC, SB) ||
2653 1.1 christos code->opcode == O (O_BRABS, SB)) /* branch */
2654 1.1 christos goto end;
2655 1.1 christos else /* call */
2656 1.1 christos goto call;
2657 1.1 christos
2658 1.1 christos case O (O_BRA, SN):
2659 1.1 christos case O (O_BRA, SL):
2660 1.1 christos case O (O_BRA, SW):
2661 1.1 christos case O (O_BRA, SB): /* bra, branch always */
2662 1.1 christos if (1)
2663 1.1 christos goto condtrue;
2664 1.1 christos goto next;
2665 1.1 christos
2666 1.1 christos case O (O_BRN, SB): /* brn, ;-/ branch never? */
2667 1.1 christos if (0)
2668 1.1 christos goto condtrue;
2669 1.1 christos goto next;
2670 1.1 christos
2671 1.1 christos case O (O_BHI, SB): /* bhi */
2672 1.1 christos if ((C || Z) == 0)
2673 1.1 christos goto condtrue;
2674 1.1 christos goto next;
2675 1.1 christos
2676 1.1 christos
2677 1.1 christos case O (O_BLS, SB): /* bls */
2678 1.1 christos if ((C || Z))
2679 1.1 christos goto condtrue;
2680 1.1 christos goto next;
2681 1.1 christos
2682 1.1 christos case O (O_BCS, SB): /* bcs, branch if carry set */
2683 1.1 christos if ((C == 1))
2684 1.1 christos goto condtrue;
2685 1.1 christos goto next;
2686 1.1 christos
2687 1.1 christos case O (O_BCC, SB): /* bcc, branch if carry clear */
2688 1.1 christos if ((C == 0))
2689 1.1 christos goto condtrue;
2690 1.1 christos goto next;
2691 1.1 christos
2692 1.1 christos case O (O_BEQ, SB): /* beq, branch if zero set */
2693 1.1 christos if (Z)
2694 1.1 christos goto condtrue;
2695 1.1 christos goto next;
2696 1.1 christos case O (O_BGT, SB): /* bgt */
2697 1.1 christos if (((Z || (N ^ V)) == 0))
2698 1.1 christos goto condtrue;
2699 1.1 christos goto next;
2700 1.1 christos
2701 1.1 christos case O (O_BLE, SB): /* ble */
2702 1.1 christos if (((Z || (N ^ V)) == 1))
2703 1.1 christos goto condtrue;
2704 1.1 christos goto next;
2705 1.1 christos
2706 1.1 christos case O (O_BGE, SB): /* bge */
2707 1.1 christos if ((N ^ V) == 0)
2708 1.1 christos goto condtrue;
2709 1.1 christos goto next;
2710 1.1 christos case O (O_BLT, SB): /* blt */
2711 1.1 christos if ((N ^ V))
2712 1.1 christos goto condtrue;
2713 1.1 christos goto next;
2714 1.1 christos case O (O_BMI, SB): /* bmi */
2715 1.1 christos if ((N))
2716 1.1 christos goto condtrue;
2717 1.1 christos goto next;
2718 1.1 christos case O (O_BNE, SB): /* bne, branch if zero clear */
2719 1.1 christos if ((Z == 0))
2720 1.1 christos goto condtrue;
2721 1.1 christos goto next;
2722 1.1 christos
2723 1.1 christos case O (O_BPL, SB): /* bpl */
2724 1.1 christos if (N == 0)
2725 1.1 christos goto condtrue;
2726 1.1 christos goto next;
2727 1.1 christos case O (O_BVC, SB): /* bvc */
2728 1.1 christos if ((V == 0))
2729 1.1 christos goto condtrue;
2730 1.1 christos goto next;
2731 1.1 christos case O (O_BVS, SB): /* bvs */
2732 1.1 christos if ((V == 1))
2733 1.1 christos goto condtrue;
2734 1.1 christos goto next;
2735 1.1 christos
2736 1.1 christos /* Trap for Command Line setup. */
2737 1.1 christos case O (O_SYS_CMDLINE, SB):
2738 1.1 christos {
2739 1.1 christos int i = 0; /* Loop counter. */
2740 1.1 christos int j = 0; /* Loop counter. */
2741 1.1 christos int ind_arg_len = 0; /* Length of each argument. */
2742 1.1 christos int no_of_args = 0; /* The no. or cmdline args. */
2743 1.1 christos int current_location = 0; /* Location of string. */
2744 1.1 christos int old_sp = 0; /* The Initial Stack Pointer. */
2745 1.1 christos int no_of_slots = 0; /* No. of slots required on the stack
2746 1.1 christos for storing cmdline args. */
2747 1.1 christos int sp_move = 0; /* No. of locations by which the stack needs
2748 1.1 christos to grow. */
2749 1.1 christos int new_sp = 0; /* The final stack pointer location passed
2750 1.1 christos back. */
2751 1.1 christos int *argv_ptrs; /* Pointers of argv strings to be stored. */
2752 1.1 christos int argv_ptrs_location = 0; /* Location of pointers to cmdline
2753 1.1 christos args on the stack. */
2754 1.1 christos int char_ptr_size = 0; /* Size of a character pointer on
2755 1.1 christos target machine. */
2756 1.1 christos int addr_cmdline = 0; /* Memory location where cmdline has
2757 1.1 christos to be stored. */
2758 1.1 christos int size_cmdline = 0; /* Size of cmdline. */
2759 1.1 christos
2760 1.1 christos /* Set the address of 256 free locations where command line is
2761 1.1 christos stored. */
2762 1.1 christos addr_cmdline = cmdline_location();
2763 1.1 christos h8_set_reg (sd, 0, addr_cmdline);
2764 1.1 christos
2765 1.1 christos /* Counting the no. of commandline arguments. */
2766 1.1 christos for (i = 0; h8_get_cmdline_arg (sd, i) != NULL; i++)
2767 1.1 christos continue;
2768 1.1 christos
2769 1.1 christos /* No. of arguments in the command line. */
2770 1.1 christos no_of_args = i;
2771 1.1 christos
2772 1.1 christos /* Current location is just a temporary variable,which we are
2773 1.1 christos setting to the point to the start of our commandline string. */
2774 1.1 christos current_location = addr_cmdline;
2775 1.1 christos
2776 1.1 christos /* Allocating space for storing pointers of the command line
2777 1.1 christos arguments. */
2778 1.1 christos argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
2779 1.1 christos
2780 1.1 christos /* Setting char_ptr_size to the sizeof (char *) on the different
2781 1.1 christos architectures. */
2782 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2783 1.1 christos {
2784 1.1 christos char_ptr_size = 4;
2785 1.1 christos }
2786 1.1 christos else
2787 1.1 christos {
2788 1.1 christos char_ptr_size = 2;
2789 1.1 christos }
2790 1.1 christos
2791 1.1 christos for (i = 0; i < no_of_args; i++)
2792 1.1 christos {
2793 1.1 christos ind_arg_len = 0;
2794 1.1 christos
2795 1.1 christos /* The size of the commandline argument. */
2796 1.1 christos ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
2797 1.1 christos
2798 1.1 christos /* The total size of the command line string. */
2799 1.1 christos size_cmdline += ind_arg_len;
2800 1.1 christos
2801 1.1 christos /* As we have only 256 bytes, we need to provide a graceful
2802 1.1 christos exit. Anyways, a program using command line arguments
2803 1.1 christos where we cannot store all the command line arguments
2804 1.1 christos given may behave unpredictably. */
2805 1.1 christos if (size_cmdline >= 256)
2806 1.1 christos {
2807 1.1 christos h8_set_reg (sd, 0, 0);
2808 1.1 christos goto next;
2809 1.1 christos }
2810 1.1 christos else
2811 1.1 christos {
2812 1.1 christos /* current_location points to the memory where the next
2813 1.1 christos commandline argument is stored. */
2814 1.1 christos argv_ptrs[i] = current_location;
2815 1.1 christos for (j = 0; j < ind_arg_len; j++)
2816 1.1 christos {
2817 1.1 christos SET_MEMORY_B ((current_location +
2818 1.1 christos (sizeof (char) * j)),
2819 1.1 christos *(h8_get_cmdline_arg (sd, i) +
2820 1.1 christos sizeof (char) * j));
2821 1.1 christos }
2822 1.1 christos
2823 1.1 christos /* Setting current_location to the starting of next
2824 1.1 christos argument. */
2825 1.1 christos current_location += ind_arg_len;
2826 1.1 christos }
2827 1.1 christos }
2828 1.1 christos
2829 1.1 christos /* This is the original position of the stack pointer. */
2830 1.1 christos old_sp = h8_get_reg (sd, SP_REGNUM);
2831 1.1 christos
2832 1.1 christos /* We need space from the stack to store the pointers to argvs. */
2833 1.1 christos /* As we will infringe on the stack, we need to shift the stack
2834 1.1 christos pointer so that the data is not overwritten. We calculate how
2835 1.1 christos much space is required. */
2836 1.1 christos sp_move = (no_of_args) * (char_ptr_size);
2837 1.1 christos
2838 1.1 christos /* The final position of stack pointer, we have thus taken some
2839 1.1 christos space from the stack. */
2840 1.1 christos new_sp = old_sp - sp_move;
2841 1.1 christos
2842 1.1 christos /* Temporary variable holding value where the argv pointers need
2843 1.1 christos to be stored. */
2844 1.1 christos argv_ptrs_location = new_sp;
2845 1.1 christos
2846 1.1 christos /* The argv pointers are stored at sequential locations. As per
2847 1.1 christos the H8300 ABI. */
2848 1.1 christos for (i = 0; i < no_of_args; i++)
2849 1.1 christos {
2850 1.1 christos /* Saving the argv pointer. */
2851 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2852 1.1 christos {
2853 1.1 christos SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
2854 1.1 christos }
2855 1.1 christos else
2856 1.1 christos {
2857 1.1 christos SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
2858 1.1 christos }
2859 1.1 christos
2860 1.1 christos /* The next location where the pointer to the next argv
2861 1.1 christos string has to be stored. */
2862 1.1 christos argv_ptrs_location += char_ptr_size;
2863 1.1 christos }
2864 1.1 christos
2865 1.1 christos /* Required by POSIX, Setting 0x0 at the end of the list of argv
2866 1.1 christos pointers. */
2867 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2868 1.1 christos {
2869 1.1 christos SET_MEMORY_L (old_sp, 0x0);
2870 1.1 christos }
2871 1.1 christos else
2872 1.1 christos {
2873 1.1 christos SET_MEMORY_W (old_sp, 0x0);
2874 1.1 christos }
2875 1.1 christos
2876 1.1 christos /* Freeing allocated memory. */
2877 1.1 christos free (argv_ptrs);
2878 1.1 christos for (i = 0; i <= no_of_args; i++)
2879 1.1 christos {
2880 1.1 christos free (h8_get_cmdline_arg (sd, i));
2881 1.1 christos }
2882 1.1 christos free (h8_get_command_line (sd));
2883 1.1 christos
2884 1.1 christos /* The no. of argv arguments are returned in Reg 0. */
2885 1.1 christos h8_set_reg (sd, 0, no_of_args);
2886 1.1 christos /* The Pointer to argv in Register 1. */
2887 1.1 christos h8_set_reg (sd, 1, new_sp);
2888 1.1 christos /* Setting the stack pointer to the new value. */
2889 1.1 christos h8_set_reg (sd, SP_REGNUM, new_sp);
2890 1.1 christos }
2891 1.1 christos goto next;
2892 1.1 christos
2893 1.1 christos /* System call processing starts. */
2894 1.1 christos case O (O_SYS_OPEN, SB):
2895 1.1 christos {
2896 1.1 christos int len = 0; /* Length of filename. */
2897 1.1 christos char *filename; /* Filename would go here. */
2898 1.1 christos char temp_char; /* Temporary character */
2899 1.1 christos int mode = 0; /* Mode bits for the file. */
2900 1.1 christos int open_return; /* Return value of open, file descriptor. */
2901 1.1 christos int i; /* Loop counter */
2902 1.1 christos int filename_ptr; /* Pointer to filename in cpu memory. */
2903 1.1 christos
2904 1.1 christos /* Setting filename_ptr to first argument of open, */
2905 1.1 christos /* and trying to get mode. */
2906 1.1 christos if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
2907 1.1 christos {
2908 1.1 christos filename_ptr = GET_L_REG (0);
2909 1.1 christos mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
2910 1.1 christos }
2911 1.1 christos else
2912 1.1 christos {
2913 1.1 christos filename_ptr = GET_W_REG (0);
2914 1.1 christos mode = GET_MEMORY_W (h8_get_reg (sd, SP_REGNUM) + 2);
2915 1.1 christos }
2916 1.1 christos
2917 1.1 christos /* Trying to find the length of the filename. */
2918 1.1 christos temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
2919 1.1 christos
2920 1.1 christos len = 1;
2921 1.1 christos while (temp_char != '\0')
2922 1.1 christos {
2923 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + len);
2924 1.1 christos len++;
2925 1.1 christos }
2926 1.1 christos
2927 1.1 christos /* Allocating space for the filename. */
2928 1.1 christos filename = (char *) malloc (sizeof (char) * len);
2929 1.1 christos
2930 1.1 christos /* String copying the filename from memory. */
2931 1.1 christos for (i = 0; i < len; i++)
2932 1.1 christos {
2933 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + i);
2934 1.1 christos filename[i] = temp_char;
2935 1.1 christos }
2936 1.1 christos
2937 1.1 christos /* Callback to open and return the file descriptor. */
2938 1.1 christos open_return = sim_callback->open (sim_callback, filename, mode);
2939 1.1 christos
2940 1.1 christos /* Return value in register 0. */
2941 1.1 christos h8_set_reg (sd, 0, open_return);
2942 1.1 christos
2943 1.1 christos /* Freeing memory used for filename. */
2944 1.1 christos free (filename);
2945 1.1 christos }
2946 1.1 christos goto next;
2947 1.1 christos
2948 1.1 christos case O (O_SYS_READ, SB):
2949 1.1 christos {
2950 1.1 christos char *char_ptr; /* Where characters read would be stored. */
2951 1.1 christos int fd; /* File descriptor */
2952 1.1 christos int buf_size; /* BUF_SIZE parameter in read. */
2953 1.1 christos int i = 0; /* Temporary Loop counter */
2954 1.1 christos int read_return = 0; /* Return value from callback to
2955 1.1 christos read. */
2956 1.1 christos
2957 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2958 1.1 christos buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
2959 1.1 christos
2960 1.1 christos char_ptr = (char *) malloc (sizeof (char) * buf_size);
2961 1.1 christos
2962 1.1 christos /* Callback to read and return the no. of characters read. */
2963 1.1 christos read_return =
2964 1.1 christos sim_callback->read (sim_callback, fd, char_ptr, buf_size);
2965 1.1 christos
2966 1.1 christos /* The characters read are stored in cpu memory. */
2967 1.1 christos for (i = 0; i < buf_size; i++)
2968 1.1 christos {
2969 1.1 christos SET_MEMORY_B ((h8_get_reg (sd, 1) + (sizeof (char) * i)),
2970 1.1 christos *(char_ptr + (sizeof (char) * i)));
2971 1.1 christos }
2972 1.1 christos
2973 1.1 christos /* Return value in Register 0. */
2974 1.1 christos h8_set_reg (sd, 0, read_return);
2975 1.1 christos
2976 1.1 christos /* Freeing memory used as buffer. */
2977 1.1 christos free (char_ptr);
2978 1.1 christos }
2979 1.1 christos goto next;
2980 1.1 christos
2981 1.1 christos case O (O_SYS_WRITE, SB):
2982 1.1 christos {
2983 1.1 christos int fd; /* File descriptor */
2984 1.1 christos char temp_char; /* Temporary character */
2985 1.1 christos int len; /* Length of write, Parameter II to write. */
2986 1.1 christos int char_ptr; /* Character Pointer, Parameter I of write. */
2987 1.1 christos char *ptr; /* Where characters to be written are stored.
2988 1.1 christos */
2989 1.1 christos int write_return; /* Return value from callback to write. */
2990 1.1 christos int i = 0; /* Loop counter */
2991 1.1 christos
2992 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2993 1.1 christos char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2994 1.1 christos len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
2995 1.1 christos
2996 1.1 christos /* Allocating space for the characters to be written. */
2997 1.1 christos ptr = (char *) malloc (sizeof (char) * len);
2998 1.1 christos
2999 1.1 christos /* Fetching the characters from cpu memory. */
3000 1.1 christos for (i = 0; i < len; i++)
3001 1.1 christos {
3002 1.1 christos temp_char = GET_MEMORY_B (char_ptr + i);
3003 1.1 christos ptr[i] = temp_char;
3004 1.1 christos }
3005 1.1 christos
3006 1.1 christos /* Callback write and return the no. of characters written. */
3007 1.1 christos write_return = sim_callback->write (sim_callback, fd, ptr, len);
3008 1.1 christos
3009 1.1 christos /* Return value in Register 0. */
3010 1.1 christos h8_set_reg (sd, 0, write_return);
3011 1.1 christos
3012 1.1 christos /* Freeing memory used as buffer. */
3013 1.1 christos free (ptr);
3014 1.1 christos }
3015 1.1 christos goto next;
3016 1.1 christos
3017 1.1 christos case O (O_SYS_LSEEK, SB):
3018 1.1 christos {
3019 1.1 christos int fd; /* File descriptor */
3020 1.1 christos int offset; /* Offset */
3021 1.1 christos int origin; /* Origin */
3022 1.1 christos int lseek_return; /* Return value from callback to lseek. */
3023 1.1 christos
3024 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3025 1.1 christos offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3026 1.1 christos origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
3027 1.1 christos
3028 1.1 christos /* Callback lseek and return offset. */
3029 1.1 christos lseek_return =
3030 1.1 christos sim_callback->lseek (sim_callback, fd, offset, origin);
3031 1.1 christos
3032 1.1 christos /* Return value in register 0. */
3033 1.1 christos h8_set_reg (sd, 0, lseek_return);
3034 1.1 christos }
3035 1.1 christos goto next;
3036 1.1 christos
3037 1.1 christos case O (O_SYS_CLOSE, SB):
3038 1.1 christos {
3039 1.1 christos int fd; /* File descriptor */
3040 1.1 christos int close_return; /* Return value from callback to close. */
3041 1.1 christos
3042 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3043 1.1 christos
3044 1.1 christos /* Callback close and return. */
3045 1.1 christos close_return = sim_callback->close (sim_callback, fd);
3046 1.1 christos
3047 1.1 christos /* Return value in register 0. */
3048 1.1 christos h8_set_reg (sd, 0, close_return);
3049 1.1 christos }
3050 1.1 christos goto next;
3051 1.1 christos
3052 1.1 christos case O (O_SYS_FSTAT, SB):
3053 1.1 christos {
3054 1.1 christos int fd; /* File descriptor */
3055 1.1 christos struct stat stat_rec; /* Stat record */
3056 1.1 christos int fstat_return; /* Return value from callback to stat. */
3057 1.1 christos int stat_ptr; /* Pointer to stat record. */
3058 1.1 christos char *temp_stat_ptr; /* Temporary stat_rec pointer. */
3059 1.1 christos
3060 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3061 1.1 christos
3062 1.1 christos /* Setting stat_ptr to second argument of stat. */
3063 1.1 christos stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3064 1.1 christos
3065 1.1 christos /* Callback stat and return. */
3066 1.1.1.2 christos fstat_return = sim_callback->to_fstat (sim_callback, fd,
3067 1.1.1.2 christos &stat_rec);
3068 1.1 christos
3069 1.1 christos /* Have stat_ptr point to starting of stat_rec. */
3070 1.1 christos temp_stat_ptr = (char *) (&stat_rec);
3071 1.1 christos
3072 1.1 christos /* Setting up the stat structure returned. */
3073 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
3074 1.1 christos stat_ptr += 2;
3075 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
3076 1.1 christos stat_ptr += 2;
3077 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
3078 1.1 christos stat_ptr += 4;
3079 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
3080 1.1 christos stat_ptr += 2;
3081 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
3082 1.1 christos stat_ptr += 2;
3083 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
3084 1.1 christos stat_ptr += 2;
3085 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
3086 1.1 christos stat_ptr += 2;
3087 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_size);
3088 1.1 christos stat_ptr += 4;
3089 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
3090 1.1 christos stat_ptr += 8;
3091 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
3092 1.1 christos stat_ptr += 8;
3093 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
3094 1.1 christos
3095 1.1 christos /* Return value in register 0. */
3096 1.1 christos h8_set_reg (sd, 0, fstat_return);
3097 1.1 christos }
3098 1.1 christos goto next;
3099 1.1 christos
3100 1.1 christos case O (O_SYS_STAT, SB):
3101 1.1 christos {
3102 1.1 christos int len = 0; /* Length of filename. */
3103 1.1 christos char *filename; /* Filename would go here. */
3104 1.1 christos char temp_char; /* Temporary character */
3105 1.1 christos int filename_ptr; /* Pointer to filename in cpu memory. */
3106 1.1 christos struct stat stat_rec; /* Stat record */
3107 1.1 christos int stat_return; /* Return value from callback to stat */
3108 1.1 christos int stat_ptr; /* Pointer to stat record. */
3109 1.1 christos char *temp_stat_ptr; /* Temporary stat_rec pointer. */
3110 1.1 christos int i = 0; /* Loop Counter */
3111 1.1 christos
3112 1.1 christos /* Setting filename_ptr to first argument of open. */
3113 1.1 christos filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3114 1.1 christos
3115 1.1 christos /* Trying to find the length of the filename. */
3116 1.1 christos temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
3117 1.1 christos
3118 1.1 christos len = 1;
3119 1.1 christos while (temp_char != '\0')
3120 1.1 christos {
3121 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + len);
3122 1.1 christos len++;
3123 1.1 christos }
3124 1.1 christos
3125 1.1 christos /* Allocating space for the filename. */
3126 1.1 christos filename = (char *) malloc (sizeof (char) * len);
3127 1.1 christos
3128 1.1 christos /* String copying the filename from memory. */
3129 1.1 christos for (i = 0; i < len; i++)
3130 1.1 christos {
3131 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + i);
3132 1.1 christos filename[i] = temp_char;
3133 1.1 christos }
3134 1.1 christos
3135 1.1 christos /* Setting stat_ptr to second argument of stat. */
3136 1.1 christos /* stat_ptr = h8_get_reg (sd, 1); */
3137 1.1 christos stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3138 1.1 christos
3139 1.1 christos /* Callback stat and return. */
3140 1.1 christos stat_return =
3141 1.1.1.2 christos sim_callback->to_stat (sim_callback, filename, &stat_rec);
3142 1.1 christos
3143 1.1 christos /* Have stat_ptr point to starting of stat_rec. */
3144 1.1 christos temp_stat_ptr = (char *) (&stat_rec);
3145 1.1 christos
3146 1.1 christos /* Freeing memory used for filename. */
3147 1.1 christos free (filename);
3148 1.1 christos
3149 1.1 christos /* Setting up the stat structure returned. */
3150 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
3151 1.1 christos stat_ptr += 2;
3152 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
3153 1.1 christos stat_ptr += 2;
3154 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
3155 1.1 christos stat_ptr += 4;
3156 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
3157 1.1 christos stat_ptr += 2;
3158 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
3159 1.1 christos stat_ptr += 2;
3160 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
3161 1.1 christos stat_ptr += 2;
3162 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
3163 1.1 christos stat_ptr += 2;
3164 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_size);
3165 1.1 christos stat_ptr += 4;
3166 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
3167 1.1 christos stat_ptr += 8;
3168 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
3169 1.1 christos stat_ptr += 8;
3170 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
3171 1.1 christos
3172 1.1 christos /* Return value in register 0. */
3173 1.1 christos h8_set_reg (sd, 0, stat_return);
3174 1.1 christos }
3175 1.1 christos goto next;
3176 1.1 christos /* End of system call processing. */
3177 1.1 christos
3178 1.1 christos case O (O_NOT, SB): /* not.b */
3179 1.1 christos if (fetch2 (sd, &code->src, &rd))
3180 1.1 christos goto end;
3181 1.1 christos rd = ~rd;
3182 1.1 christos v = 0;
3183 1.1 christos goto shift8;
3184 1.1 christos
3185 1.1 christos case O (O_NOT, SW): /* not.w */
3186 1.1 christos if (fetch2 (sd, &code->src, &rd))
3187 1.1 christos goto end;
3188 1.1 christos rd = ~rd;
3189 1.1 christos v = 0;
3190 1.1 christos goto shift16;
3191 1.1 christos
3192 1.1 christos case O (O_NOT, SL): /* not.l */
3193 1.1 christos if (fetch2 (sd, &code->src, &rd))
3194 1.1 christos goto end;
3195 1.1 christos rd = ~rd;
3196 1.1 christos v = 0;
3197 1.1 christos goto shift32;
3198 1.1 christos
3199 1.1 christos case O (O_SHLL, SB): /* shll.b */
3200 1.1 christos case O (O_SHLR, SB): /* shlr.b */
3201 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3202 1.1 christos goto end;
3203 1.1 christos
3204 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3205 1.1 christos ea = 1; /* unary op */
3206 1.1 christos else /* binary op */
3207 1.1 christos fetch (sd, &code->src, &ea);
3208 1.1 christos
3209 1.1 christos if (code->opcode == O (O_SHLL, SB))
3210 1.1 christos {
3211 1.1 christos v = (ea > 8);
3212 1.1 christos c = rd & (0x80 >> (ea - 1));
3213 1.1 christos rd <<= ea;
3214 1.1 christos }
3215 1.1 christos else
3216 1.1 christos {
3217 1.1 christos v = 0;
3218 1.1 christos c = rd & (1 << (ea - 1));
3219 1.1 christos rd = (unsigned char) rd >> ea;
3220 1.1 christos }
3221 1.1 christos goto shift8;
3222 1.1 christos
3223 1.1 christos case O (O_SHLL, SW): /* shll.w */
3224 1.1 christos case O (O_SHLR, SW): /* shlr.w */
3225 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3226 1.1 christos goto end;
3227 1.1 christos
3228 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3229 1.1 christos ea = 1; /* unary op */
3230 1.1 christos else
3231 1.1 christos fetch (sd, &code->src, &ea);
3232 1.1 christos
3233 1.1 christos if (code->opcode == O (O_SHLL, SW))
3234 1.1 christos {
3235 1.1 christos v = (ea > 16);
3236 1.1 christos c = rd & (0x8000 >> (ea - 1));
3237 1.1 christos rd <<= ea;
3238 1.1 christos }
3239 1.1 christos else
3240 1.1 christos {
3241 1.1 christos v = 0;
3242 1.1 christos c = rd & (1 << (ea - 1));
3243 1.1 christos rd = (unsigned short) rd >> ea;
3244 1.1 christos }
3245 1.1 christos goto shift16;
3246 1.1 christos
3247 1.1 christos case O (O_SHLL, SL): /* shll.l */
3248 1.1 christos case O (O_SHLR, SL): /* shlr.l */
3249 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3250 1.1 christos goto end;
3251 1.1 christos
3252 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3253 1.1 christos ea = 1; /* unary op */
3254 1.1 christos else
3255 1.1 christos fetch (sd, &code->src, &ea);
3256 1.1 christos
3257 1.1 christos if (code->opcode == O (O_SHLL, SL))
3258 1.1 christos {
3259 1.1 christos v = (ea > 32);
3260 1.1 christos c = rd & (0x80000000 >> (ea - 1));
3261 1.1 christos rd <<= ea;
3262 1.1 christos }
3263 1.1 christos else
3264 1.1 christos {
3265 1.1 christos v = 0;
3266 1.1 christos c = rd & (1 << (ea - 1));
3267 1.1 christos rd = (unsigned int) rd >> ea;
3268 1.1 christos }
3269 1.1 christos goto shift32;
3270 1.1 christos
3271 1.1 christos case O (O_SHAL, SB):
3272 1.1 christos case O (O_SHAR, SB):
3273 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3274 1.1 christos goto end;
3275 1.1 christos
3276 1.1 christos if (code->src.type == X (OP_IMM, SB))
3277 1.1 christos fetch (sd, &code->src, &ea);
3278 1.1 christos else
3279 1.1 christos ea = 1;
3280 1.1 christos
3281 1.1 christos if (code->opcode == O (O_SHAL, SB))
3282 1.1 christos {
3283 1.1 christos c = rd & (0x80 >> (ea - 1));
3284 1.1 christos res = rd >> (7 - ea);
3285 1.1 christos v = ((res & 1) && !(res & 2))
3286 1.1 christos || (!(res & 1) && (res & 2));
3287 1.1 christos rd <<= ea;
3288 1.1 christos }
3289 1.1 christos else
3290 1.1 christos {
3291 1.1 christos c = rd & (1 << (ea - 1));
3292 1.1 christos v = 0;
3293 1.1 christos rd = ((signed char) rd) >> ea;
3294 1.1 christos }
3295 1.1 christos goto shift8;
3296 1.1 christos
3297 1.1 christos case O (O_SHAL, SW):
3298 1.1 christos case O (O_SHAR, SW):
3299 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3300 1.1 christos goto end;
3301 1.1 christos
3302 1.1 christos if (code->src.type == X (OP_IMM, SW))
3303 1.1 christos fetch (sd, &code->src, &ea);
3304 1.1 christos else
3305 1.1 christos ea = 1;
3306 1.1 christos
3307 1.1 christos if (code->opcode == O (O_SHAL, SW))
3308 1.1 christos {
3309 1.1 christos c = rd & (0x8000 >> (ea - 1));
3310 1.1 christos res = rd >> (15 - ea);
3311 1.1 christos v = ((res & 1) && !(res & 2))
3312 1.1 christos || (!(res & 1) && (res & 2));
3313 1.1 christos rd <<= ea;
3314 1.1 christos }
3315 1.1 christos else
3316 1.1 christos {
3317 1.1 christos c = rd & (1 << (ea - 1));
3318 1.1 christos v = 0;
3319 1.1 christos rd = ((signed short) rd) >> ea;
3320 1.1 christos }
3321 1.1 christos goto shift16;
3322 1.1 christos
3323 1.1 christos case O (O_SHAL, SL):
3324 1.1 christos case O (O_SHAR, SL):
3325 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3326 1.1 christos goto end;
3327 1.1 christos
3328 1.1 christos if (code->src.type == X (OP_IMM, SL))
3329 1.1 christos fetch (sd, &code->src, &ea);
3330 1.1 christos else
3331 1.1 christos ea = 1;
3332 1.1 christos
3333 1.1 christos if (code->opcode == O (O_SHAL, SL))
3334 1.1 christos {
3335 1.1 christos c = rd & (0x80000000 >> (ea - 1));
3336 1.1 christos res = rd >> (31 - ea);
3337 1.1 christos v = ((res & 1) && !(res & 2))
3338 1.1 christos || (!(res & 1) && (res & 2));
3339 1.1 christos rd <<= ea;
3340 1.1 christos }
3341 1.1 christos else
3342 1.1 christos {
3343 1.1 christos c = rd & (1 << (ea - 1));
3344 1.1 christos v = 0;
3345 1.1 christos rd = ((signed int) rd) >> ea;
3346 1.1 christos }
3347 1.1 christos goto shift32;
3348 1.1 christos
3349 1.1 christos case O (O_ROTL, SB):
3350 1.1 christos case O (O_ROTR, SB):
3351 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3352 1.1 christos goto end;
3353 1.1 christos
3354 1.1 christos if (code->src.type == X (OP_IMM, SB))
3355 1.1 christos fetch (sd, &code->src, &ea);
3356 1.1 christos else
3357 1.1 christos ea = 1;
3358 1.1 christos
3359 1.1 christos while (ea--)
3360 1.1 christos if (code->opcode == O (O_ROTL, SB))
3361 1.1 christos {
3362 1.1 christos c = rd & 0x80;
3363 1.1 christos rd <<= 1;
3364 1.1 christos if (c)
3365 1.1 christos rd |= 1;
3366 1.1 christos }
3367 1.1 christos else
3368 1.1 christos {
3369 1.1 christos c = rd & 1;
3370 1.1 christos rd = ((unsigned char) rd) >> 1;
3371 1.1 christos if (c)
3372 1.1 christos rd |= 0x80;
3373 1.1 christos }
3374 1.1 christos
3375 1.1 christos v = 0;
3376 1.1 christos goto shift8;
3377 1.1 christos
3378 1.1 christos case O (O_ROTL, SW):
3379 1.1 christos case O (O_ROTR, SW):
3380 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3381 1.1 christos goto end;
3382 1.1 christos
3383 1.1 christos if (code->src.type == X (OP_IMM, SW))
3384 1.1 christos fetch (sd, &code->src, &ea);
3385 1.1 christos else
3386 1.1 christos ea = 1;
3387 1.1 christos
3388 1.1 christos while (ea--)
3389 1.1 christos if (code->opcode == O (O_ROTL, SW))
3390 1.1 christos {
3391 1.1 christos c = rd & 0x8000;
3392 1.1 christos rd <<= 1;
3393 1.1 christos if (c)
3394 1.1 christos rd |= 1;
3395 1.1 christos }
3396 1.1 christos else
3397 1.1 christos {
3398 1.1 christos c = rd & 1;
3399 1.1 christos rd = ((unsigned short) rd) >> 1;
3400 1.1 christos if (c)
3401 1.1 christos rd |= 0x8000;
3402 1.1 christos }
3403 1.1 christos
3404 1.1 christos v = 0;
3405 1.1 christos goto shift16;
3406 1.1 christos
3407 1.1 christos case O (O_ROTL, SL):
3408 1.1 christos case O (O_ROTR, SL):
3409 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3410 1.1 christos goto end;
3411 1.1 christos
3412 1.1 christos if (code->src.type == X (OP_IMM, SL))
3413 1.1 christos fetch (sd, &code->src, &ea);
3414 1.1 christos else
3415 1.1 christos ea = 1;
3416 1.1 christos
3417 1.1 christos while (ea--)
3418 1.1 christos if (code->opcode == O (O_ROTL, SL))
3419 1.1 christos {
3420 1.1 christos c = rd & 0x80000000;
3421 1.1 christos rd <<= 1;
3422 1.1 christos if (c)
3423 1.1 christos rd |= 1;
3424 1.1 christos }
3425 1.1 christos else
3426 1.1 christos {
3427 1.1 christos c = rd & 1;
3428 1.1 christos rd = ((unsigned int) rd) >> 1;
3429 1.1 christos if (c)
3430 1.1 christos rd |= 0x80000000;
3431 1.1 christos }
3432 1.1 christos
3433 1.1 christos v = 0;
3434 1.1 christos goto shift32;
3435 1.1 christos
3436 1.1 christos case O (O_ROTXL, SB):
3437 1.1 christos case O (O_ROTXR, SB):
3438 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3439 1.1 christos goto end;
3440 1.1 christos
3441 1.1 christos if (code->src.type == X (OP_IMM, SB))
3442 1.1 christos fetch (sd, &code->src, &ea);
3443 1.1 christos else
3444 1.1 christos ea = 1;
3445 1.1 christos
3446 1.1 christos while (ea--)
3447 1.1 christos if (code->opcode == O (O_ROTXL, SB))
3448 1.1 christos {
3449 1.1 christos res = rd & 0x80;
3450 1.1 christos rd <<= 1;
3451 1.1 christos if (C)
3452 1.1 christos rd |= 1;
3453 1.1 christos c = res;
3454 1.1 christos }
3455 1.1 christos else
3456 1.1 christos {
3457 1.1 christos res = rd & 1;
3458 1.1 christos rd = ((unsigned char) rd) >> 1;
3459 1.1 christos if (C)
3460 1.1 christos rd |= 0x80;
3461 1.1 christos c = res;
3462 1.1 christos }
3463 1.1 christos
3464 1.1 christos v = 0;
3465 1.1 christos goto shift8;
3466 1.1 christos
3467 1.1 christos case O (O_ROTXL, SW):
3468 1.1 christos case O (O_ROTXR, SW):
3469 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3470 1.1 christos goto end;
3471 1.1 christos
3472 1.1 christos if (code->src.type == X (OP_IMM, SW))
3473 1.1 christos fetch (sd, &code->src, &ea);
3474 1.1 christos else
3475 1.1 christos ea = 1;
3476 1.1 christos
3477 1.1 christos while (ea--)
3478 1.1 christos if (code->opcode == O (O_ROTXL, SW))
3479 1.1 christos {
3480 1.1 christos res = rd & 0x8000;
3481 1.1 christos rd <<= 1;
3482 1.1 christos if (C)
3483 1.1 christos rd |= 1;
3484 1.1 christos c = res;
3485 1.1 christos }
3486 1.1 christos else
3487 1.1 christos {
3488 1.1 christos res = rd & 1;
3489 1.1 christos rd = ((unsigned short) rd) >> 1;
3490 1.1 christos if (C)
3491 1.1 christos rd |= 0x8000;
3492 1.1 christos c = res;
3493 1.1 christos }
3494 1.1 christos
3495 1.1 christos v = 0;
3496 1.1 christos goto shift16;
3497 1.1 christos
3498 1.1 christos case O (O_ROTXL, SL):
3499 1.1 christos case O (O_ROTXR, SL):
3500 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3501 1.1 christos goto end;
3502 1.1 christos
3503 1.1 christos if (code->src.type == X (OP_IMM, SL))
3504 1.1 christos fetch (sd, &code->src, &ea);
3505 1.1 christos else
3506 1.1 christos ea = 1;
3507 1.1 christos
3508 1.1 christos while (ea--)
3509 1.1 christos if (code->opcode == O (O_ROTXL, SL))
3510 1.1 christos {
3511 1.1 christos res = rd & 0x80000000;
3512 1.1 christos rd <<= 1;
3513 1.1 christos if (C)
3514 1.1 christos rd |= 1;
3515 1.1 christos c = res;
3516 1.1 christos }
3517 1.1 christos else
3518 1.1 christos {
3519 1.1 christos res = rd & 1;
3520 1.1 christos rd = ((unsigned int) rd) >> 1;
3521 1.1 christos if (C)
3522 1.1 christos rd |= 0x80000000;
3523 1.1 christos c = res;
3524 1.1 christos }
3525 1.1 christos
3526 1.1 christos v = 0;
3527 1.1 christos goto shift32;
3528 1.1 christos
3529 1.1 christos case O (O_JMP, SN):
3530 1.1 christos case O (O_JMP, SL):
3531 1.1 christos case O (O_JMP, SB): /* jmp */
3532 1.1 christos case O (O_JMP, SW):
3533 1.1 christos fetch (sd, &code->src, &pc);
3534 1.1 christos goto end;
3535 1.1 christos
3536 1.1 christos case O (O_JSR, SN):
3537 1.1 christos case O (O_JSR, SL):
3538 1.1 christos case O (O_JSR, SB): /* jsr, jump to subroutine */
3539 1.1 christos case O (O_JSR, SW):
3540 1.1 christos if (fetch (sd, &code->src, &pc))
3541 1.1 christos goto end;
3542 1.1 christos call:
3543 1.1 christos tmp = h8_get_reg (sd, SP_REGNUM);
3544 1.1 christos
3545 1.1 christos if (h8300hmode && !h8300_normal_mode)
3546 1.1 christos {
3547 1.1 christos tmp -= 4;
3548 1.1 christos SET_MEMORY_L (tmp, code->next_pc);
3549 1.1 christos }
3550 1.1 christos else
3551 1.1 christos {
3552 1.1 christos tmp -= 2;
3553 1.1 christos SET_MEMORY_W (tmp, code->next_pc);
3554 1.1 christos }
3555 1.1 christos h8_set_reg (sd, SP_REGNUM, tmp);
3556 1.1 christos
3557 1.1 christos goto end;
3558 1.1 christos
3559 1.1 christos case O (O_BSR, SW):
3560 1.1 christos case O (O_BSR, SL):
3561 1.1 christos case O (O_BSR, SB): /* bsr, branch to subroutine */
3562 1.1 christos if (fetch (sd, &code->src, &res))
3563 1.1 christos goto end;
3564 1.1 christos pc = code->next_pc + res;
3565 1.1 christos goto call;
3566 1.1 christos
3567 1.1 christos case O (O_RTE, SN): /* rte, return from exception */
3568 1.1 christos rte:
3569 1.1 christos /* Pops exr and ccr before pc -- otherwise identical to rts. */
3570 1.1 christos tmp = h8_get_reg (sd, SP_REGNUM);
3571 1.1 christos
3572 1.1 christos if (h8300smode) /* pop exr */
3573 1.1 christos {
3574 1.1 christos h8_set_exr (sd, GET_MEMORY_L (tmp));
3575 1.1 christos tmp += 4;
3576 1.1 christos }
3577 1.1 christos if (h8300hmode && !h8300_normal_mode)
3578 1.1 christos {
3579 1.1 christos h8_set_ccr (sd, GET_MEMORY_L (tmp));
3580 1.1 christos tmp += 4;
3581 1.1 christos pc = GET_MEMORY_L (tmp);
3582 1.1 christos tmp += 4;
3583 1.1 christos }
3584 1.1 christos else
3585 1.1 christos {
3586 1.1 christos h8_set_ccr (sd, GET_MEMORY_W (tmp));
3587 1.1 christos tmp += 2;
3588 1.1 christos pc = GET_MEMORY_W (tmp);
3589 1.1 christos tmp += 2;
3590 1.1 christos }
3591 1.1 christos
3592 1.1 christos GETSR (sd);
3593 1.1 christos h8_set_reg (sd, SP_REGNUM, tmp);
3594 1.1 christos goto end;
3595 1.1 christos
3596 1.1 christos case O (O_RTS, SN): /* rts, return from subroutine */
3597 1.1 christos rts:
3598 1.1 christos tmp = h8_get_reg (sd, SP_REGNUM);
3599 1.1 christos
3600 1.1 christos if (h8300hmode && !h8300_normal_mode)
3601 1.1 christos {
3602 1.1 christos pc = GET_MEMORY_L (tmp);
3603 1.1 christos tmp += 4;
3604 1.1 christos }
3605 1.1 christos else
3606 1.1 christos {
3607 1.1 christos pc = GET_MEMORY_W (tmp);
3608 1.1 christos tmp += 2;
3609 1.1 christos }
3610 1.1 christos
3611 1.1 christos h8_set_reg (sd, SP_REGNUM, tmp);
3612 1.1 christos goto end;
3613 1.1 christos
3614 1.1 christos case O (O_ILL, SB): /* illegal */
3615 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGILL);
3616 1.1 christos goto end;
3617 1.1 christos
3618 1.1 christos case O (O_SLEEP, SN): /* sleep */
3619 1.1 christos /* Check for magic numbers in r1 and r2. */
3620 1.1 christos if ((h8_get_reg (sd, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
3621 1.1 christos (h8_get_reg (sd, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
3622 1.1 christos SIM_WIFEXITED (h8_get_reg (sd, 0)))
3623 1.1 christos {
3624 1.1 christos /* This trap comes from _exit, not from gdb. */
3625 1.1 christos sim_engine_set_run_state (sd, sim_exited,
3626 1.1 christos SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
3627 1.1 christos }
3628 1.1 christos #if 0
3629 1.1 christos /* Unfortunately this won't really work, because
3630 1.1 christos when we take a breakpoint trap, R0 has a "random",
3631 1.1 christos user-defined value. Don't see any immediate solution. */
3632 1.1 christos else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
3633 1.1 christos {
3634 1.1 christos /* Pass the stop signal up to gdb. */
3635 1.1 christos sim_engine_set_run_state (sd, sim_stopped,
3636 1.1 christos SIM_WSTOPSIG (h8_get_reg (sd, 0)));
3637 1.1 christos }
3638 1.1 christos #endif
3639 1.1 christos else
3640 1.1 christos {
3641 1.1 christos /* Treat it as a sigtrap. */
3642 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
3643 1.1 christos }
3644 1.1 christos goto end;
3645 1.1 christos
3646 1.1 christos case O (O_TRAPA, SB): /* trapa */
3647 1.1 christos if (fetch (sd, &code->src, &res))
3648 1.1 christos goto end; /* res is vector number. */
3649 1.1 christos
3650 1.1 christos tmp = h8_get_reg (sd, SP_REGNUM);
3651 1.1 christos if(h8300_normal_mode)
3652 1.1 christos {
3653 1.1 christos tmp -= 2;
3654 1.1 christos SET_MEMORY_W (tmp, code->next_pc);
3655 1.1 christos tmp -= 2;
3656 1.1 christos SET_MEMORY_W (tmp, h8_get_ccr (sd));
3657 1.1 christos }
3658 1.1 christos else
3659 1.1 christos {
3660 1.1 christos tmp -= 4;
3661 1.1 christos SET_MEMORY_L (tmp, code->next_pc);
3662 1.1 christos tmp -= 4;
3663 1.1 christos SET_MEMORY_L (tmp, h8_get_ccr (sd));
3664 1.1 christos }
3665 1.1 christos intMaskBit = 1;
3666 1.1 christos BUILDSR (sd);
3667 1.1 christos
3668 1.1 christos if (h8300smode)
3669 1.1 christos {
3670 1.1 christos tmp -= 4;
3671 1.1 christos SET_MEMORY_L (tmp, h8_get_exr (sd));
3672 1.1 christos }
3673 1.1 christos
3674 1.1 christos h8_set_reg (sd, SP_REGNUM, tmp);
3675 1.1 christos
3676 1.1 christos if(h8300_normal_mode)
3677 1.1 christos pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
3678 1.1 christos else
3679 1.1 christos pc = GET_MEMORY_L (0x20 + res * 4);
3680 1.1 christos goto end;
3681 1.1 christos
3682 1.1 christos case O (O_BPT, SN):
3683 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
3684 1.1 christos goto end;
3685 1.1 christos
3686 1.1 christos case O (O_BSETEQ, SB):
3687 1.1 christos if (Z)
3688 1.1 christos goto bset;
3689 1.1 christos goto next;
3690 1.1 christos
3691 1.1 christos case O (O_BSETNE, SB):
3692 1.1 christos if (!Z)
3693 1.1 christos goto bset;
3694 1.1 christos goto next;
3695 1.1 christos
3696 1.1 christos case O (O_BCLREQ, SB):
3697 1.1 christos if (Z)
3698 1.1 christos goto bclr;
3699 1.1 christos goto next;
3700 1.1 christos
3701 1.1 christos case O (O_BCLRNE, SB):
3702 1.1 christos if (!Z)
3703 1.1 christos goto bclr;
3704 1.1 christos goto next;
3705 1.1 christos
3706 1.1 christos OBITOP (O_BNOT, 1, 1, ea ^= m); /* bnot */
3707 1.1 christos OBITOP (O_BTST, 1, 0, nz = ea & m); /* btst */
3708 1.1 christos bset:
3709 1.1 christos OBITOP (O_BSET, 1, 1, ea |= m); /* bset */
3710 1.1 christos bclr:
3711 1.1 christos OBITOP (O_BCLR, 1, 1, ea &= ~m); /* bclr */
3712 1.1 christos OBITOP (O_BLD, 1, 0, c = ea & m); /* bld */
3713 1.1 christos OBITOP (O_BILD, 1, 0, c = !(ea & m)); /* bild */
3714 1.1 christos OBITOP (O_BST, 1, 1, ea &= ~m;
3715 1.1 christos if (C) ea |= m); /* bst */
3716 1.1 christos OBITOP (O_BIST, 1, 1, ea &= ~m;
3717 1.1 christos if (!C) ea |= m); /* bist */
3718 1.1 christos OBITOP (O_BSTZ, 1, 1, ea &= ~m;
3719 1.1 christos if (Z) ea |= m); /* bstz */
3720 1.1 christos OBITOP (O_BISTZ, 1, 1, ea &= ~m;
3721 1.1 christos if (!Z) ea |= m); /* bistz */
3722 1.1 christos OBITOP (O_BAND, 1, 0, c = (ea & m) && C); /* band */
3723 1.1 christos OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); /* biand */
3724 1.1 christos OBITOP (O_BOR, 1, 0, c = (ea & m) || C); /* bor */
3725 1.1 christos OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); /* bior */
3726 1.1 christos OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
3727 1.1 christos OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); /* bixor */
3728 1.1 christos
3729 1.1 christos case O (O_BFLD, SB): /* bfld */
3730 1.1 christos /* bitfield load */
3731 1.1 christos ea = 0;
3732 1.1 christos if (fetch (sd, &code->src, &bit))
3733 1.1 christos goto end;
3734 1.1 christos
3735 1.1 christos if (bit != 0)
3736 1.1 christos {
3737 1.1 christos if (fetch (sd, &code->dst, &ea))
3738 1.1 christos goto end;
3739 1.1 christos
3740 1.1 christos ea &= bit;
3741 1.1 christos while (!(bit & 1))
3742 1.1 christos {
3743 1.1 christos ea >>= 1;
3744 1.1 christos bit >>= 1;
3745 1.1 christos }
3746 1.1 christos }
3747 1.1 christos if (store (sd, &code->op3, ea))
3748 1.1 christos goto end;
3749 1.1 christos
3750 1.1 christos goto next;
3751 1.1 christos
3752 1.1 christos case O(O_BFST, SB): /* bfst */
3753 1.1 christos /* bitfield store */
3754 1.1 christos /* NOTE: the imm8 value is in dst, and the ea value
3755 1.1 christos (which is actually the destination) is in op3.
3756 1.1 christos It has to be that way, to avoid breaking the assembler. */
3757 1.1 christos
3758 1.1 christos if (fetch (sd, &code->dst, &bit)) /* imm8 */
3759 1.1 christos goto end;
3760 1.1 christos if (bit == 0) /* noop -- nothing to do. */
3761 1.1 christos goto next;
3762 1.1 christos
3763 1.1 christos if (fetch (sd, &code->src, &rd)) /* reg8 src */
3764 1.1 christos goto end;
3765 1.1 christos
3766 1.1 christos if (fetch2 (sd, &code->op3, &ea)) /* ea dst */
3767 1.1 christos goto end;
3768 1.1 christos
3769 1.1 christos /* Left-shift the register data into position. */
3770 1.1 christos for (tmp = bit; !(tmp & 1); tmp >>= 1)
3771 1.1 christos rd <<= 1;
3772 1.1 christos
3773 1.1 christos /* Combine it with the neighboring bits. */
3774 1.1 christos ea = (ea & ~bit) | (rd & bit);
3775 1.1 christos
3776 1.1 christos /* Put it back. */
3777 1.1 christos if (store2 (sd, &code->op3, ea))
3778 1.1 christos goto end;
3779 1.1 christos goto next;
3780 1.1 christos
3781 1.1 christos case O (O_CLRMAC, SN): /* clrmac */
3782 1.1 christos h8_set_mach (sd, 0);
3783 1.1 christos h8_set_macl (sd, 0);
3784 1.1 christos h8_set_macZ (sd, 1);
3785 1.1 christos h8_set_macV (sd, 0);
3786 1.1 christos h8_set_macN (sd, 0);
3787 1.1 christos goto next;
3788 1.1 christos
3789 1.1 christos case O (O_STMAC, SL): /* stmac, 260 */
3790 1.1 christos switch (code->src.type) {
3791 1.1 christos case X (OP_MACH, SL):
3792 1.1 christos res = h8_get_mach (sd);
3793 1.1 christos if (res & 0x200) /* sign extend */
3794 1.1 christos res |= 0xfffffc00;
3795 1.1 christos break;
3796 1.1 christos case X (OP_MACL, SL):
3797 1.1 christos res = h8_get_macl (sd);
3798 1.1 christos break;
3799 1.1 christos default: goto illegal;
3800 1.1 christos }
3801 1.1 christos nz = !h8_get_macZ (sd);
3802 1.1 christos n = h8_get_macN (sd);
3803 1.1 christos v = h8_get_macV (sd);
3804 1.1 christos
3805 1.1 christos if (store (sd, &code->dst, res))
3806 1.1 christos goto end;
3807 1.1 christos
3808 1.1 christos goto next;
3809 1.1 christos
3810 1.1 christos case O (O_LDMAC, SL): /* ldmac, 179 */
3811 1.1 christos if (fetch (sd, &code->src, &rd))
3812 1.1 christos goto end;
3813 1.1 christos
3814 1.1 christos switch (code->dst.type) {
3815 1.1 christos case X (OP_MACH, SL):
3816 1.1 christos rd &= 0x3ff; /* Truncate to 10 bits */
3817 1.1 christos h8_set_mach (sd, rd);
3818 1.1 christos break;
3819 1.1 christos case X (OP_MACL, SL):
3820 1.1 christos h8_set_macl (sd, rd);
3821 1.1 christos break;
3822 1.1 christos default: goto illegal;
3823 1.1 christos }
3824 1.1 christos h8_set_macV (sd, 0);
3825 1.1 christos goto next;
3826 1.1 christos
3827 1.1 christos case O (O_MAC, SW):
3828 1.1 christos if (fetch (sd, &code->src, &rd) ||
3829 1.1 christos fetch (sd, &code->dst, &res))
3830 1.1 christos goto end;
3831 1.1 christos
3832 1.1 christos /* Ye gods, this is non-portable!
3833 1.1 christos However, the existing mul/div code is similar. */
3834 1.1 christos res = SEXTSHORT (res) * SEXTSHORT (rd);
3835 1.1 christos
3836 1.1 christos if (h8_get_macS (sd)) /* Saturating mode */
3837 1.1 christos {
3838 1.1 christos long long mac = h8_get_macl (sd);
3839 1.1 christos
3840 1.1 christos if (mac & 0x80000000) /* sign extend */
3841 1.1 christos mac |= 0xffffffff00000000LL;
3842 1.1 christos
3843 1.1 christos mac += res;
3844 1.1 christos if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
3845 1.1 christos h8_set_macV (sd, 1);
3846 1.1 christos h8_set_macZ (sd, (mac == 0));
3847 1.1 christos h8_set_macN (sd, (mac < 0));
3848 1.1 christos h8_set_macl (sd, (int) mac);
3849 1.1 christos }
3850 1.1 christos else /* "Less Saturating" mode */
3851 1.1 christos {
3852 1.1 christos long long mac = h8_get_mach (sd);
3853 1.1 christos mac <<= 32;
3854 1.1 christos mac += h8_get_macl (sd);
3855 1.1 christos
3856 1.1 christos if (mac & 0x20000000000LL) /* sign extend */
3857 1.1 christos mac |= 0xfffffc0000000000LL;
3858 1.1 christos
3859 1.1 christos mac += res;
3860 1.1 christos if (mac > 0x1ffffffffffLL ||
3861 1.1 christos mac < (long long) 0xfffffe0000000000LL)
3862 1.1 christos h8_set_macV (sd, 1);
3863 1.1 christos h8_set_macZ (sd, (mac == 0));
3864 1.1 christos h8_set_macN (sd, (mac < 0));
3865 1.1 christos h8_set_macl (sd, (int) mac);
3866 1.1 christos mac >>= 32;
3867 1.1 christos h8_set_mach (sd, (int) (mac & 0x3ff));
3868 1.1 christos }
3869 1.1 christos goto next;
3870 1.1 christos
3871 1.1 christos case O (O_MULS, SW): /* muls.w */
3872 1.1 christos if (fetch (sd, &code->src, &ea) ||
3873 1.1 christos fetch (sd, &code->dst, &rd))
3874 1.1 christos goto end;
3875 1.1 christos
3876 1.1 christos ea = SEXTSHORT (ea);
3877 1.1 christos res = SEXTSHORT (ea * SEXTSHORT (rd));
3878 1.1 christos
3879 1.1 christos n = res & 0x8000;
3880 1.1 christos nz = res & 0xffff;
3881 1.1 christos if (store (sd, &code->dst, res))
3882 1.1 christos goto end;
3883 1.1 christos
3884 1.1 christos goto next;
3885 1.1 christos
3886 1.1 christos case O (O_MULS, SL): /* muls.l */
3887 1.1 christos if (fetch (sd, &code->src, &ea) ||
3888 1.1 christos fetch (sd, &code->dst, &rd))
3889 1.1 christos goto end;
3890 1.1 christos
3891 1.1 christos res = ea * rd;
3892 1.1 christos
3893 1.1 christos n = res & 0x80000000;
3894 1.1 christos nz = res & 0xffffffff;
3895 1.1 christos if (store (sd, &code->dst, res))
3896 1.1 christos goto end;
3897 1.1 christos goto next;
3898 1.1 christos
3899 1.1 christos case O (O_MULSU, SL): /* muls/u.l */
3900 1.1 christos if (fetch (sd, &code->src, &ea) ||
3901 1.1 christos fetch (sd, &code->dst, &rd))
3902 1.1 christos goto end;
3903 1.1 christos
3904 1.1 christos /* Compute upper 32 bits of the 64-bit result. */
3905 1.1 christos res = (((long long) ea) * ((long long) rd)) >> 32;
3906 1.1 christos
3907 1.1 christos n = res & 0x80000000;
3908 1.1 christos nz = res & 0xffffffff;
3909 1.1 christos if (store (sd, &code->dst, res))
3910 1.1 christos goto end;
3911 1.1 christos goto next;
3912 1.1 christos
3913 1.1 christos case O (O_MULU, SW): /* mulu.w */
3914 1.1 christos if (fetch (sd, &code->src, &ea) ||
3915 1.1 christos fetch (sd, &code->dst, &rd))
3916 1.1 christos goto end;
3917 1.1 christos
3918 1.1 christos res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
3919 1.1 christos
3920 1.1 christos /* Don't set Z or N. */
3921 1.1 christos if (store (sd, &code->dst, res))
3922 1.1 christos goto end;
3923 1.1 christos
3924 1.1 christos goto next;
3925 1.1 christos
3926 1.1 christos case O (O_MULU, SL): /* mulu.l */
3927 1.1 christos if (fetch (sd, &code->src, &ea) ||
3928 1.1 christos fetch (sd, &code->dst, &rd))
3929 1.1 christos goto end;
3930 1.1 christos
3931 1.1 christos res = ea * rd;
3932 1.1 christos
3933 1.1 christos /* Don't set Z or N. */
3934 1.1 christos if (store (sd, &code->dst, res))
3935 1.1 christos goto end;
3936 1.1 christos
3937 1.1 christos goto next;
3938 1.1 christos
3939 1.1 christos case O (O_MULUU, SL): /* mulu/u.l */
3940 1.1 christos if (fetch (sd, &code->src, &ea) ||
3941 1.1 christos fetch (sd, &code->dst, &rd))
3942 1.1 christos goto end;
3943 1.1 christos
3944 1.1 christos /* Compute upper 32 bits of the 64-bit result. */
3945 1.1 christos res = (((unsigned long long) (unsigned) ea) *
3946 1.1 christos ((unsigned long long) (unsigned) rd)) >> 32;
3947 1.1 christos
3948 1.1 christos /* Don't set Z or N. */
3949 1.1 christos if (store (sd, &code->dst, res))
3950 1.1 christos goto end;
3951 1.1 christos
3952 1.1 christos goto next;
3953 1.1 christos
3954 1.1 christos case O (O_MULXS, SB): /* mulxs.b */
3955 1.1 christos if (fetch (sd, &code->src, &ea) ||
3956 1.1 christos fetch (sd, &code->dst, &rd))
3957 1.1 christos goto end;
3958 1.1 christos
3959 1.1 christos ea = SEXTCHAR (ea);
3960 1.1 christos res = ea * SEXTCHAR (rd);
3961 1.1 christos
3962 1.1 christos n = res & 0x8000;
3963 1.1 christos nz = res & 0xffff;
3964 1.1 christos if (store (sd, &code->dst, res))
3965 1.1 christos goto end;
3966 1.1 christos
3967 1.1 christos goto next;
3968 1.1 christos
3969 1.1 christos case O (O_MULXS, SW): /* mulxs.w */
3970 1.1 christos if (fetch (sd, &code->src, &ea) ||
3971 1.1 christos fetch (sd, &code->dst, &rd))
3972 1.1 christos goto end;
3973 1.1 christos
3974 1.1 christos ea = SEXTSHORT (ea);
3975 1.1 christos res = ea * SEXTSHORT (rd & 0xffff);
3976 1.1 christos
3977 1.1 christos n = res & 0x80000000;
3978 1.1 christos nz = res & 0xffffffff;
3979 1.1 christos if (store (sd, &code->dst, res))
3980 1.1 christos goto end;
3981 1.1 christos
3982 1.1 christos goto next;
3983 1.1 christos
3984 1.1 christos case O (O_MULXU, SB): /* mulxu.b */
3985 1.1 christos if (fetch (sd, &code->src, &ea) ||
3986 1.1 christos fetch (sd, &code->dst, &rd))
3987 1.1 christos goto end;
3988 1.1 christos
3989 1.1 christos res = UEXTCHAR (ea) * UEXTCHAR (rd);
3990 1.1 christos
3991 1.1 christos if (store (sd, &code->dst, res))
3992 1.1 christos goto end;
3993 1.1 christos
3994 1.1 christos goto next;
3995 1.1 christos
3996 1.1 christos case O (O_MULXU, SW): /* mulxu.w */
3997 1.1 christos if (fetch (sd, &code->src, &ea) ||
3998 1.1 christos fetch (sd, &code->dst, &rd))
3999 1.1 christos goto end;
4000 1.1 christos
4001 1.1 christos res = UEXTSHORT (ea) * UEXTSHORT (rd);
4002 1.1 christos
4003 1.1 christos if (store (sd, &code->dst, res))
4004 1.1 christos goto end;
4005 1.1 christos
4006 1.1 christos goto next;
4007 1.1 christos
4008 1.1 christos case O (O_TAS, SB): /* tas (test and set) */
4009 1.1 christos if (!h8300sxmode) /* h8sx can use any register. */
4010 1.1 christos switch (code->src.reg)
4011 1.1 christos {
4012 1.1 christos case R0_REGNUM:
4013 1.1 christos case R1_REGNUM:
4014 1.1 christos case R4_REGNUM:
4015 1.1 christos case R5_REGNUM:
4016 1.1 christos break;
4017 1.1 christos default:
4018 1.1 christos goto illegal;
4019 1.1 christos }
4020 1.1 christos
4021 1.1 christos if (fetch (sd, &code->src, &res))
4022 1.1 christos goto end;
4023 1.1 christos if (store (sd, &code->src, res | 0x80))
4024 1.1 christos goto end;
4025 1.1 christos
4026 1.1 christos goto just_flags_log8;
4027 1.1 christos
4028 1.1 christos case O (O_DIVU, SW): /* divu.w */
4029 1.1 christos if (fetch (sd, &code->src, &ea) ||
4030 1.1 christos fetch (sd, &code->dst, &rd))
4031 1.1 christos goto end;
4032 1.1 christos
4033 1.1 christos n = ea & 0x8000;
4034 1.1 christos nz = ea & 0xffff;
4035 1.1 christos if (ea)
4036 1.1 christos res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
4037 1.1 christos else
4038 1.1 christos res = 0;
4039 1.1 christos
4040 1.1 christos if (store (sd, &code->dst, res))
4041 1.1 christos goto end;
4042 1.1 christos goto next;
4043 1.1 christos
4044 1.1 christos case O (O_DIVU, SL): /* divu.l */
4045 1.1 christos if (fetch (sd, &code->src, &ea) ||
4046 1.1 christos fetch (sd, &code->dst, &rd))
4047 1.1 christos goto end;
4048 1.1 christos
4049 1.1 christos n = ea & 0x80000000;
4050 1.1 christos nz = ea & 0xffffffff;
4051 1.1 christos if (ea)
4052 1.1 christos res = (unsigned) rd / ea;
4053 1.1 christos else
4054 1.1 christos res = 0;
4055 1.1 christos
4056 1.1 christos if (store (sd, &code->dst, res))
4057 1.1 christos goto end;
4058 1.1 christos goto next;
4059 1.1 christos
4060 1.1 christos case O (O_DIVS, SW): /* divs.w */
4061 1.1 christos if (fetch (sd, &code->src, &ea) ||
4062 1.1 christos fetch (sd, &code->dst, &rd))
4063 1.1 christos goto end;
4064 1.1 christos
4065 1.1 christos if (ea)
4066 1.1 christos {
4067 1.1 christos res = SEXTSHORT (rd) / SEXTSHORT (ea);
4068 1.1 christos nz = 1;
4069 1.1 christos }
4070 1.1 christos else
4071 1.1 christos {
4072 1.1 christos res = 0;
4073 1.1 christos nz = 0;
4074 1.1 christos }
4075 1.1 christos
4076 1.1 christos n = res & 0x8000;
4077 1.1 christos if (store (sd, &code->dst, res))
4078 1.1 christos goto end;
4079 1.1 christos goto next;
4080 1.1 christos
4081 1.1 christos case O (O_DIVS, SL): /* divs.l */
4082 1.1 christos if (fetch (sd, &code->src, &ea) ||
4083 1.1 christos fetch (sd, &code->dst, &rd))
4084 1.1 christos goto end;
4085 1.1 christos
4086 1.1 christos if (ea)
4087 1.1 christos {
4088 1.1 christos res = rd / ea;
4089 1.1 christos nz = 1;
4090 1.1 christos }
4091 1.1 christos else
4092 1.1 christos {
4093 1.1 christos res = 0;
4094 1.1 christos nz = 0;
4095 1.1 christos }
4096 1.1 christos
4097 1.1 christos n = res & 0x80000000;
4098 1.1 christos if (store (sd, &code->dst, res))
4099 1.1 christos goto end;
4100 1.1 christos goto next;
4101 1.1 christos
4102 1.1 christos case O (O_DIVXU, SB): /* divxu.b */
4103 1.1 christos if (fetch (sd, &code->src, &ea) ||
4104 1.1 christos fetch (sd, &code->dst, &rd))
4105 1.1 christos goto end;
4106 1.1 christos
4107 1.1 christos rd = UEXTSHORT (rd);
4108 1.1 christos ea = UEXTCHAR (ea);
4109 1.1 christos
4110 1.1 christos n = ea & 0x80;
4111 1.1 christos nz = ea & 0xff;
4112 1.1 christos if (ea)
4113 1.1 christos {
4114 1.1 christos tmp = (unsigned) rd % ea;
4115 1.1 christos res = (unsigned) rd / ea;
4116 1.1 christos }
4117 1.1 christos else
4118 1.1 christos {
4119 1.1 christos tmp = 0;
4120 1.1 christos res = 0;
4121 1.1 christos }
4122 1.1 christos
4123 1.1 christos if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
4124 1.1 christos goto end;
4125 1.1 christos goto next;
4126 1.1 christos
4127 1.1 christos case O (O_DIVXU, SW): /* divxu.w */
4128 1.1 christos if (fetch (sd, &code->src, &ea) ||
4129 1.1 christos fetch (sd, &code->dst, &rd))
4130 1.1 christos goto end;
4131 1.1 christos
4132 1.1 christos ea = UEXTSHORT (ea);
4133 1.1 christos
4134 1.1 christos n = ea & 0x8000;
4135 1.1 christos nz = ea & 0xffff;
4136 1.1 christos if (ea)
4137 1.1 christos {
4138 1.1 christos tmp = (unsigned) rd % ea;
4139 1.1 christos res = (unsigned) rd / ea;
4140 1.1 christos }
4141 1.1 christos else
4142 1.1 christos {
4143 1.1 christos tmp = 0;
4144 1.1 christos res = 0;
4145 1.1 christos }
4146 1.1 christos
4147 1.1 christos if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4148 1.1 christos goto end;
4149 1.1 christos goto next;
4150 1.1 christos
4151 1.1 christos case O (O_DIVXS, SB): /* divxs.b */
4152 1.1 christos if (fetch (sd, &code->src, &ea) ||
4153 1.1 christos fetch (sd, &code->dst, &rd))
4154 1.1 christos goto end;
4155 1.1 christos
4156 1.1 christos rd = SEXTSHORT (rd);
4157 1.1 christos ea = SEXTCHAR (ea);
4158 1.1 christos
4159 1.1 christos if (ea)
4160 1.1 christos {
4161 1.1 christos tmp = (int) rd % (int) ea;
4162 1.1 christos res = (int) rd / (int) ea;
4163 1.1 christos nz = 1;
4164 1.1 christos }
4165 1.1 christos else
4166 1.1 christos {
4167 1.1 christos tmp = 0;
4168 1.1 christos res = 0;
4169 1.1 christos nz = 0;
4170 1.1 christos }
4171 1.1 christos
4172 1.1 christos n = res & 0x8000;
4173 1.1 christos if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
4174 1.1 christos goto end;
4175 1.1 christos goto next;
4176 1.1 christos
4177 1.1 christos case O (O_DIVXS, SW): /* divxs.w */
4178 1.1 christos if (fetch (sd, &code->src, &ea) ||
4179 1.1 christos fetch (sd, &code->dst, &rd))
4180 1.1 christos goto end;
4181 1.1 christos
4182 1.1 christos ea = SEXTSHORT (ea);
4183 1.1 christos
4184 1.1 christos if (ea)
4185 1.1 christos {
4186 1.1 christos tmp = (int) rd % (int) ea;
4187 1.1 christos res = (int) rd / (int) ea;
4188 1.1 christos nz = 1;
4189 1.1 christos }
4190 1.1 christos else
4191 1.1 christos {
4192 1.1 christos tmp = 0;
4193 1.1 christos res = 0;
4194 1.1 christos nz = 0;
4195 1.1 christos }
4196 1.1 christos
4197 1.1 christos n = res & 0x80000000;
4198 1.1 christos if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4199 1.1 christos goto end;
4200 1.1 christos goto next;
4201 1.1 christos
4202 1.1 christos case O (O_EXTS, SW): /* exts.w, signed extend */
4203 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4204 1.1 christos goto end;
4205 1.1 christos ea = rd & 0x80 ? -256 : 0;
4206 1.1 christos res = (rd & 0xff) + ea;
4207 1.1 christos goto log16;
4208 1.1 christos
4209 1.1 christos case O (O_EXTS, SL): /* exts.l, signed extend */
4210 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4211 1.1 christos goto end;
4212 1.1 christos if (code->src.type == X (OP_IMM, SL))
4213 1.1 christos {
4214 1.1 christos if (fetch (sd, &code->src, &ea))
4215 1.1 christos goto end;
4216 1.1 christos
4217 1.1 christos if (ea == 2) /* exts.l #2, nn */
4218 1.1 christos {
4219 1.1 christos /* Sign-extend from 8-bit to 32-bit. */
4220 1.1 christos ea = rd & 0x80 ? -256 : 0;
4221 1.1 christos res = (rd & 0xff) + ea;
4222 1.1 christos goto log32;
4223 1.1 christos }
4224 1.1 christos }
4225 1.1 christos /* Sign-extend from 16-bit to 32-bit. */
4226 1.1 christos ea = rd & 0x8000 ? -65536 : 0;
4227 1.1 christos res = (rd & 0xffff) + ea;
4228 1.1 christos goto log32;
4229 1.1 christos
4230 1.1 christos case O (O_EXTU, SW): /* extu.w, unsigned extend */
4231 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4232 1.1 christos goto end;
4233 1.1 christos ea = 0;
4234 1.1 christos res = (rd & 0xff) + ea;
4235 1.1 christos goto log16;
4236 1.1 christos
4237 1.1 christos case O (O_EXTU, SL): /* extu.l, unsigned extend */
4238 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4239 1.1 christos goto end;
4240 1.1 christos if (code->src.type == X (OP_IMM, SL))
4241 1.1 christos {
4242 1.1 christos if (fetch (sd, &code->src, &ea))
4243 1.1 christos goto end;
4244 1.1 christos
4245 1.1 christos if (ea == 2) /* extu.l #2, nn */
4246 1.1 christos {
4247 1.1 christos /* Zero-extend from 8-bit to 32-bit. */
4248 1.1 christos ea = 0;
4249 1.1 christos res = (rd & 0xff) + ea;
4250 1.1 christos goto log32;
4251 1.1 christos }
4252 1.1 christos }
4253 1.1 christos /* Zero-extend from 16-bit to 32-bit. */
4254 1.1 christos ea = 0;
4255 1.1 christos res = (rd & 0xffff) + ea;
4256 1.1 christos goto log32;
4257 1.1 christos
4258 1.1 christos case O (O_NOP, SN): /* nop */
4259 1.1 christos goto next;
4260 1.1 christos
4261 1.1 christos case O (O_STM, SL): /* stm, store to memory */
4262 1.1 christos {
4263 1.1 christos int nregs, firstreg, i;
4264 1.1 christos
4265 1.1 christos nregs = GET_MEMORY_B (pc + 1);
4266 1.1 christos nregs >>= 4;
4267 1.1 christos nregs &= 0xf;
4268 1.1 christos firstreg = code->src.reg;
4269 1.1 christos firstreg &= 0xf;
4270 1.1 christos for (i = firstreg; i <= firstreg + nregs; i++)
4271 1.1 christos {
4272 1.1 christos h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) - 4);
4273 1.1 christos SET_MEMORY_L (h8_get_reg (sd, SP_REGNUM), h8_get_reg (sd, i));
4274 1.1 christos }
4275 1.1 christos }
4276 1.1 christos goto next;
4277 1.1 christos
4278 1.1 christos case O (O_LDM, SL): /* ldm, load from memory */
4279 1.1 christos case O (O_RTEL, SN): /* rte/l, ldm plus rte */
4280 1.1 christos case O (O_RTSL, SN): /* rts/l, ldm plus rts */
4281 1.1 christos {
4282 1.1 christos int nregs, firstreg, i;
4283 1.1 christos
4284 1.1 christos nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
4285 1.1 christos firstreg = code->dst.reg & 0xf;
4286 1.1 christos for (i = firstreg; i >= firstreg - nregs; i--)
4287 1.1 christos {
4288 1.1 christos h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
4289 1.1 christos h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
4290 1.1 christos }
4291 1.1 christos }
4292 1.1 christos switch (code->opcode) {
4293 1.1 christos case O (O_RTEL, SN):
4294 1.1 christos goto rte;
4295 1.1 christos case O (O_RTSL, SN):
4296 1.1 christos goto rts;
4297 1.1 christos case O (O_LDM, SL):
4298 1.1 christos goto next;
4299 1.1 christos default:
4300 1.1 christos goto illegal;
4301 1.1 christos }
4302 1.1 christos
4303 1.1 christos case O (O_DAA, SB):
4304 1.1 christos /* Decimal Adjust Addition. This is for BCD arithmetic. */
4305 1.1 christos res = GET_B_REG (code->src.reg); /* FIXME fetch? */
4306 1.1 christos if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4307 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4308 1.1 christos res = res; /* Value added == 0. */
4309 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4310 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4311 1.1 christos res = res + 0x6; /* Value added == 6. */
4312 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4313 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4314 1.1 christos res = res + 0x6; /* Value added == 6. */
4315 1.1 christos else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4316 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4317 1.1 christos res = res + 0x60; /* Value added == 60. */
4318 1.1 christos else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) &&
4319 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4320 1.1 christos res = res + 0x66; /* Value added == 66. */
4321 1.1 christos else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4322 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4323 1.1 christos res = res + 0x66; /* Value added == 66. */
4324 1.1 christos else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4325 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4326 1.1 christos res = res + 0x60; /* Value added == 60. */
4327 1.1 christos else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4328 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4329 1.1 christos res = res + 0x66; /* Value added == 66. */
4330 1.1 christos else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) &&
4331 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4332 1.1 christos res = res + 0x66; /* Value added == 66. */
4333 1.1 christos
4334 1.1 christos goto alu8;
4335 1.1 christos
4336 1.1 christos case O (O_DAS, SB):
4337 1.1 christos /* Decimal Adjust Subtraction. This is for BCD arithmetic. */
4338 1.1 christos res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
4339 1.1 christos if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4340 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4341 1.1 christos res = res; /* Value added == 0. */
4342 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4343 1.1 christos h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
4344 1.1 christos res = res + 0xfa; /* Value added == 0xfa. */
4345 1.1 christos else if ( c && (7 <= (res >> 4) && (res >> 4) <= 15) &&
4346 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4347 1.1 christos res = res + 0xa0; /* Value added == 0xa0. */
4348 1.1 christos else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) &&
4349 1.1 christos h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
4350 1.1 christos res = res + 0x9a; /* Value added == 0x9a. */
4351 1.1 christos
4352 1.1 christos goto alu8;
4353 1.1 christos
4354 1.1 christos default:
4355 1.1 christos illegal:
4356 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGILL);
4357 1.1 christos goto end;
4358 1.1 christos
4359 1.1 christos }
4360 1.1 christos
4361 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4362 1.1 christos "sim_resume: internal error.\n");
4363 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGILL);
4364 1.1 christos goto end;
4365 1.1 christos
4366 1.1 christos setc:
4367 1.1 christos if (code->dst.type == X (OP_CCR, SB) ||
4368 1.1 christos code->dst.type == X (OP_CCR, SW))
4369 1.1 christos {
4370 1.1 christos h8_set_ccr (sd, res);
4371 1.1 christos GETSR (sd);
4372 1.1 christos }
4373 1.1 christos else if (h8300smode &&
4374 1.1 christos (code->dst.type == X (OP_EXR, SB) ||
4375 1.1 christos code->dst.type == X (OP_EXR, SW)))
4376 1.1 christos {
4377 1.1 christos h8_set_exr (sd, res);
4378 1.1 christos if (h8300smode) /* Get exr. */
4379 1.1 christos {
4380 1.1 christos trace = (h8_get_exr (sd) >> 7) & 1;
4381 1.1 christos intMask = h8_get_exr (sd) & 7;
4382 1.1 christos }
4383 1.1 christos }
4384 1.1 christos else
4385 1.1 christos goto illegal;
4386 1.1 christos
4387 1.1 christos goto next;
4388 1.1 christos
4389 1.1 christos condtrue:
4390 1.1 christos /* When a branch works */
4391 1.1 christos if (fetch (sd, &code->src, &res))
4392 1.1 christos goto end;
4393 1.1 christos if (res & 1) /* bad address */
4394 1.1 christos goto illegal;
4395 1.1 christos pc = code->next_pc + res;
4396 1.1 christos goto end;
4397 1.1 christos
4398 1.1 christos /* Set the cond codes from res */
4399 1.1 christos bitop:
4400 1.1 christos
4401 1.1 christos /* Set the flags after an 8 bit inc/dec operation */
4402 1.1 christos just_flags_inc8:
4403 1.1 christos n = res & 0x80;
4404 1.1 christos nz = res & 0xff;
4405 1.1 christos v = (rd & 0x7f) == 0x7f;
4406 1.1 christos goto next;
4407 1.1 christos
4408 1.1 christos /* Set the flags after an 16 bit inc/dec operation */
4409 1.1 christos just_flags_inc16:
4410 1.1 christos n = res & 0x8000;
4411 1.1 christos nz = res & 0xffff;
4412 1.1 christos v = (rd & 0x7fff) == 0x7fff;
4413 1.1 christos goto next;
4414 1.1 christos
4415 1.1 christos /* Set the flags after an 32 bit inc/dec operation */
4416 1.1 christos just_flags_inc32:
4417 1.1 christos n = res & 0x80000000;
4418 1.1 christos nz = res & 0xffffffff;
4419 1.1 christos v = (rd & 0x7fffffff) == 0x7fffffff;
4420 1.1 christos goto next;
4421 1.1 christos
4422 1.1 christos shift8:
4423 1.1 christos /* Set flags after an 8 bit shift op, carry,overflow set in insn */
4424 1.1 christos n = (rd & 0x80);
4425 1.1 christos nz = rd & 0xff;
4426 1.1 christos if (store2 (sd, &code->dst, rd))
4427 1.1 christos goto end;
4428 1.1 christos goto next;
4429 1.1 christos
4430 1.1 christos shift16:
4431 1.1 christos /* Set flags after an 16 bit shift op, carry,overflow set in insn */
4432 1.1 christos n = (rd & 0x8000);
4433 1.1 christos nz = rd & 0xffff;
4434 1.1 christos if (store2 (sd, &code->dst, rd))
4435 1.1 christos goto end;
4436 1.1 christos goto next;
4437 1.1 christos
4438 1.1 christos shift32:
4439 1.1 christos /* Set flags after an 32 bit shift op, carry,overflow set in insn */
4440 1.1 christos n = (rd & 0x80000000);
4441 1.1 christos nz = rd & 0xffffffff;
4442 1.1 christos if (store2 (sd, &code->dst, rd))
4443 1.1 christos goto end;
4444 1.1 christos goto next;
4445 1.1 christos
4446 1.1 christos log32:
4447 1.1 christos if (store2 (sd, &code->dst, res))
4448 1.1 christos goto end;
4449 1.1 christos
4450 1.1 christos just_flags_log32:
4451 1.1 christos /* flags after a 32bit logical operation */
4452 1.1 christos n = res & 0x80000000;
4453 1.1 christos nz = res & 0xffffffff;
4454 1.1 christos v = 0;
4455 1.1 christos goto next;
4456 1.1 christos
4457 1.1 christos log16:
4458 1.1 christos if (store2 (sd, &code->dst, res))
4459 1.1 christos goto end;
4460 1.1 christos
4461 1.1 christos just_flags_log16:
4462 1.1 christos /* flags after a 16bit logical operation */
4463 1.1 christos n = res & 0x8000;
4464 1.1 christos nz = res & 0xffff;
4465 1.1 christos v = 0;
4466 1.1 christos goto next;
4467 1.1 christos
4468 1.1 christos log8:
4469 1.1 christos if (store2 (sd, &code->dst, res))
4470 1.1 christos goto end;
4471 1.1 christos
4472 1.1 christos just_flags_log8:
4473 1.1 christos n = res & 0x80;
4474 1.1 christos nz = res & 0xff;
4475 1.1 christos v = 0;
4476 1.1 christos goto next;
4477 1.1 christos
4478 1.1 christos alu8:
4479 1.1 christos if (store2 (sd, &code->dst, res))
4480 1.1 christos goto end;
4481 1.1 christos
4482 1.1 christos just_flags_alu8:
4483 1.1 christos n = res & 0x80;
4484 1.1 christos nz = res & 0xff;
4485 1.1 christos c = (res & 0x100);
4486 1.1 christos switch (code->opcode / 4)
4487 1.1 christos {
4488 1.1 christos case O_ADD:
4489 1.1 christos case O_ADDX:
4490 1.1 christos v = ((rd & 0x80) == (ea & 0x80)
4491 1.1 christos && (rd & 0x80) != (res & 0x80));
4492 1.1 christos break;
4493 1.1 christos case O_SUB:
4494 1.1 christos case O_SUBX:
4495 1.1 christos case O_CMP:
4496 1.1 christos v = ((rd & 0x80) != (-ea & 0x80)
4497 1.1 christos && (rd & 0x80) != (res & 0x80));
4498 1.1 christos break;
4499 1.1 christos case O_NEG:
4500 1.1 christos v = (rd == 0x80);
4501 1.1 christos break;
4502 1.1 christos case O_DAA:
4503 1.1 christos case O_DAS:
4504 1.1 christos break; /* No effect on v flag. */
4505 1.1 christos }
4506 1.1 christos goto next;
4507 1.1 christos
4508 1.1 christos alu16:
4509 1.1 christos if (store2 (sd, &code->dst, res))
4510 1.1 christos goto end;
4511 1.1 christos
4512 1.1 christos just_flags_alu16:
4513 1.1 christos n = res & 0x8000;
4514 1.1 christos nz = res & 0xffff;
4515 1.1 christos c = (res & 0x10000);
4516 1.1 christos switch (code->opcode / 4)
4517 1.1 christos {
4518 1.1 christos case O_ADD:
4519 1.1 christos case O_ADDX:
4520 1.1 christos v = ((rd & 0x8000) == (ea & 0x8000)
4521 1.1 christos && (rd & 0x8000) != (res & 0x8000));
4522 1.1 christos break;
4523 1.1 christos case O_SUB:
4524 1.1 christos case O_SUBX:
4525 1.1 christos case O_CMP:
4526 1.1 christos v = ((rd & 0x8000) != (-ea & 0x8000)
4527 1.1 christos && (rd & 0x8000) != (res & 0x8000));
4528 1.1 christos break;
4529 1.1 christos case O_NEG:
4530 1.1 christos v = (rd == 0x8000);
4531 1.1 christos break;
4532 1.1 christos }
4533 1.1 christos goto next;
4534 1.1 christos
4535 1.1 christos alu32:
4536 1.1 christos if (store2 (sd, &code->dst, res))
4537 1.1 christos goto end;
4538 1.1 christos
4539 1.1 christos just_flags_alu32:
4540 1.1 christos n = res & 0x80000000;
4541 1.1 christos nz = res & 0xffffffff;
4542 1.1 christos switch (code->opcode / 4)
4543 1.1 christos {
4544 1.1 christos case O_ADD:
4545 1.1 christos case O_ADDX:
4546 1.1 christos v = ((rd & 0x80000000) == (ea & 0x80000000)
4547 1.1 christos && (rd & 0x80000000) != (res & 0x80000000));
4548 1.1 christos c = ((unsigned) res < (unsigned) rd) ||
4549 1.1 christos ((unsigned) res < (unsigned) ea);
4550 1.1 christos break;
4551 1.1 christos case O_SUB:
4552 1.1 christos case O_SUBX:
4553 1.1 christos case O_CMP:
4554 1.1 christos v = ((rd & 0x80000000) != (-ea & 0x80000000)
4555 1.1 christos && (rd & 0x80000000) != (res & 0x80000000));
4556 1.1 christos c = (unsigned) rd < (unsigned) -ea;
4557 1.1 christos break;
4558 1.1 christos case O_NEG:
4559 1.1 christos v = (rd == 0x80000000);
4560 1.1 christos c = res != 0;
4561 1.1 christos break;
4562 1.1 christos }
4563 1.1 christos goto next;
4564 1.1 christos
4565 1.1 christos next:
4566 1.1 christos if ((res = h8_get_delayed_branch (sd)) != 0)
4567 1.1 christos {
4568 1.1 christos pc = res;
4569 1.1 christos h8_set_delayed_branch (sd, 0);
4570 1.1 christos }
4571 1.1 christos else
4572 1.1 christos pc = code->next_pc;
4573 1.1 christos
4574 1.1 christos end:
4575 1.1 christos
4576 1.1 christos if (--poll_count < 0)
4577 1.1 christos {
4578 1.1 christos poll_count = POLL_QUIT_INTERVAL;
4579 1.1 christos if ((*sim_callback->poll_quit) != NULL
4580 1.1 christos && (*sim_callback->poll_quit) (sim_callback))
4581 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGINT);
4582 1.1 christos }
4583 1.1 christos sim_engine_get_run_state (sd, &reason, &sigrc);
4584 1.1 christos } while (reason == sim_running);
4585 1.1 christos
4586 1.1 christos h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
4587 1.1 christos h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
4588 1.1 christos h8_set_insts (sd, h8_get_insts (sd) + insts);
4589 1.1 christos h8_set_pc (sd, pc);
4590 1.1 christos BUILDSR (sd);
4591 1.1 christos
4592 1.1 christos if (h8300smode)
4593 1.1 christos h8_set_exr (sd, (trace<<7) | intMask);
4594 1.1 christos
4595 1.1 christos h8_set_mask (sd, oldmask);
4596 1.1 christos }
4597 1.1 christos
4598 1.1 christos int
4599 1.1 christos sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
4600 1.1 christos {
4601 1.1 christos int i;
4602 1.1 christos
4603 1.1 christos init_pointers (sd);
4604 1.1 christos if (addr < 0)
4605 1.1 christos return 0;
4606 1.1 christos for (i = 0; i < size; i++)
4607 1.1 christos {
4608 1.1 christos if (addr < memory_size)
4609 1.1 christos {
4610 1.1 christos h8_set_memory (sd, addr + i, buffer[i]);
4611 1.1 christos h8_set_cache_idx (sd, addr + i, 0);
4612 1.1 christos }
4613 1.1 christos else
4614 1.1 christos {
4615 1.1 christos h8_set_eightbit (sd, (addr + i) & 0xff, buffer[i]);
4616 1.1 christos }
4617 1.1 christos }
4618 1.1 christos return size;
4619 1.1 christos }
4620 1.1 christos
4621 1.1 christos int
4622 1.1 christos sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
4623 1.1 christos {
4624 1.1 christos init_pointers (sd);
4625 1.1 christos if (addr < 0)
4626 1.1 christos return 0;
4627 1.1 christos if (addr < memory_size)
4628 1.1 christos memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
4629 1.1 christos else
4630 1.1 christos memcpy (buffer, h8_get_eightbit_buf (sd) + (addr & 0xff), size);
4631 1.1 christos return size;
4632 1.1 christos }
4633 1.1 christos
4634 1.1 christos
4635 1.1 christos int
4636 1.1 christos sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
4637 1.1 christos {
4638 1.1 christos int longval;
4639 1.1 christos int shortval;
4640 1.1 christos int intval;
4641 1.1 christos longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
4642 1.1 christos shortval = (value[0] << 8) | (value[1]);
4643 1.1 christos intval = h8300hmode ? longval : shortval;
4644 1.1 christos
4645 1.1 christos init_pointers (sd);
4646 1.1 christos switch (rn)
4647 1.1 christos {
4648 1.1 christos case PC_REGNUM:
4649 1.1 christos if(h8300_normal_mode)
4650 1.1 christos h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */
4651 1.1 christos else
4652 1.1 christos h8_set_pc (sd, intval);
4653 1.1 christos break;
4654 1.1 christos default:
4655 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4656 1.1 christos "sim_store_register: bad regnum %d.\n",
4657 1.1 christos rn);
4658 1.1 christos case R0_REGNUM:
4659 1.1 christos case R1_REGNUM:
4660 1.1 christos case R2_REGNUM:
4661 1.1 christos case R3_REGNUM:
4662 1.1 christos case R4_REGNUM:
4663 1.1 christos case R5_REGNUM:
4664 1.1 christos case R6_REGNUM:
4665 1.1 christos case R7_REGNUM:
4666 1.1 christos h8_set_reg (sd, rn, intval);
4667 1.1 christos break;
4668 1.1 christos case CCR_REGNUM:
4669 1.1 christos h8_set_ccr (sd, intval);
4670 1.1 christos break;
4671 1.1 christos case EXR_REGNUM:
4672 1.1 christos h8_set_exr (sd, intval);
4673 1.1 christos break;
4674 1.1 christos case SBR_REGNUM:
4675 1.1 christos h8_set_sbr (sd, intval);
4676 1.1 christos break;
4677 1.1 christos case VBR_REGNUM:
4678 1.1 christos h8_set_vbr (sd, intval);
4679 1.1 christos break;
4680 1.1 christos case MACH_REGNUM:
4681 1.1 christos h8_set_mach (sd, intval);
4682 1.1 christos break;
4683 1.1 christos case MACL_REGNUM:
4684 1.1 christos h8_set_macl (sd, intval);
4685 1.1 christos break;
4686 1.1 christos case CYCLE_REGNUM:
4687 1.1 christos h8_set_cycles (sd, longval);
4688 1.1 christos break;
4689 1.1 christos
4690 1.1 christos case INST_REGNUM:
4691 1.1 christos h8_set_insts (sd, longval);
4692 1.1 christos break;
4693 1.1 christos
4694 1.1 christos case TICK_REGNUM:
4695 1.1 christos h8_set_ticks (sd, longval);
4696 1.1 christos break;
4697 1.1 christos }
4698 1.1 christos return length;
4699 1.1 christos }
4700 1.1 christos
4701 1.1 christos int
4702 1.1 christos sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
4703 1.1 christos {
4704 1.1 christos int v;
4705 1.1 christos int longreg = 0;
4706 1.1 christos
4707 1.1 christos init_pointers (sd);
4708 1.1 christos
4709 1.1 christos if (!h8300smode && rn >= EXR_REGNUM)
4710 1.1 christos rn++;
4711 1.1 christos switch (rn)
4712 1.1 christos {
4713 1.1 christos default:
4714 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4715 1.1 christos "sim_fetch_register: bad regnum %d.\n",
4716 1.1 christos rn);
4717 1.1 christos v = 0;
4718 1.1 christos break;
4719 1.1 christos case CCR_REGNUM:
4720 1.1 christos v = h8_get_ccr (sd);
4721 1.1 christos break;
4722 1.1 christos case EXR_REGNUM:
4723 1.1 christos v = h8_get_exr (sd);
4724 1.1 christos break;
4725 1.1 christos case PC_REGNUM:
4726 1.1 christos v = h8_get_pc (sd);
4727 1.1 christos break;
4728 1.1 christos case SBR_REGNUM:
4729 1.1 christos v = h8_get_sbr (sd);
4730 1.1 christos break;
4731 1.1 christos case VBR_REGNUM:
4732 1.1 christos v = h8_get_vbr (sd);
4733 1.1 christos break;
4734 1.1 christos case MACH_REGNUM:
4735 1.1 christos v = h8_get_mach (sd);
4736 1.1 christos break;
4737 1.1 christos case MACL_REGNUM:
4738 1.1 christos v = h8_get_macl (sd);
4739 1.1 christos break;
4740 1.1 christos case R0_REGNUM:
4741 1.1 christos case R1_REGNUM:
4742 1.1 christos case R2_REGNUM:
4743 1.1 christos case R3_REGNUM:
4744 1.1 christos case R4_REGNUM:
4745 1.1 christos case R5_REGNUM:
4746 1.1 christos case R6_REGNUM:
4747 1.1 christos case R7_REGNUM:
4748 1.1 christos v = h8_get_reg (sd, rn);
4749 1.1 christos break;
4750 1.1 christos case CYCLE_REGNUM:
4751 1.1 christos v = h8_get_cycles (sd);
4752 1.1 christos longreg = 1;
4753 1.1 christos break;
4754 1.1 christos case TICK_REGNUM:
4755 1.1 christos v = h8_get_ticks (sd);
4756 1.1 christos longreg = 1;
4757 1.1 christos break;
4758 1.1 christos case INST_REGNUM:
4759 1.1 christos v = h8_get_insts (sd);
4760 1.1 christos longreg = 1;
4761 1.1 christos break;
4762 1.1 christos }
4763 1.1 christos /* In Normal mode PC is 2 byte, but other registers are 4 byte */
4764 1.1 christos if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
4765 1.1 christos {
4766 1.1 christos buf[0] = v >> 24;
4767 1.1 christos buf[1] = v >> 16;
4768 1.1 christos buf[2] = v >> 8;
4769 1.1 christos buf[3] = v >> 0;
4770 1.1 christos }
4771 1.1 christos else
4772 1.1 christos {
4773 1.1 christos buf[0] = v >> 8;
4774 1.1 christos buf[1] = v;
4775 1.1 christos }
4776 1.1 christos return -1;
4777 1.1 christos }
4778 1.1 christos
4779 1.1 christos void
4780 1.1 christos sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
4781 1.1 christos {
4782 1.1 christos sim_engine_get_run_state (sd, reason, sigrc);
4783 1.1 christos }
4784 1.1 christos
4785 1.1 christos static void
4786 1.1 christos set_simcache_size (SIM_DESC sd, int n)
4787 1.1 christos {
4788 1.1 christos if (sd->sim_cache)
4789 1.1 christos free (sd->sim_cache);
4790 1.1 christos if (n < 2)
4791 1.1 christos n = 2;
4792 1.1 christos sd->sim_cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
4793 1.1 christos memset (sd->sim_cache, 0, sizeof (decoded_inst) * n);
4794 1.1 christos sd->sim_cache_size = n;
4795 1.1 christos }
4796 1.1 christos
4797 1.1 christos
4798 1.1 christos void
4799 1.1 christos sim_info (SIM_DESC sd, int verbose)
4800 1.1 christos {
4801 1.1 christos double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
4802 1.1 christos double virttime = h8_get_cycles (sd) / 10.0e6;
4803 1.1 christos
4804 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4805 1.1 christos "\n\n#instructions executed %10d\n",
4806 1.1 christos h8_get_insts (sd));
4807 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4808 1.1 christos "#cycles (v approximate) %10d\n",
4809 1.1 christos h8_get_cycles (sd));
4810 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4811 1.1 christos "#real time taken %10.4f\n",
4812 1.1 christos timetaken);
4813 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4814 1.1 christos "#virtual time taken %10.4f\n",
4815 1.1 christos virttime);
4816 1.1 christos if (timetaken != 0.0)
4817 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4818 1.1 christos "#simulation ratio %10.4f\n",
4819 1.1 christos virttime / timetaken);
4820 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4821 1.1 christos "#compiles %10d\n",
4822 1.1 christos h8_get_compiles (sd));
4823 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4824 1.1 christos "#cache size %10d\n",
4825 1.1 christos sd->sim_cache_size);
4826 1.1 christos
4827 1.1 christos #ifdef ADEBUG
4828 1.1 christos /* This to be conditional on `what' (aka `verbose'),
4829 1.1 christos however it was never passed as non-zero. */
4830 1.1 christos if (1)
4831 1.1 christos {
4832 1.1 christos int i;
4833 1.1 christos for (i = 0; i < O_LAST; i++)
4834 1.1 christos {
4835 1.1 christos if (h8_get_stats (sd, i))
4836 1.1 christos (*sim_callback->printf_filtered) (sim_callback, "%d: %d\n",
4837 1.1 christos i, h8_get_stats (sd, i));
4838 1.1 christos }
4839 1.1 christos }
4840 1.1 christos #endif
4841 1.1 christos }
4842 1.1 christos
4843 1.1 christos /* Indicate whether the cpu is an H8/300 or H8/300H.
4844 1.1 christos FLAG is non-zero for the H8/300H. */
4845 1.1 christos
4846 1.1 christos void
4847 1.1 christos set_h8300h (unsigned long machine)
4848 1.1 christos {
4849 1.1 christos /* FIXME: Much of the code in sim_load can be moved to sim_open.
4850 1.1 christos This function being replaced by a sim_open:ARGV configuration
4851 1.1 christos option. */
4852 1.1 christos
4853 1.1 christos h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
4854 1.1 christos
4855 1.1 christos if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
4856 1.1 christos h8300sxmode = 1;
4857 1.1 christos
4858 1.1 christos if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
4859 1.1 christos h8300smode = 1;
4860 1.1 christos
4861 1.1 christos if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
4862 1.1 christos h8300hmode = 1;
4863 1.1 christos
4864 1.1 christos if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
4865 1.1 christos h8300_normal_mode = 1;
4866 1.1 christos }
4867 1.1 christos
4868 1.1.1.3 christos static sim_cia
4869 1.1.1.3 christos h8300_pc_get (sim_cpu *cpu)
4870 1.1.1.3 christos {
4871 1.1.1.3 christos return cpu->pc;
4872 1.1.1.3 christos }
4873 1.1.1.3 christos
4874 1.1.1.3 christos static void
4875 1.1.1.3 christos h8300_pc_set (sim_cpu *cpu, sim_cia pc)
4876 1.1.1.3 christos {
4877 1.1.1.3 christos cpu->pc = pc;
4878 1.1.1.3 christos }
4879 1.1.1.3 christos
4880 1.1 christos /* Cover function of sim_state_free to free the cpu buffers as well. */
4881 1.1 christos
4882 1.1 christos static void
4883 1.1 christos free_state (SIM_DESC sd)
4884 1.1 christos {
4885 1.1 christos if (STATE_MODULES (sd) != NULL)
4886 1.1 christos sim_module_uninstall (sd);
4887 1.1 christos
4888 1.1 christos /* Fixme: free buffers in _sim_cpu. */
4889 1.1 christos sim_state_free (sd);
4890 1.1 christos }
4891 1.1 christos
4892 1.1 christos SIM_DESC
4893 1.1 christos sim_open (SIM_OPEN_KIND kind,
4894 1.1 christos struct host_callback_struct *callback,
4895 1.1 christos struct bfd *abfd,
4896 1.1 christos char **argv)
4897 1.1 christos {
4898 1.1.1.3 christos int i;
4899 1.1 christos SIM_DESC sd;
4900 1.1 christos sim_cpu *cpu;
4901 1.1 christos
4902 1.1 christos sd = sim_state_alloc (kind, callback);
4903 1.1.1.3 christos
4904 1.1.1.3 christos /* The cpu data is kept in a separately allocated chunk of memory. */
4905 1.1.1.3 christos if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
4906 1.1.1.3 christos {
4907 1.1.1.3 christos free_state (sd);
4908 1.1.1.3 christos return 0;
4909 1.1.1.3 christos }
4910 1.1.1.3 christos
4911 1.1 christos cpu = STATE_CPU (sd, 0);
4912 1.1 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
4913 1.1 christos sim_state_initialize (sd, cpu);
4914 1.1 christos /* sim_cpu object is new, so some initialization is needed. */
4915 1.1 christos init_pointers_needed = 1;
4916 1.1 christos
4917 1.1 christos /* For compatibility (FIXME: is this right?). */
4918 1.1 christos current_alignment = NONSTRICT_ALIGNMENT;
4919 1.1 christos current_target_byte_order = BIG_ENDIAN;
4920 1.1 christos
4921 1.1 christos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
4922 1.1 christos {
4923 1.1 christos free_state (sd);
4924 1.1 christos return 0;
4925 1.1 christos }
4926 1.1 christos
4927 1.1 christos /* getopt will print the error message so we just have to exit if
4928 1.1 christos this fails. FIXME: Hmmm... in the case of gdb we need getopt
4929 1.1 christos to call print_filtered. */
4930 1.1 christos if (sim_parse_args (sd, argv) != SIM_RC_OK)
4931 1.1 christos {
4932 1.1 christos /* Uninstall the modules to avoid memory leaks,
4933 1.1 christos file descriptor leaks, etc. */
4934 1.1 christos free_state (sd);
4935 1.1 christos return 0;
4936 1.1 christos }
4937 1.1 christos
4938 1.1 christos /* Check for/establish the a reference program image. */
4939 1.1 christos if (sim_analyze_program (sd,
4940 1.1 christos (STATE_PROG_ARGV (sd) != NULL
4941 1.1 christos ? *STATE_PROG_ARGV (sd)
4942 1.1 christos : NULL), abfd) != SIM_RC_OK)
4943 1.1 christos {
4944 1.1 christos free_state (sd);
4945 1.1 christos return 0;
4946 1.1 christos }
4947 1.1 christos
4948 1.1 christos /* Establish any remaining configuration options. */
4949 1.1 christos if (sim_config (sd) != SIM_RC_OK)
4950 1.1 christos {
4951 1.1 christos free_state (sd);
4952 1.1 christos return 0;
4953 1.1 christos }
4954 1.1 christos
4955 1.1 christos if (sim_post_argv_init (sd) != SIM_RC_OK)
4956 1.1 christos {
4957 1.1 christos /* Uninstall the modules to avoid memory leaks,
4958 1.1 christos file descriptor leaks, etc. */
4959 1.1 christos free_state (sd);
4960 1.1 christos return 0;
4961 1.1 christos }
4962 1.1 christos
4963 1.1.1.3 christos /* CPU specific initialization. */
4964 1.1.1.3 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i)
4965 1.1.1.3 christos {
4966 1.1.1.3 christos SIM_CPU *cpu = STATE_CPU (sd, i);
4967 1.1.1.3 christos
4968 1.1.1.3 christos CPU_PC_FETCH (cpu) = h8300_pc_get;
4969 1.1.1.3 christos CPU_PC_STORE (cpu) = h8300_pc_set;
4970 1.1.1.3 christos }
4971 1.1.1.3 christos
4972 1.1 christos /* sim_hw_configure (sd); */
4973 1.1 christos
4974 1.1 christos /* FIXME: Much of the code in sim_load can be moved here. */
4975 1.1 christos
4976 1.1 christos sim_kind = kind;
4977 1.1 christos myname = argv[0];
4978 1.1 christos sim_callback = callback;
4979 1.1 christos return sd;
4980 1.1 christos }
4981 1.1 christos
4982 1.1 christos void
4983 1.1 christos sim_close (SIM_DESC sd, int quitting)
4984 1.1 christos {
4985 1.1 christos /* Nothing to do. */
4986 1.1 christos }
4987 1.1 christos
4988 1.1 christos /* Called by gdb to load a program into memory. */
4989 1.1 christos
4990 1.1 christos SIM_RC
4991 1.1.1.2 christos sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
4992 1.1 christos {
4993 1.1 christos bfd *prog_bfd;
4994 1.1 christos
4995 1.1 christos /* FIXME: The code below that sets a specific variant of the H8/300
4996 1.1 christos being simulated should be moved to sim_open(). */
4997 1.1 christos
4998 1.1 christos /* See if the file is for the H8/300 or H8/300H. */
4999 1.1 christos /* ??? This may not be the most efficient way. The z8k simulator
5000 1.1 christos does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */
5001 1.1 christos if (abfd != NULL)
5002 1.1 christos prog_bfd = abfd;
5003 1.1 christos else
5004 1.1 christos prog_bfd = bfd_openr (prog, NULL);
5005 1.1 christos if (prog_bfd != NULL)
5006 1.1 christos {
5007 1.1 christos /* Set the cpu type. We ignore failure from bfd_check_format
5008 1.1 christos and bfd_openr as sim_load_file checks too. */
5009 1.1 christos if (bfd_check_format (prog_bfd, bfd_object))
5010 1.1 christos {
5011 1.1 christos set_h8300h (bfd_get_mach (prog_bfd));
5012 1.1 christos }
5013 1.1 christos }
5014 1.1 christos
5015 1.1 christos /* If we're using gdb attached to the simulator, then we have to
5016 1.1 christos reallocate memory for the simulator.
5017 1.1 christos
5018 1.1 christos When gdb first starts, it calls fetch_registers (among other
5019 1.1 christos functions), which in turn calls init_pointers, which allocates
5020 1.1 christos simulator memory.
5021 1.1 christos
5022 1.1 christos The problem is when we do that, we don't know whether we're
5023 1.1 christos debugging an H8/300 or H8/300H program.
5024 1.1 christos
5025 1.1 christos This is the first point at which we can make that determination,
5026 1.1 christos so we just reallocate memory now; this will also allow us to handle
5027 1.1 christos switching between H8/300 and H8/300H programs without exiting
5028 1.1 christos gdb. */
5029 1.1 christos
5030 1.1 christos if (h8300smode && !h8300_normal_mode)
5031 1.1 christos memory_size = H8300S_MSIZE;
5032 1.1 christos else if (h8300hmode && !h8300_normal_mode)
5033 1.1 christos memory_size = H8300H_MSIZE;
5034 1.1 christos else
5035 1.1 christos memory_size = H8300_MSIZE;
5036 1.1 christos
5037 1.1 christos if (h8_get_memory_buf (sd))
5038 1.1 christos free (h8_get_memory_buf (sd));
5039 1.1 christos if (h8_get_cache_idx_buf (sd))
5040 1.1 christos free (h8_get_cache_idx_buf (sd));
5041 1.1 christos if (h8_get_eightbit_buf (sd))
5042 1.1 christos free (h8_get_eightbit_buf (sd));
5043 1.1 christos
5044 1.1 christos h8_set_memory_buf (sd, (unsigned char *)
5045 1.1 christos calloc (sizeof (char), memory_size));
5046 1.1 christos h8_set_cache_idx_buf (sd, (unsigned short *)
5047 1.1 christos calloc (sizeof (short), memory_size));
5048 1.1 christos sd->memory_size = memory_size;
5049 1.1 christos h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
5050 1.1 christos
5051 1.1 christos /* `msize' must be a power of two. */
5052 1.1 christos if ((memory_size & (memory_size - 1)) != 0)
5053 1.1 christos {
5054 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
5055 1.1 christos "sim_load: bad memory size.\n");
5056 1.1 christos return SIM_RC_FAIL;
5057 1.1 christos }
5058 1.1 christos h8_set_mask (sd, memory_size - 1);
5059 1.1 christos
5060 1.1 christos if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
5061 1.1 christos sim_kind == SIM_OPEN_DEBUG,
5062 1.1 christos 0, sim_write)
5063 1.1 christos == NULL)
5064 1.1 christos {
5065 1.1 christos /* Close the bfd if we opened it. */
5066 1.1 christos if (abfd == NULL && prog_bfd != NULL)
5067 1.1 christos bfd_close (prog_bfd);
5068 1.1 christos return SIM_RC_FAIL;
5069 1.1 christos }
5070 1.1 christos
5071 1.1 christos /* Close the bfd if we opened it. */
5072 1.1 christos if (abfd == NULL && prog_bfd != NULL)
5073 1.1 christos bfd_close (prog_bfd);
5074 1.1 christos return SIM_RC_OK;
5075 1.1 christos }
5076 1.1 christos
5077 1.1 christos SIM_RC
5078 1.1 christos sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
5079 1.1 christos {
5080 1.1 christos int i = 0;
5081 1.1 christos int len_arg = 0;
5082 1.1 christos int no_of_args = 0;
5083 1.1 christos
5084 1.1 christos if (abfd != NULL)
5085 1.1 christos h8_set_pc (sd, bfd_get_start_address (abfd));
5086 1.1 christos else
5087 1.1 christos h8_set_pc (sd, 0);
5088 1.1 christos
5089 1.1 christos /* Command Line support. */
5090 1.1 christos if (argv != NULL)
5091 1.1 christos {
5092 1.1 christos /* Counting the no. of commandline arguments. */
5093 1.1 christos for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
5094 1.1 christos continue;
5095 1.1 christos
5096 1.1 christos /* Allocating memory for the argv pointers. */
5097 1.1 christos h8_set_command_line (sd, (char **) malloc ((sizeof (char *))
5098 1.1 christos * (no_of_args + 1)));
5099 1.1 christos
5100 1.1 christos for (i = 0; i < no_of_args; i++)
5101 1.1 christos {
5102 1.1 christos /* Copying the argument string. */
5103 1.1 christos h8_set_cmdline_arg (sd, i, (char *) strdup (argv[i]));
5104 1.1 christos }
5105 1.1 christos h8_set_cmdline_arg (sd, i, NULL);
5106 1.1 christos }
5107 1.1 christos
5108 1.1 christos return SIM_RC_OK;
5109 1.1 christos }
5110