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