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