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