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