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