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